<div class="lui-index-layout"> <turbo-frame id="lui-index-header" class="lui-index_header"> <h1 class="lui-index_header__title"> User Groups </h1> <div> </div> </turbo-frame> <div class="w-full grow"> <a data-turbo-frame="lui-index-header" href="/turboframe_layout/change_header">Click here to change IndexHeader</a> </div> <turbo-frame class="lui-show-layout__drawer_wrapper" id="lui-main-layout-drawer_bar" class="fixed top-[106px] right-0" data-controller="drawer-bar"> </turbo-frame></div>V2::AppLayout
Description
Related components
| Used Components | Components where is Used |
|---|---|
| Label |
Usage rules
- ✅ Do
- ❌ Don't
<%= render LooposUi::IndexLayout.new() do |layout| %> <% layout.with_header(title: "User Groups") %> <%= link_to("Click here to change IndexHeader", main_app.change_header_turboframe_layout_path, data: {turbo_frame: 'lui-index-header'}) %><% end %>No notes provided.
No params configured.
AppLayout
You can use AppLayoutComponent (deprecated) or AppLayout as the name of the component. It's the top-level component that wraps the entire application layout. By default, will render the sidebar using the config from the initializer.
Arguments
| Property | Default | Description |
|---|---|---|
stream_namespaces |
[] |
Optional symbol or array of symbols used to namespace the toaster Turbo Stream subscription rendered by the layout. |
Slots
header- Open slot for the header. Each app must render the header provided by the Manager in this slot.sidebar- Typed slot (LooposUi::Sidebar). If omitted, the app will render the sidebar using the config (preferred way).select_bar- Typed slot (LooposUi::AppLayout::SelectBar). Any content may be passed in.bottom_bar- Typed slot (LooposUi::BottomBar). Displays action buttons at the bottom of the layout.
The most common usage for the sidebar will be something like this:
<%= render LooposUi::AppLayout.new do |app_layout| %> <% app_layout.with_select_bar do %> <%= form_tag("#", method: :get, data: { turbo_frame: LooposUi::MainLayout::TURBO_FRAME_ID }) do %> <%= render LooposUi::SelectBar::Selector.new(name: name, options: options, value: value) %> <% end %> <% end if show_select_bar %> <%# ... >Note: The select bar will only render if it's contents have a Selector (see above) and the selector has at least two options to choose from.
In this scenario, we use the LooposUi::SelectBar::Selector component wrapped in a form tag.
The form is mandatory, and the Selector component will always submit the form when the value changes.
The options argument is a list of hashes with value and text Eg. [{ value: "core1", text: "Core 1" }]
The value is the value of the current option, and must be one of the options.
The name is the name of the input field, and will be used to submit the form.
Toaster stream namespaces
LooposUi::V2::AppLayout now includes LooposUi::StreamToasters and subscribes to a toaster Turbo Stream target derived from stream_namespaces.
The final stream name is built from:
- the values passed through
stream_namespaces - the literal
toasters - the current user id when a user is available
This allows multiple layouts or app sections to receive different toaster streams.
Example
<%= render LooposUi::V2::AppLayout.new(stream_namespaces: :marketplace) do |app_layout| %> <% app_layout.with_navbar do %> <div>Marketplace</div> <% end %> <div>Content</div><% end %>With this setup, the layout subscribes to the same toaster target used by backend calls such as stream_toaster_success(keys: :marketplace, ...).
You can also provide multiple namespaces:
<%= render LooposUi::V2::AppLayout.new(stream_namespaces: [:marketplace, :orders]) do %> <div>Content</div><% end %>And then you can:
# In controllerstream_toaster_namespaces :marketplace, :orders# Or setting the namespace per stream call:stream_toast(..., keys: [:marketplace, :orders])Updating turbo-frames
The index layout has a turbo-frame for the header and another for the body. The content of these components can be updated individually from the app's side. To do this, the user will need to refer the turbo-frame id to update. Example:
- In this example the turbo-frame being updated is the indexheader with the turboframe id "lui-index-header";
- The controller being used is the turboframelayoutcontroller.rb and the method being called is named "change_header";
<%= link_to("Click here to change IndexHeader", change_header_turboframe_layout_index_path, data: {turbo_frame: 'lui-index-header'}) %>