mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-05 13:35:21 +02:00
Account:: namespace simplifications and cleanup (#2110)
* Flatten Holding model * Flatten balance model * Entries domain renames * Fix valuations reference * Fix trades stream * Fix brakeman warnings * Fix tests * Replace existing entryable type references in DB
This commit is contained in:
parent
f181ba941f
commit
e657c40d19
172 changed files with 1297 additions and 1258 deletions
|
@ -1,23 +0,0 @@
|
|||
<%# locals: (entry:) %>
|
||||
|
||||
<%= tag.header class: "mb-4 space-y-1", id: dom_id(entry, :header) do %>
|
||||
<div class="flex items-center gap-4">
|
||||
<h3 class="font-medium">
|
||||
<span class="text-2xl">
|
||||
<%= format_money -entry.amount_money %>
|
||||
</span>
|
||||
|
||||
<span class="text-lg text-secondary">
|
||||
<%= entry.currency %>
|
||||
</span>
|
||||
</h3>
|
||||
|
||||
<% if entry.account_transaction.transfer? %>
|
||||
<%= lucide_icon "arrow-left-right", class: "text-secondary mt-1 w-5 h-5" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<span class="text-sm text-secondary">
|
||||
<%= I18n.l(entry.date, format: :long) %>
|
||||
</span>
|
||||
<% end %>
|
|
@ -1,3 +0,0 @@
|
|||
<%= modal_form_wrapper title: t(".new_transaction") do %>
|
||||
<%= render "form", entry: @entry %>
|
||||
<% end %>
|
|
@ -11,13 +11,13 @@
|
|||
<%= tag.span t(".new") %>
|
||||
</button>
|
||||
<div data-menu-target="content" class="z-10 hidden bg-container rounded-lg border border-alpha-black-25 shadow-xs p-1">
|
||||
<%= link_to new_account_valuation_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %>
|
||||
<%= link_to new_valuation_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %>
|
||||
<%= lucide_icon("circle-dollar-sign", class: "text-secondary w-5 h-5") %>
|
||||
<%= tag.span t(".new_balance"), class: "text-sm" %>
|
||||
<% end %>
|
||||
|
||||
<% unless @account.crypto? %>
|
||||
<%= link_to @account.investment? ? new_account_trade_path(account_id: @account.id) : new_account_transaction_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %>
|
||||
<%= link_to @account.investment? ? new_trade_path(account_id: @account.id) : new_transaction_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %>
|
||||
<%= lucide_icon("credit-card", class: "text-secondary w-5 h-5") %>
|
||||
<%= tag.span t(".new_transaction"), class: "text-sm" %>
|
||||
<% end %>
|
||||
|
@ -59,7 +59,7 @@
|
|||
bulk_select_plural_label_value: t(".entries")
|
||||
} do %>
|
||||
<div id="entry-selection-bar" data-bulk-select-target="selectionBar" class="flex justify-center hidden">
|
||||
<%= render "account/entries/selection_bar" %>
|
||||
<%= render "entries/selection_bar" %>
|
||||
</div>
|
||||
|
||||
<div class="grid bg-container-inset rounded-xl grid-cols-12 items-center uppercase text-xs font-medium text-secondary px-5 py-3 mb-4">
|
||||
|
@ -76,7 +76,7 @@
|
|||
<div>
|
||||
<div class="rounded-tl-lg rounded-tr-lg bg-container border-alpha-black-25 shadow-xs">
|
||||
<div class="space-y-4">
|
||||
<% calculator = Account::BalanceTrendCalculator.for(@entries) %>
|
||||
<% calculator = Balance::TrendCalculator.for(@entries) %>
|
||||
<%= entries_by_date(@entries) do |entries| %>
|
||||
<% entries.each do |entry| %>
|
||||
<%= render entry, balance_trend: calculator&.trend_for(entry), view_ctx: "account" %>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
class: ["filterable-item flex justify-between items-center border-none rounded-lg px-2 py-1 group w-full hover:bg-gray-25 focus-within:bg-gray-25",
|
||||
{ "bg-gray-25": is_selected }],
|
||||
data: { filter_name: category.name } do %>
|
||||
<%= button_to account_transaction_category_path(
|
||||
<%= button_to transaction_category_path(
|
||||
@transaction.entry,
|
||||
account_entry: {
|
||||
entryable_type: "Account::Transaction",
|
||||
entry: {
|
||||
entryable_type: "Transaction",
|
||||
entryable_attributes: { id: @transaction.id, category_id: category.id }
|
||||
}
|
||||
),
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
<hr>
|
||||
<div class="relative p-1.5 w-full">
|
||||
<% if @transaction.category %>
|
||||
<%= button_to account_transaction_path(@transaction.entry),
|
||||
<%= button_to transaction_path(@transaction.entry),
|
||||
method: :patch,
|
||||
data: { turbo_frame: dom_id(@transaction.entry) },
|
||||
params: { account_entry: { entryable_type: "Account::Transaction", entryable_attributes: { id: @transaction.id, category_id: nil } } },
|
||||
params: { entry: { entryable_type: "Transaction", entryable_attributes: { id: @transaction.id, category_id: nil } } },
|
||||
class: "flex text-sm font-medium items-center gap-2 text-secondary w-full rounded-lg p-2 hover:bg-gray-100" do %>
|
||||
<%= lucide_icon "minus", class: "w-5 h-5" %>
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
|||
<% end %>
|
||||
|
||||
<% unless @transaction.transfer? %>
|
||||
<%= link_to new_account_transaction_transfer_match_path(@transaction.entry),
|
||||
<%= link_to new_transaction_transfer_match_path(@transaction.entry),
|
||||
class: "flex text-sm font-medium items-center gap-2 text-secondary w-full rounded-lg p-2 hover:bg-gray-100",
|
||||
data: { turbo_frame: "modal" } do %>
|
||||
<%= lucide_icon "refresh-cw", class: "w-5 h-5" %>
|
||||
|
@ -53,11 +53,11 @@
|
|||
|
||||
<div class="flex text-sm font-medium items-center gap-2 text-secondary w-full rounded-lg p-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<%= form_with url: account_transaction_path(@transaction.entry),
|
||||
<%= form_with url: transaction_path(@transaction.entry),
|
||||
method: :patch,
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<%= f.hidden_field "account_entry[excluded]", value: !@transaction.entry.excluded %>
|
||||
<%= f.check_box "account_entry[excluded]",
|
||||
<%= f.hidden_field "entry[excluded]", value: !@transaction.entry.excluded %>
|
||||
<%= f.check_box "entry[excluded]",
|
||||
checked: @transaction.entry.excluded,
|
||||
class: "checkbox checkbox--light",
|
||||
data: { auto_submit_form_target: "auto", autosubmit_trigger_event: "change" } %>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex items-center gap-1 text-secondary">
|
||||
<%= form_with url: bulk_delete_account_transactions_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %>
|
||||
<%= form_with url: transactions_bulk_deletion_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %>
|
||||
<button type="button" data-bulk-select-scope-param="bulk_delete" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Delete">
|
||||
<%= lucide_icon "trash-2", class: "w-5 group-hover:text-white" %>
|
||||
</button>
|
|
@ -6,7 +6,7 @@
|
|||
<%= image_tag "https://logo.synthfinance.com/ticker/#{holding.ticker}", class: "w-9 h-9 rounded-full", loading: "lazy" %>
|
||||
|
||||
<div class="space-y-0.5">
|
||||
<%= link_to holding.name, account_holding_path(holding), data: { turbo_frame: :drawer }, class: "hover:underline" %>
|
||||
<%= link_to holding.name, holding_path(holding), data: { turbo_frame: :drawer }, class: "hover:underline" %>
|
||||
|
||||
<% if holding.amount %>
|
||||
<%= tag.p holding.ticker, class: "text-secondary text-xs uppercase" %>
|
|
@ -2,7 +2,7 @@
|
|||
<div class="bg-container space-y-4 p-5 rounded-xl shadow-border-xs">
|
||||
<div class="flex items-center justify-between">
|
||||
<%= tag.h2 t(".holdings"), class: "font-medium text-lg" %>
|
||||
<%= link_to new_account_trade_path(account_id: @account.id),
|
||||
<%= link_to new_trade_path(account_id: @account.id),
|
||||
id: dom_id(@account, "new_trade"),
|
||||
data: { turbo_frame: :modal },
|
||||
class: "flex gap-1 font-medium items-center bg-gray-50 text-primary p-2 rounded-lg" do %>
|
||||
|
@ -21,12 +21,12 @@
|
|||
</div>
|
||||
|
||||
<div class="rounded-lg bg-container shadow-border-xs">
|
||||
<%= render "account/holdings/cash", account: @account %>
|
||||
<%= render "holdings/cash", account: @account %>
|
||||
|
||||
<%= render "account/holdings/ruler" %>
|
||||
<%= render "holdings/ruler" %>
|
||||
|
||||
<% if @account.current_holdings.any? %>
|
||||
<%= render partial: "account/holdings/holding", collection: @account.current_holdings, spacer_template: "ruler" %>
|
||||
<%= render partial: "holdings/holding", collection: @account.current_holdings, spacer_template: "ruler" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
|
@ -71,9 +71,9 @@
|
|||
|
||||
<p><%= t(
|
||||
".trade_history_entry",
|
||||
qty: trade_entry.account_trade.qty,
|
||||
security: trade_entry.account_trade.security.ticker,
|
||||
price: trade_entry.account_trade.price_money.format
|
||||
qty: trade_entry.trade.qty,
|
||||
security: trade_entry.trade.security.ticker,
|
||||
price: trade_entry.trade.price_money.format
|
||||
) %></p>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -102,7 +102,7 @@
|
|||
</div>
|
||||
|
||||
<%= button_to t(".delete"),
|
||||
account_holding_path(@holding),
|
||||
holding_path(@holding),
|
||||
method: :delete,
|
||||
class: "rounded-lg px-3 py-2 text-red-500 text-sm font-medium border border-secondary",
|
||||
data: { turbo_confirm: true } %>
|
|
@ -1,5 +1,5 @@
|
|||
<%# locals: (account:) %>
|
||||
|
||||
<%= turbo_frame_tag dom_id(account, :holdings), src: account_holdings_path(account_id: account.id) do %>
|
||||
<%= render "account/entries/loading" %>
|
||||
<%= turbo_frame_tag dom_id(account, :holdings), src: holdings_path(account_id: account.id) do %>
|
||||
<%= render "entries/loading" %>
|
||||
<% end %>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<% type = params[:type] || "buy" %>
|
||||
|
||||
<%= styled_form_with model: entry, url: account_trades_path, data: { controller: "trade-form" } do |form| %>
|
||||
<%= styled_form_with model: entry, url: trades_path, data: { controller: "trade-form" } do |form| %>
|
||||
|
||||
<%= form.hidden_field :account_id %>
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
{ label: t(".type"), selected: type },
|
||||
{ data: {
|
||||
action: "trade-form#changeType",
|
||||
trade_form_url_param: new_account_trade_path(account_id: entry.account&.id || entry.account_id),
|
||||
trade_form_url_param: new_trade_path(account_id: entry.account&.id || entry.account_id),
|
||||
trade_form_key_param: "type",
|
||||
}} %>
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
|||
<div class="form-field combobox">
|
||||
<%= form.combobox :ticker,
|
||||
securities_path(country_code: Current.family.country),
|
||||
name_when_new: "account_entry[manual_ticker]",
|
||||
name_when_new: "entry[manual_ticker]",
|
||||
label: t(".holding"),
|
||||
placeholder: t(".ticker_placeholder"),
|
||||
required: true %>
|
|
@ -23,7 +23,7 @@
|
|||
</span>
|
||||
<% end %>
|
||||
|
||||
<% trade = entry.account_trade %>
|
||||
<% trade = entry.trade %>
|
||||
|
||||
<div class="mb-2">
|
||||
<%= disclosure t(".overview") do %>
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<div class="truncate">
|
||||
<%= link_to entry.display_name,
|
||||
account_entry_path(entry),
|
||||
entry_path(entry),
|
||||
data: { turbo_frame: "drawer", turbo_prefetch: false },
|
||||
class: "hover:underline hover:text-gray-800" %>
|
||||
</div>
|
|
@ -1,3 +1,3 @@
|
|||
<%= modal_form_wrapper title: t(".title") do %>
|
||||
<%= render "account/trades/form", entry: @entry %>
|
||||
<%= render "trades/form", entry: @entry %>
|
||||
<% end %>
|
|
@ -1,14 +1,14 @@
|
|||
<%= drawer(reload_on_close: true) do %>
|
||||
<%= render "account/trades/header", entry: @entry %>
|
||||
<%= render "trades/header", entry: @entry %>
|
||||
|
||||
<% trade = @entry.account_trade %>
|
||||
<% trade = @entry.trade %>
|
||||
|
||||
<div class="space-y-2">
|
||||
<!-- Details Section -->
|
||||
<%= disclosure t(".details") do %>
|
||||
<div class="pb-4">
|
||||
<%= styled_form_with model: @entry,
|
||||
url: account_trade_path(@entry),
|
||||
url: trade_path(@entry),
|
||||
class: "space-y-2",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<%= f.date_field :date,
|
||||
|
@ -46,7 +46,7 @@
|
|||
<%= disclosure t(".additional") do %>
|
||||
<div class="pb-4">
|
||||
<%= styled_form_with model: @entry,
|
||||
url: account_trade_path(@entry),
|
||||
url: trade_path(@entry),
|
||||
class: "space-y-2",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<%= f.text_area :notes,
|
||||
|
@ -63,7 +63,7 @@
|
|||
<div class="pb-4">
|
||||
<!-- Exclude Trade Form -->
|
||||
<%= styled_form_with model: @entry,
|
||||
url: account_trade_path(@entry),
|
||||
url: trade_path(@entry),
|
||||
class: "p-3",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<div class="flex cursor-pointer items-center gap-2 justify-between">
|
||||
|
@ -76,7 +76,7 @@
|
|||
<%= f.check_box :excluded,
|
||||
class: "sr-only peer",
|
||||
"data-auto-submit-form-target": "auto" %>
|
||||
<label for="account_entry_excluded"
|
||||
<label for="entry_excluded"
|
||||
class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -90,7 +90,7 @@
|
|||
</div>
|
||||
|
||||
<%= button_to t(".delete"),
|
||||
account_entry_path(@entry),
|
||||
entry_path(@entry),
|
||||
method: :delete,
|
||||
class: "rounded-lg px-3 py-2 text-red-500 text-sm
|
||||
font-medium border border-secondary",
|
|
@ -1,4 +1,4 @@
|
|||
<%= styled_form_with model: @entry, url: account_transactions_path, class: "space-y-4" do |f| %>
|
||||
<%= styled_form_with model: @entry, url: transactions_path, class: "space-y-4" do |f| %>
|
||||
|
||||
<% if entry.errors.any? %>
|
||||
<%= render "shared/form_errors", model: entry %>
|
||||
|
@ -18,6 +18,8 @@
|
|||
<section class="space-y-2 overflow-hidden">
|
||||
<%= f.text_field :name, label: t(".description"), placeholder: t(".description_placeholder"), required: true %>
|
||||
|
||||
<%= f.hidden_field :entryable_type, value: "Transaction" %>
|
||||
|
||||
<% if @entry.account_id %>
|
||||
<%= f.hidden_field :account_id %>
|
||||
<% else %>
|
||||
|
@ -28,7 +30,7 @@
|
|||
<%= f.fields_for :entryable do |ef| %>
|
||||
<%= ef.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: t(".category_prompt"), label: t(".category") } %>
|
||||
<% end %>
|
||||
<%= f.date_field :date, label: t(".date"), required: true, min: Account::Entry.min_supported_date, max: Date.current, value: Date.current %>
|
||||
<%= f.date_field :date, label: t(".date"), required: true, min: Entry.min_supported_date, max: Date.current, value: Date.current %>
|
||||
</section>
|
||||
|
||||
<%= disclosure t(".details"), default_open: false do %>
|
|
@ -1,23 +1,23 @@
|
|||
<header class="flex justify-between items-center text-primary font-medium">
|
||||
<h1 class="text-xl">Transactions</h1>
|
||||
<div class="flex items-center gap-5">
|
||||
<div class="flex items-center gap-2">
|
||||
<%= contextual_menu do %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_categories"), categories_path, icon: "shapes", turbo_frame: :_top %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_tags"), tags_path, icon: "tags", turbo_frame: :_top %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_merchants"), merchants_path, icon: "store", turbo_frame: :_top %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_imports"), imports_path, icon: "hard-drive-upload", turbo_frame: :_top %>
|
||||
<% end %>
|
||||
<%# locals: (entry:) %>
|
||||
|
||||
<%= link_to new_import_path, class: "btn btn--outline flex items-center gap-2", data: { turbo_frame: "modal" } do %>
|
||||
<%= lucide_icon("download", class: "text-secondary w-4 h-4") %>
|
||||
<p class="text-sm font-medium text-primary"><%= t(".import") %></p>
|
||||
<% end %>
|
||||
<%= tag.header class: "mb-4 space-y-1", id: dom_id(entry, :header) do %>
|
||||
<div class="flex items-center gap-4">
|
||||
<h3 class="font-medium">
|
||||
<span class="text-2xl">
|
||||
<%= format_money -entry.amount_money %>
|
||||
</span>
|
||||
|
||||
<%= link_to new_account_transaction_path, class: "btn btn--primary flex items-center gap-2", data: { turbo_frame: :modal } do %>
|
||||
<%= lucide_icon("plus", class: "w-5 h-5") %>
|
||||
<p class="text-sm font-medium">New transaction</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<span class="text-lg text-secondary">
|
||||
<%= entry.currency %>
|
||||
</span>
|
||||
</h3>
|
||||
|
||||
<% if entry.transaction.transfer? %>
|
||||
<%= lucide_icon "arrow-left-right", class: "text-secondary mt-1 w-5 h-5" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<span class="text-sm text-secondary">
|
||||
<%= I18n.l(entry.date, format: :long) %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
|
|
@ -7,15 +7,14 @@
|
|||
|
||||
<div class="flex items-center gap-1 text-secondary">
|
||||
<%= turbo_frame_tag "bulk_transaction_edit_drawer" %>
|
||||
|
||||
<%= link_to bulk_edit_account_transactions_path,
|
||||
<%= link_to new_transactions_bulk_update_path,
|
||||
class: "p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md",
|
||||
title: "Edit",
|
||||
data: { turbo_frame: "bulk_transaction_edit_drawer" } do %>
|
||||
<%= lucide_icon "pencil-line", class: "w-5 group-hover:text-white" %>
|
||||
<% end %>
|
||||
|
||||
<%= form_with url: bulk_delete_account_transactions_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %>
|
||||
<%= form_with url: transactions_bulk_deletion_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %>
|
||||
<button type="button" data-bulk-select-scope-param="bulk_delete" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Delete">
|
||||
<%= lucide_icon "trash-2", class: "w-5 group-hover:text-white" %>
|
||||
</button>
|
|
@ -36,7 +36,7 @@
|
|||
<div class="flex items-center gap-1">
|
||||
<%= link_to(
|
||||
transaction.transfer? ? transaction.transfer.name : entry.display_name,
|
||||
transaction.transfer? ? transfer_path(transaction.transfer) : account_entry_path(entry),
|
||||
transaction.transfer? ? transfer_path(transaction.transfer) : entry_path(entry),
|
||||
data: {
|
||||
turbo_frame: "drawer",
|
||||
turbo_prefetch: false
|
||||
|
@ -51,7 +51,7 @@
|
|||
<% end %>
|
||||
|
||||
<% if transaction.transfer? %>
|
||||
<%= render "account/transactions/transfer_match", transaction: transaction %>
|
||||
<%= render "transactions/transfer_match", transaction: transaction %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex items-center gap-1 col-span-2">
|
||||
<%= render "account/transactions/transaction_category", transaction: transaction %>
|
||||
<%= render "transactions/transaction_category", transaction: transaction %>
|
||||
</div>
|
||||
|
||||
<div class="col-span-2 ml-auto">
|
|
@ -2,7 +2,7 @@
|
|||
<dialog data-controller="modal"
|
||||
data-action="mousedown->modal#clickOutside"
|
||||
class="bg-container shadow-border-xs rounded-2xl max-h-[calc(100vh-32px)] h-full max-w-[480px] w-full mt-4 mr-4 ml-auto">
|
||||
<%= styled_form_with url: bulk_update_account_transactions_path, scope: "bulk_update", class: "h-full", data: { turbo_frame: "_top" } do |form| %>
|
||||
<%= styled_form_with url: transactions_bulk_update_path, scope: "bulk_update", class: "h-full", data: { turbo_frame: "_top" } do |form| %>
|
||||
<div class="flex h-full flex-col justify-between p-4 gap-4">
|
||||
<div>
|
||||
<div class="flex h-9 items-center justify-end">
|
||||
|
@ -22,26 +22,26 @@
|
|||
<div class="space-y-2">
|
||||
<details class="group space-y-2" open>
|
||||
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
|
||||
<h4><%= t(".overview") %></h4>
|
||||
<h4>Overview</h4>
|
||||
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
|
||||
</summary>
|
||||
|
||||
<div class="pb-6 space-y-2">
|
||||
<%= form.date_field :date, label: t(".date_label"), max: Date.current %>
|
||||
<%= form.date_field :date, label: "Date", max: Date.current %>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group space-y-2" open>
|
||||
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
|
||||
<h4><%= t(".details") %></h4>
|
||||
<h4>Details</h4>
|
||||
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
|
||||
</summary>
|
||||
|
||||
<div class="space-y-2">
|
||||
<%= form.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: t(".category_placeholder"), label: t(".category_label"), class: "text-subdued" } %>
|
||||
<%= form.collection_select :merchant_id, Current.family.merchants.alphabetically, :id, :name, { prompt: t(".merchant_placeholder"), label: t(".merchant_label"), class: "text-subdued" } %>
|
||||
<%= form.select :tag_ids, Current.family.tags.alphabetically.pluck(:name, :id), { include_blank: t(".none"), multiple: true, label: t(".tag_label"), container_class: "h-40" } %>
|
||||
<%= form.text_area :notes, label: t(".note_label"), placeholder: t(".note_placeholder"), rows: 5 %>
|
||||
<%= form.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: "Select a category", label: "Category", class: "text-subdued" } %>
|
||||
<%= form.collection_select :merchant_id, Current.family.merchants.alphabetically, :id, :name, { prompt: "Select a merchant", label: "Merchant", class: "text-subdued" } %>
|
||||
<%= form.select :tag_ids, Current.family.tags.alphabetically.pluck(:name, :id), { include_blank: "None", multiple: true, label: "Tags", container_class: "h-40" } %>
|
||||
<%= form.text_area :notes, label: "Notes", placeholder: "Enter a note that will be applied to selected transactions", rows: 5 %>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
@ -50,9 +50,9 @@
|
|||
</div>
|
||||
|
||||
<div class="flex justify-end items-center gap-2">
|
||||
<%= link_to t(".cancel"), transactions_path, class: "btn btn--ghost" %>
|
||||
<%= link_to "Cancel", transactions_path, class: "btn btn--ghost" %>
|
||||
|
||||
<%= tag.button t(".save"),
|
||||
<%= tag.button "Save",
|
||||
type: "button",
|
||||
data: { "bulk-select-scope-param": "bulk_update", action: "bulk-select#submitBulkRequest" },
|
||||
class: "btn btn--primary" %>
|
|
@ -1,5 +1,27 @@
|
|||
<div class="space-y-4 pb-20 flex flex-col" data-controller="focus-record" data-focus-record-id-value="<%= @focused_record ? dom_id(@focused_record) : nil %>">
|
||||
<%= render "header" %>
|
||||
<header class="flex justify-between items-center text-primary font-medium">
|
||||
<h1 class="text-xl">Transactions</h1>
|
||||
<div class="flex items-center gap-5">
|
||||
<div class="flex items-center gap-2">
|
||||
<%= contextual_menu do %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_categories"), categories_path, icon: "shapes", turbo_frame: :_top %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_tags"), tags_path, icon: "tags", turbo_frame: :_top %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_merchants"), merchants_path, icon: "store", turbo_frame: :_top %>
|
||||
<%= contextual_menu_modal_action_item t(".edit_imports"), imports_path, icon: "hard-drive-upload", turbo_frame: :_top %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to new_import_path, class: "btn btn--outline flex items-center gap-2", data: { turbo_frame: "modal" } do %>
|
||||
<%= lucide_icon("download", class: "text-secondary w-4 h-4") %>
|
||||
<p class="text-sm font-medium text-primary"><%= t(".import") %></p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to new_transaction_path, class: "btn btn--primary flex items-center gap-2", data: { turbo_frame: :modal } do %>
|
||||
<%= lucide_icon("plus", class: "w-5 h-5") %>
|
||||
<p class="text-sm font-medium">New transaction</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<%= render "summary", totals: @totals %>
|
||||
|
||||
|
@ -11,7 +33,7 @@
|
|||
<%= render "transactions/searches/search" %>
|
||||
|
||||
<div id="entry-selection-bar" data-bulk-select-target="selectionBar" class="flex justify-center hidden">
|
||||
<%= render "account/transactions/selection_bar" %>
|
||||
<%= render "transactions/selection_bar" %>
|
||||
</div>
|
||||
|
||||
<% if @pagy.count > 0 %>
|
||||
|
@ -34,7 +56,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render "account/entries/empty" %>
|
||||
<%= render "entries/empty" %>
|
||||
<% end %>
|
||||
|
||||
<div class="pt-4">
|
||||
|
|
3
app/views/transactions/new.html.erb
Normal file
3
app/views/transactions/new.html.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<%= modal_form_wrapper title: "New transaction" do %>
|
||||
<%= render "form", entry: @entry %>
|
||||
<% end %>
|
|
@ -1,12 +1,12 @@
|
|||
<%= drawer(reload_on_close: true) do %>
|
||||
<%= render "account/transactions/header", entry: @entry %>
|
||||
<%= render "transactions/header", entry: @entry %>
|
||||
|
||||
<div class="space-y-2">
|
||||
<!-- Overview Section -->
|
||||
<%= disclosure t(".overview") do %>
|
||||
<div class="pb-4">
|
||||
<%= styled_form_with model: @entry,
|
||||
url: account_transaction_path(@entry),
|
||||
url: transaction_path(@entry),
|
||||
class: "space-y-2",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
|||
max: Date.current,
|
||||
"data-auto-submit-form-target": "auto" %>
|
||||
|
||||
<% unless @entry.account_transaction.transfer? %>
|
||||
<% unless @entry.transaction.transfer? %>
|
||||
<div class="flex items-center gap-2">
|
||||
<%= f.select :nature,
|
||||
[["Expense", "outflow"], ["Income", "inflow"]],
|
||||
|
@ -51,10 +51,10 @@
|
|||
<%= disclosure t(".details"), default_open: false do %>
|
||||
<div class="pb-4">
|
||||
<%= styled_form_with model: @entry,
|
||||
url: account_transaction_path(@entry),
|
||||
url: transaction_path(@entry),
|
||||
class: "space-y-2",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<% unless @entry.account_transaction.transfer? %>
|
||||
<% unless @entry.transaction.transfer? %>
|
||||
<%= f.select :account,
|
||||
options_for_select(
|
||||
Current.family.accounts.alphabetically.pluck(:name, :id),
|
||||
|
@ -100,7 +100,7 @@
|
|||
<div class="pb-4">
|
||||
|
||||
<%= styled_form_with model: @entry,
|
||||
url: account_transaction_path(@entry),
|
||||
url: transaction_path(@entry),
|
||||
class: "p-3",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<div class="flex cursor-pointer items-center gap-4 justify-between">
|
||||
|
@ -113,7 +113,7 @@
|
|||
<%= f.check_box :excluded,
|
||||
class: "sr-only peer",
|
||||
"data-auto-submit-form-target": "auto" %>
|
||||
<label for="account_entry_excluded"
|
||||
<label for="entry_excluded"
|
||||
class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -125,7 +125,7 @@
|
|||
<p class="text-secondary">Transfers and payments are special types of transactions that indicate money movement between 2 accounts.</p>
|
||||
</div>
|
||||
|
||||
<%= link_to new_account_transaction_transfer_match_path(@entry), class: "btn btn--outline flex items-center gap-2", data: { turbo_frame: :modal } do %>
|
||||
<%= link_to new_transaction_transfer_match_path(@entry), class: "btn btn--outline flex items-center gap-2", data: { turbo_frame: :modal } do %>
|
||||
<%= lucide_icon "arrow-left-right", class: "w-4 h-4 shrink-0" %>
|
||||
<span class="whitespace-nowrap">Open matcher</span>
|
||||
<% end %>
|
||||
|
@ -139,7 +139,7 @@
|
|||
</div>
|
||||
|
||||
<%= button_to t(".delete"),
|
||||
account_entry_path(@entry),
|
||||
entry_path(@entry),
|
||||
method: :delete,
|
||||
class: "rounded-lg px-3 py-2 text-red-500 text-sm
|
||||
font-medium border border-secondary",
|
|
@ -1,6 +1,6 @@
|
|||
<%= modal_form_wrapper title: "Match transfer or payment" do %>
|
||||
<%= styled_form_with(
|
||||
url: account_transaction_transfer_match_path(@entry),
|
||||
url: transaction_transfer_match_path(@entry),
|
||||
scope: :transfer_match,
|
||||
class: "space-y-8",
|
||||
data: { turbo_frame: :_top }
|
||||
|
@ -22,7 +22,7 @@
|
|||
disabled: true
|
||||
) %>
|
||||
<% else %>
|
||||
<%= render "account/transfer_matches/matching_fields",
|
||||
<%= render "transfer_matches/matching_fields",
|
||||
form: f, entry: @entry, candidates: @transfer_match_candidates.map { |pm| pm.outflow_transaction.entry }, accounts: @accounts %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@
|
|||
disabled: true
|
||||
) %>
|
||||
<% else %>
|
||||
<%= render "account/transfer_matches/matching_fields",
|
||||
<%= render "transfer_matches/matching_fields",
|
||||
form: f, entry: @entry, candidates: @transfer_match_candidates.map { |pm| pm.inflow_transaction.entry }, accounts: @accounts %>
|
||||
<% end %>
|
||||
</div>
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
<section>
|
||||
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
|
||||
<%= link_to new_account_transaction_path(nature: "expense"), data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued" do %>
|
||||
<%= link_to new_transaction_path(nature: "expense"), data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued" do %>
|
||||
<%= lucide_icon "minus-circle", class: "w-5 h-5" %>
|
||||
<%= tag.span t(".expense") %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to new_account_transaction_path(nature: "income"), data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued" do %>
|
||||
<%= link_to new_transaction_path(nature: "income"), data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued" do %>
|
||||
<%= lucide_icon "plus-circle", class: "w-5 h-5" %>
|
||||
<%= tag.span t(".income") %>
|
||||
<% end %>
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
<%= turbo_stream.replace @transfer.outflow_transaction.entry %>
|
||||
|
||||
<%= turbo_stream.replace dom_id(@transfer.inflow_transaction, "category_menu"),
|
||||
partial: "account/transactions/transaction_category",
|
||||
partial: "transactions/transaction_category",
|
||||
locals: { transaction: @transfer.inflow_transaction } %>
|
||||
|
||||
<%= turbo_stream.replace dom_id(@transfer.outflow_transaction, "category_menu"),
|
||||
partial: "account/transactions/transaction_category",
|
||||
partial: "transactions/transaction_category",
|
||||
locals: { transaction: @transfer.outflow_transaction } %>
|
||||
|
||||
<%= turbo_stream.replace dom_id(@transfer.inflow_transaction, "transfer_match"),
|
||||
partial: "account/transactions/transfer_match",
|
||||
partial: "transactions/transfer_match",
|
||||
locals: { transaction: @transfer.inflow_transaction } %>
|
||||
|
||||
<%= turbo_stream.replace dom_id(@transfer.outflow_transaction, "transfer_match"),
|
||||
partial: "account/transactions/transfer_match",
|
||||
partial: "transactions/transfer_match",
|
||||
locals: { transaction: @transfer.outflow_transaction } %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<%# locals: (entry:) %>
|
||||
|
||||
<%= styled_form_with model: entry, url: account_valuations_path, class: "space-y-4" do |form| %>
|
||||
<%= styled_form_with model: entry, url: valuations_path, class: "space-y-4" do |form| %>
|
||||
<%= form.hidden_field :account_id %>
|
||||
|
||||
<% if entry.errors.any? %>
|
||||
|
@ -9,7 +9,7 @@
|
|||
|
||||
<div class="space-y-3">
|
||||
<%= form.hidden_field :name, value: "Balance update" %>
|
||||
<%= form.date_field :date, label: true, required: true, value: Date.current, min: Account::Entry.min_supported_date, max: Date.current %>
|
||||
<%= form.date_field :date, label: true, required: true, value: Date.current, min: Entry.min_supported_date, max: Date.current %>
|
||||
<%= form.money_field :amount, label: t(".amount"), required: true %>
|
||||
</div>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<div class="truncate text-primary">
|
||||
<%= link_to entry.display_name,
|
||||
account_entry_path(entry),
|
||||
entry_path(entry),
|
||||
data: { turbo_frame: "drawer", turbo_prefetch: false },
|
||||
class: "hover:underline hover:text-gray-800" %>
|
||||
</div>
|
|
@ -2,8 +2,8 @@
|
|||
<div class="bg-container space-y-4 p-5 shadow-border-xs rounded-xl">
|
||||
<div class="flex items-center justify-between">
|
||||
<%= tag.h2 t(".valuations"), class: "font-medium text-lg" %>
|
||||
<%= link_to new_account_valuation_path(@account),
|
||||
data: { turbo_frame: dom_id(@account.entries.account_valuations.new) },
|
||||
<%= link_to new_valuation_path(@account),
|
||||
data: { turbo_frame: dom_id(@account.entries.valuations.new) },
|
||||
class: "flex gap-1 font-medium items-center bg-gray-50 text-primary p-2 rounded-lg" do %>
|
||||
<%= lucide_icon("plus", class: "w-5 h-5 text-primary") %>
|
||||
<%= tag.span t(".new_entry"), class: "text-sm" %>
|
||||
|
@ -19,13 +19,13 @@
|
|||
</div>
|
||||
|
||||
<div class="rounded-lg bg-container shadow-border-xs">
|
||||
<%= turbo_frame_tag dom_id(@account.entries.account_valuations.new) %>
|
||||
<%= turbo_frame_tag dom_id(@account.entries.valuations.new) %>
|
||||
|
||||
<% if @entries.any? %>
|
||||
<%= render partial: "account/valuations/valuation",
|
||||
<%= render partial: "valuations/valuation",
|
||||
collection: @entries,
|
||||
as: :entry,
|
||||
spacer_template: "account/entries/ruler" %>
|
||||
spacer_template: "entries/ruler" %>
|
||||
<% else %>
|
||||
<p class="text-secondary text-sm p-4"><%= t(".no_valuations") %></p>
|
||||
<% end %>
|
|
@ -1,14 +1,14 @@
|
|||
<% entry, account = @entry, @entry.account %>
|
||||
|
||||
<%= drawer(reload_on_close: true) do %>
|
||||
<%= render "account/valuations/header", entry: %>
|
||||
<%= render "valuations/header", entry: %>
|
||||
|
||||
<div class="space-y-2">
|
||||
<!-- Overview Section -->
|
||||
<%= disclosure t(".overview") do %>
|
||||
<div class="pb-4">
|
||||
<%= styled_form_with model: entry,
|
||||
url: account_entry_path(entry),
|
||||
url: entry_path(entry),
|
||||
class: "space-y-2",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<%= f.text_field :name,
|
||||
|
@ -33,7 +33,7 @@
|
|||
<%= disclosure t(".details") do %>
|
||||
<div class="pb-4">
|
||||
<%= styled_form_with model: entry,
|
||||
url: account_entry_path(entry),
|
||||
url: entry_path(entry),
|
||||
class: "space-y-2",
|
||||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<%= f.text_area :notes,
|
||||
|
@ -56,7 +56,7 @@
|
|||
</div>
|
||||
|
||||
<%= button_to t(".delete"),
|
||||
account_entry_path(entry),
|
||||
entry_path(entry),
|
||||
method: :delete,
|
||||
class: "rounded-lg px-3 py-2 text-red-500 text-sm font-medium border border-secondary",
|
||||
data: { turbo_confirm: true, turbo_frame: "_top" } %>
|
Loading…
Add table
Add a link
Reference in a new issue