Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a8ae0a6
feat(models): specify translation types for name and update building …
rsmithlal Oct 26, 2025
41ed515
Refactor pages controller to include filtering and sorting functionality
rsmithlal Oct 27, 2025
18e00b8
fix(tests): correct RSpec describe syntax for pages filtering and sor…
rsmithlal Oct 27, 2025
e656a98
refactor(pages): streamline filtering and sorting logic in PagesContr…
rsmithlal Oct 27, 2025
8d593c4
feat(translations): update name translations to use string type for c…
rsmithlal Oct 27, 2025
8363c53
fix(image_helper): handle ActiveStorage::FileNotFoundError in profile…
rsmithlal Oct 27, 2025
8d275ab
feat(platform_invitations): add index action and view for platform in…
rsmithlal Oct 27, 2025
0d7c254
Update platform invitations views for better performance
rsmithlal Oct 27, 2025
33d28ac
feat(platforms): optimize platform memberships loading to prevent N+1…
rsmithlal Oct 27, 2025
cbd75ba
Rubocop fixes
rsmithlal Oct 27, 2025
b4cc929
feat(metrics): implement UTF-8 URL handling and validations for LinkC…
rsmithlal Oct 27, 2025
657e91f
refactor(events): remove unnecessary text translations preload and up…
rsmithlal Oct 27, 2025
ad0d317
test(metrics): refactor UTF-8 URL handling tests for clarity and stru…
rsmithlal Oct 27, 2025
2f06a62
refactor(person): remove unnecessary text translations from event inc…
rsmithlal Oct 27, 2025
fedc926
refactor(locales): reorder and standardize translations in English, S…
rsmithlal Oct 28, 2025
882f013
refactor(image_helper_spec): simplify response stubbing for profile i…
rsmithlal Oct 28, 2025
6fd2cd3
Rubocop fixes
rsmithlal Oct 28, 2025
54fd526
refactor(locales): remove unused platform invitation translations fro…
rsmithlal Oct 28, 2025
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

This file was deleted.

1 change: 1 addition & 0 deletions app/assets/stylesheets/better_together/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
@use 'metrics';
@use 'navigation';
@use 'notifications';
@use 'pagination';
@use 'profiles';
@use 'share';
@use 'sidebar_nav';
Expand Down
79 changes: 79 additions & 0 deletions app/assets/stylesheets/better_together/pagination.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* Better Together Pagination Styles */
.pagination {
--bs-pagination-padding-x: 0.75rem;
--bs-pagination-padding-y: 0.5rem;
--bs-pagination-font-size: 0.875rem;
--bs-pagination-color: var(--bs-link-color);
--bs-pagination-bg: transparent;
--bs-pagination-border-width: 0;
--bs-pagination-border-color: transparent;
--bs-pagination-border-radius: 0.375rem;
--bs-pagination-hover-color: var(--bs-primary);
--bs-pagination-hover-bg: var(--bs-gray-100);
--bs-pagination-hover-border-color: transparent;
--bs-pagination-focus-color: var(--bs-primary);
--bs-pagination-focus-bg: var(--bs-gray-100);
--bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
--bs-pagination-active-color: #fff;
--bs-pagination-active-bg: var(--bs-primary);
--bs-pagination-active-border-color: var(--bs-primary);
--bs-pagination-disabled-color: var(--bs-secondary-color);
--bs-pagination-disabled-bg: transparent;
--bs-pagination-disabled-border-color: transparent;
}

.pagination-info {
display: flex;
align-items: center;
min-height: 2rem;
}

.pagination-info small {
font-weight: 500;
letter-spacing: 0.025em;
}

/* Responsive pagination */
@media (max-width: 768px) {
.pagination-info {
margin-bottom: 0.75rem;
text-align: center;
width: 100%;
}

.pagination {
justify-content: center !important;
}

.d-flex.justify-content-between.align-items-center.flex-wrap {
flex-direction: column;
align-items: center;
}
}

/* Enhanced focus states for accessibility */
.page-link:focus {
outline: 2px solid transparent;
outline-offset: 2px;
}

.page-link:focus-visible {
box-shadow: var(--bs-pagination-focus-box-shadow);
outline: 2px solid var(--bs-primary);
outline-offset: 2px;
}

/* Smooth transitions */
.page-link {
transition: all 0.15s ease-in-out;
}

/* Card styling for pagination container */
.pagination .card {
background: var(--bs-gray-50);
border: 1px solid var(--bs-border-color-translucent);
}

.pagination .card-body {
background: transparent;
}
1 change: 0 additions & 1 deletion app/controllers/better_together/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,6 @@ def preload_event_associations! # rubocop:todo Metrics/CyclomaticComplexity, Met

# Preload translations for the event itself
@event.string_translations.load
@event.text_translations.load

# Preload cover image attachment to avoid attachment queries
@event.cover_image_attachment&.blob&.load if @event.cover_image.attached?
Expand Down
116 changes: 95 additions & 21 deletions app/controllers/better_together/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@ class PagesController < FriendlyResourceController # rubocop:todo Metrics/ClassL

def index
authorize resource_class
@pages = resource_collection

@pages = build_filtered_collection
@pages = apply_sorting(@pages)
@pages = @pages.page(params[:page]).per(25)
end

def show
# Hide pages that don't exist or aren't viewable to the current user as 404s
render_not_found and return if @page.nil?

@content_blocks = @page.content_blocks
# Preload content blocks with their associations for better performance
@content_blocks = @page.content_blocks.includes(
background_image_file_attachment: :blob
)
@layout = 'layouts/better_together/page'
@layout = @page.layout if @page.layout.present?
end
Expand Down Expand Up @@ -141,29 +147,13 @@ def safe_page_redirect_url

def set_page
@page = set_resource_instance
return unless @page

@page = preload_page_associations(@page)
rescue ActiveRecord::RecordNotFound
render_not_found && return
end

def page_params # rubocop:todo Metrics/MethodLength
params.require(:page).permit(
:meta_description, :keywords, :published_at, :sidebar_nav_id,
:privacy, :layout, :template, *Page.localized_attribute_list,
*Page.extra_permitted_attributes,
page_blocks_attributes: [
:id, :position, :_destroy,
{
block_attributes: [
:id, :type, :identifier, :_destroy,
*BetterTogether::Content::Block.localized_block_attributes,
*BetterTogether::Content::Block.storext_keys,
*BetterTogether::Content::Block.extra_permitted_attributes
]
}
]
)
end

def resource_class
::BetterTogether::Page
end
Expand All @@ -172,8 +162,92 @@ def resource_collection
policy_scope(resource_class)
end

def apply_sorting(collection)
sort_by = params[:sort_by]
sort_direction = params[:sort_direction] == 'desc' ? :desc : :asc

case sort_by
when 'title', 'slug'
collection.i18n.order(sort_by.to_sym => sort_direction)
else
collection.order(collection.arel_table[:identifier].send(sort_direction))
end
end

def build_filtered_collection
collection = base_collection
collection = apply_title_filter(collection) if params[:title_filter].present?
collection = apply_slug_filter(collection) if params[:slug_filter].present?
collection
end

def translatable_conditions
[]
end

def base_collection
resource_collection.includes(
:string_translations,
page_blocks: {
block: [{ background_image_file_attachment: :blob }]
}
)
end

def apply_title_filter(collection)
search_term = params[:title_filter].strip
collection.i18n { title.matches("%#{search_term}%") }
end

def apply_slug_filter(collection)
search_term = params[:slug_filter].strip
collection.i18n { slug.matches("%#{search_term}%") }
end

def preload_page_associations(page)
resource_class.includes(page_includes).find(page.id)
end

def page_includes
[
:string_translations,
:sidebar_nav,
{ page_blocks: {
block: [{ background_image_file_attachment: :blob }]
} }
]
end

def page_params
params.require(:page).permit(
basic_page_attributes + page_blocks_permitted_attributes
)
end

def basic_page_attributes
[
:meta_description, :keywords, :published_at, :sidebar_nav_id,
:privacy, :layout, :template, *Page.localized_attribute_list,
*Page.extra_permitted_attributes
]
end

def page_blocks_permitted_attributes
[
page_blocks_attributes: [
:id, :position, :_destroy,
{ block_attributes: block_permitted_attributes }
]
]
end

def block_permitted_attributes
[
:id, :type, :identifier, :_destroy,
*BetterTogether::Content::Block.localized_block_attributes,
*BetterTogether::Content::Block.storext_keys,
*BetterTogether::Content::Block.extra_permitted_attributes
]
end
end
end
Loading
Loading