diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/ConfirmationDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/ConfirmationDialog.java index b8a2af2f7c7..a9fb207a5c6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/ConfirmationDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/ConfirmationDialog.java @@ -12,13 +12,24 @@ import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.raceboard.tagging.TagPanelResources.TagPanelStyle; /** - * Used to show generic confirmation dialog to ask user for explicit confirmation of an action. + * Used to show generic confirmation dialog to ask user for explicit confirmation of an action. Can be used to make sure + * the user wants to delete something. */ public class ConfirmationDialog extends DialogBox { private final TagPanelResources resources = TagPanelResources.INSTANCE; private final TagPanelStyle style = resources.style(); + /** + * Shows a centered dialog popup wich asks the user if the given action (text) should be confirmed. + * + * @param title + * title of dialog popup + * @param text + * question shown to user which needs confirmation + * @param consumer + * returns true if user clicks the confirm-button, otherwise false. + */ public ConfirmationDialog(StringMessages stringMessages, String title, String text, Consumer consumer) { Panel mainPanel = new FlowPanel(); mainPanel.setStyleName(style.confirmationDialogPanel()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButton.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButton.java index cbb3570acd6..f7f0a89f6e2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButton.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButton.java @@ -6,7 +6,9 @@ import com.google.gwt.user.client.ui.Button; import com.sap.sailing.gwt.ui.raceboard.tagging.TagPanelResources.TagPanelStyle; /** - * Used to store tag button data and creates new tag event when clicking the button. + * Used to store preset {@link com.sap.sailing.gwt.ui.shared.TagDTO tags} which will be rendered in {@link TaggingPanel} + * as buttons for quick and easy access. Clicking on tag-buttons does not have any effect until click listener gets + * added manually! See example at {@link TaggingPanel#addTagButton(TagButton) addTagButton()}. */ public class TagButton extends Button implements Serializable { @@ -17,8 +19,21 @@ public class TagButton extends Button implements Serializable { private String tag, imageURL, comment; private boolean visibleForPublic; - public TagButton(String buttonName, String tag, String imageURL, String comment, - boolean visibleForPublic) { + /** + * Creates tag button with given attributes. + * + * @param buttonName + * Usually equal with title + * @param tag + * title of corresponding tag + * @param imageURL + * URL to optional image of corresponding tag, may be null in case of missing image + * @param comment + * optional comment of corresponding tag, may be null in case of missing comment + * @param visibleForPublic + * should be true if everybody should see the generated tag, otherwise false + */ + protected TagButton(String buttonName, String tag, String imageURL, String comment, boolean visibleForPublic) { super(buttonName); setStyleName(style.tagDialogButton()); @@ -30,35 +45,79 @@ public class TagButton extends Button implements Serializable { addStyleName("gwt-Button"); } - public String getTag() { + /** + * Returns title of corresponding tag. + * + * @return title of tag + */ + protected String getTag() { return tag; } - public String getImageURL() { + /** + * Returns image URL of corresponding tag. + * + * @return image URL of tag + */ + protected String getImageURL() { return imageURL; } - public String getComment() { + /** + * Returns comment of corresponding tag. + * + * @return comment of tag + */ + protected String getComment() { return comment; } - public boolean isVisibleForPublic() { + /** + * Returns visibility of corresponding tag. + * + * @return true if tag is visible for public, otherwise false + */ + protected boolean isVisibleForPublic() { return visibleForPublic; } - public void setTag(String tag) { + /** + * Sets title of corresponding tag. + * + * @param tag + * title, must not be null + */ + protected void setTag(String tag) { this.tag = tag; } - public void setImageURL(String imageURL) { + /** + * Sets optional image URL of corresponding tag. + * + * @param imageURL + * image URL, may be null + */ + protected void setImageURL(String imageURL) { this.imageURL = imageURL; } - public void setComment(String comment) { + /** + * Sets optional comment of corresponding tag. + * + * @param comment + * comment, may be null + */ + protected void setComment(String comment) { this.comment = comment; } - public void setVisibleForPublic(boolean visibleForPublic) { + /** + * Sets visibility of corresponding tag. + * + * @param visibleForPublic + * should be true if tag is visible for public, otherwise false + */ + protected void setVisibleForPublic(boolean visibleForPublic) { this.visibleForPublic = visibleForPublic; } } \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonCellTableResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonCellTableResources.java index b6612eb4fc9..b90bfeff0c2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonCellTableResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonCellTableResources.java @@ -3,6 +3,9 @@ package com.sap.sailing.gwt.ui.raceboard.tagging; import com.google.gwt.core.shared.GWT; import com.google.gwt.user.cellview.client.CellTable; +/** + * Interface for styling cell table containing {@link TagButton} at {@link TagButtonDialog}. + */ public interface TagButtonCellTableResources extends CellTable.Resources { public static final TagButtonCellTableResources INSTANCE = GWT.create(TagCellListResources.class); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonDialog.java index aeff3feb556..0ebce35784b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonDialog.java @@ -25,10 +25,14 @@ import com.sap.sse.gwt.client.Notification; import com.sap.sse.gwt.client.Notification.NotificationType; /** - * Dialog for modifying tag buttons + * Dialog which allows users to modify their personal {@link TagButton tag-buttons}. */ public class TagButtonDialog extends DialogBox { + /** + * Preset layout for action column at the {@link TagButtonDialog#createTable tag button table} used in the + * {@link TagButtonDialog}. + */ private class EditTagButtonsImagesBarCell extends ImagesBarCell { public static final String ACTION_REMOVE = "ACTION_REMOVE"; public static final String ACTION_EDIT = "ACTION_EDIT"; @@ -57,6 +61,14 @@ public class TagButtonDialog extends DialogBox { private Button closeButton, saveButton, cancelButton, addTagButtonButton; private TagButton selectedTagButton; + /** + * Centered dialog wich allows users to edit their personal {@link TagButton tag-buttons}. + * + * @param taggingPanel + * {@link TaggingPanel} which creates this {@link TagButtonDialog}. + * @param footerPanel + * footer panel of {@link TaggingPanel} + */ public TagButtonDialog(TaggingPanel taggingPanel, TagFooterPanel footerPanel) { this.taggingPanel = taggingPanel; this.stringMessages = taggingPanel.getStringMessages(); @@ -87,6 +99,18 @@ public class TagButtonDialog extends DialogBox { center(); } + /** + * Creates table which shows tag buttons as a compact overview in form of a table. + * + * @param footerPanel + * footer panel of {@link TaggingPanel} + * @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 + * @return {@link com.google.gwt.user.cellview.client.CellTable CellTable} containing {@link TagButton tag-buttons} + */ private CellTable createTable(TagFooterPanel footerPanel, TagInputPanel inputPanel, TagPreviewPanel tagPreviewPanel) { CellTable tagButtonTable = new CellTable(15, buttonTableResources); @@ -175,6 +199,22 @@ public class TagButtonDialog extends DialogBox { return tagButtonTable; } + /** + * Creates a {@link Panel} containing all action buttons of the {@link TagButtonDialog} to create {@link TagButton + * tag-buttons}, save changes, discard changes and 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 + * @param footerPanel + * footer panel of {@link TaggingPanel} + * @return {@link Panel} containing all action buttons + */ private Panel createButtonPanel(CellTable tagButtonTable, TagInputPanel inputPanel, TagPreviewPanel tagPreviewPanel, TagFooterPanel footerPanel) { addSaveButton(footerPanel, tagButtonTable, inputPanel, tagPreviewPanel); @@ -192,6 +232,20 @@ public class TagButtonDialog extends DialogBox { 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 tagButtonTable, TagInputPanel inputPanel, TagPreviewPanel tagPreviewPanel) { saveButton = new Button(stringMessages.save()); @@ -223,6 +277,18 @@ public class TagButtonDialog extends DialogBox { }); } + /** + * 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 tagButtonTable) { cancelButton = new Button(stringMessages.cancel()); @@ -242,6 +308,18 @@ public class TagButtonDialog extends DialogBox { }); } + /** + * 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()); @@ -249,6 +327,20 @@ public class TagButtonDialog extends DialogBox { 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 tagButtonTable, TagInputPanel inputPanel, TagPreviewPanel tagPreviewPanel) { addTagButtonButton = new Button(stringMessages.tagAddCustomTagButton()); @@ -271,6 +363,17 @@ public class TagButtonDialog extends DialogBox { }); } + /** + * Sets the given buttons as value for the given tagButtonTable. If buttons + * is empty, tagButtonTable will be hidden. + * + * @param tagButtonTable + * {@link com.google.gwt.user.cellview.client.CellTable CellTable} containing {@link TagButton + * tag-buttons} + * @param buttons + * List of {@link TagButton tag-buttons} which represents the local version of the current users + * {@link TagButton tag-buttons}. + */ private void setRowData(CellTable tagButtonTable, List buttons) { tagButtonTable.setRowData(buttons); tagButtonTable.setVisible(!buttons.isEmpty()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonJsonDeSerializer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonJsonDeSerializer.java index beafdfbfe1c..97409158ca3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonJsonDeSerializer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonJsonDeSerializer.java @@ -10,7 +10,8 @@ import com.google.gwt.json.client.JSONString; import com.sap.sailing.gwt.ui.client.GwtJsonDeSerializer; /** - * Serializes and deserializes TagButtons to save them in User Storage. + * Serializes and deserializes {@link TagButton tag-buttons} to save them in the {@link com.sap.sse.security.UserStore + * UserStore}. */ public class TagButtonJsonDeSerializer implements GwtJsonDeSerializer> { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonPanel.java index b0de1178919..a1775b64288 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagButtonPanel.java @@ -14,7 +14,7 @@ import com.sap.sse.gwt.client.Notification.NotificationType; import com.sap.sse.security.ui.client.UserService; /** - * Displays tag buttons of current user. + * Panel used to show the {@link TagButton tag-buttons} of {@link UserService#getCurrentUser() current user}. */ public class TagButtonPanel extends FlowPanel { @@ -30,7 +30,11 @@ public class TagButtonPanel extends FlowPanel { private final Label heading; private final Panel tagButtonsPanel; - public TagButtonPanel(TagFooterPanel footerPanel, TaggingPanel taggingPanel) { + /** + * Displays {@link TagButton tag-buttons} of {@link UserService#getCurrentUser() current user} at the footer of the + * {@link TaggingPanel}. + */ + protected TagButtonPanel(TaggingPanel taggingPanel, TagFooterPanel footerPanel) { this.footerPanel = footerPanel; this.taggingPanel = taggingPanel; this.stringMessages = taggingPanel.getStringMessages(); @@ -47,25 +51,8 @@ public class TagButtonPanel extends FlowPanel { } /** - * Stores local copy of tag buttons from current user in user storage. - */ - protected void storeAllTagButtons() { - TagButtonJsonDeSerializer serializer = new TagButtonJsonDeSerializer(); - JSONObject jsonObject = serializer.serialize(taggingPanel.getTagButtons()); - userService.setPreference(USER_STORAGE_TAG_BUTTONS_KEY, jsonObject.toString(), new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - Notification.notify(stringMessages.tagButtonNotSavable(), NotificationType.WARNING); - } - - @Override - public void onSuccess(Void result) { - } - }); - } - - /** - * Loads all tag buttons from current user from user storage and displays them. + * Loads all {@link TagButton tag-buttons} of {@link UserService#getCurrentUser() current user} from + * {@link com.sap.sse.security.UserStore UserStore} and displays them. */ protected void loadAllTagButtons() { tagButtonsPanel.clear(); @@ -100,9 +87,31 @@ public class TagButtonPanel extends FlowPanel { } /** - * If the height of the tagButtonsPanel has changed after deleting all tag buttons (delta not equals 0 ), the - * footerWidget of the TaggingPanel has a different height, which in this case might cause the contentWidget to be - * to small. In case no tag buttons are available for the current user, tag button panel will be hidden. + * Stores {@link TaggingPanel#getTagButtons() local copy} of {@link TagButton tag-buttons} of the + * {@link UserService#getCurrentUser() current user} in {@link com.sap.sse.security.UserStore UserStore}. + */ + protected void storeAllTagButtons() { + TagButtonJsonDeSerializer serializer = new TagButtonJsonDeSerializer(); + JSONObject jsonObject = serializer.serialize(taggingPanel.getTagButtons()); + userService.setPreference(USER_STORAGE_TAG_BUTTONS_KEY, jsonObject.toString(), new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + Notification.notify(stringMessages.tagButtonNotSavable(), NotificationType.WARNING); + } + + @Override + public void onSuccess(Void result) { + } + }); + } + + /** + * If the height of the {@link #tagButtonsPanel} has changed after deleting all {@link TagButton tag-buttons} (delta + * height does not equal 0), the {@link TaggingPanel}s + * {@link com.google.gwt.user.client.ui.HeaderPanel#getFooterWidget() footer widget} has a different height, which + * in this case might cause the {@link TaggingPanel#contentPanel contentWidget} to be to small. In case no + * {@link TagButton tag-buttons} are available for the {@link UserService#getCurrentUser() current user}, + * {@link TagButtonPanel} will be hidden. */ protected void recalculateHeight() { if (taggingPanel.getTagButtons().size() == 0) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCell.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCell.java index 225c268cb40..77ebf9881ac 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCell.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCell.java @@ -23,30 +23,108 @@ import com.sap.sse.security.ui.client.UserService; */ public class TagCell extends AbstractCell { - public interface TagCellTemplate extends SafeHtmlTemplates { + /** + * Contains different configurations for {@link TagCell}s. Used as {@link SafeHtmlTemplates template} for + * {@link TagCell}s.
+ *
+ * Notice: CSS classes need to be provied as parameters as CSS classnames are context sensitive and can't be + * hardcoded. + */ + protected interface TagCellTemplate extends SafeHtmlTemplates { + /** + * Renders public, non-removable cell with different content configurations + * + * @param tag + * title + * @param createdAt + * contains author name and createdAt time + * @param content + * available configurations are {@link #contentWithCommentWithImage}, + * {@link #contentWithCommentWithoutImage} and {@link #contentWithoutCommentWithImage}. + * @return {@link SafeHtml HTML template} + */ @Template("
{3}
{4}
{5}
") SafeHtml cell(String styleTag, String styleTagHeading, String styleTagCreated, SafeHtml tag, SafeHtml createdAt, SafeHtml content); + /** + * Renders public, removable cell with different content configurations + * + * @param tag + * title + * @param createdAt + * contains author name and createdAt time + * @param content + * available configurations are {@link #contentWithCommentWithImage}, + * {@link #contentWithCommentWithoutImage} and {@link #contentWithoutCommentWithImage}. + * @return {@link SafeHtml HTML template} + */ @Template("
{3}
{4}
{5}
") SafeHtml cellRemovable(String styleTag, String styleTagHeading, String styleTagCreated, SafeHtml tag, SafeHtml createdAt, SafeHtml content); + /** + * Renders private, non-removable cell with different content configurations + * + * @param tag + * title + * @param createdAt + * contains author name and createdAt time + * @param content + * available configurations are {@link #contentWithCommentWithImage}, + * {@link #contentWithCommentWithoutImage} and {@link #contentWithoutCommentWithImage}. + * @return {@link SafeHtml HTML template} + */ @Template("
{3}
{4}
{5}
") SafeHtml privateCell(String styleTag, String styleTagHeading, String styleTagCreated, SafeHtml tag, SafeHtml createdAt, SafeHtml content, SafeUri safeUri); + /** + * Renders private, removable cell with different content configurations + * + * @param tag + * title + * @param createdAt + * contains author name and createdAt time + * @param content + * available configurations are {@link #contentWithCommentWithImage}, + * {@link #contentWithCommentWithoutImage} and {@link #contentWithoutCommentWithImage}. + * @return {@link SafeHtml HTML template} + */ @Template("
{3}
{4}
{5}
") SafeHtml privateCellRemovable(String styleTag, String styleTagHeading, String styleTagCreated, SafeHtml tag, SafeHtml createdAt, SafeHtml content, SafeUri safeUri); + /** + * Renders content with maximal configuration (comment and image). + * + * @param imageURL + * image URL + * @param comment + * comment + * @return {@link SafeHtml HTML template} + */ @Template("
{3}
") SafeHtml contentWithCommentWithImage(String styleTagImage, String styleTagComment, SafeUri imageURL, SafeHtml comment); + /** + * Renders content with mixed configuration (comment, no image). + * + * @param comment + * comment + * @return {@link SafeHtml HTML template} + */ @Template("
{1}
") SafeHtml contentWithCommentWithoutImage(String styleTagComment, SafeHtml comment); + /** + * Renders content with mixed configuration (image, no comment). + * + * @param imageURL + * image URL + * @return {@link SafeHtml HTML template} + */ @Template("
") SafeHtml contentWithoutCommentWithImage(String styleTagImage, SafeUri imageURL); } @@ -60,6 +138,15 @@ public class TagCell extends AbstractCell { private final UserService userService; private final boolean isPreviewCell; + /** + * Displays the content of a {@link TagDTO tag} by using {@link SafeHtmlTemplates}. + * + * @param taggingPanel + * instance of {@link TaggingPanel} + * @param isPreviewCell + * should be true if {@link TagCell cell} is used as {@link TagPreviewPanel preview cell}, + * otherwise false + */ public TagCell(TaggingPanel taggingPanel, boolean isPreviewCell) { super("click"); this.taggingPanel = taggingPanel; @@ -68,6 +155,10 @@ public class TagCell extends AbstractCell { this.isPreviewCell = isPreviewCell; } + /** + * Renders {@link TagDTO tag} and appends it to given {@link SafeHtmlBuilder html builder}. Checks tag for available + * attributes and chooses suitable {@link TagCellTemplate rendering template}. + */ @Override public void render(Context context, TagDTO tag, SafeHtmlBuilder htmlBuilder) { if (tag == null) { @@ -121,6 +212,12 @@ public class TagCell extends AbstractCell { htmlBuilder.append(cell); } + /** + * Asks user for confirmation if user presses the delete button on the {@link TagCell}. If user confirms deletion, + * {@link TagDTO tag} will be deleted from {@link TaggingPanel} including + * {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog} or {@link com.sap.sse.security.UserStore + * UserStore}, depending on where the tag is saved. + */ @Override public void onBrowserEvent(Context context, Element parent, TagDTO tag, NativeEvent event, ValueUpdater valueUpdater) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCellListResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCellListResources.java index 7d7b4e49ac8..be9740306f3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCellListResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCellListResources.java @@ -3,6 +3,10 @@ package com.sap.sailing.gwt.ui.raceboard.tagging; import com.google.gwt.core.shared.GWT; import com.google.gwt.user.cellview.client.CellList; +/** + * Interface for styling {@link TaggingPanel#tagCellList cell list} containing {@link TagCell} at + * {@link TaggingPanel#contentPanel TaggingPanel}. + */ public interface TagCellListResources extends CellList.Resources { public static final TagCellListResources INSTANCE = GWT.create(TagCellListResources.class); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCreationPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCreationPanel.java index a3873ddea64..2f20ac70806 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCreationPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagCreationPanel.java @@ -9,7 +9,8 @@ import com.sap.sailing.gwt.ui.raceboard.tagging.TagPanelResources.TagPanelStyle; import com.sap.sailing.gwt.ui.raceboard.tagging.TaggingPanel.State; /** - * Panel used to create tags and tag buttons in side menu of RaceBoard. + * Panel used to create tags and {@link TagButton tag-buttons} at the {@link TaggingPanel#footerPanel footer} of the + * {@link TaggingPanel}. */ public class TagCreationPanel extends FlowPanel { @@ -17,7 +18,15 @@ public class TagCreationPanel extends FlowPanel { private final StringMessages stringMessages; - public TagCreationPanel(TagFooterPanel tagFooterPanel, TaggingPanel taggingPanel) { + /** + * Creates panel used to create tags and {@link TagButton tag-buttons}. + * + * @param taggingPanel + * provides reference to {@link StringMessages} + * @param tagFooterPanel + * required for creation of {@link TagButton tag-buttons} + */ + protected TagCreationPanel(TaggingPanel taggingPanel, TagFooterPanel tagFooterPanel) { this.stringMessages = taggingPanel.getStringMessages(); setStyleName(style.tagCreationPanel()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagDTOJsonDeSerializer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagDTOJsonDeSerializer.java index a63caed10b6..de468875da1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagDTOJsonDeSerializer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagDTOJsonDeSerializer.java @@ -12,7 +12,7 @@ import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; /** - * Serializes and deserializes TagDTOs. + * Serializes and deserializes {@link TagDTO}. */ public class TagDTOJsonDeSerializer { @@ -26,6 +26,13 @@ public class TagDTOJsonDeSerializer { private static final String FIELD_CREATED_AT = "createdAt"; private static final String FIELD_REVOKED_AT = "revokedAt"; + /** + * Serializes list of {@link TagDTO tags} to {@link JSONObject json}. + * + * @param tags + * list to be seriaized + * @return {@link JSONObject json object} + */ public JSONObject serialize(List tags) { JSONObject result = new JSONObject(); @@ -41,18 +48,25 @@ public class TagDTOJsonDeSerializer { tagObject.put(FIELD_IMAGE_URL, new JSONString(tag.getImageURL())); tagObject.put(FIELD_USERNAME, new JSONString(tag.getUsername())); tagObject.put(FIELD_VISIBLE_FOR_PUBLIC, JSONBoolean.getInstance(tag.isVisibleForPublic())); - tagObject.put(FIELD_RACE_TIMEPOINT, timePointToString(tag.getRaceTimepoint())); - tagObject.put(FIELD_CREATED_AT, timePointToString(tag.getCreatedAt())); - tagObject.put(FIELD_REVOKED_AT, timePointToString(tag.getRevokedAt())); + tagObject.put(FIELD_RACE_TIMEPOINT, serializeTimePoint(tag.getRaceTimepoint())); + tagObject.put(FIELD_CREATED_AT, serializeTimePoint(tag.getCreatedAt())); + tagObject.put(FIELD_REVOKED_AT, serializeTimePoint(tag.getRevokedAt())); } return result; } - public List deserialize(JSONObject rootObject) { + /** + * Deserializes {@link JSONObject json} to list of {@link TagDTO tags}. + * + * @param jsonObject + * {@link JSONObject json} to be deserialized + * @return {@link TagDTO list of tags} + */ + public List deserialize(JSONObject jsonObject) { List result = null; - if (rootObject != null) { + if (jsonObject != null) { result = new ArrayList(); - JSONArray tagsArray = (JSONArray) rootObject.get(FIELD_TAGS); + JSONArray tagsArray = (JSONArray) jsonObject.get(FIELD_TAGS); for (int i = 0; i < tagsArray.size(); i++) { JSONObject tagValue = (JSONObject) tagsArray.get(i); JSONString tag = (JSONString) tagValue.get(FIELD_TAG); @@ -75,7 +89,14 @@ public class TagDTOJsonDeSerializer { return result; } - private JSONString timePointToString(TimePoint timepoint) { + /** + * Serializes given {@link TimePoint} to {@link JSONString json}. + * + * @param timepoint + * {@link TimePoint} to be serialized + * @return {@link JSONString json} + */ + private JSONString serializeTimePoint(TimePoint timepoint) { if (timepoint != null) { return new JSONString(Long.toString(timepoint.asMillis())); } else { @@ -83,6 +104,13 @@ public class TagDTOJsonDeSerializer { } } + /** + * Deserializes {@link String timepoint-string} to {@link TimePoint}. + * + * @param timepoint + * {@link String timepoint} to be deserialized + * @return {@link TimePoint} + */ private TimePoint deserilizeTimePoint(String timepoint) { if (!timepoint.isEmpty()) { return new MillisecondsTimePoint(Long.parseLong(timepoint)); @@ -91,11 +119,35 @@ public class TagDTOJsonDeSerializer { } } - public String createIdenticalKeyFromThreeStrings(String racecolumn, String fleet, String leaderboard) { + /** + * Combines leaderboard, racecolumn and fleet to a unique key. Used to store + * private tags in {@link com.sap.sse.security.UserStore UserStore}. + * + * @param leaderboard + * leaderboard name + * @param racecolumn + * race column name + * @param fleet + * fleet name + * @return unique key for given race + */ + public String createIdenticalKeyFromThreeStrings(String leaderboard, String racecolumn, String fleet) { return "Private tags:" + escape(racecolumn) + "+" + escape(fleet) + "+" + escape(leaderboard); } + /** + * Escapes given string by replacing every occurence of '/' by '//' and '+' by '/p'. + * + * @param string + * string to be escaped + * @return escaped string + */ private String escape(String string) { + // '+' needs to be escaped as method replaceAll() expects the first parameter to be a regular expression and not + // a + // simple string. As '+' has a different meaning in context of a regex it needs to be escaped by '\+' which + // again + // needs to be escaped by '\\+'. return string.replaceAll("/", "//").replaceAll("\\+", "/p"); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterLabel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterLabel.java index 787e372dd20..e79eba47597 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterLabel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterLabel.java @@ -8,7 +8,8 @@ import com.sap.sse.common.filter.Filter; import com.sap.sse.common.filter.FilterSet; /** - * Shows current selected filter. + * Shows current selected filter used at {@link TagFilterPanel}. Observes {@link TagListProvider} for changes of the + * selected filter. */ public class TagFilterLabel extends Label { @@ -17,6 +18,12 @@ public class TagFilterLabel extends Label { private final TaggingPanel taggingPanel; private final StringMessages stringMessages; + /** + * Creates {@link Label} and adds it as observer at the {@link TagListProvider}. + * + * @param taggingPanel + * provides reference to {@link TagListProvider} and {@link StringMessages}. + */ public TagFilterLabel(TaggingPanel taggingPanel) { this.taggingPanel = taggingPanel; this.stringMessages = taggingPanel.getStringMessages(); @@ -26,9 +33,16 @@ public class TagFilterLabel extends Label { taggingPanel.getTagListProvider().addObserveringLabel(this); } - public void update(FilterSet> tagsFilterSet) { - if (tagsFilterSet != null && !tagsFilterSet.getName().isEmpty()) { - setText(stringMessages.tagCurrentFilter() + " " + tagsFilterSet.getName()); + /** + * Updates label text to match given tagFilterSet. Hides label if no filter is applied, otherwise label + * is shown. + * + * @param tagFilterSet + * current selected filter + */ + public void update(FilterSet> tagFilterSet) { + if (tagFilterSet != null && !tagFilterSet.getName().isEmpty()) { + setText(stringMessages.tagCurrentFilter() + " " + tagFilterSet.getName()); removeStyleName(style.hidden()); } else { setText(""); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterPanel.java index 02d521c4980..9a70d463da8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFilterPanel.java @@ -54,7 +54,13 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit private FilterSet> lastActiveTagFilterSet; private final TagFilterLabel currentFilter; - public TagFilterPanel(TaggingPanel taggingPanel) { + /** + * Creates panel which allows filtering of tags and shows current selected filter. + * + * @param taggingPanel + * provides reference to {@link StringMessages}, {@link UserService} and {@link TagListProvider}. + */ + protected TagFilterPanel(TaggingPanel taggingPanel) { this.taggingPanel = taggingPanel; this.stringMessages = taggingPanel.getStringMessages(); this.userService = taggingPanel.getUserSerivce(); @@ -80,6 +86,9 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit initializeUI(); } + /** + * Initializes UI. + */ private void initializeUI() { setStyleName(style.tagFilterPanel()); @@ -122,9 +131,16 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit add(currentFilter); } + /** + * Opens up filter dialog to configure filters. + */ private void showFilterDialog() { TagFilterSetsDialog tagsFilterSetsDialog = new TagFilterSetsDialog(tagFilterSets, stringMessages, new DialogCallback() { + @Override + public void cancel() { + } + @Override public void ok(final TagFilterSets newTagFilterSets) { tagFilterSets.getFilterSets().clear(); @@ -141,18 +157,14 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit } taggingPanel.updateContent(); } - - @Override - public void cancel() { - } }, userService); tagsFilterSetsDialog.show(); } /** - * Updates the tags filter checkbox state by setting its check mark and updating its label according to the current - * filter selected + * Updates the {@link #filterSettingsButton tag filter checkbox} state by setting its check mark and updating its + * title according to the {@link #lastActiveTagFilterSet current selected filter}. */ private void updateTagFilterControlState(TagFilterSets filterSets) { String tagsFilterTitle = stringMessages.tagsFilter(); @@ -178,8 +190,8 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit } } - /* - * loads users Tag Filter Sets from server and stores it into tagFilterSets + /** + * Loads the users {@link TagFilterSets} from {@link UserService} and saves it into {@link #tagFilterSets}. */ protected void loadTagFilterSets() { if (userService.getCurrentUser() != null) { @@ -213,6 +225,12 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit } } + /** + * Stores newTagsFilterSets via {@link UserService}. + * + * @param newTagsFilterSets + * filter sets to be stored + */ private void storeTagFilterSets(TagFilterSets newTagsFilterSets) { TagFilterSetsJsonDeSerializer serializer = new TagFilterSetsJsonDeSerializer(); JSONObject jsonObject = serializer.serialize(newTagsFilterSets); @@ -228,12 +246,18 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit }); } + /** + * Clears searchbox and removes key-up-listener. + */ private void clearSelection() { searchTextBox.setText(""); clearTextBoxButton.addStyleName(style.tagFilterHiddenButton()); onKeyUp(null); } + /** + * Adds {@link TagFilterPanel} to applied filters at {@link TagListProvider} to apply searchbox filter. + */ private void ensureSetSearchFilter() { if (tagListProvider.getTagFilterSet() == null || !Util.contains(tagListProvider.getTagFilterSet().getFilters(), this)) { @@ -248,6 +272,9 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit } } + /** + * Removes {@link TagFilterPanel} from applied filters at {@link TagListProvider} to remove searchbox filter. + */ private void removeSearchFilter() { if (tagListProvider.getTagFilterSet() != null && Util.contains(tagListProvider.getTagFilterSet().getFilters(), this)) { @@ -262,6 +289,13 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit } } + /** + * Checks if given tag matches the current filter. + * + * @param tag + * tag to be compared to + * @return true if tag matches filter, otherwise false + */ @Override public boolean matches(TagDTO tag) { final Iterable lowercaseKeywords = Util @@ -300,6 +334,8 @@ public class TagFilterPanel extends FlowPanel implements KeyUpHandler, FilterWit } /** + * Applies filter entered by using search textbox to filterset. + * * @param event * ignored; may be null */ diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFooterPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFooterPanel.java index f03904d3aff..c37375e1cab 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFooterPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagFooterPanel.java @@ -3,7 +3,8 @@ package com.sap.sailing.gwt.ui.raceboard.tagging; import com.google.gwt.user.client.ui.FlowPanel; /** - * Panel containg TagCreationPanel and TagButtonPanel which is used as footer in TaggingPanel. + * Panel containg {@link TagCreationPanel} and {@link TagButtonPanel} which is used as {@link TaggingPanel#footerPanel + * footer} in {@link TaggingPanel}. */ public class TagFooterPanel extends FlowPanel { @@ -12,13 +13,20 @@ public class TagFooterPanel extends FlowPanel { private final TagCreationPanel tagCreationPanel; private final TagButtonPanel tagButtonPanel; - public TagFooterPanel(TaggingPanel taggingPanel) { + /** + * Creates footer panel and loads {@link TagButton tag-buttons} from {@link com.sap.sse.security.UserStore + * UserStore}. + * + * @param taggingPanel + * required to instantiate {@link TagCreationPanel} and {@link TagButtonPanel} + */ + protected TagFooterPanel(TaggingPanel taggingPanel) { this.taggingPanel = taggingPanel; - tagCreationPanel = new TagCreationPanel(this, taggingPanel); - tagButtonPanel = new TagButtonPanel(this, taggingPanel); + tagCreationPanel = new TagCreationPanel(taggingPanel, this); + tagButtonPanel = new TagButtonPanel(taggingPanel, this); - // Tag buttons are only shown if amount of tag buttons is greater then 0! + // Tag-buttons are only shown if amount of tag-buttons is greater then 0! setTagButtonsVisibility(true); // input fields are hidden by default @@ -28,11 +36,13 @@ public class TagFooterPanel extends FlowPanel { } /** - * Sets visibility of input fields for new tag and "Edit Tag-Buttons"-button. Input fields will not be hidden but - * removed completly from DOM in case parameter visible is set to false! + * Sets visibility of {@link TagCreationPanel input fields} for new tag and {@link TaggingPanel#createTagsButton + * "Edit Tag-Buttons"-button}. {@link TagCreationPanel Input fields} will not be hidden but removed completly from + * DOM in case visible is set to false! * * @param visible - * should be true when user is logged in and tagging panel is in EDIT-mode, otherwise false + * should be true when user is logged in and {@link TaggingPanel} is in + * {@link TaggingPanel#currentState EDIT-mode}, otherwise false */ protected void setInputFieldsVisibility(boolean visible) { if (visible) { @@ -45,10 +55,11 @@ public class TagFooterPanel extends FlowPanel { } /** - * Sets visibility of tag buttons. Tag buttons panel will only be shown if amount of tag buttons is greater then 0! + * Sets visibility of {@link TagButtonPanel tagButtonPanel}. {@link TagButtonPanel tagButtonPanel} will only be + * shown if amount of {@link TaggingPanel#getTagButtons() tag-buttons} is greater then 0! * * @param visible - * should be true when user is logged in, otherwise false + * should be true when user is logged in, otherwise false */ protected void setTagButtonsVisibility(boolean visible) { if (taggingPanel.getTagButtons().size() > 0) { @@ -61,22 +72,23 @@ public class TagFooterPanel extends FlowPanel { } /** - * If the height of the tagButtonPanel has changed after deleting (delta not equals 0 ), the footerWidget of the - * TaggingPanel has a different height, which in this case might cause the contentWidget to be to small. + * If height of the {@link TagButtonPanel tagButtonPanel} has changed after deleting (delta height does not equal + * 0), the {@link TaggingPanel#footerPanel footer widget} of the {@link TaggingPanel} has a different height, which + * in this case might cause the {@link TaggingPanel#contentPanel content widget} to be to small. */ protected void recalculateHeight() { tagButtonPanel.recalculateHeight(); } /** - * Loads all tag buttons from user storage and displays them. + * Loads all {@link TagButton tag-buttons} from {@link com.sap.sse.security.UserStore UserStore} and displays them. */ protected void loadAllTagButtons() { tagButtonPanel.loadAllTagButtons(); } /** - * Stores all tag buttons into user storage. + * Stores all {@link TagButton tag-buttons} into {@link com.sap.sse.security.UserStore UserStore}. */ protected void storeAllTagButtons() { tagButtonPanel.storeAllTagButtons(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagInputPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagInputPanel.java index d0ed99bf6b9..62fe256326e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagInputPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagInputPanel.java @@ -23,7 +23,10 @@ public class TagInputPanel extends FlowPanel { private final TextArea commentTextArea; private final CheckBox visibleForPublicCheckBox; - public TagInputPanel(StringMessages stringMessages) { + /** + * Creates view allowing users to input values for tags and {@link TagButton tag-buttons}. + */ + protected TagInputPanel(StringMessages stringMessages) { setStyleName(style.tagInputPanel()); tagTextBox = new TextBox(); @@ -56,58 +59,61 @@ public class TagInputPanel extends FlowPanel { add(checkboxWrapper); } - public TextBox getTagTextBox() { - return tagTextBox; - } - - public TextBox getImageURLTextBox() { - return imageURLTextBox; - } - - public TextArea getCommentTextArea() { - return commentTextArea; - } - - public CheckBox getVisibleForPublicCheckBox() { - return visibleForPublicCheckBox; - } - - public String getTag() { - return tagTextBox.getValue(); - } - - public String getComment() { - return commentTextArea.getValue(); - } - - public String getImageURL() { - return imageURLTextBox.getValue(); - } - - public boolean isVisibleForPublic() { - return visibleForPublicCheckBox.getValue(); - } - - public void setTag(String tag) { - tagTextBox.setValue(tag); - } - - public void setComment(String comment) { - commentTextArea.setValue(comment); - } - - public void setImageURL(String imageURL) { - imageURLTextBox.setValue(imageURL); - } - - public void setVisibleForPublic(boolean visibleForPublic) { - visibleForPublicCheckBox.setValue(visibleForPublic); - } - - public void clearAllValues() { + /** + * Clears all input fields. + */ + protected void clearAllValues() { tagTextBox.setText(""); imageURLTextBox.setText(""); commentTextArea.setText(""); setVisibleForPublic(DEFAULT_VISIBLE_FOR_PUBLIC); } + + protected String getTag() { + return tagTextBox.getValue(); + } + + protected String getComment() { + return commentTextArea.getValue(); + } + + protected String getImageURL() { + return imageURLTextBox.getValue(); + } + + protected boolean isVisibleForPublic() { + return visibleForPublicCheckBox.getValue(); + } + + protected void setTag(String tag) { + tagTextBox.setValue(tag); + } + + protected void setComment(String comment) { + commentTextArea.setValue(comment); + } + + protected void setImageURL(String imageURL) { + imageURLTextBox.setValue(imageURL); + } + + protected void setVisibleForPublic(boolean visibleForPublic) { + visibleForPublicCheckBox.setValue(visibleForPublic); + } + + protected TextBox getTagTextBox() { + return tagTextBox; + } + + protected TextBox getImageURLTextBox() { + return imageURLTextBox; + } + + protected TextArea getCommentTextArea() { + return commentTextArea; + } + + protected CheckBox getVisibleForPublicCheckBox() { + return visibleForPublicCheckBox; + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagListProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagListProvider.java index 90a4b5059d1..123f14ad440 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagListProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagListProvider.java @@ -7,12 +7,12 @@ import java.util.List; import com.google.gwt.view.client.ListDataProvider; import com.sap.sailing.gwt.ui.shared.TagDTO; -import com.sap.sse.common.Util; import com.sap.sse.common.filter.Filter; import com.sap.sse.common.filter.FilterSet; /** - * Used to store tags and filter sets and to apply these filters on the tags + * Provides list of {@link TagDTO tags} and is able to filter theses {@link TagDTO tags} with the current selected + * {@link FilterSet}. */ public class TagListProvider extends ListDataProvider { @@ -20,26 +20,45 @@ public class TagListProvider extends ListDataProvider { private FilterSet> currentFilterSet; private TagFilterLabel observingLabel; - public TagListProvider() { + /** + * Creates instance without tags or filters. + */ + protected TagListProvider() { allTags = new ArrayList(); } - public void addObserveringLabel(TagFilterLabel tagFilterLabel) { + /** + * Used by {@link TagFilterLabel} to inform {@link TagFilterLabel} about changes of the {@link #currentFilterSet + * current filter set}. + * + * @param tagFilterLabel + */ + protected void addObserveringLabel(TagFilterLabel tagFilterLabel) { observingLabel = tagFilterLabel; } - public List getAllTags() { + /** + * Returns list of all {@link TagDTO tags} ignoring the {@link #currentFilterSet current filter set}. + * + * @return list of all {@link TagDTO tags} + */ + protected List getAllTags() { return allTags; } - public List getFilteredTags() { + /** + * Returns list of all {@link TagDTO tags} which are filtered by {@link #currentFilterSet current filter set}. + * + * @return list of filtered {@link TagDTO tags} + */ + protected List getFilteredTags() { return getList(); } /** - * filter all tags by tagsFilterSet + * Updates {@link #getList() list} of filtered {@link TagDTO tags} by applying {@link #currentFilterSet}. */ - public void updateFilteredTags() { + protected void updateFilteredTags() { List currentFilteredList = new ArrayList(getAllTags()); if (currentFilterSet != null) { for (Filter filter : currentFilterSet.getFilters()) { @@ -63,20 +82,27 @@ public class TagListProvider extends ListDataProvider { setList(currentFilteredList); } - public FilterSet> getTagFilterSet() { + /** + * Returns {@link #currentFilterSet current filter set}. + * + * @return current selected filter set + */ + protected FilterSet> getTagFilterSet() { return currentFilterSet; } - public void setCurrentFilterSet(FilterSet> tagsFilterSet) { - currentFilterSet = tagsFilterSet; + /** + * Sets {@link #currentFilterSet current selected filter set} to given tagFilterSet. + * + * @param tagFilterSet + * selected filter set + */ + protected void setCurrentFilterSet(FilterSet> tagFilterSet) { + currentFilterSet = tagFilterSet; if (observingLabel != null) { - observingLabel.update(tagsFilterSet); + observingLabel.update(tagFilterSet); } updateFilteredTags(); refresh(); } - - public int getFilteredTagsListSize() { - return Util.size(getFilteredTags()); - } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPanelResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPanelResources.java index af314b3f69c..c028d6e02bb 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPanelResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPanelResources.java @@ -5,10 +5,12 @@ import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; import com.google.gwt.resources.client.ImageResource; +/** + * Interface for styling {@link TaggingPanel} and its content. + */ public interface TagPanelResources extends ClientBundle { public static final TagPanelResources INSTANCE = GWT.create(TagPanelResources.class); - // TODO image is stored in wrong folder @Source("com/sap/sailing/gwt/ui/client/images/edit.png") ImageResource editIcon(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPreviewPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPreviewPanel.java index 6989bdbfef7..a173d943a79 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPreviewPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TagPreviewPanel.java @@ -3,8 +3,6 @@ package com.sap.sailing.gwt.ui.raceboard.tagging; import java.util.ArrayList; import java.util.List; -import com.google.gwt.event.logical.shared.ValueChangeEvent; -import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.cellview.client.CellList; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Label; @@ -14,7 +12,7 @@ import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.security.ui.client.UserService; /** - * Panel used to preview a tag. + * Panel showing {@link TagCell} as preview used at {@link TagButtonDialog}. */ public class TagPreviewPanel extends FlowPanel { @@ -27,7 +25,16 @@ public class TagPreviewPanel extends FlowPanel { private final CellList tagPreviewCellList; private List listContainingPreviewTag; - public TagPreviewPanel(TaggingPanel taggingPanel, TagInputPanel inputPanel) { + /** + * Creates panel showing preview of tag when creating a {@link TagButton}. Adds change listener on input fields to + * be able to rerender the {@link TagCell preview cell} whenever user changes values of the input fields. + * + * @param taggingPanel + * references {@link UserService} + * @param inputPanel + * references input fields used to get current user input + */ + protected TagPreviewPanel(TaggingPanel taggingPanel, TagInputPanel inputPanel) { this.taggingPanel = taggingPanel; this.userService = taggingPanel.getUserSerivce(); @@ -39,37 +46,28 @@ public class TagPreviewPanel extends FlowPanel { add(new Label(taggingPanel.getStringMessages().tagPreview())); add(tagPreviewCellList); - inputPanel.getTagTextBox().addValueChangeHandler(new ValueChangeHandler() { - @Override - public void onValueChange(ValueChangeEvent event) { - renderPreview(inputPanel); - } - + inputPanel.getTagTextBox().addValueChangeHandler(event -> { + renderPreview(inputPanel); }); - inputPanel.getImageURLTextBox().addValueChangeHandler(new ValueChangeHandler() { - @Override - public void onValueChange(ValueChangeEvent event) { - renderPreview(inputPanel); - } - + inputPanel.getImageURLTextBox().addValueChangeHandler(event -> { + renderPreview(inputPanel); }); - inputPanel.getCommentTextArea().addValueChangeHandler(new ValueChangeHandler() { - @Override - public void onValueChange(ValueChangeEvent event) { - renderPreview(inputPanel); - } - + inputPanel.getCommentTextArea().addValueChangeHandler(event -> { + renderPreview(inputPanel); }); - inputPanel.getVisibleForPublicCheckBox().addValueChangeHandler(new ValueChangeHandler() { - @Override - public void onValueChange(ValueChangeEvent event) { - renderPreview(inputPanel); - } + inputPanel.getVisibleForPublicCheckBox().addValueChangeHandler(event -> { + renderPreview(inputPanel); }); renderPreview(inputPanel); } - public void renderPreview(TagInputPanel inputPanel) { + /** + * Renders preview of tag by getting data from the input fields. + * + * @param inputPanel + * used to get input values from user + */ + protected void renderPreview(TagInputPanel inputPanel) { listContainingPreviewTag.removeAll(listContainingPreviewTag); listContainingPreviewTag.add(new TagDTO(inputPanel.getTag(), inputPanel.getComment(), inputPanel.getImageURL(), userService.getCurrentUser().getName(), inputPanel.isVisibleForPublic(), diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java index f2ff9aa9f88..6feb4a1a855 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java @@ -42,11 +42,18 @@ import com.sap.sse.security.ui.client.UserStatusEventHandler; import com.sap.sse.security.ui.shared.SuccessInfo; import com.sap.sse.security.ui.shared.UserDTO; +/** + * A view showing tags which are connected to a specific race and allowing users to add own tags to a race. This view is + * shown at the {@link com.sap.sailing.gwt.ui.raceboard.RaceBoardPanel RaceBoard}. Tags consist of a heading and + * optional a comment and/or image. Tag-Buttons allow to preset tags which are used more frequently by an user. Public + * tags will be stored as an {@link com.sap.sailing.domain.abstractlog.race.RaceLogEvent RaceLogEvent}, private tags + * will be stored in the {@link com.sap.sse.security.UserStore UserStore}. + */ public class TaggingPanel extends ComponentWithoutSettings implements RaceTimesInfoProviderListener, UserStatusEventHandler { /** - * Describes the current state of the Tagging-Panel. + * Describes the {@link TaggingPanel#currentState current state} of the {@link TaggingPanel}. */ protected enum State { VIEW, // default @@ -122,7 +129,7 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * Initializes UI of Tagging-Panel. + * Initializes UI of {@link TaggingPanel}. */ private void initializePanel() { taggingPanel.setStyleName(style.taggingPanel()); @@ -162,7 +169,8 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * Updates parameters required to save to/revoke from race log. + * Updates parameters required to save/revoke {@link com.sap.sailing.domain.abstractlog.race.RaceLogEvent events} + * to/from {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog}. */ public void updateRace(String leaderboardName, RaceColumnDTO raceColumn, FleetDTO fleet) { if (leaderboardName != null && !leaderboardName.equals(this.leaderboardName)) { @@ -189,8 +197,21 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * Sends request to SailingService to add the given tag to the race log if the parameter - * isVisibleForPublic is set to true. Otherwise tag will be stored in the user storage. + * Checks if {@link UserService#getCurrentUser() current user} is non-null and if + * {@link #leaderboardName}, {@link #raceColumn} and {@link #fleet} are non-null. + * + * @return true if current user, {@link #leaderboardName}, {@link #raceColumn} and {@link #fleet} are + * non-null, otherwise false. + */ + protected boolean isLoggedInAndRaceLogAvailable() { + return userService.getCurrentUser() != null && leaderboardName != null && raceColumn != null && fleet != null; + } + + /** + * Sends request to {@link SailingServiceAsync SailingService} to add the given tag to the + * {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog} if the parameter isVisibleForPublic + * is set to true. Otherwise tag will be stored in the {@link com.sap.sse.security.UserStore + * UserStore}. */ protected void saveTag(String tag, String comment, String imageURL, boolean isVisibleForPublic) { if (!isLoggedInAndRaceLogAvailable()) { @@ -241,8 +262,8 @@ public class TaggingPanel extends ComponentWithoutSettings // store list of loaded private tags also containing the new tag TagDTOJsonDeSerializer serializer = new TagDTOJsonDeSerializer(); JSONObject jsonObject = serializer.serialize(loadedPrivateTags); - userService.setPreference(serializer.createIdenticalKeyFromThreeStrings(leaderboardName, - raceColumn.getName(), fleet.getName()), jsonObject.toString(), new AsyncCallback() { + userService.setPreference(serializer.createIdenticalKeyFromThreeStrings(fleet.getName(), + leaderboardName, raceColumn.getName()), jsonObject.toString(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { Notification.notify(stringMessages.tagButtonNotSavable(), NotificationType.WARNING); @@ -262,9 +283,11 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * If the parameter tag is visible for the public a request to the SailingService is sent to revoke the - * given tag in race log. Otherwise the parameter tag is private and so the tag must be removed from - * the user storage. + * If attribute isVisibleForPublic of given tag is set to true, a request to the + * {@link SailingServiceAsync SailingService} is sent to revoke the given + * {@link com.sap.sailing.domain.abstractlog.race.RaceLogTagEvent RaceLogTagEvent} in + * {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog}. Otherwise the given tag is private and must be + * removed from the {@link com.sap.sse.security.UserStore UserStore}. */ protected void removeTag(TagDTO tagToRemove) { if (tagToRemove.isVisibleForPublic()) { @@ -305,8 +328,8 @@ public class TaggingPanel extends ComponentWithoutSettings // store list in user storage TagDTOJsonDeSerializer serializer = new TagDTOJsonDeSerializer(); JSONObject jsonObject = serializer.serialize(privateTags); - userService.setPreference(serializer.createIdenticalKeyFromThreeStrings(leaderboardName, - raceColumn.getName(), fleet.getName()), jsonObject.toString(), new AsyncCallback() { + userService.setPreference(serializer.createIdenticalKeyFromThreeStrings(fleet.getName(), + leaderboardName, raceColumn.getName()), jsonObject.toString(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { Notification.notify(stringMessages.tagNotRemoved(), NotificationType.ERROR); @@ -327,57 +350,49 @@ public class TaggingPanel extends ComponentWithoutSettings } } - private void removePrivateTagsFromProvider() { - tagListProvider.getAllTags().removeIf(tag -> !tag.isVisibleForPublic()); - } - + /** + * Adds a list of {@link TagDTO tags} to the {@link TagListProvider}. + */ private void addTagsToProvider(List tags) { tags.forEach(tag -> tagListProvider.getAllTags().add(tag)); } /** - * Checks if currentUser (read from UserService) is non-null and if leaderboardName, fleet and - * raceColumn are not null. - * - * @return true if current user, leaderboardName, raceColumn and fleet are non-null, otherwise false. + * Removes all private tags from {@link TagListProvider}. */ - protected boolean isLoggedInAndRaceLogAvailable() { - return userService.getCurrentUser() != null && leaderboardName != null && raceColumn != null && fleet != null; + private void removePrivateTagsFromProvider() { + tagListProvider.getAllTags().removeIf(tag -> !tag.isVisibleForPublic()); } /** - * Controls the visibility of UI elements in case the content or current state changes. + * Controls the visibility of UI elements in case the content or {@link #currentState} changes. */ protected void updateContent() { setFooterPanelVisibility(currentState == State.EDIT); setCreateTagsButtonVisibility(currentState == State.VIEW); tagListProvider.updateFilteredTags(); - tagCellList.setVisibleRange(0, tagListProvider.getFilteredTagsListSize()); + tagCellList.setVisibleRange(0, tagListProvider.getFilteredTags().size()); tagListProvider.refresh(); } /** - * Forces tagging panel to rerender content. + * Forces {@link #contentPanel} to rerender. */ protected void refreshContentPanel() { taggingPanel.setContentWidget(contentPanel); } - + /** - * Forces tagging panel to rerender footer. + * Forces {@link #footerPanel} to rerender. */ protected void refreshFooterPanel() { taggingPanel.setFooterWidget(footerPanel); } - protected Date getTimerTime() { - return timer.getTime(); - } - - protected List getTagButtons() { - return tagButtons; - } - + /** + * Adds {@link TagButton} to {@link #tagButtons list} of all {@link TagButton tag-buttons} and applies + * {@link com.google.gwt.event.dom.client.ClickHandler ClickHandler} on it which allows saving of tags. + */ protected void addTagButton(TagButton tagButton) { tagButton.addClickHandler(event -> { saveTag(tagButton.getTag(), tagButton.getComment(), tagButton.getImageURL(), @@ -386,26 +401,18 @@ public class TaggingPanel extends ComponentWithoutSettings tagButtons.add(tagButton); } - protected TagListProvider getTagListProvider() { - return tagListProvider; - } - - protected UserService getUserSerivce() { - return userService; - } - - protected StringMessages getStringMessages() { - return stringMessages; - } - + /** + * Loads private tags of {@link UserService#getCurrentUser() current user} from + * {@link com.sap.sse.security.UserStore UserStore}. Callback will be triggered if receiving of tags was successful. + */ private void loadAllPrivateTags(AsyncCallback> callback) { // only reload tags if user is logged in if (userService.getCurrentUser() != null) { TagDTOJsonDeSerializer tagDTODeSerializer = new TagDTOJsonDeSerializer(); // load all private tags from user storage - userService.getPreference(tagDTODeSerializer.createIdenticalKeyFromThreeStrings(leaderboardName, - raceColumn.getName(), fleet.getName()), new AsyncCallback() { + userService.getPreference(tagDTODeSerializer.createIdenticalKeyFromThreeStrings(fleet.getName(), + leaderboardName, raceColumn.getName()), new AsyncCallback() { @Override public void onFailure(Throwable caught) { // TODO: Add error handling @@ -432,7 +439,46 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * Sets the current state and updates the UI. + * Returns time of {@link #timer}. + */ + protected Date getTimerTime() { + return timer.getTime(); + } + + /** + * Returns {@link #tagButtons list} of all {@link TagButton tag-buttons} of the {@link UserService#getCurrentUser() + * current user}. + */ + protected List getTagButtons() { + return tagButtons; + } + + /** + * Returns instance of {@link TagListProvider} so it does not have to be a constructor parameter of every sub + * component of the {@link TaggingPanel}. + */ + protected TagListProvider getTagListProvider() { + return tagListProvider; + } + + /** + * Returns instance of {@link UserService} so it does not have to be a constructor parameter of every sub component + * of the {@link TaggingPanel}. + */ + protected UserService getUserSerivce() { + return userService; + } + + /** + * Returns instance of {@link StringMessages} so it does not have to be a constructor parameter of every sub + * component of the {@link TaggingPanel}. + */ + protected StringMessages getStringMessages() { + return stringMessages; + } + + /** + * Sets the {@link #currentState} to the given {@link State state} and updates the UI. * * @param state * new state @@ -443,9 +489,10 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * Updates the visibility of the footer and it's components. Input fields will NOT get displayed if user is not - * logged in, even if showInputFields is set to true! Tag buttons can't be hidden and will get displayed - * automatically when user is logged in. + * Updates the visibility of the {@link #footerPanel} and it's components. Input fields will NOT get displayed if + * user is not logged in, even if showInputFields is set to true! {@link TagButton}s can't + * be hidden and will get displayed automatically when {@link UserService#getCurrentUser() current user} is logged + * in. */ private void setFooterPanelVisibility(boolean showInputFields) { // Setting footerPanel.setVisible(false) is not sufficient as panel would still be @@ -461,19 +508,20 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * Updates the visibility of the "Add Tags"-button. Button will NOT get displayed if user is not logged in, even if - * showButton is set to true! + * Updates the visibility of the {@link #createTagsButton "Add Tags"-button}. {@link #createTagsButton Button} will + * NOT get displayed if {@link UserService#getCurrentUser() current user} is not logged in, even if + * showButton is set to true! */ private void setCreateTagsButtonVisibility(boolean showButton) { createTagsButton.setVisible(userService.getCurrentUser() != null && showButton); } /** - * Update local list of tags when response of server gets dispatched to all listeners by RaceTimesInfoProvider. - * Server sends only difference of tags in comparison based on the createdAt-timestamp of the latest received tag - * event. + * Updates {@link TagListProvider#getAllTags() local list of tags} when response of {@link SailingServiceAsync + * SailingService} gets dispatched to all listeners by {@link RaceTimesInfoProvider}. {@link SailingServiceAsync + * SailingService} sends only difference of tags in comparison based on the createdAt-timestamp of the + * {@link RaceTimesInfoProvider#latestReceivedTagTimes latest received tag events}. */ - @Override public void raceTimesInfosReceived(Map raceTimesInfo, long clientTimeWhenRequestWasSent, Date serverTimeDuringRequest, long clientTimeWhenResponseWasReceived) { @@ -526,9 +574,11 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * When the user logs in or out the content needs to be reset to hide private tags of the previous user. This gets - * achieved by resetting the local list of tags and resetting all latest received tag times at the - * RaceTimesInfoProvider. + * When the {@link UserService#getCurrentUser() current user} logs in or out the {@link #contentPanel content} needs + * to be reset to hide private tags of the previous {@link UserService#getCurrentUser() current user}. This gets + * achieved by resetting the {@link TagListProvider#getAllTags() local list of tags} and resetting all + * {@link RaceTimesInfoProvider#latestReceivedTagTimes latest received tag events} at the + * {@link RaceTimesInfoProvider}. */ @Override public void onUserStatusChange(UserDTO user, boolean preAuthenticated) { @@ -575,7 +625,7 @@ public class TaggingPanel extends ComponentWithoutSettings } /** - * Only request tags from server if Tagging-Panel is visible. + * Only request tags from server if {@link TaggingPanel} is visible. */ @Override public void setVisible(boolean visible) {