Skip to content

[Map] Create Map component#1937

Merged
javiereguiluz merged 1 commit into
symfony:2.xfrom
Kocal:feat/38-map-component
Aug 7, 2024
Merged

[Map] Create Map component#1937
javiereguiluz merged 1 commit into
symfony:2.xfrom
Kocal:feat/38-map-component

Conversation

@Kocal

@Kocal Kocal commented Jun 24, 2024

Copy link
Copy Markdown
Member
Q A
Bug fix? no
New feature? yes
Issues Fix #38
License MIT

Hi :)

This PR is a proposal for #38 a replacement for #39.

Symfony UX Map is a new Symfony UX component that makes it easy to create, customize and use interactive JavaScript maps.

The package ships with:

Example

Bridge configuration

# .env
UX_MAP_DSN=leaflet://default
# config/packages/ux_map.yaml
ux_map:
    renderer: '%env(UX_MAP_DSN)%'

Map creation

An example to render a map, custom center and zoom, some markers and info windows:

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\UX\Map\InfoWindow;
use Symfony\UX\Map\MapFactoryInterface;
use Symfony\UX\Map\Marker;
use Symfony\UX\Map\Point;

final class ContactController extends AbstractController
{
    #[Route('/contact')]
    public function __invoke(): Response
    {
            // 1. Create a new map instance
            $myMap = (new Map());
                ->center(new Point(46.903354, 1.888334))
                ->zoom(6)
            ;
    
            // 2. You can add markers, with an optional info window
            $myMap
                ->addMarker(new Marker(
                    position: new Point(48.8566, 2.3522), 
                    title: 'Paris'
                ))
                ->addMarker(new Marker(
                    position: new Point(45.7640, 4.8357), 
                    title: 'Lyon',
                    // With an info window
                    infoWindow: new InfoWindow(
                        headerContent: '<b>Lyon</b>',
                        content: 'The French town in the historic Rhône-Alpes region, located at the junction of the Rhône and Saône rivers.'
                    )
                ));
    
            // 3. And inject the map in your template to render it
            return $this->render('contact/index.html.twig', [
                'my_map' => $myMap,
            ]);
    }
}

Map rendering

You must call render_map(map) to render the map:

{{ render_map(map, { style: 'height: 700px; width: 1024px; margin: 10px' }) }}

It gives you this interactive Leaflet map:

image

@carsonbot carsonbot added Feature New Feature Status: Needs Review Needs to be reviewed labels Jun 24, 2024
@Kocal
Kocal force-pushed the feat/38-map-component branch 4 times, most recently from 4fd1a57 to 1fb9b9b Compare June 24, 2024 08:24
@seb-jean

Copy link
Copy Markdown
Contributor

Very useful component :)

@Kocal
Kocal force-pushed the feat/38-map-component branch 4 times, most recently from c97965e to f73bf19 Compare June 24, 2024 11:47
Comment thread src/Map/assets/package.json Outdated
Comment thread src/Map/assets/src/google_maps_controller.ts Outdated
Comment thread src/Map/assets/vitest.config.js
Comment thread src/Map/src/AssetMapper/ImportMap/Resolver/LeafletPackageResolver.php Outdated
@simondaigre

Copy link
Copy Markdown
Contributor

That's awesome ! Thank you for this PR ! I checked my projects with Google Maps integration, there is some features missing here :

  • allow to set a custom icon on Marker
  • allow to customize map styles (styles parameter as array ?)
  • on some projects I also use @googlemaps/markerclusterer. Not sure if you should include it in ux/maps but I'll do a doc PR with explanations if you want

@Kocal

Kocal commented Jun 24, 2024

Copy link
Copy Markdown
Member Author

Hi @simondaigre, and thank you! :)

allow to set a custom icon on Marker

It's already on my list! I will need this feature aswell for my website where I use custom marker icons:
image

But I don't wanted to do too much things in a single PR. Implementing PinElement PHP-side is a small challenge which I think can already be done user-side with event listeners.

allow to customize map styles (styles parameter as array ?)

I've started to implement the API/configuration for map styles (with some classes and enums), but I've finally removed it when I knew about Cloud-based maps styling.
You can pass the mapId or call ->setMapId('...') to customize your map styles.

on some projects I also use @googlemaps/markerclusterer. Not sure if you should include it in ux/maps but I'll do a doc PR with explanations if you want

I think we would not include it in Symfony UX Map by default, a documentation would be enough IMO :)

@smnandre

Copy link
Copy Markdown
Member

(i will make a big review this week-end ;) )

@smnandre

Copy link
Copy Markdown
Member

A first comment before touching the real work :)

It is not possible to use Google Map without explicit consent of the user in Europe, California i think, Japan maybe, Australia too

You are of course not responsible of this, but i think some use case or implementation consequences should be discussed now

  • can we expose some hook to load scripts & maps on trigger (can be the CMP or GMT for instance) ?
  • can we ease the privacy compliance in any way (because as we discussed a few times with @WebMamba this is probably where some good DX can make a big difference) ?

@Kocal

Kocal commented Jun 27, 2024

Copy link
Copy Markdown
Member Author

... 😮‍💨 , but yeah you're right, thanks for pointing it out.

I think the easiest way to do that is to:

  • never load Google Maps maps implicitly, or at least makes it configurable server-side
    • when calling render_map(...), we won't render data-controller attribute but something else (e.g.: data-controller-wait-for-consent or something more related to Symfony UX Map), so the GoogleMaps Stimulus controller & Google Maps API won't be loaded
  • provide a global function like loadSymfonyUxGoogleMaps():
    • which can be easily created on-the-fly by {{ ux_map_script_tags() }}
    • calling it will rename data-controller-wait-for-consent to data-controller, which will load the Stimulus controller & Google Maps API
  • and let the developper execute loadSymfonyUxGoogleMaps() when needed

For example with the Didomi CMP:

<script>
    window.didomiOnReady = window.didomiOnReady || [];
    window.didomiOnReady.push(() => {
        function loadGoogleMapsIfConsentGiven() {
            const googleMapsPurposeId = '...';
            const googleMapsVendorId = '...';

            const userStatus = Didomi.getUserStatus();
            const enabledPurposeConsent = userStatus.purposes.consent.enabled;
            const enabledVendorConsent = userStatus.vendors.consent.enabled;

            if (enabledPurposeConsent.includes(googleMapsPurposeId) && enabledVendorConsent.includes(googleMapsVendorId)) {
                window.loadSymfonyUxGoogleMaps();
            }
        }

        if (Didomi.shouldConsentBeCollected()) {
            window.didomiEventListeners = window.didomiEventListeners || [];
            window.didomiEventListeners.push({
                event: 'consent.changed',
                listener: function (event) {
                    loadGoogleMapsIfConsentGiven();
                }
            });
        } else {
            loadGoogleMapsIfConsentGiven();
        }
    });
</script>

WDYT?

Comment thread src/Map/.gitignore Outdated
Comment thread src/Map/LICENSE Outdated
Comment thread src/Map/README.md Outdated
Comment thread src/Map/assets/package.json Outdated
Comment thread src/Map/composer.json Outdated
Comment thread src/Map/composer.json Outdated
Comment thread src/Map/composer.json Outdated
Comment thread src/Map/config/asset_mapper.php Outdated
Comment thread src/Map/src/DependencyInjection/UXMapExtension.php Outdated
Comment thread src/Map/src/DependencyInjection/UXMapExtension.php Outdated
@Kocal
Kocal force-pushed the feat/38-map-component branch 6 times, most recently from 5dbbc6d to 09be8b1 Compare July 31, 2024 15:13
@javiereguiluz

Copy link
Copy Markdown
Member

Do we have a list of things left to do here before making this mergeable?

Or is this fully finished and just needs a final review?

Thanks!

@Kocal

Kocal commented Aug 6, 2024

Copy link
Copy Markdown
Member Author

Hi, I don't have more things to do, I've already processed the ~250+ comments :D

Final reviews are welcome of course, but I think we planned to merge this PR soonly so we can iterate on it (especially the documentation), cc @kbond @smnandre

@Kocal
Kocal requested a review from kbond August 6, 2024 14:32
@javiereguiluz

Copy link
Copy Markdown
Member

It's merged now! 🎉🎉🎉

Hugo, infinite thanks for contributing this amazing new component 🙇🙇🙇 and thank you all for the nice discussion and review that you did here.

Now, let's test it in real apps, let's iterate on it and let's add good docs for the community. Thanks!

@Kocal

Kocal commented Aug 7, 2024

Copy link
Copy Markdown
Member Author

Thanks @javiereguiluz :)

But we still need to set-up git repositories for UX Map bridges (Google and Leaflet), AFAIK only Fabien can do that..? Do you think we can get in touch with him? 🙏

Thanks!

@fabpot

fabpot commented Aug 7, 2024

Copy link
Copy Markdown
Member

@Kocal Can you list what needs to be done? Based on that, I will do the magic ;)

@Kocal

Kocal commented Aug 7, 2024

Copy link
Copy Markdown
Member Author

So quick! :D

We will need dedicated repositories for:

So packages symfony/ux-map, symfony/ux-map-google and symfony/ux-map-leaflet can be published on Packagist, and so downloadable by people.

And like other Symfony components, bridges source code should not be present in symfony/ux-map repo/package.

Thanks :)

@@ -0,0 +1,33 @@
{
"name": "symfony/ux-map-google",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should be symfony/ux-google-map to be consistent with how we are naming bridges in Symfony.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm working on it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See #2031

@@ -0,0 +1,33 @@
{
"name": "symfony/ux-map-leaflet",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should be symfony/ux-leaflet-map to be consistent with how we are naming bridges in Symfony.

@fabpot

fabpot commented Aug 7, 2024

Copy link
Copy Markdown
Member

@Kocal All done. Can you double-check that everything has been configured properly?

@Kocal

Kocal commented Aug 7, 2024

Copy link
Copy Markdown
Member Author

@fabpot thanks!
Except for the folder src/Bridge that should not be present in symfony/ux-map, everything is perfect!

@smnandre

smnandre commented Aug 7, 2024

Copy link
Copy Markdown
Member

Cannot wait to play with it!

What an incredible PR this was, thank you very much for your patience, hard work and positive spirit @Kocal!

👏

@fabpot

fabpot commented Aug 7, 2024

Copy link
Copy Markdown
Member

@fabpot thanks! Except for the folder src/Bridge that should not be present in symfony/ux-map, everything is perfect!

Good catch, I used Bridge like for Symfony, the src/xxx/src/yyy disturbed me :)
BUT, excluding a deep directory is NOT supported by the splitter currently. I don't remember why I put this restriction in place, so I need to double-check that.

@smnandre

smnandre commented Aug 7, 2024

Copy link
Copy Markdown
Member

We can move folders around in the ux mono if that can ease things.

@fabpot

fabpot commented Aug 7, 2024

Copy link
Copy Markdown
Member

All good now 🤞

@Kocal

Kocal commented Aug 8, 2024

Copy link
Copy Markdown
Member Author

Thanks Fabien :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature New Feature Map Status: Needs Review Needs to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: map component

8 participants