mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-09 15:35:22 +02:00
Checkpoint: fix tests, all buttons and menus converted
This commit is contained in:
parent
2bfd00f611
commit
cbd05ae3da
21 changed files with 111 additions and 92 deletions
|
@ -1,4 +1,4 @@
|
|||
<div data-controller="menu" data-menu-placement-value="<%= @placement %>" data-menu-offset-value="<%= @offset %>">
|
||||
<%= tag.div data: merged_data do %>
|
||||
<% if @variant == :icon %>
|
||||
<%= render ButtonComponent.new(variant: "icon", icon: @icon_vertical ? "more-vertical" : "more-horizontal", data: { menu_target: "button" }) %>
|
||||
<% elsif @variant == :button %>
|
||||
|
@ -22,4 +22,4 @@
|
|||
<%= custom_content %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -25,11 +25,20 @@ class MenuComponent < ViewComponent::Base
|
|||
avatar: {}
|
||||
}
|
||||
|
||||
def initialize(variant: "icon", avatar_url: nil, placement: "bottom-end", offset: 12, icon_vertical: false)
|
||||
def initialize(variant: "icon", avatar_url: nil, placement: "bottom-end", offset: 12, icon_vertical: false, data: {})
|
||||
@variant = variant.to_sym
|
||||
@avatar_url = avatar_url
|
||||
@placement = placement
|
||||
@offset = offset
|
||||
@icon_vertical = icon_vertical
|
||||
@data = data
|
||||
end
|
||||
|
||||
def merged_data
|
||||
{
|
||||
controller: "menu",
|
||||
menu_placement_value: @placement,
|
||||
menu_offset_value: @offset
|
||||
}.merge(@data)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
<div class="flex items-center gap-5">
|
||||
<div class="flex items-center gap-2">
|
||||
<%= render ButtonComponent.new(
|
||||
text: "Sync all",
|
||||
href: sync_all_accounts_path,
|
||||
text: "Sync all",
|
||||
href: sync_all_accounts_path,
|
||||
method: :post,
|
||||
variant: "outline",
|
||||
variant: "outline",
|
||||
disabled: Current.family.syncing?,
|
||||
leading_icon: "refresh-cw"
|
||||
) %>
|
||||
|
||||
<%= render ButtonComponent.new(
|
||||
text: "New account",
|
||||
href: new_account_path(return_to: accounts_path),
|
||||
variant: "primary",
|
||||
text: "New account",
|
||||
href: new_account_path(return_to: accounts_path),
|
||||
variant: "primary",
|
||||
leading_icon: "plus",
|
||||
data: { turbo_frame: "modal" }
|
||||
) %>
|
||||
|
|
|
@ -5,20 +5,20 @@
|
|||
<div class="flex items-center justify-between mb-4">
|
||||
<%= tag.h2 t(".title"), class: "font-medium text-lg" %>
|
||||
<% unless @account.plaid_account_id.present? %>
|
||||
<%= render MenuComponent.new(variant: "button") do |menu| %>
|
||||
<%= render MenuComponent.new(variant: "button", data: { testid: "activity-menu" }) do |menu| %>
|
||||
<% menu.with_button(text: "New", variant: "secondary", leading_icon: "plus") %>
|
||||
|
||||
<% menu.with_item(
|
||||
text: "New balance",
|
||||
icon: "circle-dollar-sign",
|
||||
text: "New balance",
|
||||
icon: "circle-dollar-sign",
|
||||
href: new_valuation_path(account_id: @account.id), data: { turbo_frame: :modal }) %>
|
||||
|
||||
<% unless @account.crypto? %>
|
||||
<% href = @account.investment? ? new_trade_path(account_id: @account.id) : new_transaction_path(account_id: @account.id) %>
|
||||
<% menu.with_item(
|
||||
text: "New transaction",
|
||||
icon: "credit-card",
|
||||
href: href,
|
||||
text: "New transaction",
|
||||
icon: "credit-card",
|
||||
href: href,
|
||||
data: { turbo_frame: :modal }) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
<%# locals: (account:) %>
|
||||
|
||||
<%= render MenuComponent.new do |menu| %>
|
||||
<% menu.with_item(text: "Edit", href: edit_account_path(account), icon: "pencil-line", data: { turbo_frame: :modal })%>
|
||||
<% menu.with_item(text: "Edit", href: edit_account_path(account), icon: "pencil-line", data: { turbo_frame: :modal }) %>
|
||||
|
||||
<% unless account.crypto? %>
|
||||
<% menu.with_item(
|
||||
text: "Import transactions",
|
||||
href: imports_path({ import: { type: account.investment? ? "TradeImport" : "TransactionImport", account_id: account.id } }),
|
||||
text: "Import transactions",
|
||||
href: imports_path({ import: { type: account.investment? ? "TradeImport" : "TransactionImport", account_id: account.id } }),
|
||||
icon: "download",
|
||||
data: { turbo_frame: :_top }
|
||||
) %>
|
||||
<% end %>
|
||||
|
||||
<% menu.with_item(
|
||||
text: "Delete account",
|
||||
href: account_path(account),
|
||||
method: :delete,
|
||||
icon: "trash-2",
|
||||
text: "Delete account",
|
||||
href: account_path(account),
|
||||
method: :delete,
|
||||
icon: "trash-2",
|
||||
data: { turbo_frame: :_top, turbo_confirm: {
|
||||
title: t(".confirm_title"),
|
||||
body: t(".confirm_body_html"),
|
||||
accept: t(".confirm_accept", name: account.name)
|
||||
}}
|
||||
)%>
|
||||
) %>
|
||||
<% end %>
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
<p class="text-sm text-secondary font-normal mb-4"><%= t(".empty") %></p>
|
||||
|
||||
<%= render ButtonComponent.new(
|
||||
text: t(".bootstrap"),
|
||||
variant: "outline",
|
||||
href: bootstrap_categories_path,
|
||||
text: t(".bootstrap"),
|
||||
variant: "outline",
|
||||
href: bootstrap_categories_path,
|
||||
method: :post,
|
||||
data: { turbo_frame: :_top }) %>
|
||||
</div>
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
<%= render MenuComponent.new(icon_vertical: true) do |menu| %>
|
||||
<% menu.with_item(text: "Edit chat", href: edit_chat_path(chat), icon: "pencil", data: { turbo_frame: dom_id(chat, "title") }) %>
|
||||
<% menu.with_item(
|
||||
text: "Delete chat",
|
||||
href: chat_path(chat),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Are you sure you want to delete this chat?",
|
||||
variant: "outline-destructive"
|
||||
text: "Delete chat",
|
||||
href: chat_path(chat),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Are you sure you want to delete this chat?",
|
||||
variant: "outline-destructive"
|
||||
}
|
||||
}) %>
|
||||
<% end %>
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
<% unless chat.new_record? %>
|
||||
<% menu.with_item(text: "Edit chat title", href: edit_chat_path(chat, ctx: "chat"), icon: "pencil", data: { turbo_frame: dom_id(chat, "title") }) %>
|
||||
<% menu.with_item(
|
||||
text: "Delete chat",
|
||||
href: chat_path(chat),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Are you sure you want to delete this chat?",
|
||||
variant: "outline-destructive"
|
||||
text: "Delete chat",
|
||||
href: chat_path(chat),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Are you sure you want to delete this chat?",
|
||||
variant: "outline-destructive"
|
||||
}
|
||||
}) %>
|
||||
<% end %>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
<div class="justify-self-end">
|
||||
<%= render MenuComponent.new do |menu| %>
|
||||
<% menu.with_item(text: "Edit", href: edit_family_merchant_path(family_merchant), icon: "pencil", data: { turbo_frame: "modal" }) %>
|
||||
<% menu.with_item(text: "Delete", href: family_merchant_path(family_merchant), icon: "trash-2", method: :delete, data: { turbo_confirm: {
|
||||
title: "Delete #{family_merchant.name}?",
|
||||
<% menu.with_item(text: "Delete", href: family_merchant_path(family_merchant), icon: "trash-2", method: :delete, data: { turbo_confirm: {
|
||||
title: "Delete #{family_merchant.name}?",
|
||||
body: "This will remove this merchant from all transactions it has been assigned to.",
|
||||
variant: "outline-destructive"
|
||||
variant: "outline-destructive"
|
||||
} }) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
<p class="text-sm text-secondary">We found a configuration from a previous import for this account. Would you like to apply it to this import?</p>
|
||||
|
||||
<div class="mt-4 flex gap-2 items-center">
|
||||
<%= ButtonComponent.new(text: "Manually configure", href: import_configuration_path(@import), variant: "outline") %>
|
||||
<%= ButtonComponent.new(text: "Apply template", href: apply_template_import_path(@import), method: :put, data: { turbo_frame: :_top }) %>
|
||||
<%= render ButtonComponent.new(text: "Manually configure", href: import_configuration_path(@import), variant: "outline") %>
|
||||
<%= render ButtonComponent.new(text: "Apply template", href: apply_template_import_path(@import), method: :put, data: { turbo_frame: :_top }) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -41,11 +41,11 @@
|
|||
|
||||
<% if import.complete? || import.revert_failed? %>
|
||||
<% menu.with_item(
|
||||
text: t(".revert"),
|
||||
href: revert_import_path(import),
|
||||
icon: "rotate-ccw",
|
||||
method: :put,
|
||||
data: {
|
||||
text: t(".revert"),
|
||||
href: revert_import_path(import),
|
||||
icon: "rotate-ccw",
|
||||
method: :put,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Revert import?",
|
||||
body: "This will delete transactions that were imported, but you will still be able to review and re-import your data at any time.",
|
||||
|
@ -55,16 +55,16 @@
|
|||
|
||||
<% else %>
|
||||
<% menu.with_item(
|
||||
text: t(".delete"),
|
||||
href: import_path(import),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Delete import?",
|
||||
body: "This will delete the import and is not reversible.",
|
||||
variant: "outline-destructive"
|
||||
}
|
||||
text: t(".delete"),
|
||||
href: import_path(import),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Delete import?",
|
||||
body: "This will delete the import and is not reversible.",
|
||||
variant: "outline-destructive"
|
||||
}
|
||||
}) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -35,5 +35,5 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<%= ButtonComponent.new(text: "Publish import", href: publish_import_path(import), method: :post) %>
|
||||
<%= render ButtonComponent.new(text: "Publish import", href: publish_import_path(import), method: :post) %>
|
||||
</div>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<h3 class="font-medium text-primary" data-confirm-dialog-target="title">Are you sure?</h3>
|
||||
|
||||
<%= render ButtonComponent.new(
|
||||
variant: "icon",
|
||||
icon: "x",
|
||||
variant: "icon",
|
||||
icon: "x",
|
||||
value: "cancel",
|
||||
type: "submit"
|
||||
) %>
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
<%= render MenuComponent.new do |menu| %>
|
||||
<% menu.with_item(text: t(".edit"), href: edit_merchant_path(merchant), icon: "pencil", data: { turbo_frame: "modal" }) %>
|
||||
<% menu.with_item(
|
||||
text: t(".delete"),
|
||||
href: merchant_path(merchant),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
text: t(".delete"),
|
||||
href: merchant_path(merchant),
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: { turbo_confirm: {
|
||||
title: t(".confirm_title"),
|
||||
body: t(".confirm_body"),
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
</div>
|
||||
|
||||
<%= render ButtonComponent.new(
|
||||
text: "Confirm changes",
|
||||
href: apply_rule_path(@rule),
|
||||
method: :post,
|
||||
text: "Confirm changes",
|
||||
href: apply_rule_path(@rule),
|
||||
method: :post,
|
||||
full_width: true,
|
||||
data: { turbo_frame: "_top" }) %>
|
||||
</div>
|
||||
|
|
|
@ -5,17 +5,17 @@
|
|||
<% if @rules.any? %>
|
||||
<%= render MenuComponent.new do |menu| %>
|
||||
<% menu.with_item(
|
||||
text: "Delete all rules",
|
||||
href: destroy_all_rules_path,
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
text: "Delete all rules",
|
||||
href: destroy_all_rules_path,
|
||||
icon: "trash-2",
|
||||
method: :delete,
|
||||
data: {
|
||||
turbo_confirm: {
|
||||
title: "Delete all rules",
|
||||
body: "Are you sure you want to delete all rules? This action cannot be undone.",
|
||||
confirmText: "Delete all rules",
|
||||
variant: "destructive"
|
||||
}
|
||||
}
|
||||
}) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -46,9 +46,9 @@
|
|||
<%= form_with model: @user, class: "flex flex-col md:flex-row justify-between items-center gap-4", id: "theme_form",
|
||||
data: { controller: "auto-submit-form", auto_submit_form_trigger_event_value: "change" } do |form| %>
|
||||
<%= form.hidden_field :redirect_to, value: "preferences" %>
|
||||
|
||||
|
||||
<% theme_option_class = "text-center transition-all duration-200 p-3 rounded-lg hover:bg-surface-hover cursor-pointer [&:has(input:checked)]:bg-surface-hover [&:has(input:checked)]:border [&:has(input:checked)]:border-primary [&:has(input:checked)]:shadow-xs" %>
|
||||
|
||||
|
||||
<% [
|
||||
{ value: "light", image: "light-mode-preview.png" },
|
||||
{ value: "dark", image: "dark-mode-preview.png" },
|
||||
|
@ -57,8 +57,8 @@
|
|||
<%= form.label :"theme_#{theme[:value]}", class: "group" do %>
|
||||
<div class="<%= theme_option_class %>">
|
||||
<%= image_tag(theme[:image], alt: "#{theme[:value].titleize} Theme Preview", class: "h-44 mb-2") %>
|
||||
<div class="<%= theme[:value] == 'system' ? 'flex items-center gap-2 justify-center' : 'text-sm font-medium text-primary' %>">
|
||||
<%= form.radio_button :theme, theme[:value], checked: @user.theme == theme[:value], class: "sr-only",
|
||||
<div class="<%= theme[:value] == "system" ? "flex items-center gap-2 justify-center" : "text-sm font-medium text-primary" %>">
|
||||
<%= form.radio_button :theme, theme[:value], checked: @user.theme == theme[:value], class: "sr-only",
|
||||
data: { auto_submit_form_target: "auto", autosubmit_trigger_event: "change", action: "theme#updateTheme" } %>
|
||||
<%= t(".theme_#{theme[:value]}") %>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
|
||||
<% active_tab = local_assigns[:active_tab] || 'expense' %>
|
||||
<% active_tab = local_assigns[:active_tab] || "expense" %>
|
||||
|
||||
<%= link_to new_transaction_path(nature: 'outflow'),
|
||||
<%= link_to new_transaction_path(nature: "outflow"),
|
||||
data: { turbo_frame: :modal },
|
||||
class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-sm md:text-normal text-subdued #{active_tab == 'expense' ? 'bg-container text-gray-800 shadow-sm' : 'hover:bg-container hover:text-gray-800 hover:shadow-sm'}" do %>
|
||||
<%= lucide_icon "minus-circle", class: "w-4 h-4 md:w-5 md:h-5" %>
|
||||
<%= tag.span t("shared.transaction_tabs.expense") %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to new_transaction_path(nature: 'inflow'),
|
||||
<%= link_to new_transaction_path(nature: "inflow"),
|
||||
data: { turbo_frame: :modal },
|
||||
class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-sm md:text-normal text-subdued #{active_tab == 'income' ? 'bg-container text-gray-800 shadow-sm' : 'hover:bg-container hover:text-gray-800 hover:shadow-sm'}" do %>
|
||||
<%= lucide_icon "plus-circle", class: "w-4 h-4 md:w-5 md:h-5" %>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<%# locals: (user:, placement: "right-start", offset: 16) %>
|
||||
|
||||
<%= render MenuComponent.new(variant: "avatar", avatar_url: user.profile_image&.variant(:small)&.url, placement: placement, offset: offset) do |menu| %>
|
||||
<%= render MenuComponent.new(variant: "avatar", avatar_url: user.profile_image&.variant(:small)&.url, placement: placement, offset: offset, data: { testid: "user-menu" }) do |menu| %>
|
||||
<%= menu.with_header do %>
|
||||
<div class="px-4 py-3 flex items-center gap-3">
|
||||
<div class="w-9 h-9 shrink-0">
|
||||
|
@ -42,4 +42,4 @@
|
|||
<% menu.with_item(variant: "divider") %>
|
||||
|
||||
<% menu.with_item(text: "Log out", icon: "log-out", href: session_path(Current.session), method: :delete) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -19,7 +19,9 @@ class ImportsTest < ApplicationSystemTestCase
|
|||
|
||||
fill_in "import[raw_file_str]", with: file_fixture("imports/transactions.csv").read
|
||||
|
||||
find('input[type="submit"][value="Upload CSV"]').click
|
||||
within "form" do
|
||||
click_on "Upload CSV"
|
||||
end
|
||||
|
||||
select "Date", from: "import[date_col_label]"
|
||||
select "YYYY-MM-DD", from: "import[date_format]"
|
||||
|
@ -65,7 +67,9 @@ class ImportsTest < ApplicationSystemTestCase
|
|||
|
||||
fill_in "import[raw_file_str]", with: file_fixture("imports/trades.csv").read
|
||||
|
||||
find('input[type="submit"][value="Upload CSV"]').click
|
||||
within "form" do
|
||||
click_on "Upload CSV"
|
||||
end
|
||||
|
||||
select "date", from: "import[date_col_label]"
|
||||
select "YYYY-MM-DD", from: "import[date_format]"
|
||||
|
@ -103,7 +107,9 @@ class ImportsTest < ApplicationSystemTestCase
|
|||
|
||||
fill_in "import[raw_file_str]", with: file_fixture("imports/accounts.csv").read
|
||||
|
||||
find('input[type="submit"][value="Upload CSV"]').click
|
||||
within "form" do
|
||||
click_on "Upload CSV"
|
||||
end
|
||||
|
||||
select "type", from: "import[entity_type_col_label]"
|
||||
select "name", from: "import[name_col_label]"
|
||||
|
@ -147,7 +153,9 @@ class ImportsTest < ApplicationSystemTestCase
|
|||
|
||||
fill_in "import[raw_file_str]", with: file_fixture("imports/mint.csv").read
|
||||
|
||||
find('input[type="submit"][value="Upload CSV"]').click
|
||||
within "form" do
|
||||
click_on "Upload CSV"
|
||||
end
|
||||
|
||||
click_on "Apply configuration"
|
||||
|
||||
|
|
|
@ -56,7 +56,9 @@ class SettingsTest < ApplicationSystemTestCase
|
|||
private
|
||||
|
||||
def open_settings_from_sidebar
|
||||
find("#user-menu").click
|
||||
within "div[data-testid=user-menu]" do
|
||||
find("button").click
|
||||
end
|
||||
click_link "Settings"
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue