mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 03:54:08 +00:00
feat(settings): add pagination to imports and exports pages (#598)
* feat(settings): split imports and exports * feat(security): sanitize pagination params to prevent abuse * fix(settings): fix syntax in settings nav * feat(settings): internationalize family_exports and imports UI strings * fix(settings): fix coderabbit review * fix(settings): fix coderabbit review * fix(settings): fix coderabbit review * Change default per_page value from 20 to 10 Signed-off-by: Juan José Mata <jjmata@jjmata.com> * Add `/family_export` to navigation * Consistency with old defaults * Align `safe_per_page` even if not DRY --------- Signed-off-by: Julien Orain <julien.orain@gmail.com> Signed-off-by: Juan José Mata <jjmata@jjmata.com> Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: JulienOrain <your-github-email@example.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
@@ -38,7 +38,7 @@ class AccountsController < ApplicationController
|
||||
@q = params.fetch(:q, {}).permit(:search, status: [])
|
||||
entries = @account.entries.where(excluded: false).search(@q).reverse_chronological
|
||||
|
||||
@pagy, @entries = pagy(entries, limit: params[:per_page] || "10")
|
||||
@pagy, @entries = pagy(entries, limit: safe_per_page)
|
||||
|
||||
@activity_feed_data = Account::ActivityFeedData.new(@account, @entries)
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class ApplicationController < ActionController::Base
|
||||
include RestoreLayoutPreferences, Onboardable, Localize, AutoSync, Authentication, Invitable,
|
||||
SelfHostable, StoreLocation, Impersonatable, Breadcrumbable,
|
||||
FeatureGuardable, Notifiable
|
||||
FeatureGuardable, Notifiable, SafePagination
|
||||
include Pundit::Authorization
|
||||
|
||||
include Pagy::Backend
|
||||
|
||||
@@ -27,7 +27,7 @@ module AccountableResource
|
||||
@q = params.fetch(:q, {}).permit(:search)
|
||||
entries = @account.entries.search(@q).reverse_chronological
|
||||
|
||||
@pagy, @entries = pagy(entries, limit: params[:per_page] || "10")
|
||||
@pagy, @entries = pagy(entries, limit: safe_per_page(10))
|
||||
end
|
||||
|
||||
def edit
|
||||
|
||||
15
app/controllers/concerns/safe_pagination.rb
Normal file
15
app/controllers/concerns/safe_pagination.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SafePagination
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
private
|
||||
def safe_per_page(default = 10)
|
||||
allowed_values = [ 10, 20, 30, 50, 100 ]
|
||||
per_page = params[:per_page].to_i
|
||||
|
||||
return default if per_page <= 0
|
||||
|
||||
allowed_values.include?(per_page) ? per_page : allowed_values.min_by { |v| (v - per_page).abs }
|
||||
end
|
||||
end
|
||||
@@ -13,29 +13,33 @@ class FamilyExportsController < ApplicationController
|
||||
FamilyDataExportJob.perform_later(@export)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to imports_path, notice: "Export started. You'll be able to download it shortly." }
|
||||
format.html { redirect_to family_exports_path, notice: t("family_exports.create.success") }
|
||||
format.turbo_stream {
|
||||
stream_redirect_to imports_path, notice: "Export started. You'll be able to download it shortly."
|
||||
stream_redirect_to family_exports_path, notice: t("family_exports.create.success")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
@exports = Current.family.family_exports.ordered.limit(10)
|
||||
render layout: false # For turbo frame
|
||||
@pagy, @exports = pagy(Current.family.family_exports.ordered, limit: safe_per_page)
|
||||
@breadcrumbs = [
|
||||
[ t("breadcrumbs.home"), root_path ],
|
||||
[ t("breadcrumbs.exports"), family_exports_path ]
|
||||
]
|
||||
render layout: "settings"
|
||||
end
|
||||
|
||||
def download
|
||||
if @export.downloadable?
|
||||
redirect_to @export.export_file, allow_other_host: true
|
||||
else
|
||||
redirect_to imports_path, alert: "Export not ready for download"
|
||||
redirect_to family_exports_path, alert: t("family_exports.export_not_ready")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@export.destroy
|
||||
redirect_to imports_path, notice: "Export deleted successfully"
|
||||
redirect_to family_exports_path, notice: t("family_exports.destroy.success")
|
||||
end
|
||||
|
||||
private
|
||||
@@ -46,7 +50,7 @@ class FamilyExportsController < ApplicationController
|
||||
|
||||
def require_admin
|
||||
unless Current.user.admin?
|
||||
redirect_to root_path, alert: "Access denied"
|
||||
redirect_to root_path, alert: t("family_exports.access_denied")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,11 +12,10 @@ class ImportsController < ApplicationController
|
||||
end
|
||||
|
||||
def index
|
||||
@imports = Current.family.imports
|
||||
@exports = Current.user.admin? ? Current.family.family_exports.ordered.limit(10) : nil
|
||||
@pagy, @imports = pagy(Current.family.imports.where(type: Import::TYPES).ordered, limit: safe_per_page)
|
||||
@breadcrumbs = [
|
||||
[ "Home", root_path ],
|
||||
[ "Import/Export", imports_path ]
|
||||
[ t("breadcrumbs.home"), root_path ],
|
||||
[ t("breadcrumbs.imports"), imports_path ]
|
||||
]
|
||||
render layout: "settings"
|
||||
end
|
||||
@@ -90,7 +89,7 @@ class ImportsController < ApplicationController
|
||||
|
||||
private
|
||||
def set_import
|
||||
@import = Current.family.imports.find(params[:id])
|
||||
@import = Current.family.imports.includes(:account).find(params[:id])
|
||||
end
|
||||
|
||||
def import_params
|
||||
|
||||
@@ -20,7 +20,7 @@ class RulesController < ApplicationController
|
||||
.recent
|
||||
.includes(:rule)
|
||||
|
||||
@pagy, @recent_runs = pagy(recent_runs_scope, limit: params[:per_page] || 20, page_param: :runs_page)
|
||||
@pagy, @recent_runs = pagy(recent_runs_scope, limit: safe_per_page, page_param: :runs_page)
|
||||
|
||||
render layout: "settings"
|
||||
end
|
||||
|
||||
@@ -21,7 +21,7 @@ class TransactionsController < ApplicationController
|
||||
:transfer_as_inflow, :transfer_as_outflow
|
||||
)
|
||||
|
||||
@pagy, @transactions = pagy(base_scope, limit: per_page)
|
||||
@pagy, @transactions = pagy(base_scope, limit: safe_per_page)
|
||||
|
||||
# Load projected recurring transactions for next month
|
||||
@projected_recurring = Current.family.recurring_transactions
|
||||
@@ -281,10 +281,6 @@ class TransactionsController < ApplicationController
|
||||
end
|
||||
|
||||
private
|
||||
def per_page
|
||||
params[:per_page].to_i.positive? ? params[:per_page].to_i : 20
|
||||
end
|
||||
|
||||
def needs_rule_notification?(transaction)
|
||||
return false if Current.user.rule_prompts_disabled
|
||||
|
||||
|
||||
Reference in New Issue
Block a user