1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-19 13:19:39 +02:00

Improve account internal linking and redirect behavior (#864)

* Fix transaction row link and overflow

* Allow user to access imports from account page

* Clean up accounts controller, add link to account page from settings

* Add link to accounts management from accounts summary page

* Cleanup styles
This commit is contained in:
Zach Gollwitzer 2024-06-11 18:47:38 -04:00 committed by GitHub
parent 8372e26864
commit c5704ffd45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 86 additions and 62 deletions

View file

@ -2,7 +2,7 @@ class AccountsController < ApplicationController
layout "with_sidebar" layout "with_sidebar"
include Filterable include Filterable
before_action :set_account, only: %i[ show update destroy sync ] before_action :set_account, only: %i[ show destroy sync update ]
def index def index
@accounts = Current.family.accounts @accounts = Current.family.accounts
@ -32,26 +32,9 @@ class AccountsController < ApplicationController
@valuation_series = @account.valuations.to_series @valuation_series = @account.valuations.to_series
end end
def edit
end
def update def update
if @account.update(account_params.except(:accountable_type)) @account.update! account_params.except(:accountable_type)
redirect_back_or_to account_path(@account), notice: t(".success")
@account.sync_later if account_params[:is_active] == "1" && @account.can_sync?
respond_to do |format|
format.html { redirect_to accounts_path, notice: t(".success") }
format.turbo_stream do
render turbo_stream: [
turbo_stream.append("notification-tray", partial: "shared/notification", locals: { type: "success", content: { body: t(".success") } }),
turbo_stream.replace("account_#{@account.id}", partial: "accounts/account", locals: { account: @account })
]
end
end
else
render "show", status: :unprocessable_entity
end
end end
def create def create
@ -62,7 +45,7 @@ class AccountsController < ApplicationController
@valuation = @account.valuations.new(date: account_params[:start_date] || Date.today, value: @account.balance, currency: @account.currency) @valuation = @account.valuations.new(date: account_params[:start_date] || Date.today, value: @account.balance, currency: @account.currency)
@valuation.save! @valuation.save!
redirect_to accounts_path, notice: t(".success") redirect_to account_path(@account), notice: t(".success")
else else
render "new", status: :unprocessable_entity render "new", status: :unprocessable_entity
end end

View file

@ -9,7 +9,8 @@ class ImportsController < ApplicationController
end end
def new def new
@import = Import.new account = Current.family.accounts.find_by(id: params[:account_id])
@import = Import.new account: account
end end
def edit def edit

View file

@ -4,18 +4,20 @@
<div class="w-8 h-8 flex items-center justify-center rounded-full text-xs font-medium <%= account.is_active ? "bg-blue-500/10 text-blue-500" : "bg-gray-500/10 text-gray-500" %>"> <div class="w-8 h-8 flex items-center justify-center rounded-full text-xs font-medium <%= account.is_active ? "bg-blue-500/10 text-blue-500" : "bg-gray-500/10 text-gray-500" %>">
<%= account.name[0].upcase %> <%= account.name[0].upcase %>
</div> </div>
<p class="text-sm font-medium <%= account.is_active ? "text-gray-900" : "text-gray-400" %>"> <%= link_to account.name, account, class: [(account.is_active ? "text-gray-900" : "text-gray-400"), "text-sm font-medium hover:underline"], data: { turbo_frame: "_top" } %>
<%= account.name %>
</p>
</div> </div>
<div class="flex items-center gap-8"> <div class="flex items-center gap-8">
<p class="text-sm font-medium <%= account.is_active ? "text-gray-900" : "text-gray-400" %>"> <p class="text-sm font-medium <%= account.is_active ? "text-gray-900" : "text-gray-400" %>">
<%= format_money account.balance_money %> <%= format_money account.balance_money %>
</p> </p>
<%= form_with model: account, method: :patch, html: { class: "flex items-center", data: { turbo_frame: "_top" } } do |form| %>
<%= form_with model: account,
namespace: account.id,
builder: ActionView::Helpers::FormBuilder,
data: { controller: "auto-submit-form", turbo_frame: "_top" } do |form| %>
<div class="relative inline-block select-none"> <div class="relative inline-block select-none">
<%= form.check_box :is_active, class: "sr-only peer", id: "is_active_#{account.id}", onchange: "this.form.requestSubmit();" %> <%= form.check_box :is_active, { class: "sr-only peer", data: { "auto-submit-form-target": "auto" } } %>
<label for="is_active_<%= account.id %>" class="block bg-gray-100 w-9 h-5 rounded-full cursor-pointer after:content-[''] after:block after:absolute after:top-0.5 after:left-0.5 after:bg-white after:w-4 after:h-4 after:rounded-full after:transition-transform after:duration-300 after:ease-in-out peer-checked:bg-green-600 peer-checked:after:translate-x-4"></label> <%= form.label :is_active, "&nbsp;".html_safe, class: "maybe-switch" %>
</div> </div>
<% end %> <% end %>
</div> </div>

View file

@ -0,0 +1,21 @@
<header class="flex justify-between items-center text-gray-900 font-medium">
<h1 class="text-xl"><%= t(".accounts") %></h1>
<div class="flex items-center gap-2">
<%= contextual_menu do %>
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<%= link_to accounts_path(return_to: summary_accounts_path),
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg font-normal" do %>
<%= lucide_icon "settings", class: "w-5 h-5 text-gray-500" %>
<span class="text-black"><%= t(".manage") %></span>
<% end %>
</div>
<% end %>
<%= link_to new_account_path, class: "rounded-lg bg-gray-900 text-white flex items-center gap-1 justify-center hover:bg-gray-700 px-3 py-2", data: { turbo_frame: :modal } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %>
<p class="text-sm font-medium"><%= t(".new") %></p>
<% end %>
</div>
</header>

View file

@ -15,27 +15,30 @@
<%= lucide_icon("chevron-down", class: "w-5 h-5 text-gray-500") %> <%= lucide_icon("chevron-down", class: "w-5 h-5 text-gray-500") %>
</div> </div>
</div> </div>
<div class="relative cursor-pointer" data-controller="menu">
<button data-menu-target="button" class="flex hover:bg-gray-100 p-2 rounded"> <%= contextual_menu do %>
<%= lucide_icon("more-horizontal", class: "w-5 h-5 text-gray-500") %> <div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
</button> <%= link_to new_import_path(account_id: @account.id),
<div data-menu-target="content" class="absolute z-10 top-10 right-0 border border-alpha-black-25 bg-white rounded-lg shadow-xs hidden"> class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg" do %>
<div class="w-48 px-3 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5"> <%= lucide_icon "download", class: "w-5 h-5 text-gray-500" %>
<%= button_to account_path(@account),
method: :delete, <span><%= t(".import") %></span>
class: "block w-full py-2 text-red-600 hover:text-red-800 flex items-center", <% end %>
data: {
turbo_confirm: { <%= button_to account_path(@account),
title: t(".confirm_title"), method: :delete,
body: t(".confirm_body_html"), class: "block w-full py-2 px-3 space-x-2 text-red-600 hover:bg-red-50 flex items-center rounded-lg",
accept: t(".confirm_accept", name: @account.name) data: {
} turbo_confirm: {
} do %> title: t(".confirm_title"),
<%= lucide_icon("trash-2", class: "w-5 h-5 mr-2") %> Delete account body: t(".confirm_body_html"),
<% end %> accept: t(".confirm_accept", name: @account.name)
</div> }
} do %>
<%= lucide_icon("trash-2", class: "w-5 h-5 mr-2") %> Delete account
<% end %>
</div> </div>
</div> <% end %>
</div> </div>
</div> </div>
<%= turbo_frame_tag "sync_message" do %> <%= turbo_frame_tag "sync_message" do %>

View file

@ -1,11 +1,6 @@
<div class="space-y-4"> <div class="space-y-4">
<div class="flex items-center justify-between">
<h1 class="text-xl font-medium text-gray-900">Accounts</h1> <%= render "header" %>
<%= link_to new_account_path, class: "flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2 pr-3", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %>
<span><%= t(".new") %></span>
<% end %>
</div>
<% if @accounts.empty? %> <% if @accounts.empty? %>
<%= render "shared/no_account_empty_state" %> <%= render "shared/no_account_empty_state" %>

View file

@ -1,5 +1,5 @@
<div class="text-gray-900 flex items-center py-4 text-sm font-medium px-4"> <div class="text-gray-900 flex items-center py-4 text-sm font-medium px-4">
<div class="grow"> <div class="grow max-w-72">
<%= render "transactions/name", transaction: transaction %> <%= render "transactions/name", transaction: transaction %>
</div> </div>

View file

@ -1,5 +1,5 @@
<div class="flex items-center gap-1 mb-6"> <div class="flex items-center gap-1 mb-6">
<%= link_to root_path, class: "flex items-center gap-1 text-gray-900 font-medium text-sm" do %> <%= link_to return_to_path(params), class: "flex items-center gap-1 text-gray-900 font-medium text-sm" do %>
<%= lucide_icon "chevron-left", class: "w-5 h-5 text-gray-500" %> <%= lucide_icon "chevron-left", class: "w-5 h-5 text-gray-500" %>
<span>Back</span> <span>Back</span>
<% end %> <% end %>

View file

@ -1,9 +1,9 @@
<%= content_tag :div, class: ["flex items-center gap-2"] do %> <%= content_tag :div, class: ["flex items-center gap-2"] do %>
<div class="w-8 h-8 flex items-center justify-center rounded-full bg-gray-600/5 text-gray-600"> <div class="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-gray-600/5 text-gray-600">
<%= transaction.name[0].upcase %> <%= transaction.name[0].upcase %>
</div> </div>
<div class="text-gray-900 truncate"> <div class="truncate text-gray-900">
<% if transaction.new_record? %> <% if transaction.new_record? %>
<%= content_tag :p, transaction.name %> <%= content_tag :p, transaction.name %>
<% else %> <% else %>

View file

@ -4,7 +4,9 @@
class: "maybe-checkbox maybe-checkbox--light", class: "maybe-checkbox maybe-checkbox--light",
data: { id: transaction.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %> data: { id: transaction.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %>
<%= render "transactions/name", transaction: transaction %> <div class="max-w-full pr-10">
<%= render "transactions/name", transaction: transaction %>
</div>
</div> </div>
<div class="col-span-3"> <div class="col-span-3">
@ -13,6 +15,7 @@
<%= link_to transaction.account.name, <%= link_to transaction.account.name,
account_path(transaction.account), account_path(transaction.account),
data: { turbo_frame: "_top" },
class: ["col-span-3 hover:underline"] %> class: ["col-span-3 hover:underline"] %>
<div class="col-span-2 ml-auto"> <div class="col-span-2 ml-auto">

View file

@ -12,6 +12,10 @@ en:
success: New account created successfully success: New account created successfully
destroy: destroy:
success: Account deleted successfully success: Account deleted successfully
header:
accounts: Accounts
manage: Manage accounts
new: New account
index: index:
new_account: New account new_account: New account
new: new:
@ -35,6 +39,7 @@ en:
/> <p>After deletion, there is no way you'll be able to restore the account /> <p>After deletion, there is no way you'll be able to restore the account
information because you'll need to add it as a new account.</p>" information because you'll need to add it as a new account.</p>"
confirm_title: Delete account? confirm_title: Delete account?
import: Import transactions
sync_message_missing_rates: Since exchange rates haven't been synced, balance sync_message_missing_rates: Since exchange rates haven't been synced, balance
graphs may not reflect accurate values. graphs may not reflect accurate values.
sync_message_unknown_error: An error has occurred during the sync. sync_message_unknown_error: An error has occurred during the sync.
@ -44,4 +49,4 @@ en:
cannot_sync: Account cannot be synced at the moment cannot_sync: Account cannot be synced at the moment
success: Account sync started success: Account sync started
update: update:
success: Account updated successfully success: Account updated

View file

@ -16,10 +16,21 @@ class AccountsControllerTest < ActionDispatch::IntegrationTest
assert_response :ok assert_response :ok
end end
test "should update account" do
patch account_url(@account), params: {
account: {
is_active: "0"
}
}
assert_redirected_to account_url(@account)
assert_equal "Account updated", flash[:notice]
end
test "should create account" do test "should create account" do
assert_difference -> { Account.count }, +1 do assert_difference -> { Account.count }, +1 do
post accounts_path, params: { account: { accountable_type: "Account::Credit" } } post accounts_path, params: { account: { accountable_type: "Account::Credit" } }
assert_redirected_to accounts_url assert_redirected_to account_url(Account.order(:created_at).last)
end end
end end