Skip to content

Commit

Permalink
Fix budget allocation forms from resetting and clearing data on slow …
Browse files Browse the repository at this point in the history
…networks (#1804)

* First pass

* Fix null constraint bug for budget category assignment

* Fix autofocus reset when allocating budget

* Lint fix
  • Loading branch information
zachgoll authored Feb 5, 2025
1 parent f498212 commit 5b083c9
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 53 deletions.
24 changes: 18 additions & 6 deletions app/controllers/budget_categories_controller.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class BudgetCategoriesController < ApplicationController
before_action :set_budget

def index
@budget = Current.family.budgets.find(params[:budget_id])
@budget_categories = @budget.budget_categories.includes(:category)
render layout: "wizard"
end

def show
@budget = Current.family.budgets.find(params[:budget_id])

@recent_transactions = @budget.entries

if params[:id] == BudgetCategory.uncategorized.id
Expand All @@ -23,13 +23,25 @@ def show

def update
@budget_category = Current.family.budget_categories.find(params[:id])
@budget_category.update!(budget_category_params)

redirect_to budget_budget_categories_path(@budget_category.budget)
if @budget_category.update(budget_category_params)
respond_to do |format|
format.turbo_stream
format.html { redirect_to budget_budget_categories_path(@budget) }
end
else
render :index, status: :unprocessable_entity
end
end

private
def budget_category_params
params.require(:budget_category).permit(:budgeted_spending)
params.require(:budget_category).permit(:budgeted_spending).tap do |params|
params[:budgeted_spending] = params[:budgeted_spending].presence || 0
end
end

def set_budget
@budget = Current.family.budgets.find(params[:budget_id])
end
end
12 changes: 6 additions & 6 deletions app/javascript/controllers/auto_submit_form_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default class extends Controller {
}

handleInput = (event) => {
const target = event.target
const target = event.target;

clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
Expand All @@ -34,18 +34,18 @@ export default class extends Controller {
};

#debounceTimeout(element) {
if(element.dataset.autosubmitDebounceTimeout) {
if (element.dataset.autosubmitDebounceTimeout) {
return Number.parseInt(element.dataset.autosubmitDebounceTimeout);
}

const type = element.type || element.tagName;

switch (type.toLowerCase()) {
case 'input':
case 'textarea':
case "input":
case "textarea":
return 500;
case 'select-one':
case 'select-multiple':
case "select-one":
case "select-multiple":
return 0;
default:
return 500;
Expand Down
36 changes: 27 additions & 9 deletions app/views/budget_categories/_allocation_progress.erb
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
<%# locals: (budget:) %>

<div class="space-y-2 mb-6">
<div id="<%= dom_id(budget, :allocation_progress) %>" class="space-y-2 mb-6">
<div class="flex items-center gap-2">
<div class="rounded-full w-1.5 h-1.5 <%= budget.allocated_spending > 0 ? "bg-gray-900" : "bg-gray-100" %>"></div>
<% if budget.available_to_allocate.negative? %>
<div class="rounded-full w-1.5 h-1.5 bg-red-500"></div>
<% else %>
<div class="rounded-full w-1.5 h-1.5 <%= budget.allocated_spending > 0 ? "bg-gray-900" : "bg-gray-100" %>"></div>
<% end %>

<p class="text-gray-500 text-sm">
<%= number_to_percentage(budget.allocated_percent, precision: 0) %> set
</p>
<% if budget.available_to_allocate.negative? %>
<p class="text-gray-900 text-sm">&gt; 100% set</p>
<% else %>
<p class="text-gray-500 text-sm">
<%= number_to_percentage(budget.allocated_percent, precision: 0) %> set
</p>
<% end %>

<p class="ml-auto text-sm space-x-1">
<span class="text-gray-900"><%= format_money(budget.allocated_spending_money) %></span>
<span class="<%= budget.available_to_allocate.negative? ? "text-red-500" : "text-gray-900" %>"><%= format_money(budget.allocated_spending_money) %></span>
<span class="text-gray-500"> / </span>
<span class="text-gray-500"><%= format_money(budget.budgeted_spending_money) %></span>
</p>
</div>

<div class="relative h-1.5 rounded-2xl bg-gray-100">
<div class="absolute inset-0 bg-gray-900 rounded-2xl" style="width: <%= budget.allocated_percent %>%;"></div>
<% if budget.available_to_allocate.negative? %>
<div class="absolute inset-0 bg-red-500 rounded-2xl" style="width: 100%;"></div>
<% else %>
<div class="absolute inset-0 bg-gray-900 rounded-2xl" style="width: <%= budget.allocated_percent %>%;"></div>
<% end %>
</div>

<div class="text-sm">
<span class="text-gray-900"><%= format_money(budget.available_to_allocate_money) %></span>
<span class="text-gray-500">left to allocate</span>
<% if budget.available_to_allocate.negative? %>
<p class="text-gray-500">
Budget exceeded by <span class="text-red-500"><%= format_money(budget.available_to_allocate_money.abs) %></span>
</p>
<% else %>
<span class="text-gray-900"><%= format_money(budget.available_to_allocate_money) %></span>
<span class="text-gray-500">left to allocate</span>
<% end %>
</div>
</div>
25 changes: 0 additions & 25 deletions app/views/budget_categories/_allocation_progress_overage.html.erb

This file was deleted.

3 changes: 2 additions & 1 deletion app/views/budget_categories/_budget_category_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
</div>

<div class="ml-auto">
<%= form_with model: [budget_category.budget, budget_category], data: { controller: "auto-submit-form", auto_submit_form_trigger_event_value: "blur", turbo_frame: :_top } do |f| %>
<%= form_with model: [budget_category.budget, budget_category], data: { controller: "auto-submit-form preserve-focus" } do |f| %>
<div class="form-field w-[120px]">
<div class="flex items-center">
<span class="text-gray-500 text-sm mr-2"><%= currency.symbol %></span>
<%= f.number_field :budgeted_spending,
class: "form-field__input text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
placeholder: "0",
step: currency.step,
id: dom_id(budget_category, :budgeted_spending),
min: 0,
data: { auto_submit_form_target: "auto" } %>
</div>
Expand Down
8 changes: 2 additions & 6 deletions app/views/budget_categories/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,10 @@
</div>
<% else %>
<div class="max-w-md mx-auto">
<% if @budget.available_to_allocate.negative? %>
<%= render "budget_categories/allocation_progress_overage", budget: @budget %>
<% else %>
<%= render "budget_categories/allocation_progress", budget: @budget %>
<% end %>
<%= render "budget_categories/allocation_progress", budget: @budget %>

<div class="space-y-4 mb-4">
<% BudgetCategory::Group.for(@budget.budget_categories).sort_by(&:name).each do |group| %>
<% BudgetCategory::Group.for(@budget_categories).sort_by(&:name).each do |group| %>
<div class="space-y-4">
<%= render "budget_categories/budget_category_form", budget_category: group.budget_category %>

Expand Down
1 change: 1 addition & 0 deletions app/views/budget_categories/update.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= turbo_stream.replace dom_id(@budget, :allocation_progress), partial: "budget_categories/allocation_progress", locals: { budget: @budget } %>

0 comments on commit 5b083c9

Please sign in to comment.