Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add/remove custom controls dynamically #138

Merged
merged 7 commits into from
Sep 26, 2024
Merged

Add/remove custom controls dynamically #138

merged 7 commits into from
Sep 26, 2024

Conversation

paodb
Copy link
Member

@paodb paodb commented Sep 23, 2024

This depends on the merge of FlowingCode/google-map#35 and the release of the new version of the web-component.

This PR adds the possibility to add and remove custom controls dynamically. Also adds a method to remove all existing custom controls. Web component version was updated to 3.8.0.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a demo application showcasing custom controls for Google Maps, allowing dynamic addition and removal of controls.
    • Added a new CSS file for styling custom control buttons.
  • Enhancements

    • Updated the Google Maps addon version to improve functionality and performance.
    • Enhanced management of custom controls within the Google Map component, including new methods for adding and removing controls.
  • Bug Fixes

    • Resolved issues related to the handling of custom controls in the Google Map component.

Copy link

coderabbitai bot commented Sep 23, 2024

Walkthrough

The pull request introduces updates to the Google Maps Addon for the Vaadin platform, focusing on version increments and enhancements to custom control management within the GoogleMap class. The NPM package version has been updated from 3.7.1 to 3.8.0 across multiple classes. A new demo application showcasing custom controls has been added, along with corresponding styling rules.

Changes

File Change Summary
pom.xml Updated google-maps version from 2.1.1-SNAPSHOT to 2.2.0-SNAPSHOT.
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java Updated @NpmPackage version from 3.7.1 to 3.8.0, added methods for managing custom controls.
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java Updated @NpmPackage version from 3.7.1 to 3.8.0.
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoint.java Updated @NpmPackage version from 3.7.1 to 3.8.0.
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoly.java Updated @NpmPackage version from 3.7.1 to 3.8.0.
src/test/java/com/flowingcode/vaadin/addons/googlemaps/CustomControlsDemo.java Added a new demo application for Google Maps with custom controls.
src/test/java/com/flowingcode/vaadin/addons/googlemaps/GooglemapsDemoView.java Added CustomControlsDemo to the demo view.
src/test/resources/META-INF/resources/frontend/styles/google-maps/custom-controls-demo-styles.css Added new CSS file for custom control button styling.

Possibly related PRs

🐰 In the meadow where the maps do play,
A bunny hops with joy today.
Custom controls are here to stay,
With styles so bright, they'll lead the way!
Version updates, oh what a cheer,
Google Maps shines, let’s all draw near! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@javier-godoy
Copy link
Member

@paodb FlowingCode/google-map#35 has been merged.

@paodb paodb marked this pull request as ready for review September 25, 2024 20:31
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (9)
src/test/resources/META-INF/resources/frontend/styles/google-maps/custom-controls-demo-styles.css (1)

21-31: LGTM: CSS styling is appropriate for a Google Maps control button.

The styling provides a clean, material design-like appearance suitable for a Google Maps control. Here are some suggestions for potential improvements:

  1. Consider using relative units (e.g., em or rem) for font-size and margins to improve responsiveness across different screen sizes.
  2. You might want to add hover and active states to provide better user feedback. For example:
.custom-control-button:hover {
    background: #f0f0f0;
}

.custom-control-button:active {
    background: #e0e0e0;
    box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 2px -1px;
}
  1. For accessibility, consider adding a focus state:
.custom-control-button:focus {
    outline: 2px solid #4285f4;
    outline-offset: 2px;
}
src/test/java/com/flowingcode/vaadin/addons/googlemaps/CustomControlsDemo.java (3)

38-39: Consider removing the @SuppressWarnings("serial") annotation.

The @SuppressWarnings("serial") annotation is typically used for classes that implement Serializable. Since this is a demo class and doesn't seem to be serializable, this annotation may not be necessary. Consider removing it to keep the code clean and avoid suppressing warnings that don't apply.


98-102: Reconsider disabling buttons on click for demo purposes.

The createDemoButton method currently sets setDisableOnClick(true) for all buttons. While this can prevent multiple clicks, it might not be the best approach for a demo application where users might want to interact with the buttons multiple times.

Consider removing the setDisableOnClick(true) line:

private Button createDemoButton(String caption) {
    return new Button(caption);
}

This change would allow users to interact with the buttons multiple times without needing to refresh the page, which is typically more desirable in a demo scenario. The button states can be managed through the logic in the click listeners instead.


1-103: Approve the overall implementation with a suggestion for enhancement.

The implementation effectively demonstrates the use of custom controls in Google Maps, providing a good user experience with interactive elements. The code is well-organized and follows a logical flow.

As a potential enhancement, consider adding comments to explain the purpose of each custom control and button. This would make the demo more educational for developers who might be looking at this code to learn how to implement custom controls in their own applications.

For example:

// Custom control at the top center of the map
CustomControl customControl1 = new CustomControl(customControlButton1, ControlPosition.TOP_CENTER);

// Button to add a new control dynamically
Button addCustomControl3Button = createDemoButton("Add Custom Control 3");

These comments would provide context and make the demo more self-explanatory.

src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java (1)

Line range hint 1-424: Consider reviewing other files for new feature implementation.

The update to the NPM package version in this file is the only change, and it has been approved. However, the PR objectives mention adding and removing custom controls dynamically, which is not implemented in the GoogleMapMarker class.

To complete the review of this PR:

  1. Verify that the implementation for adding and removing custom controls is present in other files of the project.
  2. Ensure that any new methods or classes related to custom controls are properly integrated with the existing GoogleMapMarker class if necessary.
  3. Update the documentation to reflect the new features and any changes in usage.
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (4)

810-810: Simplify array conversion by using toArray directly

In the addCustomControl method, you're converting customControls to an array using the Stream API. You can simplify the code by using the toArray method directly, which is more efficient and readable.

Apply this change:

-  this.setCustomControls(this.customControls.stream().toArray(CustomControl[]::new));
+  this.setCustomControls(this.customControls.toArray(new CustomControl[0]));

820-820: Simplify array conversion by using toArray directly

Similarly, in the removeCustomControl method, you can simplify the array conversion.

Apply this change:

-  this.setCustomControls(this.customControls.stream().toArray(CustomControl[]::new));
+  this.setCustomControls(this.customControls.toArray(new CustomControl[0]));

45-47: Unused import statement

The import statement for java.util.List on line 46 is not used in the modified code. Consider removing it to clean up the imports.

Apply this diff to remove the unused import:

 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;

59-60: Remove redundant initialization of trackLocationId

The trackLocationId field is initialized to null by default. Explicitly setting it to null is redundant.

Apply this change:

-private Integer trackLocationId = null;  
+private Integer trackLocationId;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 42e4769 and 2cf597a.

📒 Files selected for processing (8)
  • pom.xml (1 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (2 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java (1 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoint.java (1 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoly.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/addons/googlemaps/CustomControlsDemo.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/addons/googlemaps/GooglemapsDemoView.java (1 hunks)
  • src/test/resources/META-INF/resources/frontend/styles/google-maps/custom-controls-demo-styles.css (1 hunks)
🔇 Additional comments not posted (8)
src/test/resources/META-INF/resources/frontend/styles/google-maps/custom-controls-demo-styles.css (1)

1-19: LGTM: License header is correct and up-to-date.

The Apache License 2.0 header is properly formatted and includes the correct copyright information for Flowing Code, with years 2020-2024.

src/test/java/com/flowingcode/vaadin/addons/googlemaps/GooglemapsDemoView.java (1)

51-51: LGTM! The new demo has been successfully integrated.

The addition of CustomControlsDemo.class aligns well with the PR objectives of adding functionality for dynamic custom controls. The placement at the end of the demo list maintains the existing structure and is consistent with the pattern of other demo additions.

To ensure the CustomControlsDemo class exists and is properly implemented, let's run the following verification script:

✅ Verification successful

Verified! The CustomControlsDemo class exists and is properly implemented.

The CustomControlsDemo.java file is present and the class structure aligns with the expected design. The addition integrates seamlessly with the existing demos and adheres to the project's standards.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and basic structure of CustomControlsDemo class

# Test 1: Check if the CustomControlsDemo.java file exists
echo "Checking for CustomControlsDemo.java file:"
fd --type f "CustomControlsDemo.java$"

# Test 2: Verify the basic structure of the CustomControlsDemo class
echo -e "\nVerifying CustomControlsDemo class structure:"
rg --type java -A 10 "class CustomControlsDemo"

Length of output: 1641

src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoint.java (1)

31-31: LGTM! Verify version consistency and check for breaking changes.

The update of the @flowingcode/google-map NPM package version to 3.8.0 aligns with the PR objectives. This change is likely a prerequisite for the new features mentioned in the PR description (adding/removing custom controls dynamically).

To ensure consistency and check for potential breaking changes, please run the following verification steps:

Please review the results of these checks to ensure there are no inconsistencies or potential breaking changes introduced by this version update.

src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoly.java (2)

Line range hint 1-42: Clarify implementation of new features mentioned in PR objectives.

The PR objectives mention adding/removing custom controls dynamically and a method to remove all existing custom controls. However, this file only contains an NPM package version update, with no visible implementation of these features.

Please clarify:

  1. Where are the new features for adding/removing custom controls implemented?
  2. Are there other files in this PR that contain the actual implementation of these features?
  3. If the implementation is solely in the updated NPM package, should this class or other Java classes be updated to expose these new features?

To help investigate this, please run the following script to search for relevant changes across the project:

#!/bin/bash
# Description: Search for implementations related to custom controls

# Test 1: Look for files with recent changes related to custom controls
echo "Files with recent changes related to custom controls:"
git log --name-only --since="1 month ago" | sort -u | xargs rg -l -i 'custom.*control'

# Test 2: Search for new methods or classes related to custom controls
echo "New methods or classes related to custom controls:"
git diff --name-only HEAD~10 | xargs rg -n -i '(class|interface|enum|method).*control'

# Test 3: Check for changes in other key files
echo "Changes in other key Google Maps related files:"
git diff --name-only HEAD~10 | grep -i 'googlemap'

42-42: Approve NPM package update and verify new features.

The NPM package version update for "@flowingcode/google-map" from 3.7.1 to 3.8.0 is approved. This change likely enables the new features mentioned in the PR objectives (adding/removing custom controls dynamically).

To ensure the new features are properly implemented and documented:

  1. Verify that the new version (3.8.0) of "@flowingcode/google-map" includes the functionality for adding and removing custom controls dynamically.
  2. Check if any additional changes or new methods are required in this GoogleMapPoly class to support the new features.
  3. Consider updating the class documentation to reflect any new capabilities related to custom controls, if applicable.
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java (1)

42-42: LGTM! Verify new features in updated NPM package.

The update of the @flowingcode/google-map NPM package from version 3.7.1 to 3.8.0 is appropriate and aligns with the PR objectives. This minor version bump likely includes the new functionality for adding and removing custom controls dynamically.

To ensure that the new version includes the expected features, please run the following verification steps:

  1. Check the changelog or release notes for version 3.8.0 of the @flowingcode/google-map package.
  2. Verify that the new version includes the functionality for adding and removing custom controls dynamically.
  3. Test the new features in your local environment to ensure they work as expected with the GoogleMapMarker class.
pom.xml (1)

7-7: Version update looks good and aligns with PR objectives.

The version change from 2.1.1-SNAPSHOT to 2.2.0-SNAPSHOT is appropriate for the new features being introduced (adding/removing custom controls dynamically). This minor version increment correctly reflects the addition of new functionality without breaking changes.

To ensure this version update is consistent across the project, let's check for any other occurrences of the version number:

✅ Verification successful

Version update is consistent across the project.

No additional occurrences of the old or new version numbers were found outside of pom.xml, ensuring that the version update is properly localized and does not impact other parts of the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any other occurrences of the old or new version number
echo "Searching for old version (2.1.1-SNAPSHOT):"
grep -r "2.1.1-SNAPSHOT" . --exclude=pom.xml
echo "Searching for new version (2.2.0-SNAPSHOT):"
grep -r "2.2.0-SNAPSHOT" . --exclude=pom.xml

Length of output: 283

src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (1)

54-54: Update NPM package to the latest version

Ensure that updating the @flowingcode/google-map NPM package version to "3.8.0" is compatible with all existing functionalities and doesn't introduce breaking changes.

Run the following script to check for any breaking changes in the dependency:

✅ Verification successful

Update Verified: The @flowingcode/google-map NPM package has been successfully updated to version "3.8.0" without introducing any breaking changes that affect current functionalities.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for breaking changes in the updated NPM package.

# Test: Review the changelog for version 3.8.0. Expect: No breaking changes that affect current usage.
gh api repos/FlowingCode/google-map/releases --jq '.[] | select(.tag_name=="3.8.0") | .body'

Length of output: 319

@paodb
Copy link
Member Author

paodb commented Sep 25, 2024

@coderabbitai review

Copy link

coderabbitai bot commented Sep 25, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

sonarcloud bot commented Sep 26, 2024

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 4fa18e3 and 4d7ec71.

📒 Files selected for processing (1)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (2 hunks)
🔇 Additional comments (1)
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (1)

54-54: Update of @flowingcode/google-map to version 3.8.0

The NpmPackage annotation has been correctly updated to version 3.8.0 to include the latest features required for dynamic custom controls.

Comment on lines +809 to +823
public void addCustomControl(CustomControl customControl) {
this.customControls.add(customControl);
this.setCustomControls(this.customControls.stream().toArray(CustomControl[]::new));
}

/**
* Removes a custom control added to the map.
*
* @param customControl the custom control to be removed
*/
public void removeCustomControl(CustomControl customControl) {
this.customControls.remove(customControl);
this.setCustomControls(this.customControls.stream().toArray(CustomControl[]::new));
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize addCustomControl and removeCustomControl methods to improve performance

Currently, addCustomControl and removeCustomControl invoke setCustomControls, which resets all custom controls. This approach can be inefficient, especially when adding or removing controls frequently.

Consider modifying addCustomControl and removeCustomControl to update the controls incrementally without resetting all existing controls. You can directly add or remove the specific control and update the map accordingly. This change will enhance performance and provide a smoother user experience.

Comment on lines +45 to +46
import java.util.ArrayList;
import java.util.ArrayList;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicate import statements

Lines 45 and 46 both import java.util.ArrayList. This duplicate import is unnecessary and should be removed.

Apply this diff to remove the duplicate import:

-import java.util.ArrayList;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.ArrayList;

Comment on lines +790 to +802
this.customControls.clear();
this.getElement().executeJs("this._removeCustomControls()").then((e) -> {
JsonArray jsonArray = Json.createArray();
for (int i = 0; i < customControls.length; i++) {
CustomControl customControl = customControls[i];
jsonArray.set(i, customControl.getJson(i));
customControl.getControlButton().getElement().setAttribute("slot", "customControlSlot_" + i);
this.getElement().appendChild(customControl.getControlButton().getElement());
this.customControls.add(customControl);
}
this.getElement().setPropertyJson("customControls", jsonArray);
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential concurrency issue when modifying customControls

In the setCustomControls method, this.customControls.clear() is called synchronously, whereas this.customControls.add(customControl) is called inside the asynchronous callback of executeJs(...).then(...). This could lead to an inconsistent state of customControls if other methods access it before the callback completes.

Consider moving this.customControls.clear() inside the then block to ensure that all modifications to customControls occur sequentially after the JavaScript execution. This adjustment will help maintain consistency in the state of customControls.

Apply this diff to adjust the code:

 public void setCustomControls(CustomControl... customControls) {
-  this.customControls.clear();
   this.getElement().executeJs("this._removeCustomControls()").then((e) -> {
+    this.customControls.clear();
     JsonArray jsonArray = Json.createArray();
     for (int i = 0; i < customControls.length; i++) {
       CustomControl customControl = customControls[i];
       jsonArray.set(i, customControl.getJson(i));
       customControl.getControlButton().getElement().setAttribute("slot", "customControlSlot_" + i);
       this.getElement().appendChild(customControl.getControlButton().getElement());
       this.customControls.add(customControl);
     }
     this.getElement().setPropertyJson("customControls", jsonArray);
   });    
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.customControls.clear();
this.getElement().executeJs("this._removeCustomControls()").then((e) -> {
JsonArray jsonArray = Json.createArray();
for (int i = 0; i < customControls.length; i++) {
CustomControl customControl = customControls[i];
jsonArray.set(i, customControl.getJson(i));
customControl.getControlButton().getElement().setAttribute("slot", "customControlSlot_" + i);
this.getElement().appendChild(customControl.getControlButton().getElement());
this.customControls.add(customControl);
}
this.getElement().setPropertyJson("customControls", jsonArray);
});
}
public void setCustomControls(CustomControl... customControls) {
this.getElement().executeJs("this._removeCustomControls()").then((e) -> {
this.customControls.clear();
JsonArray jsonArray = Json.createArray();
for (int i = 0; i < customControls.length; i++) {
CustomControl customControl = customControls[i];
jsonArray.set(i, customControl.getJson(i));
customControl.getControlButton().getElement().setAttribute("slot", "customControlSlot_" + i);
this.getElement().appendChild(customControl.getControlButton().getElement());
this.customControls.add(customControl);
}
this.getElement().setPropertyJson("customControls", jsonArray);
});
}

@javier-godoy javier-godoy merged commit dcd1b6d into master Sep 26, 2024
5 checks passed
@javier-godoy javier-godoy deleted the issue-128 branch September 26, 2024 19:04
@coderabbitai coderabbitai bot mentioned this pull request Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

2 participants