Using Trestle 0.10.0 - unable to use Stimulus controller
Hi!
I am working on adding "Reset password" to trestle-auth provided login page. During that I have discovered that my simple controller is not being connected.
First I wanted to add this:
config.hook("auth.login.form.after") do
content_tag(:div, data: { controller: "auth" }, class: "forgot-password-container") do
button_tag "Forgot password?", type: "button", class: "btn btn-link forgot-password-btn", data: { action: "click->auth#forgotPassword" }
end
end
The auth_controller.js:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
console.log("Started")
}
// other code
}
Then I tried to see if I am able to load this controller at all in Trestle, so I tried adding this in one of the admin files:
col(sm: 6) { password_field :password_confirmation, data: { controller: "auth" } }
Still nothing. I was able to see data-controller="auth" in the source page for given elements, but connect was not ran.
Then I added the same controller to a main page(that is not using Trestle) and the controller connected.
Do I need to add some special configuration?
Thanks!
Right now, trestle-auth doesn't include any JavaScript by default on the login page, which for this case in particular means the Stimulus initialization code is not being ran. See the auth layout for what it does include.
At some point in the future I'd like to add better support for a multi-step 2FA (or oAuth) login flow, which might mean I split up the JavaScript into 'core' and 'main' chunks, where 'core' includes the Stimulus / Turbo setup and other basics.
As a workaround for now you can inject your custom JavaScript using the "auth.head" hook and a custom entry point JS file. This file should require and register your controllers but also initialize Stimulus:
import { Application } from '@hotwired/stimulus'
window.Stimulus = Application.start()
// Manual registration or use:
// import { definitionsFromContext } from '@hotwired/stimulus-webpack-helpers'
import AuthController from "./auth"
Stimulus.register("auth", AuthController)
When I added loading of this js to trestle.rb hook, I got:
I get this error: "Uncaught TypeError: Failed to resolve module specifier "@hotwired/stimulus". Relative references must start with either "/", "./", or "../""
Also as I mentioned, that controller didn't connect even when added data-controller='auth' to one of users_admin.rb fields. Like Trestle wouldn't see that controller. Do I need to register it with something like that: Stimulus.register("auth", AuthController) ?
Now I am thinking on using devise build in views for user login related stuff, but when I uninstall trestle-auth, how hard will it be to require logging in before user is redirected to admin pages?
Or would you recommend sticking with trestle-auth and adding new views and controllers?
Thanks!
When I added loading of this js to trestle.rb hook, I got: I get this error: "Uncaught TypeError: Failed to resolve module specifier "@hotwired/stimulus". Relative references must start with either "/", "./", or "../""
This sounds like you might need to have the script run through JS precompilation. I'm working on some docs to cover custom assets with the main JS asset bundling solutions, but if you let me know which one you are using (e.g. jsbundling-rails with esbuild), I can give you some specific examples.
Do I need to register it with something like that: Stimulus.register("auth", AuthController) ?
Yes, you will need to register manually with Stimulus.register if you are not using the stimulus-webpack-helpers import.
Now I am thinking on using devise build in views for user login related stuff, but when I uninstall trestle-auth, how hard will it be to require logging in before user is redirected to admin pages?
Or would you recommend sticking with trestle-auth and adding new views and controllers?
I'd definitely recommend using trestle-auth with the Devise integration, though in your situation you may want to disable Trestle's login/logout routes and use Devise's, by setting config.auth.enable_login / config.auth.enable_logout (to false) as well as config.auth.login_url to the Devise login path (e.g. main_app.new_user_session_path).
I'd definitely recommend using trestle-auth with the Devise integration, though in your situation you may want to disable Trestle's login/logout routes and use Devise's, by setting config.auth.enable_login / config.auth.enable_logout (to false) as well as config.auth.login_url to the Devise login path (e.g. main_app.new_user_session_path).
@spohlenz Thanks for the tip with using both trestle-auth and Devise login pages! Works like a charm!
This sounds like you might need to have the script run through JS precompilation. I'm working on some docs to cover custom assets with the main JS asset bundling solutions, but if you let me know which one you are using (e.g. jsbundling-rails with esbuild), I can give you some specific examples.
I am using Importmap for Rails
This sounds like you might need to have the script run through JS precompilation. I'm working on some docs to cover custom assets with the main JS asset bundling solutions, but if you let me know which one you are using (e.g. jsbundling-rails with esbuild), I can give you some specific examples.
I am using Importmap for Rails
Trestle unfortunately doesn't yet support importmaps. There are a couple of open PRs in importmap-rails for dealing with multiple entry points (i.e. your app vs Trestle admin) so I'll need to see how they shake out before I can add support.
You may find success by, instead of importing Controller from '@hotwired/stimulus', to instead extend your controller from Trestle.ApplicationController without any imports. You'll then need to call Stimulus.register with your controller class but should then work, at least within the main Trestle admin pages.
For the login page, you can try adding javascript_include_tag "trestle/admin", 'data-turbo-track': 'reload' to the "auth.head" hook. It might be a bit bulky for the login page but should work.