diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 1c286290788..e41ec729a8d 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -2,8 +2,7 @@ class TagsController < ApplicationController before_action :set_tag, only: %i[edit update destroy] def index - @tags = Current.family.tags.alphabetically - + @tags = Current.family.tags.sorted_naturally render layout: "settings" end diff --git a/app/models/rule/action_executor/set_transaction_category.rb b/app/models/rule/action_executor/set_transaction_category.rb index 6360e45a287..1b4dbaf68ce 100644 --- a/app/models/rule/action_executor/set_transaction_category.rb +++ b/app/models/rule/action_executor/set_transaction_category.rb @@ -4,7 +4,7 @@ def type end def options - family.categories.pluck(:name, :id) + family.categories.order(:name).pluck(:name, :id) end def execute(transaction_scope, value: nil, ignore_attribute_locks: false) diff --git a/app/models/rule/action_executor/set_transaction_tags.rb b/app/models/rule/action_executor/set_transaction_tags.rb index d74029ca1ed..ff92872b1e5 100644 --- a/app/models/rule/action_executor/set_transaction_tags.rb +++ b/app/models/rule/action_executor/set_transaction_tags.rb @@ -4,7 +4,7 @@ def type end def options - family.tags.pluck(:name, :id) + family.tags.order(:name).pluck(:name, :id) end def execute(transaction_scope, value: nil, ignore_attribute_locks: false) diff --git a/app/models/rule/registry/transaction_resource.rb b/app/models/rule/registry/transaction_resource.rb index d00f2b1ea8b..af0c1c03dc9 100644 --- a/app/models/rule/registry/transaction_resource.rb +++ b/app/models/rule/registry/transaction_resource.rb @@ -8,7 +8,7 @@ def condition_filters Rule::ConditionFilter::TransactionName.new(rule), Rule::ConditionFilter::TransactionAmount.new(rule), Rule::ConditionFilter::TransactionMerchant.new(rule) - ] + ].sort_by { |filter| filter.label.downcase } end def action_executors @@ -24,7 +24,7 @@ def action_executors enabled_executors << Rule::ActionExecutor::AutoDetectMerchants.new(rule) end - enabled_executors + enabled_executors.sort_by { |executor| executor.label.downcase } end private diff --git a/app/models/tag.rb b/app/models/tag.rb index c5bdc0bc244..a86490fc5e4 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -8,6 +8,15 @@ class Tag < ApplicationRecord scope :alphabetically, -> { order(:name) } + scope :sorted_naturally_db, -> { + order( + Arel.sql( + "REGEXP_REPLACE(name, '\\d+$', '') ASC, " \ + "CAST(REGEXP_REPLACE(name, '\\D+', '') AS INTEGER) ASC" + ) + ) + } + COLORS = %w[#e99537 #4da568 #6471eb #db5a54 #df4e92 #c44fe9 #eb5429 #61c9ea #805dee #6ad28a] UNCATEGORIZED_COLOR = "#737373" @@ -23,4 +32,10 @@ def replace_and_destroy!(replacement) destroy! end end + + def self.sorted_naturally + all.to_a.sort_by do |tag| + tag.name.to_s.scan(/\d+|\D+/).map { |s| s =~ /\d+/ ? s.to_i : s.downcase } + end + end end diff --git a/app/views/transactions/_form.html.erb b/app/views/transactions/_form.html.erb index 3760f7dd0a9..00f17b3c464 100644 --- a/app/views/transactions/_form.html.erb +++ b/app/views/transactions/_form.html.erb @@ -32,7 +32,7 @@ <%= render DS::Disclosure.new(title: t(".details")) do %> <%= f.fields_for :entryable do |ef| %> <%= ef.select :tag_ids, - Current.family.tags.alphabetically.pluck(:name, :id), + Current.family.tags.sorted_naturally.pluck(:name, :id), { include_blank: t(".none"), multiple: true, diff --git a/app/views/transactions/show.html.erb b/app/views/transactions/show.html.erb index 4111cd437cb..394ac0f9b20 100644 --- a/app/views/transactions/show.html.erb +++ b/app/views/transactions/show.html.erb @@ -77,7 +77,7 @@ "data-auto-submit-form-target": "auto" %> <%= ef.select :tag_ids, - Current.family.tags.alphabetically.pluck(:name, :id), + Current.family.tags.sorted_naturally.pluck(:name, :id), { include_blank: t(".none"), multiple: true,