EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
3.99k stars 1.01k forks source link

Some bootstrap functionnalities don't work if we use stimulus #6247

Open bastien70 opened 1 month ago

bastien70 commented 1 month ago

Describe the bug On a custom action, I need to import live-component from Symfony UX.

For this I need to load stimulus. We have the app.js file that does this:

app.js :

// start the Stimulus application
import './bootstrap';

bootstrap.js :

import { startStimulusApp } from '@symfony/stimulus-bridge';

// Registers Stimulus controllers from controllers.json and in the controllers/ directory
export const app = startStimulusApp(require.context(
    '@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
    true,
    /\.[jt]sx?$/
));
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

And in webpack.config.js :

.addEntry("app", "./assets/app.js")

And now in my template :

{% extends '@EasyAdmin/page/content.html.twig' %}

{% block content_title %}Déclaration des droits{% endblock %}
{% block page_title %}Déclaration des droits{% endblock %}

{% block head_stylesheets %}
    {{ encore_entry_link_tags('app') }}
    {{ parent() }}
{% endblock head_stylesheets %}

{% block head_javascript %}
    {{ encore_entry_script_tags('app') }}
    {{ parent() }}
{% endblock head_javascript %}

{% block main %}//...{%endblock}

The problem when importing stimulus is that certain bootstrap features no longer work, such as collapse.

For example, when an element of an accordion is displayed, if we want to collapse it, nothing happens, and no error

tomjanke28 commented 1 month ago

Hey, I think I got that very same "bug" some time ago.

The issue is, that you probably import some Bootstrap js in your own app.js file or somewhere else in your own code. Therefore the collapse will initialize twice and immediatly close directly after opening, or vice versa. The bootstrap widgets are asynchronous, and therefore you will probably not catch a difference in the UI, but looking at the DevTools you may find the collapse element "flicker", which indicates a change.

The solution to your problem is to simply use the EasyAdmin Bootstrap instance, provided in window.bootstrap instead of importing the files on your own. See https://github.com/EasyCorp/EasyAdminBundle/blob/df81f104910137d382e48cf821290de877ffc1ca/assets/js/app.js#L10

For example, instead of import { Collapse } from 'bootstrap'; you can use const { Collapse } = window.bootstrap;.

I know this is kinda far fetched, but it may help. 😉

dragosprotung commented 1 month ago

@tomjanke28 is right. Importing bootstrap can have side efects because it's already loaded by EasyAdmin.

You can use it like:

let modal = bootstrap.Modal.getOrCreateInstance('#modal')
raffcioo commented 1 month ago

I also have this problem. I have working app written in Symfony 6.4 using AssetMapper which came with Stimulus and Turbo itegrated and I also use Bootstrap. I wanted to integrate EasyAdmin into it. They say in documentation that it works with Symfony 5.4+ but I think it is just not true because its javascript is not current Symfony ecosystem compatible? I can have EasyAdmin working or my app working, I can't have both at the same time, with Bootstrap. I can't change my working app Stimulus controllers to make EasyAdmin working. It would be nice to somehow maybe make a new 'admin' entry point for admin, and bootstrap Stimulus from there, but with different controllers folder (is it possible with AssetMapper?), so my app Stimulus controllers from assets/controllers on admin pages are not loaded and do not break EasyAdmin's Booststrap funcionality?, run from dashboard's configureAssets() addAssetMapperEntry('admin')... but don't know how to do that with AssetMapper and documentaion is silent about that. It is not EasyAdmin but HardAdmin for me! :)

pa- commented 1 day ago

We recently ran into the same problem (the dropdown with the actions on the index page wasnt working anymore). Turns out: We had an extra entrypoint in our importmap.php which only starts stimulus:

import {startStimulusApp} from '@symfony/stimulus-bundle';
startStimulusApp();

but that loaded all our controllers, not just the one we needed in easyadmin. And one of these controllers contains an import {Modal} from 'bootstrap'; which we need in the app/frontend. We then made all controllers lazy (https://symfony.com/bundles/StimulusBundle/current/index.html#lazy-stimulus-controllers) so that only the "easyadmin_controller" is loaded and used in easyadmin and conflicts are avoided

raffcioo commented 1 day ago

@pa- I tried this but in my case it was not a solution because when I made all stimulus controllers lazy some GUI elements on frontend started flickering on first page load. Javascript was loading too late causing flickering, especially when a controller used some third party library. I ended up removing EasyAdmin completely and writing my own (was not too big and it was quick) so now both frontend app and backend admin are written with Symfony, Stimulus, Turbo and everything is working nice together, and as an additional plus I could make some fields to be edited inline so everything can be edited on one page, instead of going to every field's edit page to edit it like it was before. Maybe next major version of EasyAdmin will be more compatible with current Symfony ecosystem with Stimulus and Turbo and then I will use it. Regards.

pa- commented 1 day ago

@pa- Maybe next major version of EasyAdmin will be more compatible with current Symfony ecosystem with Stimulus and Turbo and then I will use it. Regards.

yes! there is already a request/suggestion on this: https://github.com/EasyCorp/EasyAdminBundle/issues/6247#issuecomment-2111746102