Top Menu

Jump to content
Home
    Modules
      • Projects
      • Activity
      • Work packages
      • Gantt charts
      • Calendars
      • Team planners
      • Boards
      • News
    • Getting started
    • Introduction video
      Welcome to OpenProject Community
      Get a quick overview of project management and team collaboration with OpenProject. You can restart this video from the help menu.

    • Help and support
    • Upgrade to Enterprise edition
    • User guides
    • Videos
    • Shortcuts
    • Community forum
    • Enterprise support

    • Additional resources
    • Data privacy and security policy
    • Digital accessibility (DE)
    • OpenProject website
    • Security alerts / Newsletter
    • OpenProject blog
    • Release notes
    • Report a bug
    • Development roadmap
    • Add and edit translations
    • API documentation
  • Sign in
      Forgot your password?

      or sign in with your existing account

      Google

Side Menu

  • Overview
  • Activity
    Activity
  • Roadmap
  • Work packages
    Work packages
  • Gantt charts
    Gantt charts
  • Calendars
    Calendars
  • Team planners
    Team planners
  • Boards
    Boards
  • News
  • Forums

Content

Development
  1. OpenProject
  2. Forums
  3. Development
  4. Stimulus in Plugin

Stimulus in Plugin

Added by Niclas UNIBE about 1 year ago

Hei there!

I'm currently working on a plugin and I would like to use hotwire stimulus.

I don't see how to do this from the documentation or sample plugins.

When using the dynamic loading of the stimulus controller, the plugin's controller file is not found (not surprisingly).


To me it seems like the problem is that the stimulus OpApplicationController needs the dynamically loaded stimulus controller to be in the <op-core-root>/frontend/src/stimulus/controllers/dynamic directory.

However the plugin frontend linking symlinks to <op-core-root>/frontend/src/app/features/plugins.
So there is no way to import the symlinked stimulus controller files.

So I see two solutions:

  1. Symlinking the plugin controllers/dynamic directory to the OpenProject core's stimulus controllers directory (plus probably adjusting the OpApplicationController a bit)
  2. Using stimulus' application.register() function to add the plugins controller in a JS script in the plugin.

The first solution would be a lot nicer since it ties in nicely with the symlinking used for angluar already, but requires a change in OP.

The second approach feels a bit like a hack, but wouldn't require a change in OP.

I could make a merge request for option 1 if that is a favorable solution.

What is your opinion?

PS: I really like the OP code in general. It's challenging to understand, but I learn so much from it!


Replies (4)

RE: Stimulus in Plugin - Added by Niclas UNIBE about 1 year ago

Another solution I got working is to create a second stimulus instance.
This is of course very dissatisfying and I also loose the "dynamic" loading of stimulus controllers implemented in OP.

What I did is starting another stimulus application like this:

import { Application } from '@hotwired/stimulus';
import { HelloController }  from "./stimulus/controllers/dynamic/hello.controller";

const instance = Application.start();
window.StimulusCustom = instance;

instance.handleError = (error, message, detail) => {
  console.warn(error, message, detail);
};
instance.register('hello', HelloController);

and in my erb

<div data-controller="hello">
<input data-hello-target="name" type="text">
  <button data-action="click->hello#greet">Greet</button>
</div>

The hello.controller.ts ist the stimulus controller from the official tutorial example.

RE: Stimulus in Plugin - Added by Alexander Aleschenko 7 months ago

Got into the same question: made a plugin with new pages in admin part and want to add some fancy "(Un)Check All" icons for tables like at workflows status matrix but don't want to start another stimulus instance.

RE: Stimulus in Plugin - Added by Niclas UNIBE 7 months ago

I haven't found any better solution than the one described above.

The frontend/module/main.ts registers all the stimulus controllers to a new stimulus instance just for the plugin.
And I keep all stimulus controllers in a subdirectory frontend/module/stimulus .
That's it.

# import the MyStimulusController

declare global {
    interface Window {
        StimulusIBU:Application
    }
}

const instance = Application.start()
window.StimulusPlugin = instance

instance.register("my-stimulus", MyStimulusController)

What can I say... it works. And it's the only way I got it to work.
And it's managable and extendable.
I haven't found any other plugins that use stimulus. The modules that are part of the OpenProject source (modules/in the OP code) all put their stimulus controllers into the frontend/src/stimulus/controllers/dynamic and not into their own module/xyz-module/frontend directory. So there's no solution for us to copy from there either.
I wish I could give you a more satisfying answer...

RE: Stimulus in Plugin - Added by Alexander Aleschenko 6 months ago

Thanks for your answer, Niclas. I came with kinda same result while experimenting, unfortunately I'm not a frontend guy and can't do a lot. So your way is the best ATM i thing.

  • (1 - 4/4)
Loading...