diff --git a/app/controllers/transaction/rows_controller.rb b/app/controllers/account/transaction/rows_controller.rb similarity index 51% rename from app/controllers/transaction/rows_controller.rb rename to app/controllers/account/transaction/rows_controller.rb index 08f081b9..9bc823f3 100644 --- a/app/controllers/transaction/rows_controller.rb +++ b/app/controllers/account/transaction/rows_controller.rb @@ -1,4 +1,4 @@ -class Transaction::RowsController < ApplicationController +class Account::Transaction::RowsController < ApplicationController before_action :set_transaction, only: %i[ show update ] def show @@ -7,7 +7,7 @@ class Transaction::RowsController < ApplicationController def update @transaction.update! transaction_params - redirect_to transaction_row_path(@transaction) + redirect_to account_transaction_row_path(@transaction.account, @transaction) end private @@ -17,6 +17,6 @@ class Transaction::RowsController < ApplicationController end def set_transaction - @transaction = Current.family.transactions.find(params[:id]) + @transaction = Current.family.accounts.find(params[:account_id]).transactions.find(params[:transaction_id]) end end diff --git a/app/controllers/account/transaction/rules_controller.rb b/app/controllers/account/transaction/rules_controller.rb new file mode 100644 index 00000000..704b2119 --- /dev/null +++ b/app/controllers/account/transaction/rules_controller.rb @@ -0,0 +1,6 @@ +class Account::Transaction::RulesController < ApplicationController + layout "with_sidebar" + + def index + end +end diff --git a/app/controllers/account/transactions_controller.rb b/app/controllers/account/transactions_controller.rb new file mode 100644 index 00000000..184725f6 --- /dev/null +++ b/app/controllers/account/transactions_controller.rb @@ -0,0 +1,44 @@ +class Account::TransactionsController < ApplicationController + layout "with_sidebar" + + before_action :set_account + before_action :set_transaction, only: %i[ show update destroy ] + + def index + @transactions = @account.transactions.ordered + end + + def show + end + + def update + @transaction.update! transaction_params + @transaction.sync_account_later + + redirect_back_or_to account_transaction_url(@transaction.account, @transaction), notice: t(".success") + end + + def destroy + @transaction.destroy! + @transaction.sync_account_later + redirect_back_or_to account_url(@transaction.account), notice: t(".success") + end + + private + + def set_account + @account = Current.family.accounts.find(params[:account_id]) + end + + def set_transaction + @transaction = @account.transactions.find(params[:id]) + end + + def search_params + params.fetch(:q, {}).permit(:start_date, :end_date, :search, accounts: [], account_ids: [], categories: [], merchants: []) + end + + def transaction_params + params.require(:transaction).permit(:name, :date, :amount, :currency, :notes, :excluded, :category_id, :merchant_id, tag_ids: []) + end +end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 5b8c5eed..42cdd1f2 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -21,7 +21,7 @@ class PagesController < ApplicationController @accounts = Current.family.accounts @account_groups = @accounts.by_group(period: @period, currency: Current.family.currency) - @transactions = Current.family.transactions.limit(5).order(date: :desc) + @transactions = Current.family.transactions.limit(6).order(date: :desc) # TODO: Placeholders for trendlines placeholder_series_data = 10.times.map do |i| diff --git a/app/controllers/transaction/rules_controller.rb b/app/controllers/transaction/rules_controller.rb deleted file mode 100644 index 7c7b157a..00000000 --- a/app/controllers/transaction/rules_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Transaction::RulesController < ApplicationController - layout "with_sidebar" - - def index - end -end diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 98be1c39..ed38b535 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -1,8 +1,6 @@ class TransactionsController < ApplicationController layout "with_sidebar" - before_action :set_transaction, only: %i[ show edit update destroy ] - def index @q = search_params result = Current.family.transactions.search(@q).ordered @@ -15,41 +13,22 @@ class TransactionsController < ApplicationController } end - def show - end - def new - @transaction = Transaction.new.tap do |txn| + @transaction = Account::Transaction.new.tap do |txn| if params[:account_id] txn.account = Current.family.accounts.find(params[:account_id]) end end end - def edit - end - def create @transaction = Current.family.accounts - .find(params[:transaction][:account_id]) - .transactions.build(transaction_params.merge(amount: amount)) + .find(params[:transaction][:account_id]) + .transactions + .create!(transaction_params.merge(amount: amount)) - @transaction.save! @transaction.sync_account_later - redirect_to transactions_url, notice: t(".success") - end - - def update - @transaction.update! transaction_params - @transaction.sync_account_later - - redirect_to transaction_url(@transaction), notice: t(".success") - end - - def destroy - @transaction.destroy! - @transaction.sync_account_later - redirect_to transactions_url, notice: t(".success") + redirect_back_or_to account_path(@transaction.account), notice: t(".success") end def bulk_delete @@ -90,10 +69,6 @@ class TransactionsController < ApplicationController private - def set_transaction - @transaction = Current.family.transactions.find(params[:id]) - end - def amount if nature.income? transaction_params[:amount].to_d * -1 @@ -119,6 +94,6 @@ class TransactionsController < ApplicationController end def transaction_params - params.require(:transaction).permit(:name, :date, :amount, :currency, :notes, :excluded, :category_id, :merchant_id, tag_ids: []) + params.require(:transaction).permit(:name, :date, :amount, :currency, :category_id, tag_ids: []) end end diff --git a/app/helpers/transactions/searches_helper.rb b/app/helpers/account/transaction/searches_helper.rb similarity index 96% rename from app/helpers/transactions/searches_helper.rb rename to app/helpers/account/transaction/searches_helper.rb index 09bd882a..09d3e0dc 100644 --- a/app/helpers/transactions/searches_helper.rb +++ b/app/helpers/account/transaction/searches_helper.rb @@ -1,4 +1,4 @@ -module Transactions::SearchesHelper +module Account::Transaction::SearchesHelper def transaction_search_filters [ { key: "account_filter", name: "Account", icon: "layers" }, diff --git a/app/helpers/transactions_helper.rb b/app/helpers/account/transactions_helper.rb similarity index 57% rename from app/helpers/transactions_helper.rb rename to app/helpers/account/transactions_helper.rb index 67758978..bc888360 100644 --- a/app/helpers/transactions_helper.rb +++ b/app/helpers/account/transactions_helper.rb @@ -1,23 +1,4 @@ -module TransactionsHelper - def transactions_group(date, transactions, transaction_partial_path = "transactions/transaction") - header_left = content_tag :span do - "#{date.strftime('%b %d, %Y')} · #{transactions.size}".html_safe - end - - header_right = content_tag :span do - format_money(-transactions.sum(&:amount_money)) - end - - header = header_left.concat(header_right) - - content = render partial: transaction_partial_path, collection: transactions - - render partial: "shared/list_group", locals: { - header: header, - content: content - } - end - +module Account::TransactionsHelper def unconfirmed_transfer?(transaction) transaction.marked_as_transfer && transaction.transfer.nil? end diff --git a/app/helpers/account/valuations_helper.rb b/app/helpers/account/valuations_helper.rb index e1a93dde..5143e43d 100644 --- a/app/helpers/account/valuations_helper.rb +++ b/app/helpers/account/valuations_helper.rb @@ -1,6 +1,6 @@ module Account::ValuationsHelper def valuation_icon(valuation) - if valuation.first_of_series? + if valuation.oldest? "keyboard" elsif valuation.trend.direction.up? "arrow-up" @@ -12,7 +12,7 @@ module Account::ValuationsHelper end def valuation_style(valuation) - color = valuation.first_of_series? ? "#D444F1" : valuation.trend.color + color = valuation.oldest? ? "#D444F1" : valuation.trend.color <<-STYLE.strip background-color: color-mix(in srgb, #{color} 5%, white); diff --git a/app/models/transaction.rb b/app/models/account/transaction.rb similarity index 88% rename from app/models/transaction.rb rename to app/models/account/transaction.rb index bad2aaf6..df4b4621 100644 --- a/app/models/transaction.rb +++ b/app/models/account/transaction.rb @@ -1,4 +1,4 @@ -class Transaction < ApplicationRecord +class Account::Transaction < ApplicationRecord include Monetizable monetize :amount @@ -17,22 +17,22 @@ class Transaction < ApplicationRecord scope :active, -> { where(excluded: false) } scope :inflows, -> { where("amount <= 0") } scope :outflows, -> { where("amount > 0") } - scope :by_name, ->(name) { where("transactions.name ILIKE ?", "%#{name}%") } + scope :by_name, ->(name) { where("account_transactions.name ILIKE ?", "%#{name}%") } scope :with_categories, ->(categories) { joins(:category).where(categories: { name: categories }) } scope :with_accounts, ->(accounts) { joins(:account).where(accounts: { name: accounts }) } scope :with_account_ids, ->(account_ids) { joins(:account).where(accounts: { id: account_ids }) } scope :with_merchants, ->(merchants) { joins(:merchant).where(merchants: { name: merchants }) } - scope :on_or_after_date, ->(date) { where("transactions.date >= ?", date) } - scope :on_or_before_date, ->(date) { where("transactions.date <= ?", date) } + scope :on_or_after_date, ->(date) { where("account_transactions.date >= ?", date) } + scope :on_or_before_date, ->(date) { where("account_transactions.date <= ?", date) } scope :with_converted_amount, ->(currency = Current.family.currency) { # Join with exchange rates to convert the amount to the given currency # If no rate is available, exclude the transaction from the results select( - "transactions.*", - "transactions.amount * COALESCE(er.rate, 1) AS converted_amount" + "account_transactions.*", + "account_transactions.amount * COALESCE(er.rate, 1) AS converted_amount" ) - .joins(sanitize_sql_array([ "LEFT JOIN exchange_rates er ON transactions.date = er.date AND transactions.currency = er.base_currency AND er.converted_currency = ?", currency ])) - .where("er.rate IS NOT NULL OR transactions.currency = ?", currency) + .joins(sanitize_sql_array([ "LEFT JOIN exchange_rates er ON account_transactions.date = er.date AND account_transactions.currency = er.base_currency AND er.converted_currency = ?", currency ])) + .where("er.rate IS NOT NULL OR account_transactions.currency = ?", currency) } def inflow? diff --git a/app/models/account/valuation.rb b/app/models/account/valuation.rb index ddbb519c..ffe21abe 100644 --- a/app/models/account/valuation.rb +++ b/app/models/account/valuation.rb @@ -15,14 +15,10 @@ class Account::Valuation < ApplicationRecord @trend ||= create_trend end - def first_of_series? + def oldest? account.valuations.chronological.limit(1).pluck(:date).first == self.date end - def last_of_series? - account.valuations.reverse_chronological.limit(1).pluck(:date).first == self.date - end - def sync_account_later if destroyed? sync_start_date = previous_valuation&.date diff --git a/app/models/category.rb b/app/models/category.rb index b846ca51..cfcab4ef 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,5 +1,5 @@ class Category < ApplicationRecord - has_many :transactions, dependent: :nullify + has_many :transactions, dependent: :nullify, class_name: "Account::Transaction" belongs_to :family validates :name, :color, :family, presence: true diff --git a/app/models/family.rb b/app/models/family.rb index 1159fd87..378dd76e 100644 --- a/app/models/family.rb +++ b/app/models/family.rb @@ -3,7 +3,7 @@ class Family < ApplicationRecord has_many :tags, dependent: :destroy has_many :accounts, dependent: :destroy has_many :institutions, dependent: :destroy - has_many :transactions, through: :accounts + has_many :transactions, through: :accounts, class_name: "Account::Transaction" has_many :imports, through: :accounts has_many :categories, dependent: :destroy has_many :merchants, dependent: :destroy @@ -40,9 +40,9 @@ class Family < ApplicationRecord "COALESCE(SUM(amount) FILTER (WHERE amount > 0), 0) AS spending", "COALESCE(SUM(-amount) FILTER (WHERE amount < 0), 0) AS income" ) - .where("transactions.date >= ?", period.date_range.begin) - .where("transactions.date <= ?", period.date_range.end) - .where("transactions.marked_as_transfer = ?", false) + .where("account_transactions.date >= ?", period.date_range.begin) + .where("account_transactions.date <= ?", period.date_range.end) + .where("account_transactions.marked_as_transfer = ?", false) .group("id") .to_a @@ -60,7 +60,7 @@ class Family < ApplicationRecord end def snapshot_transactions - rolling_totals = Transaction.daily_rolling_totals(transactions, period: Period.last_30_days, currency: self.currency) + rolling_totals = Account::Transaction.daily_rolling_totals(transactions, period: Period.last_30_days, currency: self.currency) spending = [] income = [] diff --git a/app/models/merchant.rb b/app/models/merchant.rb index 5e657763..3d1448e2 100644 --- a/app/models/merchant.rb +++ b/app/models/merchant.rb @@ -1,5 +1,5 @@ class Merchant < ApplicationRecord - has_many :transactions, dependent: :nullify + has_many :transactions, dependent: :nullify, class_name: "Account::Transaction" belongs_to :family validates :name, :color, :family, presence: true diff --git a/app/models/tag.rb b/app/models/tag.rb index 6dd5988c..eab4d866 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -1,7 +1,7 @@ class Tag < ApplicationRecord belongs_to :family has_many :taggings, dependent: :destroy - has_many :transactions, through: :taggings, source: :taggable, source_type: "Transaction" + has_many :transactions, through: :taggings, source: :taggable, source_type: "Account::Transaction" validates :name, presence: true, uniqueness: { scope: :family } diff --git a/app/views/account/transaction/rows/show.html.erb b/app/views/account/transaction/rows/show.html.erb new file mode 100644 index 00000000..473d8200 --- /dev/null +++ b/app/views/account/transaction/rows/show.html.erb @@ -0,0 +1 @@ +<%= render "account/transactions/transaction", transaction: @transaction %> diff --git a/app/views/transaction/rules/index.html.erb b/app/views/account/transaction/rules/index.html.erb similarity index 99% rename from app/views/transaction/rules/index.html.erb rename to app/views/account/transaction/rules/index.html.erb index 6e3162a7..62222550 100644 --- a/app/views/transaction/rules/index.html.erb +++ b/app/views/account/transaction/rules/index.html.erb @@ -1,6 +1,7 @@ <% content_for :sidebar do %> <%= render "settings/nav" %> <% end %> +

Rules

diff --git a/app/views/transactions/_empty.html.erb b/app/views/account/transactions/_empty.html.erb similarity index 100% rename from app/views/transactions/_empty.html.erb rename to app/views/account/transactions/_empty.html.erb diff --git a/app/views/account/transactions/_loading.html.erb b/app/views/account/transactions/_loading.html.erb new file mode 100644 index 00000000..4f49ca61 --- /dev/null +++ b/app/views/account/transactions/_loading.html.erb @@ -0,0 +1,5 @@ +
+
+ <%= tag.p t(".loading"), class: "text-gray-500 animate-pulse text-sm" %> +
+
diff --git a/app/views/transactions/_selection_bar.html.erb b/app/views/account/transactions/_selection_bar.html.erb similarity index 93% rename from app/views/transactions/_selection_bar.html.erb rename to app/views/account/transactions/_selection_bar.html.erb index 3def43bb..50655998 100644 --- a/app/views/transactions/_selection_bar.html.erb +++ b/app/views/account/transactions/_selection_bar.html.erb @@ -12,6 +12,7 @@ builder: ActionView::Helpers::FormBuilder, scope: "bulk_update", data: { + turbo_frame: "_top", turbo_confirm: { title: t(".mark_transfers"), body: t(".mark_transfers_message"), @@ -30,7 +31,7 @@ <%= lucide_icon "pencil-line", class: "w-5 group-hover:text-white" %> <% end %> - <%= form_with url: bulk_delete_transactions_path, builder: ActionView::Helpers::FormBuilder, data: { turbo_confirm: true } do %> + <%= form_with url: bulk_delete_transactions_path, builder: ActionView::Helpers::FormBuilder, data: { turbo_confirm: true, turbo_frame: "_top" } do %> diff --git a/app/views/account/transactions/_transaction.html.erb b/app/views/account/transactions/_transaction.html.erb new file mode 100644 index 00000000..8d341a18 --- /dev/null +++ b/app/views/account/transactions/_transaction.html.erb @@ -0,0 +1,89 @@ +<%# locals: (transaction:, selectable: true, editable: true, short: false, show_tags: false) %> +<%= turbo_frame_tag dom_id(transaction), class: "grid grid-cols-12 items-center text-gray-900 text-sm font-medium p-4" do %> + + <% name_col_span = transaction.transfer? ? "col-span-10" : short ? "col-span-6" : "col-span-4" %> +
+ <% if selectable %> + <%= check_box_tag dom_id(transaction, "selection"), + class: "maybe-checkbox maybe-checkbox--light", + data: { id: transaction.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %> + <% end %> + +
+ <%= content_tag :div, class: ["flex items-center gap-2"] do %> +
+ <%= transaction.name[0].upcase %> +
+ +
+ <% if transaction.new_record? %> + <%= content_tag :p, transaction.name %> + <% else %> + <%= link_to transaction.name, + account_transaction_path(transaction.account, transaction), + data: { turbo_frame: "drawer", turbo_prefetch: false }, + class: "hover:underline hover:text-gray-800" %> + <% end %> +
+ <% end %> +
+ + <% if unconfirmed_transfer?(transaction) %> + <% if editable %> + <%= form_with url: unmark_transfers_transactions_path, builder: ActionView::Helpers::FormBuilder, class: "flex items-center", data: { + turbo_confirm: { + title: t(".remove_transfer"), + body: t(".remove_transfer_body"), + accept: t(".remove_transfer_confirm"), + }, + turbo_frame: "_top" + } do |f| %> + <%= f.hidden_field "bulk_update[transaction_ids][]", value: transaction.id %> + <%= f.button class: "flex items-center justify-center group", title: "Remove transfer" do %> + <%= lucide_icon "arrow-left-right", class: "group-hover:hidden text-gray-500 w-4 h-4" %> + <%= lucide_icon "unlink", class: "hidden group-hover:inline-block text-gray-900 w-4 h-4" %> + <% end %> + <% end %> + <% else %> + <%= lucide_icon "arrow-left-right", class: "text-gray-500 w-4 h-4" %> + <% end %> + <% end %> +
+ + <% unless transaction.transfer? %> + <% unless short %> +
"> + <% if editable %> + <%= render "categories/menu", transaction: transaction %> + <% else %> + <%= render "categories/badge", category: transaction.category %> + <% end %> + + <% if show_tags %> + <% transaction.tags.each do |tag| %> + <%= render partial: "tags/badge", locals: { tag: tag } %> + <% end %> + <% end %> +
+ <% end %> + + <% unless show_tags %> + <%= tag.div class: short ? "col-span-4" : "col-span-3" do %> + <% if transaction.new_record? %> + <%= tag.p transaction.account.name %> + <% else %> + <%= link_to transaction.account.name, + account_path(transaction.account, tab: "transactions"), + data: { turbo_frame: "_top" }, + class: "hover:underline" %> + <% end %> + <% end %> + <% end %> + <% end %> + +
+ <%= content_tag :p, + format_money(-transaction.amount_money), + class: ["text-green-600": transaction.inflow?] %> +
+<% end %> diff --git a/app/views/account/transactions/_transaction_group.html.erb b/app/views/account/transactions/_transaction_group.html.erb new file mode 100644 index 00000000..54ab5520 --- /dev/null +++ b/app/views/account/transactions/_transaction_group.html.erb @@ -0,0 +1,21 @@ +<%# locals: (date:, transactions:, transfers: [], selectable: true, **transaction_opts) %> +
+
+
+ <% if selectable %> + <%= check_box_tag "#{date}_transactions_selection", + class: ["maybe-checkbox maybe-checkbox--light", "hidden": transactions.count == 0], + id: "selection_transaction_#{date}", + data: { action: "bulk-select#toggleGroupSelection" } %> + <% end %> + + <%= tag.span "#{date.strftime('%b %d, %Y')} · #{transactions.size + (transfers.size * 2)}" %> +
+ + <%= totals_by_currency(collection: transactions, money_method: :amount_money, negate: true) %> +
+
+ <%= render transactions, selectable:, **transaction_opts.except(:selectable) %> + <%= render transfers %> +
+
diff --git a/app/views/account/transactions/index.html.erb b/app/views/account/transactions/index.html.erb new file mode 100644 index 00000000..371a6bc4 --- /dev/null +++ b/app/views/account/transactions/index.html.erb @@ -0,0 +1,29 @@ +<%= turbo_frame_tag dom_id(@account, "transactions") do %> +
+
+

<%= t(".transactions") %>

+ <%= link_to new_transaction_path(account_id: @account), + class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg", + data: { turbo_frame: :modal } do %> + <%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> + <%= t(".new") %> + <% end %> +
+ +
"> + + + <% if @transactions.empty? %> +

<%= t(".no_transactions") %>

+ <% else %> +
+ <% group_transactions_by_date(@transactions).each do |date, group| %> + <%= render "transaction_group", date:, transactions: group[:transactions], transfers: group[:transfers] %> + <% end %> +
+ <% end %> +
+
+<% end %> diff --git a/app/views/transactions/show.html.erb b/app/views/account/transactions/show.html.erb similarity index 98% rename from app/views/transactions/show.html.erb rename to app/views/account/transactions/show.html.erb index e83e4c59..b2c48555 100644 --- a/app/views/transactions/show.html.erb +++ b/app/views/account/transactions/show.html.erb @@ -90,7 +90,7 @@
<%= button_to t(".delete"), - transaction_path(@transaction), + account_transaction_path(@transaction), method: :delete, class: "rounded-lg px-3 py-2 text-red-500 text-sm font-medium border border-alpha-black-200", data: { turbo_confirm: true, turbo_frame: "_top" } %> diff --git a/app/views/account/transfers/_transfer.html.erb b/app/views/account/transfers/_transfer.html.erb index eeec6868..3a04b3f5 100644 --- a/app/views/account/transfers/_transfer.html.erb +++ b/app/views/account/transfers/_transfer.html.erb @@ -1,6 +1,6 @@ <%= turbo_frame_tag dom_id(transfer), class: "block" do %> -
- +
+
<%= button_to account_transfer_path(transfer), method: :delete, @@ -25,16 +25,9 @@ <%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %>
-
+
<% transfer.transactions.each do |transaction| %> -
-
- <%= render "transactions/name", transaction: transaction %> -
-
- <%= render "transactions/amount", transaction: transaction %> -
-
+ <%= render transaction, selectable: false, editable: false %> <% end %>
diff --git a/app/views/account/valuations/_loading.html.erb b/app/views/account/valuations/_loading.html.erb new file mode 100644 index 00000000..4f49ca61 --- /dev/null +++ b/app/views/account/valuations/_loading.html.erb @@ -0,0 +1,5 @@ +
+
+ <%= tag.p t(".loading"), class: "text-gray-500 animate-pulse text-sm" %> +
+
diff --git a/app/views/account/valuations/_valuation.html.erb b/app/views/account/valuations/_valuation.html.erb index 2d496e98..7fa0021d 100644 --- a/app/views/account/valuations/_valuation.html.erb +++ b/app/views/account/valuations/_valuation.html.erb @@ -1,5 +1,3 @@ -<%# locals: (valuation:) %> - <%= turbo_frame_tag dom_id(valuation) do %>
@@ -9,7 +7,7 @@
<%= tag.p valuation.date, class: "text-gray-900 font-medium" %> - <%= tag.p valuation.first_of_series? ? t(".start_balance") : t(".value_update"), class: "text-gray-500" %> + <%= tag.p valuation.oldest? ? t(".start_balance") : t(".value_update"), class: "text-gray-500" %>
@@ -43,8 +41,4 @@ <% end %>
- - <% unless valuation.last_of_series? %> -
- <% end %> <% end %> diff --git a/app/views/account/valuations/_valuation_ruler.html.erb b/app/views/account/valuations/_valuation_ruler.html.erb new file mode 100644 index 00000000..31c6ee6c --- /dev/null +++ b/app/views/account/valuations/_valuation_ruler.html.erb @@ -0,0 +1 @@ +
diff --git a/app/views/account/valuations/index.html.erb b/app/views/account/valuations/index.html.erb index 4fa523bb..e4062d9f 100644 --- a/app/views/account/valuations/index.html.erb +++ b/app/views/account/valuations/index.html.erb @@ -1,15 +1,35 @@ <%= turbo_frame_tag dom_id(@account, "valuations") do %> -
- <%= tag.p t(".date"), class: "col-span-5" %> - <%= tag.p t(".value"), class: "col-span-2 justify-self-end" %> - <%= tag.p t(".change"), class: "col-span-2 justify-self-end" %> - <%= tag.div class: "col-span-1" %> -
+
+
+ <%= tag.h2 t(".valuations"), class: "font-medium text-lg" %> + <%= link_to new_account_valuation_path(@account), + data: { turbo_frame: dom_id(Account::Valuation.new) }, + class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg" do %> + <%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> + <%= tag.span t(".new_entry"), class: "text-sm" %> + <% end %> +
-
- <%= turbo_frame_tag dom_id(Account::Valuation.new) %> - <% @account.valuations.reverse_chronological.each do |valuation| %> - <%= render valuation %> - <% end %> +
+
+ <%= tag.p t(".date"), class: "col-span-5" %> + <%= tag.p t(".value"), class: "col-span-2 justify-self-end" %> + <%= tag.p t(".change"), class: "col-span-2 justify-self-end" %> + <%= tag.div class: "col-span-1" %> +
+ +
+ <%= turbo_frame_tag dom_id(Account::Valuation.new) %> + + <% valuations = @account.valuations.reverse_chronological %> + <% if valuations.any? %> + <%= render partial: "valuation", + collection: @account.valuations.reverse_chronological, + spacer_template: "valuation_ruler" %> + <% else %> +

<%= t(".no_valuations") %>

+ <% end %> +
+
<% end %> diff --git a/app/views/accounts/_transactions.html.erb b/app/views/accounts/_transactions.html.erb deleted file mode 100644 index 4f90c021..00000000 --- a/app/views/accounts/_transactions.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -<%# locals: (account:, transactions:)%> -
-
-

Transactions

- <%= link_to new_transaction_path(account_id: account), class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg", data: { turbo_frame: :modal } do %> - <%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> - New transaction - <% end %> -
- - <% if transactions.empty? %> -

No transactions for this account yet.

- <% else %> -
- <% transactions.group_by(&:date).each do |date, transactions| %> - <%= transactions_group(date, transactions, "accounts/transactions/transaction") %> - <% end %> -
- <% end %> -
diff --git a/app/views/accounts/show.html.erb b/app/views/accounts/show.html.erb index 38c76f6f..58d31cfd 100644 --- a/app/views/accounts/show.html.erb +++ b/app/views/accounts/show.html.erb @@ -1,4 +1,5 @@ <%= turbo_stream_from @account %> +
@@ -70,34 +71,23 @@ <%= render partial: "shared/line_chart", locals: { series: @balance_series } %>
-
-
- - -
-
-
-
-
- <%= tag.h2 t(".valuations"), class: "font-medium text-lg" %> - <%= link_to new_account_valuation_path(@account), data: { turbo_frame: dom_id(Account::Valuation.new) }, class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg" do %> - <%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> - <%= tag.span t(".new_entry"), class: "text-sm" %> - <% end %> -
-
- <%= turbo_frame_tag dom_id(@account, "valuations"), src: account_valuations_path(@account) do %> -
- <%= tag.p t(".loading_history"), class: "text-gray-500 animate-pulse text-sm" %> -
- <% end %> -
-
-
- -
+ <% selected_tab = params[:tab] || "history" %> + +
+ <%= link_to "History", account_path(tab: "history"), class: ["p-2 rounded-lg", "bg-gray-100": selected_tab == "history"] %> + <%= link_to "Transactions", account_path(tab: "transactions"), class: ["p-2 rounded-lg", "bg-gray-100": selected_tab == "transactions"] %> +
+ +
+ <% if selected_tab == "transactions" %> + <%= turbo_frame_tag dom_id(@account, "transactions"), src: account_transactions_path(@account) do %> + <%= render "account/transactions/loading" %> + <% end %> + <% else %> + <%= turbo_frame_tag dom_id(@account, "valuations"), src: account_valuations_path(@account) do %> + <%= render "account/valuations/loading" %> + <% end %> + <% end %>
diff --git a/app/views/accounts/transactions/_transaction.html.erb b/app/views/accounts/transactions/_transaction.html.erb deleted file mode 100644 index e725c818..00000000 --- a/app/views/accounts/transactions/_transaction.html.erb +++ /dev/null @@ -1,24 +0,0 @@ -<%= turbo_frame_tag dom_id(transaction), class: "grid grid-cols-12 items-center text-gray-900 py-4 text-sm font-medium px-4" do %> -
- <%= render "transactions/name", transaction: transaction %> -
- -
- <% if transaction.marked_as_transfer %> -
- <%= lucide_icon "arrow-right-left", class: "w-4 h-4 text-gray-500" %> -

Transfer

-
- <% else %> - <%= render "categories/badge", category: transaction.category %> - <% end %> -
- - <%= link_to transaction.account.name, - account_path(transaction.account), - class: ["col-span-3 hover:underline"] %> - -
- <%= render "transactions/amount", transaction: transaction %> -
-<% end %> diff --git a/app/views/category/dropdowns/_row.html.erb b/app/views/category/dropdowns/_row.html.erb index 44d47fef..bca65ceb 100644 --- a/app/views/category/dropdowns/_row.html.erb +++ b/app/views/category/dropdowns/_row.html.erb @@ -2,7 +2,7 @@ <% is_selected = category.id === @selected_category&.id %> <%= content_tag :div, class: ["filterable-item flex justify-between items-center border-none rounded-lg px-2 py-1 group w-full", { "bg-gray-25": is_selected }], data: { filter_name: category.name } do %> - <%= button_to transaction_row_path(@transaction, transaction: { category_id: category.id }), method: :patch, data: { turbo_frame: dom_id(@transaction) }, class: "flex w-full items-center gap-1.5 cursor-pointer" do %> + <%= button_to account_transaction_row_path(@transaction.account, @transaction, transaction: { category_id: category.id }), method: :patch, data: { turbo_frame: dom_id(@transaction) }, class: "flex w-full items-center gap-1.5 cursor-pointer" do %> <%= lucide_icon("check", class: "w-5 h-5 text-gray-500") if is_selected %> diff --git a/app/views/category/dropdowns/show.html.erb b/app/views/category/dropdowns/show.html.erb index 0ddfd1ec..fd966334 100644 --- a/app/views/category/dropdowns/show.html.erb +++ b/app/views/category/dropdowns/show.html.erb @@ -25,7 +25,7 @@ <% end %> <% if @transaction.category %> - <%= button_to transaction_row_path(@transaction), + <%= button_to account_transaction_row_path(@transaction.account, @transaction), method: :patch, data: { turbo_frame: dom_id(@transaction) }, params: { transaction: { category_id: nil } }, diff --git a/app/views/imports/confirm.html.erb b/app/views/imports/confirm.html.erb index 32694dff..cc47b42b 100644 --- a/app/views/imports/confirm.html.erb +++ b/app/views/imports/confirm.html.erb @@ -9,8 +9,15 @@
- <% @import.dry_run.group_by(&:date).each do |date, draft_transactions| %> - <%= transactions_group(date, draft_transactions, "imports/transactions/transaction") %> + <% transactions = @import.dry_run %> + <% group_transactions_by_date(transactions).each do |date, group| %> + <%= render "account/transactions/transaction_group", + date: date, + transactions: group[:transactions], + transfers: group[:transfers], + show_tags: true, + selectable: false, + editable: false %> <% end %>
diff --git a/app/views/imports/index.html.erb b/app/views/imports/index.html.erb index 3406f8c2..8f0435dc 100644 --- a/app/views/imports/index.html.erb +++ b/app/views/imports/index.html.erb @@ -25,7 +25,7 @@ <% end %>
- <%= previous_setting("Rules", transaction_rules_path) %> + <%= previous_setting("Rules", account_transaction_rules_path) %> <%= next_setting("What's new", changelog_path) %>
diff --git a/app/views/imports/transactions/_transaction.html.erb b/app/views/imports/transactions/_transaction.html.erb deleted file mode 100644 index d3594222..00000000 --- a/app/views/imports/transactions/_transaction.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -<%# locals: (transaction:) %> -
-
- <%= render "transactions/name", transaction: transaction %> -
- -
- <%= render partial: "categories/badge", locals: { category: transaction.category } %> -
- -
- <% transaction.tags.each do |tag| %> - <%= render partial: "tags/badge", locals: { tag: tag } %> - <% end %> -
- -
- <%= render "transactions/amount", transaction: transaction %> -
-
diff --git a/app/views/merchants/index.html.erb b/app/views/merchants/index.html.erb index 0629c818..8e3eca22 100644 --- a/app/views/merchants/index.html.erb +++ b/app/views/merchants/index.html.erb @@ -35,6 +35,6 @@
<%= previous_setting("Categories", categories_path) %> - <%= next_setting("Rules", transaction_rules_path) %> + <%= next_setting("Rules", account_transaction_rules_path) %>
diff --git a/app/views/pages/dashboard.html.erb b/app/views/pages/dashboard.html.erb index 9296f5f8..5909d1fb 100644 --- a/app/views/pages/dashboard.html.erb +++ b/app/views/pages/dashboard.html.erb @@ -3,7 +3,7 @@

Dashboard

<%= t(".greeting", name: Current.user.first_name ) %>

- <% if !@accounts.blank? %> + <% unless @accounts.blank? %>

<%= t(".subtitle") %>

<% end %>
@@ -162,8 +162,14 @@ <% else %>
- <% @transactions.group_by(&:date).each do |date, transactions| %> - <%= transactions_group(date, transactions, "pages/dashboard/transactions/transaction") %> + <% group_transactions_by_date(@transactions).each do |date, group| %> + <%= render "account/transactions/transaction_group", + date: date, + transactions: group[:transactions], + transfers: group[:transfers], + selectable: false, + editable: false, + short: true %> <% end %>

<%= link_to t(".view_all"), transactions_path %>

diff --git a/app/views/pages/dashboard/transactions/_transaction.html.erb b/app/views/pages/dashboard/transactions/_transaction.html.erb deleted file mode 100644 index 49fc3be3..00000000 --- a/app/views/pages/dashboard/transactions/_transaction.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -
-
- <%= render "transactions/name", transaction: transaction %> -
- -
- <%= render "transactions/amount", transaction: transaction %> -
-
diff --git a/app/views/settings/_nav.html.erb b/app/views/settings/_nav.html.erb index cf0a8209..333ee3bc 100644 --- a/app/views/settings/_nav.html.erb +++ b/app/views/settings/_nav.html.erb @@ -56,7 +56,7 @@ <%= sidebar_link_to t(".merchants_label"), merchants_path, icon: "store" %>
  • - <%= sidebar_link_to t(".rules_label"), transaction_rules_path, icon: "list-checks" %> + <%= sidebar_link_to t(".rules_label"), account_transaction_rules_path, icon: "list-checks" %>
  • <%= sidebar_link_to t(".imports_label"), imports_path, icon: "download" %> diff --git a/app/views/transaction/rows/show.html.erb b/app/views/transaction/rows/show.html.erb deleted file mode 100644 index e40ab43e..00000000 --- a/app/views/transaction/rows/show.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render "transactions/transaction", transaction: @transaction %> diff --git a/app/views/transactions/_amount.html.erb b/app/views/transactions/_amount.html.erb deleted file mode 100644 index 1ebf81ff..00000000 --- a/app/views/transactions/_amount.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= content_tag :p, - format_money(-transaction.amount_money), - class: ["text-green-600": transaction.inflow?] %> diff --git a/app/views/transactions/_date_group.html.erb b/app/views/transactions/_date_group.html.erb deleted file mode 100644 index a464cfc9..00000000 --- a/app/views/transactions/_date_group.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -<%# locals: (date:, group:) %> -
    -
    -
    - <%= check_box_tag "#{date}_transactions_selection", - class: ["maybe-checkbox maybe-checkbox--light", "hidden": group[:transactions].count == 0], - id: "selection_transaction_#{date}", - data: { action: "bulk-select#toggleGroupSelection" } %> - - <%= tag.span "#{date.strftime('%b %d, %Y')} · #{group[:transactions].size + (group[:transfers].size * 2)}" %> -
    - -
    - <%= totals_by_currency(collection: group[:transactions], money_method: :amount_money, negate: true) %> -
    -
    -
    - <%= render group[:transactions] %> - <%= render group[:transfers] %> -
    -
    diff --git a/app/views/transactions/_form.html.erb b/app/views/transactions/_form.html.erb index 575e9fc6..46f00a38 100644 --- a/app/views/transactions/_form.html.erb +++ b/app/views/transactions/_form.html.erb @@ -1,4 +1,4 @@ -<%= form_with model: @transaction, data: { turbo_frame: "_top" } do |f| %> +<%= form_with model: @transaction, url: transactions_path, scope: "transaction", data: { turbo_frame: "_top" } do |f| %>
    <%= radio_tab_tag form: f, name: :nature, value: :expense, label: t(".expense"), icon: "minus-circle", checked: params[:nature] == "expense" || params[:nature].nil? %> diff --git a/app/views/transactions/_name.html.erb b/app/views/transactions/_name.html.erb deleted file mode 100644 index 32891964..00000000 --- a/app/views/transactions/_name.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<%= content_tag :div, class: ["flex items-center gap-2"] do %> -
    - <%= transaction.name[0].upcase %> -
    - -
    - <% if transaction.new_record? %> - <%= content_tag :p, transaction.name %> - <% else %> - <%= link_to transaction.name, - transaction_path(transaction), - data: { turbo_frame: "drawer", turbo_prefetch: false }, - class: "hover:underline hover:text-gray-800" %> - <% end %> -
    -<% end %> diff --git a/app/views/transactions/_pagination.html.erb b/app/views/transactions/_pagination.html.erb index a485ce71..ae481645 100644 --- a/app/views/transactions/_pagination.html.erb +++ b/app/views/transactions/_pagination.html.erb @@ -1,3 +1,4 @@ +<%# locals: (pagy:) %>