mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 13:19:39 +02:00
Add apply button, improve transaction filters (#655)
* Add apply button, improve transaction filters * Remove temp log * Fix lint errors
This commit is contained in:
parent
0277bc94f3
commit
c46662c99f
8 changed files with 89 additions and 49 deletions
|
@ -24,7 +24,16 @@ class TransactionsController < ApplicationController
|
|||
session.delete(ransack_session_key)
|
||||
elsif params[:remove_param]
|
||||
current_params = session[ransack_session_key] || {}
|
||||
updated_params = delete_search_param(current_params, params[:remove_param], value: params[:remove_param_value])
|
||||
if params[:remove_param] == "date_range"
|
||||
updated_params = current_params.except("date_gteq", "date_lteq")
|
||||
elsif params[:remove_param_value]
|
||||
key_to_remove = params[:remove_param]
|
||||
value_to_remove = params[:remove_param_value]
|
||||
updated_params = current_params.deep_dup
|
||||
updated_params[key_to_remove] = updated_params[key_to_remove] - [ value_to_remove ]
|
||||
else
|
||||
updated_params = current_params.except(params[:remove_param])
|
||||
end
|
||||
session[ransack_session_key] = updated_params
|
||||
elsif params[:q]
|
||||
session[ransack_session_key] = params[:q]
|
||||
|
|
|
@ -1,2 +1,20 @@
|
|||
module TransactionsHelper
|
||||
def transaction_filters
|
||||
[
|
||||
{ name: "Account", partial: "account_filter", icon: "layers" },
|
||||
{ name: "Date", partial: "date_filter", icon: "calendar" },
|
||||
{ name: "Type", partial: "type_filter", icon: "shapes" },
|
||||
{ name: "Amount", partial: "amount_filter", icon: "hash" },
|
||||
{ name: "Category", partial: "category_filter", icon: "tag" },
|
||||
{ name: "Merchant", partial: "merchant_filter", icon: "store" }
|
||||
]
|
||||
end
|
||||
|
||||
def transaction_filter_id(filter)
|
||||
"txn-#{filter[:name].downcase}-filter"
|
||||
end
|
||||
|
||||
def transaction_filter_by_name(name)
|
||||
transaction_filters.find { |filter| filter[:name] == name }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,6 +23,8 @@ class Transaction < ApplicationRecord
|
|||
def self.build_filter_list(params, family)
|
||||
filters = []
|
||||
|
||||
date_filters = { gteq: nil, lteq: nil }
|
||||
|
||||
if params
|
||||
params.each do |key, value|
|
||||
next if value.blank?
|
||||
|
@ -38,8 +40,16 @@ class Transaction < ApplicationRecord
|
|||
end
|
||||
when "category_name_or_account_name_or_name_cont"
|
||||
filters << { type: "search", value: value, original: { key: key, value: nil } }
|
||||
when "date_gteq"
|
||||
date_filters[:gteq] = value
|
||||
when "date_lteq"
|
||||
date_filters[:lteq] = value
|
||||
end
|
||||
end
|
||||
|
||||
unless date_filters.values.compact.empty?
|
||||
filters << { type: "date_range", value: date_filters, original: { key: "date_range", value: nil } }
|
||||
end
|
||||
end
|
||||
|
||||
filters
|
||||
|
|
|
@ -16,11 +16,25 @@
|
|||
<%= lucide_icon "text", class: "w-5 h-5 text-gray-500" %>
|
||||
<p><%= "\"#{filter[:value]}\"".truncate(20) %></p>
|
||||
</div>
|
||||
<% when "date_range" %>
|
||||
<div class="flex items-center gap-2">
|
||||
<%= lucide_icon "calendar", class: "w-5 h-5 text-gray-500" %>
|
||||
<p>
|
||||
<% if filter[:value][:gteq] && filter[:value][:lteq] %>
|
||||
<%= filter[:value][:gteq] %> → <%= filter[:value][:lteq] %>
|
||||
<% elsif filter[:value][:gteq] %>
|
||||
on or after <%= filter[:value][:gteq] %>
|
||||
<% elsif filter[:value][:lteq] %>
|
||||
on or before <%= filter[:value][:lteq] %>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= form_with url: search_transactions_path, html: { class: "flex items-center" } do |form| %>
|
||||
<%= form.hidden_field :remove_param, value: filter[:original][:key] %>
|
||||
<% if filter[:original][:value] %>
|
||||
<%= form.hidden_field :remove_param_value, value: filter[:original][:value] %>
|
||||
<% else %>
|
||||
<% end %>
|
||||
<%= form.button type: "submit", class: "hover:text-gray-900" do %>
|
||||
<%= lucide_icon "x", class: "w-4 h-4 text-gray-500" %>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<%# locals: (filters:) %>
|
||||
<div>
|
||||
<%= turbo_frame_tag "transactions_filters" do %>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center flex-wrap gap-2">
|
||||
<% filters.each do |filter| %>
|
||||
<%= render partial: "transactions/filter", locals: { filter: filter } %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<%# locals: (q:) %>
|
||||
<div>
|
||||
<%= turbo_frame_tag "transactions_search_form" do %>
|
||||
<%= search_form_for @q, url: search_transactions_path, html: { method: :post, data: { turbo_frame: "transactions_list", "controller": "auto-submit-form" } } do |form| %>
|
||||
<%= search_form_for @q, url: search_transactions_path, html: { method: :post, data: { turbo_frame: "transactions_list" } } do |form| %>
|
||||
<div class="flex gap-2 mb-4">
|
||||
<div class="grow">
|
||||
<%= render partial: "transactions/search_form/search_filter", locals: { form: form } %>
|
||||
|
@ -11,52 +11,40 @@
|
|||
<%= lucide_icon("list-filter", class: "w-5 h-5 text-gray-500") %>
|
||||
<p class="text-sm font-medium text-gray-900">Filter</p>
|
||||
</button>
|
||||
<%# TODO: Refactor this for readability and maintainability %>
|
||||
<div data-menu-target="content" data-controller="tabs" data-tabs-active-class="bg-gray-25 text-gray-900" data-tabs-default-tab-value="txn-account-filter" class="hidden absolute flex z-10 h-80 w-[540px] top-12 right-0 border border-alpha-black-25 bg-white rounded-lg shadow-xs">
|
||||
<div
|
||||
data-menu-target="content"
|
||||
data-controller="tabs"
|
||||
data-tabs-active-class="bg-gray-25 text-gray-900"
|
||||
data-tabs-default-tab-value="<%= transaction_filter_id(transaction_filter_by_name("Account")) %>"
|
||||
class="hidden absolute flex z-10 h-80 w-[540px] top-12 right-0 border border-alpha-black-25 bg-white rounded-lg shadow-xs">
|
||||
<div class="flex w-44 flex-col items-start p-3 text-sm font-medium text-gray-500 border-r border-r-alpha-black-25">
|
||||
<button class="flex text-gray-500 hover:bg-gray-25 items-center gap-2 px-3 rounded-md py-2 w-full" type="button" data-id="txn-date-filter" data-tabs-target="btn" data-action="tabs#select">
|
||||
<%= lucide_icon("calendar", class: "w-5 h-5") %>
|
||||
<span class="text-sm font-medium">Date</span>
|
||||
</button>
|
||||
<button class="flex text-gray-500 hover:bg-gray-25 items-center gap-2 px-3 rounded-md py-2 w-full" type="button" data-id="txn-account-filter" data-tabs-target="btn" data-action="tabs#select">
|
||||
<%= lucide_icon("layers", class: "w-5 h-5") %>
|
||||
<span class="text-sm font-medium">Account</span>
|
||||
</button>
|
||||
<button class="flex text-gray-500 hover:bg-gray-25 items-center gap-2 px-3 rounded-md py-2 w-full" type="button" data-id="txn-type-filter" data-tabs-target="btn" data-action="tabs#select">
|
||||
<%= lucide_icon("shapes", class: "w-5 h-5") %>
|
||||
<span class="text-sm font-medium">Type</span>
|
||||
</button>
|
||||
<button class="flex text-gray-500 hover:bg-gray-25 items-center gap-2 px-3 rounded-md py-2 w-full" type="button" data-id="txn-amount-filter" data-tabs-target="btn" data-action="tabs#select">
|
||||
<%= lucide_icon("hash", class: "w-5 h-5") %>
|
||||
<span class="text-sm font-medium">Amount</span>
|
||||
</button>
|
||||
<button class="flex text-gray-500 hover:bg-gray-25 items-center gap-2 px-3 rounded-md py-2 w-full" type="button" data-id="txn-category-filter" data-tabs-target="btn" data-action="tabs#select">
|
||||
<%= lucide_icon("tag", class: "w-5 h-5") %>
|
||||
<span class="text-sm font-medium">Category</span>
|
||||
</button>
|
||||
<button class="flex text-gray-500 hover:bg-gray-25 items-center gap-2 px-3 rounded-md py-2 w-full" type="button" data-id="txn-merchant-filter" data-tabs-target="btn" data-action="tabs#select">
|
||||
<%= lucide_icon("store", class: "w-5 h-5") %>
|
||||
<span class="text-sm font-medium">Merchant</span>
|
||||
<% transaction_filters.each do |filter| %>
|
||||
<button
|
||||
class="flex text-gray-500 hover:bg-gray-25 items-center gap-2 px-3 rounded-md py-2 w-full"
|
||||
type="button"
|
||||
data-id="<%= transaction_filter_id(filter) %>"
|
||||
data-tabs-target="btn"
|
||||
data-action="tabs#select">
|
||||
<%= lucide_icon(filter[:icon], class: "w-5 h-5") %>
|
||||
<span class="text-sm font-medium"><%= filter[:name] %></span>
|
||||
</button>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="p-2 max-h-full overflow-y-auto grow">
|
||||
<div id="txn-date-filter" data-tabs-target="tab">
|
||||
<%= render partial: "transactions/search_form/date_filter", locals: { form: form } %>
|
||||
<div class="flex flex-col grow">
|
||||
<div class="grow p-2 border-b border-b-alpha-black-25 overflow-y-auto">
|
||||
<% transaction_filters.each do |filter| %>
|
||||
<div id="<%= transaction_filter_id(filter) %>" data-tabs-target="tab">
|
||||
<%= render partial: "transactions/search_form/#{filter[:partial]}", locals: { form: form } %>
|
||||
</div>
|
||||
<div id="txn-account-filter" data-tabs-target="tab">
|
||||
<%= render partial: "transactions/search_form/account_filter", locals: { form: form } %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div id="txn-type-filter" data-tabs-target="tab">
|
||||
<%= render partial: "transactions/search_form/type_filter", locals: { form: form } %>
|
||||
</div>
|
||||
<div id="txn-amount-filter" data-tabs-target="tab">
|
||||
<%= render partial: "transactions/search_form/amount_filter", locals: { form: form } %>
|
||||
</div>
|
||||
<div id="txn-category-filter" data-tabs-target="tab">
|
||||
<%= render partial: "transactions/search_form/category_filter", locals: { form: form } %>
|
||||
</div>
|
||||
<div id="txn-merchant-filter" data-tabs-target="tab">
|
||||
<%= render partial: "transactions/search_form/merchant_filter", locals: { form: form } %>
|
||||
<div class="flex justify-end items-center gap-2 bg-white p-3">
|
||||
<%= button_tag type: "reset", data: { action: "menu#close" }, class: "py-2 px-3 bg-gray-50 rounded-lg text-sm text-gray-900 font-medium" do %>
|
||||
Cancel
|
||||
<% end %>
|
||||
<%= button_tag type: "submit", class: "py-2 px-3 bg-gray-900 rounded-lg text-sm text-white font-medium" do %>
|
||||
Apply
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="my-2" id="list" data-list-filter-target="list">
|
||||
<% Current.family.accounts.each do |account| %>
|
||||
<div class="filterable-item flex items-center gap-2 p-2" data-filter-name="<%= account.name %>">
|
||||
<%= form.check_box :account_id_in, { "data-auto-submit-form-target": "auto", multiple: true, class: "rounded-sm border-gray-300 text-indigo-600 shadow-xs focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" }, account.id, nil %>
|
||||
<%= form.check_box :account_id_in, { multiple: true, class: "rounded-sm border-gray-300 text-indigo-600 shadow-xs focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" }, account.id, nil %>
|
||||
<%= form.label :account_id_in, account.name, value: account.id, class: "text-sm text-gray-900" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<%# locals: (form:) %>
|
||||
<div class="py-12 flex items-center justify-center">
|
||||
<p class="text-gray-500 text-sm">Filter by date coming soon...</p>
|
||||
<div class="p-3">
|
||||
<%= form.date_field :date_gteq, placeholder: "Start date", class: "block w-full border border-gray-200 rounded-md py-2 pl-3 pr-3 focus:border-gray-500 focus:ring-gray-500 sm:text-sm" %>
|
||||
<%= form.date_field :date_lteq, placeholder: "End date", class: "block w-full border border-gray-200 rounded-md py-2 pl-3 pr-3 focus:border-gray-500 focus:ring-gray-500 sm:text-sm mt-2" %>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue