admin/docs/index_pages.md
Index pages are common in the admin interface, and they are used to display a list of records for a specific model.
Since these pages often have a similar appearance, we have a dedicated component to build them. This component helps avoid writing repetitive boilerplate code.
index actionThe index action is the standard action used to display index pages. It's a standard GET action that renders the index component.
To support search scopes and filters the controller should include the SolidusAdmin::ControllerHelpers::Search module and call
apply_search_to as follows:
class SolidusAdmin::UsersController < SolidusAdmin::BaseController
include SolidusAdmin::ControllerHelpers::Search
def index
users = apply_search_to(Spree.user_class.order(id: :desc), param: :q)
# ...
For pagination support, the index action should also call the set_page_and_extract_portion_from method provided by the geared_pagination gem. This method sets the @page instance variable to the paginated collection and returns the portion of the collection to be displayed on the current page.
def index
users = apply_search_to(Spree.user_class.order(id: :desc), param: :q)
set_page_and_extract_portion_from(users)
# ...
Finally, the index action should render the index component passing the @page instance variable as the collection prop.
def index
users = apply_search_to(Spree.user_class.order(id: :desc), param: :q)
set_page_and_extract_portion_from(users)
render component('users/index').new(page: @page)
end
ui/pages/index componentThe ui/pages/index component is an abstract component that provides sensible defaults for index pages. It also offers template methods that can be used to customize the behavior of these pages.
We recommend examining existing index pages and the UI component itself to understand how they work. In this section, we'll cover the most important aspects.
The index component requires only the page argument during initialization, all other parameters are provided through template methods.
class SolidusAdmin::Users::Index < Solidus::Admin::UI::Pages::Index
def model_class
Spree.user_class
end
end
render component('users/index').new(page: @page)
Batch actions are operations that can be performed on multiple records simultaneously. The index page internally uses the ui/table component and depends on the batch_actions method to render the batch actions dropdown.
In the component, batch actions are provided as an array of hashes, with each hash representing a single batch action. Each hash must contain the following keys:
label: the name of the batch action, this will be used as the label of the dropdown itemicon: the remix icon-name to be used as the icon of the dropdown item (see the ui/icon component for more information)action: the name of the action to be performed when the batch action is selected. It can be a URL or a pathmethod: the HTTP method to be used when performing the action, such as :deleteThe batch_actions method is called in the context of the controller, so you can use any controller method or helper to build the batch actions.
Batch actions will be submitted to the specified action with an id parameter containing the IDs of the selected records. Using id as the
parameter name allows the same action to support both batch and single-record actions for standard routes.
E.g.
# in the component
def batch_actions
[
{
label: "Delete",
icon: "trash",
action: solidus_admin.delete_admin_users_path,
method: :delete
}
]
end
# in the controller
def delete
@users = Spree.user_class.where(id: params[:id])
@users.destroy_all
flash[:notice] = "Admin users deleted"
redirect_to solidus_admin.users_path, status: :see_other
end
Search scopes are used to filter the records displayed on the index page. The index page internally uses the ui/table component and relies on the scopes method to render the search scope buttons.
In the component, search scopes are provided as an array of hashes, with each hash representing a single search scope. Each hash must contain the following keys:
label: the name of the search scope, used as the label of the buttonname: the name of the search scope, sent via q[scope] parameter when the button is clickeddefault: whether this is the default search scope, used to highlight the button when when the page is loadedOn the controller side, search scopes can be defined with the search_scope helper, provided by SolidusAdmin::ControllerHelpers::Search. This helper takes a name, an optional default keyword argument, and a block. The block will be called with the current scope and should return a new ActiveRecord scope.
E.g.
module SolidusAdmin
class UsersController < SolidusAdmin::BaseController
include SolidusAdmin::ControllerHelpers::Search
search_scope(:customers, default: true) { _1.left_outer_joins(:role_users).where(role_users: { id: nil }) }
search_scope(:admin) { _1.joins(:role_users).distinct }
search_scope(:with_orders) { _1.joins(:orders).distinct }
search_scope(:without_orders) { _1.left_outer_joins(:orders).where(orders: { id: nil }) }
search_scope(:all)
def index
users = apply_search_to(Spree.user_class.order(id: :desc), param: :q)
# ...
Filters are used to narrow down the records displayed on the index page. The index page internally uses the ui/table/ransack_filter component and depends on the filters method to render the filters dropdown.
In the component, filters are represented as an array of hashes, with each hash representing a single filter. Each hash must contain the following keys:
label: the name of the filter, used as the label in the filter barattribute: the name of the ransack-enabled attribute to be filteredpredicate: the name of the ransack predicate to be used, e.g. eq, in, contoptions: an array of options to be used for the filter, in the standard rails form of [["label", "value"], ...]On the controller side it's enough to add ransack support to the index action by including SolidusAdmin::ControllerHelpers::Search and calling
apply_search_to as explained in the Index action section.
On the controller side, you simply need to add Ransack support to the index action by including the SolidusAdmin::ControllerHelpers::Search module and calling the apply_search_to method, as explained in the Index action section.