Closed azal-io closed 3 years ago
@BrandonShar i don't think there's a clean way to change the inertia layout inside a controller, is there?
what about adding a layout:
key to the renderer that could dynamically override the layout?
You can change the config on the fly, would that cover this use case?
We do this in one of our apps with a before action on a controller:
before_action -> {
InertiaRails.configure do |config|
config.layout = 'hq'
end
}
@BrandonShar that is also what I did, but it feels like a hackish style, I would prefer more rails way of changing the layout either per controller or per action.
There is also one issue when root template changes, Inertia doesn't just load the new template, you need to do a full page refresh. An expectation would be that Inertia recognizes root template changes and force refresh so two templates don't collide with each other.
before_action -> { InertiaRails.configure do |config| config.layout = 'hq' end }
This only changes server-side but Inertia has no idea about the change until you refresh the page.
So, it is critical to have client-side change as well.
@codecourse-cc that's an interesting use case; it sounds like it would make a great feature.
Adding something like a layout key to the inertia renderer would be simple enough, but in order to support dynamic reloads, we'd need to have the inertia client library send up the current layout on every request (so that we can be sure it actually changed).
This seems reasonable to me, but we'd need to get that client PR accepted and tagged before moving forward with the backend changes.
@BrandonShar yes, that would be one way to do it. I have a Rails app that has multiple user roles. And for each user role we load a different UI Framework. Main App uses heavy JS libraries and we are ok with that, but customer side uses less of them and sometimes totally different ones. For example, we use Vuetify on main app but on customer side we only have like 3-4 views just showing them reports that main dashboard generates, and it uses custom Vue UIs. We can do multi user sign ins by devise but the main feature of app is that a user can have multiple roles and hence access multiple layouts but without manual refresh user will just see the previously used UI (or whatever the layout gives.). I tried to send redirect with inline location.reload() but it just keeps showing modal error page (in development. has not checked in prod). AS you know in traditional Rails, we can change the layout and the app will just work or show it since it is a full request.
this is good discussion... one other thing to watch out for: the configuration is stored globally on the InertiaRails
module... the 1.4.0 update stores this on the thread, but if you get a single thread handling repeated requests, any change you make to the InertiaRails
configuration will carry over to the the request. you might need to manually reset the value, or set it explicitly on every controller action.
https://github.com/inertiajs/inertia-laravel/issues/114
fwiw, multiple root templates seems to be difficult in Laravel, as well
@bknoles I am going to try https://github.com/inertiajs/inertia-laravel/issues/57#issuecomment-570581851 force conflict which I guess will full reload the page. Do you think this might work?
Thanks
If this doesn't work as expected, then I guess I will just create a regular rails root page and have users select their login page, either engineer which is main app, or customer which is the smaller one, and based on that the Rails should load the appropriate Inertia root layout (before action).
This seems working on Rails: But I need to check to more. This does load the right UI for the user role, just a full page reload after login. But I would prefer the Inertia way of things. this seems like a hack.
def create
if (self.resource = warden.authenticate(auth_options))
set_flash_message!(:notice, :signed_in)
sign_in(resource_name, resource)
yield resource if block_given?
# respond_with resource, location: after_sign_in_path_for(resource)
head 409
response.set_header('X-Inertia-Location', after_sign_in_path_for(resource))
else
flash.alert = 'Invalid email or password!'
redirect_to new_user_session_path
end
end
I think the way to do this with the current version of things would be:
before_action -> { InertiaRails.configure do |config| config.layout = 'hq' end }
@BrandonShar can you check this logic?
yea @azal-io i think what we are learning is that there is (currently) no "Inertia" way at all to deal with multiple root templates... we have to implement that logic within the actual app.
i will continue to chew on this, though... perhaps we can come up with something to the gem to help support this
Inertia Rails automatically uses your default application layout. If you'd like to change that, you can do so via the Inertia config.
How I can set root layout dynamically?
I have two devise models, user, and customer
Based on the type I use different layouts but inertia sets root layout at config, is it possible to change the layout dynamically at a controller level?
Thanks