diff --git a/README.md b/README.md index 0163d7f32..07ec5fa01 100644 --- a/README.md +++ b/README.md @@ -108,3 +108,17 @@ Run the RSpec tests: ```bash bin/dc-run app rspec ``` + +## Host Dashboard Customization + +Host applications can modify which resources appear on the host dashboard by adjusting the resource definition arrays in an initializer. Each resource hash accepts a `:model` and `:url_helper` with optional `:collection` and `:count` lambdas. + +```ruby +# config/initializers/host_dashboard_resources.rb +BetterTogether::HostDashboardController::ROOT_RESOURCE_DEFINITIONS << { + model: -> { MyResource }, + url_helper: -> { :my_resource_path } +} +``` + +See `docs/host_dashboard_extensions.md` for more customization examples. diff --git a/app/controllers/better_together/host_dashboard_controller.rb b/app/controllers/better_together/host_dashboard_controller.rb index d0fd6dcaf..d11313797 100644 --- a/app/controllers/better_together/host_dashboard_controller.rb +++ b/app/controllers/better_together/host_dashboard_controller.rb @@ -2,43 +2,71 @@ module BetterTogether class HostDashboardController < ApplicationController # rubocop:todo Style/Documentation - def index # rubocop:todo Metrics/MethodLength - root_classes = [ - Community, NavigationArea, Page, Platform, Person, Role, ResourcePermission, User, - Conversation, Message, Category - ] - - root_classes.each do |klass| - # sets @klasses and @klass_count instance variables - set_resource_variables(klass) - end + ROOT_RESOURCE_DEFINITIONS = [ + { model: Community, url_helper: :community_path }, + { model: NavigationArea, url_helper: :navigation_area_path }, + { model: Page, url_helper: :page_path }, + { model: Platform, url_helper: :platform_path }, + { model: Person, url_helper: :person_path }, + { model: Role, url_helper: :role_path }, + { model: ResourcePermission, url_helper: :resource_permission_path }, + { model: User, url_helper: :user_path }, + { model: Conversation, url_helper: :conversation_path }, + { model: Message, url_helper: :message_path }, + { model: Category, url_helper: :category_path } + ] - content_classes = [ - Content::Block - ] + CONTENT_RESOURCE_DEFINITIONS = [ + { model: Content::Block, url_helper: :content_block_path } + ] - content_classes.each do |klass| - # sets @content_klasses and @content_klass_count instance variables - set_resource_variables(klass, prefix: 'content') - end + GEOGRAPHY_RESOURCE_DEFINITIONS = [ + { model: Geography::Continent, url_helper: :geography_continent_path }, + { model: Geography::Country, url_helper: :geography_country_path }, + { model: Geography::State, url_helper: :geography_state_path }, + { model: Geography::Region, url_helper: :geography_region_path }, + { model: Geography::Settlement, url_helper: :geography_settlement_path } + ] + + def index + @root_resources = build_resources(ROOT_RESOURCE_DEFINITIONS) + @content_resources = build_resources(CONTENT_RESOURCE_DEFINITIONS) + @geography_resources = build_resources(GEOGRAPHY_RESOURCE_DEFINITIONS) + end + + protected + + def build_resources(definitions) + definitions.map do |definition| + model = evaluate(definition[:model]) + url_helper = evaluate(definition[:url_helper]) + + collection = if definition[:collection]&.respond_to?(:call) + definition[:collection].call + else + model.order(created_at: :desc).limit(3) + end - geography_classes = [ - Geography::Continent, Geography::Country, Geography::State, Geography::Region, Geography::Settlement - ] + count = if definition[:count]&.respond_to?(:call) + definition[:count].call + else + model.count + end - geography_classes.each do |klass| - # sets @geography_klasses and @geography_klass_count instance variables - set_resource_variables(klass, prefix: 'geography') + { + model_class: model, + collection: collection, + count: count, + url_helper: url_helper + } end end - protected + private - def set_resource_variables(klass, prefix: nil) - variable_name = klass.model_name.name.demodulize.underscore - instance_variable_set(:"@#{"#{prefix}_" if prefix}#{variable_name.pluralize}", - klass.order(created_at: :desc).limit(3)) - instance_variable_set(:"@#{"#{prefix}_" if prefix}#{variable_name}_count", klass.count) + def evaluate(value) + value.respond_to?(:call) ? value.call : value end end end + diff --git a/app/views/better_together/host_dashboard/index.html.erb b/app/views/better_together/host_dashboard/index.html.erb index d43f729ea..1c9173494 100644 --- a/app/views/better_together/host_dashboard/index.html.erb +++ b/app/views/better_together/host_dashboard/index.html.erb @@ -12,50 +12,27 @@

<%= t('host_dashboard.index.better_together') %>

- - <%= render partial: 'resource_card', locals: { collection: @communities, count: @community_count, url_helper: :community_path } %> - - - <%= render partial: 'resource_card', locals: { collection: @navigation_areas, count: @navigation_area_count, url_helper: :navigation_area_path } %> - - - <%= render partial: 'resource_card', locals: { collection: @pages, count: @page_count, url_helper: :page_path } %> - - - <%= render partial: 'resource_card', locals: { collection: @platforms, count: @platform_count, url_helper: :platform_path } %> - - - <%= render partial: 'resource_card', locals: { collection: @people, count: @person_count, url_helper: :person_path } %> - - - <%= render partial: 'resource_card', locals: { collection: @roles, count: @role_count, url_helper: :role_path } %> - - - <%= render partial: 'resource_card', locals: { collection: @resource_permissions, count: @resource_permission_count, url_helper: :resource_permission_path } %> - - - <%= render partial: 'resource_card', locals: { collection: @users, count: @user_count, url_helper: :user_path } %> - <%= render partial: 'resource_card', locals: { collection: @conversations, count: @conversation_count, url_helper: :conversation_path } %> - <%= render partial: 'resource_card', locals: { collection: @messages, count: @message_count, url_helper: :message_path } %> - <%= render partial: 'resource_card', locals: { collection: @categories, count: @category_count, url_helper: :category_path } %> + <% @root_resources.each do |resource| %> + <%= render partial: 'resource_card', locals: resource %> + <% end %>

<%= t('host_dashboard.index.content') %>

- <%= render partial: 'resource_card', locals: { model_class: ::BetterTogether::Content::Block, collection: @content_blocks, count: @content_block_count, url_helper: :content_block_path } %> + <% @content_resources.each do |resource| %> + <%= render partial: 'resource_card', locals: resource %> + <% end %>

<%= t('host_dashboard.index.geography') %>

- <%= render partial: 'resource_card', locals: {collection: @geography_continents, count: @geography_continent_count, url_helper: :geography_continent_path } %> - <%= render partial: 'resource_card', locals: {collection: @geography_countries, count: @geography_country_count, url_helper: :geography_country_path } %> - <%= render partial: 'resource_card', locals: {collection: @geography_states, count: @geography_state_count, url_helper: :geography_state_path } %> - <%= render partial: 'resource_card', locals: {collection: @geography_regions, count: @geography_region_count, url_helper: :geography_region_path } %> - <%= render partial: 'resource_card', locals: {collection: @geography_settlements, count: @geography_settlement_count, url_helper: :geography_settlement_path } %> + <% @geography_resources.each do |resource| %> + <%= render partial: 'resource_card', locals: resource %> + <% end %>
diff --git a/docs/host_dashboard_extensions.md b/docs/host_dashboard_extensions.md index c7df9ac9b..ac39cd6fe 100644 --- a/docs/host_dashboard_extensions.md +++ b/docs/host_dashboard_extensions.md @@ -22,3 +22,29 @@ Example: ``` If the partial is absent, the dashboard simply skips this section. + +## Customizing Resource Listings + +Host applications can also adjust the resources displayed on the dashboard by modifying the resource definition arrays exposed by the controller. Each definition hash expects a `:model` and `:url_helper` with optional `:collection` and `:count` lambdas. + +Append a new resource: + +```ruby +# config/initializers/host_dashboard_resources.rb +BetterTogether::HostDashboardController::ROOT_RESOURCE_DEFINITIONS << { + model: -> { MyResource }, + url_helper: -> { :my_resource_path }, + collection: -> { MyResource.limit(5) }, # optional + count: -> { MyResource.count } # optional +} +``` + +Or replace the entire list: + +```ruby +BetterTogether::HostDashboardController::CONTENT_RESOURCE_DEFINITIONS = [ + { model: -> { MyOtherResource }, url_helper: -> { :my_other_resource_path } } +] +``` + +When `:collection` or `:count` are omitted, the dashboard falls back to the model's latest three records and total count.