<%= link_to entry.name,
diff --git a/app/views/valuations/confirm_create.html.erb b/app/views/valuations/confirm_create.html.erb
index 3e3a4a90..906c957d 100644
--- a/app/views/valuations/confirm_create.html.erb
+++ b/app/views/valuations/confirm_create.html.erb
@@ -1,4 +1,4 @@
-<%= render DialogComponent.new do |dialog| %>
+<%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: "Confirm new balance") %>
<% dialog.with_body do %>
<%= styled_form_with model: @entry, url: valuations_path, class: "space-y-4" do |form| %>
diff --git a/app/views/valuations/confirm_update.html.erb b/app/views/valuations/confirm_update.html.erb
index c24e27cf..720f7bd5 100644
--- a/app/views/valuations/confirm_update.html.erb
+++ b/app/views/valuations/confirm_update.html.erb
@@ -1,4 +1,4 @@
-<%= render DialogComponent.new do |dialog| %>
+<%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: "Update balance") %>
<% dialog.with_body do %>
<%= styled_form_with model: @entry, url: valuation_path(@entry), method: :patch, class: "space-y-4", data: { turbo_frame: :_top } do |form| %>
diff --git a/app/views/valuations/new.html.erb b/app/views/valuations/new.html.erb
index bfa8d5e2..cf805d67 100644
--- a/app/views/valuations/new.html.erb
+++ b/app/views/valuations/new.html.erb
@@ -1,11 +1,11 @@
-<%= render DialogComponent.new do |dialog| %>
+<%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %>
<%= styled_form_with model: @entry, url: confirm_create_valuations_path, class: "space-y-4" do |form| %>
<%= form.hidden_field :account_id %>
<% if @error_message.present? %>
- <%= render AlertComponent.new(message: @error_message, variant: :error) %>
+ <%= render DS::Alert.new(message: @error_message, variant: :error) %>
<% end %>
diff --git a/app/views/valuations/show.html.erb b/app/views/valuations/show.html.erb
index 3cd44f9f..f58be03e 100644
--- a/app/views/valuations/show.html.erb
+++ b/app/views/valuations/show.html.erb
@@ -1,6 +1,6 @@
<% entry, account = @entry, @entry.account %>
-<%= render DialogComponent.new(variant: "drawer") do |dialog| %>
+<%= render DS::Dialog.new(variant: "drawer") do |dialog| %>
<% dialog.with_header do %>
<%= render "valuations/header", entry: @entry %>
<% end %>
@@ -8,7 +8,7 @@
<% dialog.with_body do %>
<% if @error_message.present? %>
- <%= render AlertComponent.new(message: @error_message, variant: :error) %>
+ <%= render DS::Alert.new(message: @error_message, variant: :error) %>
<% end %>
@@ -28,7 +28,7 @@
disable_currency: true %>
- <%= render ButtonComponent.new(
+ <%= render DS::Button.new(
text: "Update value",
variant: :primary,
type: "submit"
diff --git a/app/views/vehicles/edit.html.erb b/app/views/vehicles/edit.html.erb
index 00424799..87308377 100644
--- a/app/views/vehicles/edit.html.erb
+++ b/app/views/vehicles/edit.html.erb
@@ -1,4 +1,4 @@
-<%= render DialogComponent.new do |dialog| %>
+<%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".edit", account: @account.name)) %>
<% dialog.with_body do %>
<%= render "form", account: @account, url: vehicle_path(@account) %>
diff --git a/app/views/vehicles/new.html.erb b/app/views/vehicles/new.html.erb
index 56422ce8..2f09bcf4 100644
--- a/app/views/vehicles/new.html.erb
+++ b/app/views/vehicles/new.html.erb
@@ -1,4 +1,4 @@
-<%= render DialogComponent.new do |dialog| %>
+<%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %>
<%= render "vehicles/form", account: @account, url: vehicles_path(return_to: params[:return_to]) %>
diff --git a/app/views/vehicles/tabs/_overview.html.erb b/app/views/vehicles/tabs/_overview.html.erb
index e8592533..b71793bb 100644
--- a/app/views/vehicles/tabs/_overview.html.erb
+++ b/app/views/vehicles/tabs/_overview.html.erb
@@ -33,7 +33,7 @@
- <%= render LinkComponent.new(
+ <%= render DS::Link.new(
text: "Edit account details",
variant: "ghost",
href: edit_vehicle_path(account),
diff --git a/db/migrate/20250718120146_add_indexes_to_core_models.rb b/db/migrate/20250718120146_add_indexes_to_core_models.rb
new file mode 100644
index 00000000..bac38c8c
--- /dev/null
+++ b/db/migrate/20250718120146_add_indexes_to_core_models.rb
@@ -0,0 +1,20 @@
+class AddIndexesToCoreModels < ActiveRecord::Migration[7.2]
+ def change
+ # Accounts table indexes
+ add_index :accounts, [ :family_id, :status ]
+ add_index :accounts, :status
+ add_index :accounts, :currency
+
+ # Balances table indexes
+ add_index :balances, [ :account_id, :date ], order: { date: :desc }
+
+ # Entries table indexes
+ add_index :entries, [ :account_id, :date ]
+ add_index :entries, :date
+ add_index :entries, :entryable_type
+ add_index :entries, "lower(name)", name: "index_entries_on_lower_name"
+
+ # Transfers table indexes
+ add_index :transfers, :status
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 56d7ba09..3b839c95 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.2].define(version: 2025_07_10_225721) do
+ActiveRecord::Schema[7.2].define(version: 2025_07_18_120146) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@@ -37,11 +37,14 @@ ActiveRecord::Schema[7.2].define(version: 2025_07_10_225721) do
t.string "status", default: "active"
t.index ["accountable_id", "accountable_type"], name: "index_accounts_on_accountable_id_and_accountable_type"
t.index ["accountable_type"], name: "index_accounts_on_accountable_type"
+ t.index ["currency"], name: "index_accounts_on_currency"
t.index ["family_id", "accountable_type"], name: "index_accounts_on_family_id_and_accountable_type"
t.index ["family_id", "id"], name: "index_accounts_on_family_id_and_id"
+ t.index ["family_id", "status"], name: "index_accounts_on_family_id_and_status"
t.index ["family_id"], name: "index_accounts_on_family_id"
t.index ["import_id"], name: "index_accounts_on_import_id"
t.index ["plaid_account_id"], name: "index_accounts_on_plaid_account_id"
+ t.index ["status"], name: "index_accounts_on_status"
end
create_table "active_storage_attachments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
@@ -113,6 +116,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_07_10_225721) do
t.datetime "updated_at", null: false
t.decimal "cash_balance", precision: 19, scale: 4, default: "0.0"
t.index ["account_id", "date", "currency"], name: "index_account_balances_on_account_id_date_currency_unique", unique: true
+ t.index ["account_id", "date"], name: "index_balances_on_account_id_and_date", order: { date: :desc }
t.index ["account_id"], name: "index_balances_on_account_id"
end
@@ -215,7 +219,11 @@ ActiveRecord::Schema[7.2].define(version: 2025_07_10_225721) do
t.boolean "excluded", default: false
t.string "plaid_id"
t.jsonb "locked_attributes", default: {}
+ t.index "lower((name)::text)", name: "index_entries_on_lower_name"
+ t.index ["account_id", "date"], name: "index_entries_on_account_id_and_date"
t.index ["account_id"], name: "index_entries_on_account_id"
+ t.index ["date"], name: "index_entries_on_date"
+ t.index ["entryable_type"], name: "index_entries_on_entryable_type"
t.index ["import_id"], name: "index_entries_on_import_id"
end
@@ -741,6 +749,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_07_10_225721) do
t.index ["inflow_transaction_id", "outflow_transaction_id"], name: "idx_on_inflow_transaction_id_outflow_transaction_id_8cd07a28bd", unique: true
t.index ["inflow_transaction_id"], name: "index_transfers_on_inflow_transaction_id"
t.index ["outflow_transaction_id"], name: "index_transfers_on_outflow_transaction_id"
+ t.index ["status"], name: "index_transfers_on_status"
end
create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
diff --git a/test/components/previews/alert_component_preview.rb b/test/components/previews/alert_component_preview.rb
index 34abcb37..ddd91183 100644
--- a/test/components/previews/alert_component_preview.rb
+++ b/test/components/previews/alert_component_preview.rb
@@ -2,6 +2,6 @@ class AlertComponentPreview < Lookbook::Preview
# @param message text
# @param variant select [info, success, warning, error]
def default(message: "This is an alert message.", variant: :info)
- render AlertComponent.new(message: message, variant: variant.to_sym)
+ render DS::Alert.new(message: message, variant: variant.to_sym)
end
end
diff --git a/test/components/previews/button_component_preview.rb b/test/components/previews/button_component_preview.rb
index 499d36b3..e6045ab2 100644
--- a/test/components/previews/button_component_preview.rb
+++ b/test/components/previews/button_component_preview.rb
@@ -1,10 +1,10 @@
class ButtonComponentPreview < ViewComponent::Preview
- # @param variant select {{ ButtonComponent::VARIANTS.keys }}
- # @param size select {{ ButtonComponent::SIZES.keys }}
+ # @param variant select {{ DS::Button::VARIANTS.keys }}
+ # @param size select {{ DS::Button::SIZES.keys }}
# @param disabled toggle
# @param icon select ["plus", "circle"]
def default(variant: "primary", size: "md", disabled: false, icon: "plus")
- render ButtonComponent.new(
+ render DS::Button.new(
text: "Sample button",
variant: variant,
size: size,
diff --git a/test/components/previews/dialog_component_preview.rb b/test/components/previews/dialog_component_preview.rb
index a1b81340..5f5c78d9 100644
--- a/test/components/previews/dialog_component_preview.rb
+++ b/test/components/previews/dialog_component_preview.rb
@@ -1,7 +1,7 @@
class DialogComponentPreview < ViewComponent::Preview
# @param show_overflow toggle
def modal(show_overflow: false)
- render DialogComponent.new(variant: "modal") do |dialog|
+ render DS::Dialog.new(variant: "modal") do |dialog|
dialog.with_header(title: "Sample modal title")
dialog.with_body do
@@ -21,7 +21,7 @@ class DialogComponentPreview < ViewComponent::Preview
# @param show_overflow toggle
def drawer(show_overflow: false)
- render DialogComponent.new(variant: "drawer") do |dialog|
+ render DS::Dialog.new(variant: "drawer") do |dialog|
dialog.with_header(title: "Drawer title")
dialog.with_body do
diff --git a/test/components/previews/disclosure_component_preview.rb b/test/components/previews/disclosure_component_preview.rb
index ec6e6d1d..51b9a8a0 100644
--- a/test/components/previews/disclosure_component_preview.rb
+++ b/test/components/previews/disclosure_component_preview.rb
@@ -2,7 +2,7 @@ class DisclosureComponentPreview < ViewComponent::Preview
# @display container_classes max-w-[400px]
# @param align select ["left", "right"]
def default(align: "right")
- render DisclosureComponent.new(title: "Title", align: align, open: true) do |disclosure|
+ render DS::Disclosure.new(title: "Title", align: align, open: true) do |disclosure|
disclosure.with_summary_content do
content_tag(:p, "$200.25", class: "text-xs font-mono font-medium")
end
diff --git a/test/components/previews/filled_icon_component_preview.rb b/test/components/previews/filled_icon_component_preview.rb
index c2670308..3b0ee022 100644
--- a/test/components/previews/filled_icon_component_preview.rb
+++ b/test/components/previews/filled_icon_component_preview.rb
@@ -1,11 +1,11 @@
class FilledIconComponentPreview < ViewComponent::Preview
# @param size select ["sm", "md", "lg"]
def default(size: "md")
- render FilledIconComponent.new(icon: "home", variant: :default, size: size)
+ render DS::FilledIcon.new(icon: "home", variant: :default, size: size)
end
# @param size select ["sm", "md", "lg"]
def text(size: "md")
- render FilledIconComponent.new(variant: :text, text: "Test", size: size, rounded: true)
+ render DS::FilledIcon.new(variant: :text, text: "Test", size: size, rounded: true)
end
end
diff --git a/test/components/previews/link_component_preview.rb b/test/components/previews/link_component_preview.rb
index 17150204..d3600bf3 100644
--- a/test/components/previews/link_component_preview.rb
+++ b/test/components/previews/link_component_preview.rb
@@ -2,17 +2,17 @@ class LinkComponentPreview < ViewComponent::Preview
# Usage
# -------------
#
- # LinkComponent is a small abstraction on top of the `link_to` helper.
+ # DS::Link is a small abstraction on top of the `link_to` helper.
#
- # It can be used as a regular link or styled as a "Link button" using any of the available ButtonComponent variants.
+ # It can be used as a regular link or styled as a "Link button" using any of the available DS::Button variants.
#
- # @param variant select {{ LinkComponent::VARIANTS.keys }}
- # @param size select {{ LinkComponent::SIZES.keys }}
+ # @param variant select {{ DS::Link::VARIANTS.keys }}
+ # @param size select {{ DS::Link::SIZES.keys }}
# @param icon select ["", "plus", "arrow-right"]
# @param icon_position select ["left", "right"]
# @param full_width toggle
def default(variant: "default", size: "md", icon: "plus", icon_position: "left", full_width: false)
- render LinkComponent.new(
+ render DS::Link.new(
href: "#",
text: "Preview link",
variant: variant,
diff --git a/test/components/previews/menu_component_preview.rb b/test/components/previews/menu_component_preview.rb
index 6c210437..592b276c 100644
--- a/test/components/previews/menu_component_preview.rb
+++ b/test/components/previews/menu_component_preview.rb
@@ -1,19 +1,19 @@
class MenuComponentPreview < ViewComponent::Preview
def icon
- render MenuComponent.new(variant: "icon") do |menu|
+ render DS::Menu.new(variant: "icon") do |menu|
menu_contents(menu)
end
end
def button
- render MenuComponent.new(variant: "button") do |menu|
+ render DS::Menu.new(variant: "button") do |menu|
menu.with_button(text: "Open menu", variant: "secondary")
menu_contents(menu)
end
end
def avatar
- render MenuComponent.new(variant: "avatar") do |menu|
+ render DS::Menu.new(variant: "avatar") do |menu|
menu_contents(menu)
end
end
diff --git a/test/components/previews/toggle_component_preview.rb b/test/components/previews/toggle_component_preview.rb
index 9ab3d014..27eeff52 100644
--- a/test/components/previews/toggle_component_preview.rb
+++ b/test/components/previews/toggle_component_preview.rb
@@ -2,7 +2,7 @@ class ToggleComponentPreview < ViewComponent::Preview
# @param disabled toggle
def default(disabled: false)
render(
- ToggleComponent.new(
+ DS::Toggle.new(
id: "toggle-component-id",
name: "toggle-component-name",
checked: false,
diff --git a/test/system/accounts_test.rb b/test/system/accounts_test.rb
index e910a3ac..da1b5938 100644
--- a/test/system/accounts_test.rb
+++ b/test/system/accounts_test.rb
@@ -98,7 +98,7 @@ class AccountsTest < ApplicationSystemTestCase
private
def open_new_account_modal
- within "[data-controller='tabs']" do
+ within "[data-controller='DS--tabs']" do
click_button "All"
click_link "New account"
end