mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 12:04:08 +00:00
Add customizable menu order for user accounts (#44)
* Add customizable menu order for user accounts Introduces a MenuOrder model and concern to allow users to select their preferred account ordering (by name or balance, ascending or descending). Adds a default_order field to users, updates user preferences UI, and applies the selected order to balance sheet account listings. * Rename MenuOrder to AccountOrder and update user order field Refactors the MenuOrder model to AccountOrder and updates all references accordingly. Replaces the user's default_order field with default_account_order, including migration changes, validations, and form fields. Updates localization and schema to reflect the new naming. * Update balance_sheet.rb * Fix for nil Current.user when rake runs in balance_sheet model --------- Signed-off-by: Aluisio Pereira <oaluiser@gmail.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
14
app/controllers/concerns/orderable.rb
Normal file
14
app/controllers/concerns/orderable.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
module Orderable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
before_action :set_order
|
||||
end
|
||||
|
||||
private
|
||||
def set_order
|
||||
@order = AccountOrder.find(params[:order] || Current.user&.default_account_order)
|
||||
rescue ArgumentError
|
||||
@order = AccountOrder.default
|
||||
end
|
||||
end
|
||||
@@ -88,7 +88,7 @@ class UsersController < ApplicationController
|
||||
def user_params
|
||||
params.require(:user).permit(
|
||||
:first_name, :last_name, :email, :profile_image, :redirect_to, :delete_profile_image, :onboarded_at,
|
||||
:show_sidebar, :default_period, :show_ai_sidebar, :ai_enabled, :theme, :set_onboarding_preferences_at, :set_onboarding_goals_at,
|
||||
:show_sidebar, :default_period, :default_account_order, :show_ai_sidebar, :ai_enabled, :theme, :set_onboarding_preferences_at, :set_onboarding_goals_at,
|
||||
family_attributes: [ :name, :currency, :country, :locale, :date_format, :timezone, :id ],
|
||||
goals: []
|
||||
)
|
||||
|
||||
60
app/models/account_order.rb
Normal file
60
app/models/account_order.rb
Normal file
@@ -0,0 +1,60 @@
|
||||
class AccountOrder
|
||||
include ActiveModel::Model
|
||||
include ActiveModel::Attributes
|
||||
|
||||
ORDERS = {
|
||||
"name_asc" => {
|
||||
label: "Name (A-Z)",
|
||||
label_short: "Name ↑",
|
||||
sql_order: "name ASC"
|
||||
},
|
||||
"name_desc" => {
|
||||
label: "Name (Z-A)",
|
||||
label_short: "Name ↓",
|
||||
sql_order: "name DESC"
|
||||
},
|
||||
"balance_asc" => {
|
||||
label: "Balance (Low to High)",
|
||||
label_short: "Balance ↑",
|
||||
sql_order: "balance ASC"
|
||||
},
|
||||
"balance_desc" => {
|
||||
label: "Balance (High to Low)",
|
||||
label_short: "Balance ↓",
|
||||
sql_order: "balance DESC"
|
||||
}
|
||||
}.freeze
|
||||
|
||||
attr_accessor :key
|
||||
|
||||
def initialize(key)
|
||||
@key = key.to_s
|
||||
raise ArgumentError, "Invalid order key: #{@key}" unless ORDERS.key?(@key)
|
||||
end
|
||||
|
||||
def label
|
||||
ORDERS.dig(key, :label)
|
||||
end
|
||||
|
||||
def label_short
|
||||
ORDERS.dig(key, :label_short)
|
||||
end
|
||||
|
||||
def sql_order
|
||||
ORDERS.dig(key, :sql_order)
|
||||
end
|
||||
|
||||
class << self
|
||||
def all
|
||||
ORDERS.keys.map { |key| new(key) }
|
||||
end
|
||||
|
||||
def find(key)
|
||||
new(key) if ORDERS.key?(key.to_s)
|
||||
end
|
||||
|
||||
def default
|
||||
new("name_asc")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,7 +13,7 @@ class BalanceSheet
|
||||
@assets ||= ClassificationGroup.new(
|
||||
classification: "asset",
|
||||
currency: family.currency,
|
||||
accounts: account_totals.asset_accounts.sort_by(&:name)
|
||||
accounts: sorted(account_totals.asset_accounts)
|
||||
)
|
||||
end
|
||||
|
||||
@@ -21,7 +21,7 @@ class BalanceSheet
|
||||
@liabilities ||= ClassificationGroup.new(
|
||||
classification: "liability",
|
||||
currency: family.currency,
|
||||
accounts: account_totals.liability_accounts.sort_by(&:name)
|
||||
accounts: sorted(account_totals.liability_accounts)
|
||||
)
|
||||
end
|
||||
|
||||
@@ -61,4 +61,22 @@ class BalanceSheet
|
||||
def net_worth_series_builder
|
||||
@net_worth_series_builder ||= NetWorthSeriesBuilder.new(family)
|
||||
end
|
||||
|
||||
def sorted(accounts)
|
||||
account_order = Current.user&.account_order
|
||||
order_key = account_order&.key || "name_asc"
|
||||
|
||||
case order_key
|
||||
when "name_asc"
|
||||
accounts.sort_by(&:name)
|
||||
when "name_desc"
|
||||
accounts.sort_by(&:name).reverse
|
||||
when "balance_asc"
|
||||
accounts.sort_by(&:balance)
|
||||
when "balance_desc"
|
||||
accounts.sort_by(&:balance).reverse
|
||||
else
|
||||
accounts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,6 +15,7 @@ class User < ApplicationRecord
|
||||
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
|
||||
validate :ensure_valid_profile_image
|
||||
validates :default_period, inclusion: { in: Period::PERIODS.keys }
|
||||
validates :default_account_order, inclusion: { in: AccountOrder::ORDERS.keys }
|
||||
normalizes :email, with: ->(email) { email.strip.downcase }
|
||||
normalizes :unconfirmed_email, with: ->(email) { email&.strip&.downcase }
|
||||
|
||||
@@ -163,6 +164,10 @@ class User < ApplicationRecord
|
||||
!onboarded?
|
||||
end
|
||||
|
||||
def account_order
|
||||
AccountOrder.find(default_account_order) || AccountOrder.default
|
||||
end
|
||||
|
||||
private
|
||||
def ensure_valid_profile_image
|
||||
return unless profile_image.attached?
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
{ label: t(".default_period") },
|
||||
{ data: { auto_submit_form_target: "auto" } } %>
|
||||
|
||||
<%= form.select :default_account_order,
|
||||
AccountOrder.all.map { |order| [ order.label, order.key ] },
|
||||
{ label: t(".default_account_order") },
|
||||
{ data: { auto_submit_form_target: "auto" } } %>
|
||||
|
||||
<%= family_form.select :country,
|
||||
country_options,
|
||||
{ label: t(".country") },
|
||||
|
||||
Reference in New Issue
Block a user