mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-02 20:15:22 +02:00
Account::Entry Delegated Type (namespace updates part 7) (#923)
* Initial entryable models * Update transfer and tests * Update transaction controllers and tests * Update sync process to use new entries model * Get dashboard working again * Update transfers, imports, and accounts to use Account::Entry * Update system tests * Consolidate transaction management into entries controller * Add permitted partial key helper * Move account transactions list to entries controller * Delegate transaction entries search * Move transfer relation to entry * Update bulk transaction management flows to use entries * Remove test code * Test fix attempt * Update demo data script * Consolidate remaining transaction partials to entries * Consolidate valuations controller to entries controller * Lint fix * Remove unused files, additional cleanup * Add back valuation creation * Make migrations fully reversible * Stale routes cleanup * Migrations reversible fix * Move types to entryable concern * Fix search when no entries found * Remove more unused code
This commit is contained in:
parent
320954282a
commit
c3314e62d1
105 changed files with 2150 additions and 1576 deletions
|
@ -1,4 +1,4 @@
|
|||
<%= form_with model: @transaction, url: transactions_path, scope: "transaction", data: { turbo_frame: "_top" } do |f| %>
|
||||
<%= form_with model: @entry, url: transactions_path, data: { turbo_frame: "_top" } do |f| %>
|
||||
<section>
|
||||
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
|
||||
<%= radio_tab_tag form: f, name: :nature, value: :expense, label: t(".expense"), icon: "minus-circle", checked: params[:nature] == "expense" || params[:nature].nil? %>
|
||||
|
@ -14,7 +14,10 @@
|
|||
<%= f.text_field :name, label: t(".description"), placeholder: t(".description_placeholder"), required: true %>
|
||||
<%= f.collection_select :account_id, Current.family.accounts.alphabetically, :id, :name, { prompt: t(".account_prompt"), label: t(".account") }, required: true %>
|
||||
<%= f.money_field :amount_money, label: t(".amount"), required: true %>
|
||||
<%= f.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: t(".category_prompt"), label: t(".category") } %>
|
||||
<%= f.hidden_field :entryable_type, value: "Account::Transaction" %>
|
||||
<%= 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, max: Date.today %>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
<%# locals: (pagy:) %>
|
||||
<nav class="flex items-center justify-between px-4 mt-4 sm:px-0 w-full">
|
||||
<div class="flex">
|
||||
<nav class="flex w-full items-center justify-between">
|
||||
<div class="flex items-center gap-1">
|
||||
<div>
|
||||
<% if pagy.prev %>
|
||||
<%= link_to pagy_url_for(pagy, pagy.prev), class: "inline-flex items-center px-3 py-3 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %>
|
||||
<%= link_to pagy_url_for(pagy, pagy.prev), class: "inline-flex items-center p-2 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %>
|
||||
<%= lucide_icon("chevron-left", class: "w-5 h-5 text-gray-500") %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="inline-flex items-center px-3 py-3 text-sm font-medium hover:border-gray-300">
|
||||
<div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300">
|
||||
<%= lucide_icon("chevron-left", class: "w-5 h-5 text-gray-200") %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="bg-gray-25 rounded-xl">
|
||||
<div class="rounded-xl p-1 bg-gray-25">
|
||||
<% pagy.series.each do |series_item| %>
|
||||
<% if series_item.is_a?(Integer) %>
|
||||
<%= link_to pagy_url_for(pagy, series_item), class: "inline-flex items-center px-3 py-3 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %>
|
||||
<%= link_to pagy_url_for(pagy, series_item), class: "rounded-md px-2 py-1 inline-flex items-center text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %>
|
||||
<%= series_item %>
|
||||
<% end %>
|
||||
<% elsif series_item.is_a?(String) %>
|
||||
<%= link_to pagy_url_for(pagy, series_item), class: "shadow-lg ring-2 ring-inset ring-gray-200 rounded-xl bg-white inline-flex items-center m-1 px-4 py-2 text-sm font-medium text-gray-900" do %>
|
||||
<%= link_to pagy_url_for(pagy, series_item), class: "rounded-md px-2 py-1 bg-white border border-alpha-black-25 shadow-xs inline-flex items-center text-sm font-medium text-gray-900" do %>
|
||||
<%= series_item %>
|
||||
<% end %>
|
||||
<% elsif series_item == :gap %>
|
||||
<span class="inline-flex items-center px-3 py-3 text-sm font-medium text-gray-500">...</span>
|
||||
<span class="inline-flex items-center px-2 py-1 text-sm font-medium text-gray-500">...</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div>
|
||||
<% if pagy.next %>
|
||||
<%= link_to pagy_url_for(pagy, pagy.next), class: "inline-flex items-center px-3 py-3 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %>
|
||||
<%= link_to pagy_url_for(pagy, pagy.next), class: "inline-flex items-center p-2 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %>
|
||||
<%= lucide_icon("chevron-right", class: "w-5 h-5 text-gray-500") %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="inline-flex items-center px-3 py-3 text-sm font-medium hover:border-gray-300">
|
||||
<div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300">
|
||||
<%= lucide_icon("chevron-right", class: "w-5 h-5 text-gray-200") %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
@ -47,7 +47,7 @@
|
|||
data: { controller: "auto-submit-form" } do |f| %>
|
||||
<%= f.label :per_page, t(".rows_per_page"), class: "text-sm text-gray-500" %>
|
||||
<%= f.select :per_page,
|
||||
options_for_select(["10", "20", "30", "50"], params[:per_page]),
|
||||
options_for_select(["10", "20", "30", "50"], pagy.items),
|
||||
{},
|
||||
class: "py-1.5 pr-8 text-sm text-gray-900 font-medium border border-gray-200 rounded-lg focus:border-gray-900 focus:ring-gray-900 focus-visible:ring-gray-900",
|
||||
data: { "auto-submit-form-target": "auto" } %>
|
||||
|
|
|
@ -28,44 +28,26 @@
|
|||
|
||||
<div class="pb-6 space-y-2">
|
||||
<%= form.date_field :date, label: t(".date_label"), 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-gray-500 bg-gray-25 focus-visible:outline-none">
|
||||
<h4><%= t(".details") %></h4>
|
||||
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 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-gray-400" } %>
|
||||
<%= form.collection_select :merchant_id, Current.family.merchants.alphabetically, :id, :name, { prompt: t(".merchant_placeholder"), label: t(".merchant_label"), class: "text-gray-400" } %>
|
||||
</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-gray-500 bg-gray-25 focus-visible:outline-none">
|
||||
<h4><%= t(".additional") %></h4>
|
||||
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %>
|
||||
</summary>
|
||||
|
||||
<div>
|
||||
<%= form.text_area :notes, label: t(".note_label"), placeholder: t(".note_placeholder"), rows: 5 %>
|
||||
</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-gray-500 bg-gray-25 focus-visible:outline-none">
|
||||
<h4><%= t(".settings") %></h4>
|
||||
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %>
|
||||
</summary>
|
||||
|
||||
<div class="flex cursor-pointer items-center justify-between gap-4 p-3 pb-6">
|
||||
<div class="text-sm space-y-1">
|
||||
<h4 class="text-gray-900"><%= t(".exclude_title") %></h4>
|
||||
<p class="text-gray-500"><%= t(".exclude_subtitle") %></p>
|
||||
</div>
|
||||
|
||||
<div class="relative inline-block select-none">
|
||||
<%= form.check_box :excluded, class: "sr-only peer" %>
|
||||
<label for="bulk_update_excluded" class="maybe-switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end items-center gap-2">
|
||||
<%= link_to t(".cancel"), transactions_path, class: "text-sm font-medium text-gray-900 px-3 py-2" %>
|
||||
|
||||
|
|
|
@ -3,19 +3,20 @@
|
|||
|
||||
<%= render "summary", totals: @totals %>
|
||||
|
||||
<div id="transactions" data-controller="bulk-select" data-bulk-select-resource-value="<%= t(".transaction") %>" class="overflow-y-auto flex flex-col bg-white rounded-xl border border-alpha-black-25 shadow-xs pb-4">
|
||||
<div class="p-4 pb-0">
|
||||
<%= render partial: "transactions/searches/search", locals: { transactions: @transactions } %>
|
||||
</div>
|
||||
<div id="transactions"
|
||||
data-controller="bulk-select"
|
||||
data-bulk-select-resource-value="<%= t(".transaction") %>"
|
||||
class="overflow-y-auto flex flex-col bg-white rounded-xl border border-alpha-black-25 shadow-xs p-4">
|
||||
<%= render "transactions/searches/search" %>
|
||||
|
||||
<% if @transactions.present? %>
|
||||
<div hidden id="transaction-selection-bar" data-bulk-select-target="selectionBar">
|
||||
<%= render "account/transactions/selection_bar" %>
|
||||
<% if @transaction_entries.present? %>
|
||||
<div hidden id="entry-selection-bar" data-bulk-select-target="selectionBar">
|
||||
<%= render "account/entries/selection_bar" %>
|
||||
</div>
|
||||
<div class="grow overflow-y-auto px-4">
|
||||
<div class="grow overflow-y-auto">
|
||||
<div class="grid grid-cols-12 bg-gray-25 rounded-xl px-5 py-3 text-xs uppercase font-medium text-gray-500 items-center mb-4">
|
||||
<div class="pl-0.5 col-span-4 flex items-center gap-4">
|
||||
<%= check_box_tag "selection_transaction",
|
||||
<%= check_box_tag "selection_entry",
|
||||
class: "maybe-checkbox maybe-checkbox--light",
|
||||
data: { action: "bulk-select#togglePageSelection" } %>
|
||||
<p class="col-span-4">transaction</p>
|
||||
|
@ -26,19 +27,17 @@
|
|||
<p class="col-span-2 justify-self-end">amount</p>
|
||||
</div>
|
||||
<div class="space-y-6">
|
||||
<% group_transactions_by_date(@transactions).each do |date, group| %>
|
||||
<%= render "account/transactions/transaction_group", date:, transactions: group[:transactions], transfers: group[:transfers] %>
|
||||
<% @transaction_entries.group_by(&:date).each do |date, entries| %>
|
||||
<%= render "account/entries/entry_group", date:, entries: %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render "account/transactions/empty" %>
|
||||
<%= render "account/entries/empty" %>
|
||||
<% end %>
|
||||
|
||||
<div class="px-4">
|
||||
<% if @pagy.pages > 1 %>
|
||||
<%= render "pagination", pagy: @pagy %>
|
||||
<% end %>
|
||||
<div class="pt-4">
|
||||
<%= render "pagination", pagy: @pagy %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
<%= lucide_icon "x", class: "w-5 h-5 text-gray-500", data: { action: "click->modal#close" } %>
|
||||
</header>
|
||||
|
||||
<%= render "form", transaction: @transaction %>
|
||||
<%= render "form", transaction: @transaction, entry: @entry %>
|
||||
</article>
|
||||
<% end %>
|
||||
|
|
16
app/views/transactions/rules.html.erb
Normal file
16
app/views/transactions/rules.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<% content_for :sidebar do %>
|
||||
<%= render "settings/nav" %>
|
||||
<% end %>
|
||||
|
||||
<div class="space-y-4">
|
||||
<h1 class="text-gray-900 text-xl font-medium mb-4">Rules</h1>
|
||||
<div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4">
|
||||
<div class="flex justify-center items-center py-20">
|
||||
<p class="text-gray-500">Transaction rules coming soon...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between gap-4">
|
||||
<%= previous_setting("Merchants", merchants_path) %>
|
||||
<%= next_setting("Imports", imports_path) %>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,3 @@
|
|||
<%# locals: (transactions:) %>
|
||||
<%= form_with url: transactions_path,
|
||||
id: "transactions-search",
|
||||
scope: :q,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<%= render partial: "transactions/searches/form", locals: { transactions: transactions } %>
|
||||
<%= render "transactions/searches/form" %>
|
||||
|
||||
<ul id="transaction-search-filters" class="flex items-center flex-wrap gap-2">
|
||||
<% @q.each do |param_key, param_value| %>
|
||||
<% unless param_value.blank? %>
|
||||
<div class="pb-4">
|
||||
<% Array(param_value).each do |value| %>
|
||||
<%= render partial: "transactions/searches/filters/badge", locals: { param_key: param_key, param_value: value } %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pb-4">
|
||||
<% Array(param_value).each do |value| %>
|
||||
<%= render partial: "transactions/searches/filters/badge", locals: { param_key: param_key, param_value: value } %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue