Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
86 changes: 57 additions & 29 deletions app/controllers/better_together/host_dashboard_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

41 changes: 9 additions & 32 deletions app/views/better_together/host_dashboard/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,50 +12,27 @@
<div class="better-together-resources mt-4">
<h2><%= t('host_dashboard.index.better_together') %></h2>
<div class="row mt-3 row-cols-1 row-cols-sm-2 row-cols-md-3">
<!-- Communities -->
<%= render partial: 'resource_card', locals: { collection: @communities, count: @community_count, url_helper: :community_path } %>

<!-- Navigation Areas -->
<%= render partial: 'resource_card', locals: { collection: @navigation_areas, count: @navigation_area_count, url_helper: :navigation_area_path } %>

<!-- Pages -->
<%= render partial: 'resource_card', locals: { collection: @pages, count: @page_count, url_helper: :page_path } %>

<!-- Platforms -->
<%= render partial: 'resource_card', locals: { collection: @platforms, count: @platform_count, url_helper: :platform_path } %>

<!-- People -->
<%= render partial: 'resource_card', locals: { collection: @people, count: @person_count, url_helper: :person_path } %>

<!-- Roles -->
<%= render partial: 'resource_card', locals: { collection: @roles, count: @role_count, url_helper: :role_path } %>

<!-- Resource Permissions -->
<%= render partial: 'resource_card', locals: { collection: @resource_permissions, count: @resource_permission_count, url_helper: :resource_permission_path } %>

<!-- Users -->
<%= 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 %>
</div>

<div id="content-section" class="row mt-3">
<div class="col-12">
<h3><%= t('host_dashboard.index.content') %></h3>
</div>
<%= 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 %>
</div>

<div id="geography-section" class="row mt-3">
<div class="col-12">
<h3><%= t('host_dashboard.index.geography') %></h3>
</div>
<%= 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 %>
</div>
</div>
</div>
26 changes: 26 additions & 0 deletions docs/host_dashboard_extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Loading