diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index f5bab529d..0a31eb593 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -56,7 +56,10 @@ class AccountsController < ApplicationController end def new - @show_lunchflow_link = family.can_connect_lunchflow? + # Get all registered providers with any credentials configured + @provider_configs = Provider::Factory.registered_adapters.flat_map do |adapter_class| + adapter_class.connection_configs(family: family) + end end def sync_all @@ -158,45 +161,21 @@ class AccountsController < ApplicationController return end - @available_providers = [] + account_type_name = @account.accountable_type - # Check SimpleFIN - if family.can_connect_simplefin? - @available_providers << { - name: "SimpleFIN", - key: "simplefin", - description: "Connect to your bank via SimpleFIN", - path: select_existing_account_simplefin_items_path(account_id: @account.id) - } - end + # Get all available provider configs dynamically for this account type + provider_configs = Provider::Factory.connection_configs_for_account_type( + account_type: account_type_name, + family: family + ) - # Check Plaid US - if family.can_connect_plaid_us? - @available_providers << { - name: "Plaid", - key: "plaid_us", - description: "Connect to your US bank via Plaid", - path: select_existing_account_plaid_items_path(account_id: @account.id, region: "us") - } - end - - # Check Plaid EU - if family.can_connect_plaid_eu? - @available_providers << { - name: "Plaid (EU)", - key: "plaid_eu", - description: "Connect to your EU bank via Plaid", - path: select_existing_account_plaid_items_path(account_id: @account.id, region: "eu") - } - end - - # Check Lunch Flow - if family.can_connect_lunchflow? - @available_providers << { - name: "Lunch Flow", - key: "lunchflow", - description: "Connect to your bank via Lunch Flow", - path: select_existing_account_lunchflow_items_path(account_id: @account.id) + # Build available providers list with paths resolved for this specific account + @available_providers = provider_configs.map do |config| + { + name: config[:name], + key: config[:key], + description: config[:description], + path: config[:existing_account_path].call(@account.id) } end diff --git a/app/controllers/concerns/accountable_resource.rb b/app/controllers/concerns/accountable_resource.rb index 4d70a225d..bc1d636f4 100644 --- a/app/controllers/concerns/accountable_resource.rb +++ b/app/controllers/concerns/accountable_resource.rb @@ -66,9 +66,13 @@ module AccountableResource private def set_link_options - @show_us_link = Current.family.can_connect_plaid_us? - @show_eu_link = Current.family.can_connect_plaid_eu? - @show_lunchflow_link = Current.family.can_connect_lunchflow? + account_type_name = accountable_type.name + + # Get all available provider configs dynamically for this account type + @provider_configs = Provider::Factory.connection_configs_for_account_type( + account_type: account_type_name, + family: Current.family + ) end def accountable_type diff --git a/app/models/provider/base.rb b/app/models/provider/base.rb index 22b1263aa..37f63577a 100644 --- a/app/models/provider/base.rb +++ b/app/models/provider/base.rb @@ -31,6 +31,27 @@ class Provider::Base raise NotImplementedError, "#{self.class} must implement #provider_name" end + # Defines which account types this provider supports + # Override in subclasses to specify supported account types + # @return [Array] Array of account type class names (e.g., ["Depository", "CreditCard"]) + def self.supported_account_types + [] + end + + # Returns provider connection configurations + # Override in subclasses to provide connection metadata for UI + # @param family [Family] The family to check connection availability for + # @return [Array] Array of connection configurations with keys: + # - key: Unique identifier (e.g., "lunchflow", "plaid_us") + # - name: Display name (e.g., "Lunch Flow", "Plaid") + # - description: User-facing description + # - can_connect: Boolean, whether family can connect to this provider + # - new_account_path: Proc that generates path for new account flow + # - existing_account_path: Proc that generates path for linking existing account + def self.connection_configs(family:) + [] + end + # Returns the provider type (class name) # @return [String] The provider account class name def provider_type diff --git a/app/models/provider/factory.rb b/app/models/provider/factory.rb index cf8bae9b7..f8d5ac688 100644 --- a/app/models/provider/factory.rb +++ b/app/models/provider/factory.rb @@ -63,6 +63,39 @@ class Provider::Factory find_adapter_class(provider_type).present? end + # Get all registered adapter classes + # @return [Array] List of registered adapter classes + def registered_adapters + ensure_adapters_loaded + registry.values.uniq + end + + # Get adapters that support a specific account type + # @param account_type [String] The account type class name (e.g., "Depository", "CreditCard") + # @return [Array] List of adapter classes that support this account type + def adapters_for_account_type(account_type) + registered_adapters.select do |adapter_class| + adapter_class.supported_account_types.include?(account_type) + end + end + + # Check if any provider supports a given account type + # @param account_type [String] The account type class name + # @return [Boolean] + def supports_account_type?(account_type) + adapters_for_account_type(account_type).any? + end + + # Get all available provider connection configs for a given account type + # @param account_type [String] The account type class name (e.g., "Depository") + # @param family [Family] The family to check connection availability for + # @return [Array] Array of connection configurations from all providers + def connection_configs_for_account_type(account_type:, family:) + adapters_for_account_type(account_type).flat_map do |adapter_class| + adapter_class.connection_configs(family: family) + end + end + # Clear all registered adapters (useful for testing) def clear_registry! @registry = {} diff --git a/app/models/provider/lunchflow_adapter.rb b/app/models/provider/lunchflow_adapter.rb index 8cd2bb69d..ec5b3ef92 100644 --- a/app/models/provider/lunchflow_adapter.rb +++ b/app/models/provider/lunchflow_adapter.rb @@ -5,6 +5,34 @@ class Provider::LunchflowAdapter < Provider::Base # Register this adapter with the factory Provider::Factory.register("LunchflowAccount", self) + # Define which account types this provider supports + def self.supported_account_types + %w[Depository CreditCard Loan] + end + + # Returns connection configurations for this provider + def self.connection_configs(family:) + return [] unless family.can_connect_lunchflow? + + [ { + key: "lunchflow", + name: "Lunch Flow", + description: "Connect to your bank via Lunch Flow", + can_connect: true, + new_account_path: ->(accountable_type, return_to) { + Rails.application.routes.url_helpers.select_accounts_lunchflow_items_path( + accountable_type: accountable_type, + return_to: return_to + ) + }, + existing_account_path: ->(account_id) { + Rails.application.routes.url_helpers.select_existing_account_lunchflow_items_path( + account_id: account_id + ) + } + } ] + end + def provider_name "lunchflow" end diff --git a/app/models/provider/plaid_adapter.rb b/app/models/provider/plaid_adapter.rb index 098447dc0..d42e2ef93 100644 --- a/app/models/provider/plaid_adapter.rb +++ b/app/models/provider/plaid_adapter.rb @@ -17,6 +17,63 @@ class Provider::PlaidAdapter < Provider::Base # Register this adapter with the factory for ALL PlaidAccount instances Provider::Factory.register("PlaidAccount", self) + # Define which account types this provider supports (US region) + def self.supported_account_types + %w[Depository CreditCard Loan Investment] + end + + # Returns connection configurations for this provider + # Plaid can return multiple configs (US and EU) depending on family setup + def self.connection_configs(family:) + configs = [] + + # US configuration + if family.can_connect_plaid_us? + configs << { + key: "plaid_us", + name: "Plaid", + description: "Connect to your US bank via Plaid", + can_connect: true, + new_account_path: ->(accountable_type, return_to) { + Rails.application.routes.url_helpers.new_plaid_item_path( + region: "us", + accountable_type: accountable_type + ) + }, + existing_account_path: ->(account_id) { + Rails.application.routes.url_helpers.select_existing_account_plaid_items_path( + account_id: account_id, + region: "us" + ) + } + } + end + + # EU configuration + if family.can_connect_plaid_eu? + configs << { + key: "plaid_eu", + name: "Plaid (EU)", + description: "Connect to your EU bank via Plaid", + can_connect: true, + new_account_path: ->(accountable_type, return_to) { + Rails.application.routes.url_helpers.new_plaid_item_path( + region: "eu", + accountable_type: accountable_type + ) + }, + existing_account_path: ->(account_id) { + Rails.application.routes.url_helpers.select_existing_account_plaid_items_path( + account_id: account_id, + region: "eu" + ) + } + } + end + + configs + end + # Mutex for thread-safe configuration loading # Initialized at class load time to avoid race conditions on mutex creation @config_mutex = Mutex.new diff --git a/app/models/provider/simplefin_adapter.rb b/app/models/provider/simplefin_adapter.rb index 9cd758347..0d76acad3 100644 --- a/app/models/provider/simplefin_adapter.rb +++ b/app/models/provider/simplefin_adapter.rb @@ -5,6 +5,33 @@ class Provider::SimplefinAdapter < Provider::Base # Register this adapter with the factory Provider::Factory.register("SimplefinAccount", self) + # Define which account types this provider supports + def self.supported_account_types + %w[Depository CreditCard Loan Investment] + end + + # Returns connection configurations for this provider + def self.connection_configs(family:) + return [] unless family.can_connect_simplefin? + + [ { + key: "simplefin", + name: "SimpleFIN", + description: "Connect to your bank via SimpleFIN", + can_connect: true, + new_account_path: ->(accountable_type, return_to) { + Rails.application.routes.url_helpers.new_simplefin_item_path( + accountable_type: accountable_type + ) + }, + existing_account_path: ->(account_id) { + Rails.application.routes.url_helpers.select_existing_account_simplefin_items_path( + account_id: account_id + ) + } + } ] + end + def provider_name "simplefin" end diff --git a/app/views/accounts/new.html.erb b/app/views/accounts/new.html.erb index 34b338c4f..01b02a575 100644 --- a/app/views/accounts/new.html.erb +++ b/app/views/accounts/new.html.erb @@ -1,6 +1,6 @@ <%= render layout: "accounts/new/container", locals: { title: t(".title") } do %>
+ <% if @provider_configs.any? { |c| c[:key] == "lunchflow" } %> data-controller="lunchflow-preload" <% end %>> <% unless params[:classification] == "liability" %> diff --git a/app/views/accounts/new/_method_selector.html.erb b/app/views/accounts/new/_method_selector.html.erb index 6c2419236..135cd0104 100644 --- a/app/views/accounts/new/_method_selector.html.erb +++ b/app/views/accounts/new/_method_selector.html.erb @@ -1,14 +1,15 @@ -<%# locals: (path:, accountable_type:, show_us_link: true, show_eu_link: true, show_lunchflow_link: false) %> +<%# locals: (path:, accountable_type:, provider_configs:) %> <%= render layout: "accounts/new/container", locals: { title: t(".title"), back_path: new_account_path } do %>
+ <% if provider_configs.any? { |c| c[:key] == "lunchflow" } %> data-controller="lunchflow-preload" data-lunchflow-preload-accountable-type-value="<%= h(accountable_type) %>" <% if params[:return_to] %> data-lunchflow-preload-return-to-value="<%= h(params[:return_to]) %>" <% end %> <% end %>> + <%# Manual entry option %> <%= link_to path, class: "flex items-center gap-4 w-full text-center text-primary focus:outline-hidden focus:bg-surface border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-surface rounded-lg p-2" do %> <%= icon("keyboard") %> @@ -16,48 +17,31 @@ <%= t("accounts.new.method_selector.manual_entry") %> <% end %> - <% if show_us_link %> - <%# Default US-only Link %> - <%= link_to new_plaid_item_path(region: "us", accountable_type: accountable_type), - class: "text-primary flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-surface border border-transparent focus:border focus:border-primary px-2 hover:bg-surface rounded-lg p-2", - data: { turbo_frame: "modal" } do %> - - <%= icon("link-2") %> - - <%= t("accounts.new.method_selector.connected_entry") %> - <% end %> - <% end %> + <%# Dynamic provider links %> + <% provider_configs.each do |config| %> + <% link_path = config[:new_account_path].call(accountable_type, params[:return_to]) %> + <% is_lunchflow = config[:key] == "lunchflow" %> - <%# EU Link %> - <% if show_eu_link %> - <%= link_to new_plaid_item_path(region: "eu", accountable_type: accountable_type), + <%= link_to link_path, class: "text-primary flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-surface border border-transparent focus:border focus:border-primary px-2 hover:bg-surface rounded-lg p-2", - data: { turbo_frame: "modal" } do %> - - <%= icon("link-2") %> - - <%= t("accounts.new.method_selector.connected_entry_eu") %> - <% end %> - <% end %> - - <%# Lunchflow Link %> - <% if show_lunchflow_link %> - <%= link_to select_accounts_lunchflow_items_path(accountable_type: accountable_type, return_to: params[:return_to]), - class: "text-primary flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-surface border border-transparent focus:border focus:border-primary px-2 hover:bg-surface rounded-lg p-2", - data: { + data: is_lunchflow ? { turbo_frame: "modal", turbo_action: "advance", lunchflow_preload_target: "link" - } do %> + } : { turbo_frame: "modal" } do %> <%= icon("link-2") %> - - <%= t("accounts.new.method_selector.lunchflow_entry") %> - + <% else %> + <%= t("accounts.new.method_selector.link_with_provider", provider: config[:name]) %> + <% end %> <% end %> <% end %> diff --git a/app/views/credit_cards/new.html.erb b/app/views/credit_cards/new.html.erb index 3d751334f..97c6472b7 100644 --- a/app/views/credit_cards/new.html.erb +++ b/app/views/credit_cards/new.html.erb @@ -1,9 +1,7 @@ <% if params[:step] == "method_select" %> <%= render "accounts/new/method_selector", path: new_credit_card_path(return_to: params[:return_to]), - show_us_link: @show_us_link, - show_eu_link: @show_eu_link, - show_lunchflow_link: @show_lunchflow_link, + provider_configs: @provider_configs, accountable_type: "CreditCard" %> <% else %> <%= render DS::Dialog.new do |dialog| %> diff --git a/app/views/cryptos/new.html.erb b/app/views/cryptos/new.html.erb index 97fcccdc1..dd455aa1e 100644 --- a/app/views/cryptos/new.html.erb +++ b/app/views/cryptos/new.html.erb @@ -1,8 +1,7 @@ <% if params[:step] == "method_select" %> <%= render "accounts/new/method_selector", path: new_crypto_path(return_to: params[:return_to]), - show_us_link: @show_us_link, - show_eu_link: @show_eu_link, + provider_configs: @provider_configs, accountable_type: "Crypto" %> <% else %> <%= render DS::Dialog.new do |dialog| %> diff --git a/app/views/depositories/new.html.erb b/app/views/depositories/new.html.erb index 331facaa0..f0f06828c 100644 --- a/app/views/depositories/new.html.erb +++ b/app/views/depositories/new.html.erb @@ -1,9 +1,7 @@ <% if params[:step] == "method_select" %> <%= render "accounts/new/method_selector", path: new_depository_path(return_to: params[:return_to]), - show_us_link: @show_us_link, - show_eu_link: @show_eu_link, - show_lunchflow_link: @show_lunchflow_link, + provider_configs: @provider_configs, accountable_type: "Depository" %> <% else %> <%= render DS::Dialog.new do |dialog| %> diff --git a/app/views/investments/new.html.erb b/app/views/investments/new.html.erb index acfaa6edd..5a89f5eaf 100644 --- a/app/views/investments/new.html.erb +++ b/app/views/investments/new.html.erb @@ -1,8 +1,7 @@ <% if params[:step] == "method_select" %> <%= render "accounts/new/method_selector", path: new_investment_path(return_to: params[:return_to]), - show_us_link: @show_us_link, - show_eu_link: @show_eu_link, + provider_configs: @provider_configs, accountable_type: "Investment" %> <% else %> <%= render DS::Dialog.new do |dialog| %> diff --git a/app/views/loans/new.html.erb b/app/views/loans/new.html.erb index 8ca62d369..569782c4f 100644 --- a/app/views/loans/new.html.erb +++ b/app/views/loans/new.html.erb @@ -1,9 +1,7 @@ <% if params[:step] == "method_select" %> <%= render "accounts/new/method_selector", path: new_loan_path(return_to: params[:return_to]), - show_us_link: @show_us_link, - show_eu_link: @show_eu_link, - show_lunchflow_link: @show_lunchflow_link, + provider_configs: @provider_configs, accountable_type: "Loan" %> <% else %> <%= render DS::Dialog.new do |dialog| %> diff --git a/app/views/simplefin_items/new.html.erb b/app/views/simplefin_items/new.html.erb index f76a2c8e0..ade7c448c 100644 --- a/app/views/simplefin_items/new.html.erb +++ b/app/views/simplefin_items/new.html.erb @@ -1,24 +1,26 @@ -
-

Connect SimpleFin

-
+<%= turbo_frame_tag "modal" do %> + <%= render DS::Dialog.new do |dialog| %> + <% dialog.with_header(title: t(".title")) %> -<% if @error_message.present? %> -
- <%= @error_message %> -
-<% end %> + <% dialog.with_body do %> + <% if @error_message.present? %> +
+ <%= @error_message %> +
+ <% end %> -
- <%= form_with model: @simplefin_item, url: simplefin_items_path, method: :post, data: { turbo: true } do |f| %> -
-
- <%= f.label :setup_token, "Setup token", class: "text-sm text-secondary block mb-1" %> - <%= f.text_field :setup_token, class: "input", placeholder: "paste your SimpleFin setup token" %> -
-
- <%= f.submit "Connect", class: "btn btn--primary" %> - <%= link_to "Cancel", accounts_path, class: "btn" %> -
-
+ <%= form_with model: @simplefin_item, url: simplefin_items_path, method: :post, data: { turbo: true, turbo_frame: "_top" } do |f| %> +
+
+ <%= f.label :setup_token, t(".setup_token"), class: "text-sm text-secondary block mb-1" %> + <%= f.text_field :setup_token, class: "input", placeholder: t(".setup_token_placeholder") %> +
+
+ <%= link_to t(".cancel"), accounts_path, class: "btn", data: { turbo_frame: "_top", action: "DS--dialog#close" } %> + <%= f.submit t(".connect"), class: "btn btn--primary" %> +
+
+ <% end %> + <% end %> <% end %> -
+<% end %> diff --git a/config/locales/views/accounts/ca.yml b/config/locales/views/accounts/ca.yml index b3e7c204e..8d568a520 100644 --- a/config/locales/views/accounts/ca.yml +++ b/config/locales/views/accounts/ca.yml @@ -28,6 +28,7 @@ ca: method_selector: connected_entry: Enllaça el compte connected_entry_eu: Enllaça el compte de la UE + link_with_provider: "Enllaça amb %{provider}" manual_entry: Introdueix el saldo del compte title: Com vols afegir-lo? title: Què vols afegir? diff --git a/config/locales/views/accounts/de.yml b/config/locales/views/accounts/de.yml index 08afc4999..0e9196476 100644 --- a/config/locales/views/accounts/de.yml +++ b/config/locales/views/accounts/de.yml @@ -28,6 +28,7 @@ de: method_selector: connected_entry: Konto verknüpfen connected_entry_eu: EU-Konto verknüpfen + link_with_provider: "Mit %{provider} verknüpfen" manual_entry: Kontostand manuell eingeben title: Wie möchtest du es hinzufügen title: Was möchtest du hinzufügen diff --git a/config/locales/views/accounts/en.yml b/config/locales/views/accounts/en.yml index 25bacd2ee..e3911b1ab 100644 --- a/config/locales/views/accounts/en.yml +++ b/config/locales/views/accounts/en.yml @@ -34,6 +34,7 @@ en: method_selector: connected_entry: Link account connected_entry_eu: Link EU account + link_with_provider: "Link with %{provider}" lunchflow_entry: Link Lunch Flow account manual_entry: Enter account balance title: How would you like to add it? diff --git a/config/locales/views/accounts/es.yml b/config/locales/views/accounts/es.yml index f2e499bf4..c99a987a1 100644 --- a/config/locales/views/accounts/es.yml +++ b/config/locales/views/accounts/es.yml @@ -29,6 +29,7 @@ es: method_selector: connected_entry: Vincular cuenta connected_entry_eu: Vincular cuenta de la UE + link_with_provider: "Vincular con %{provider}" lunchflow_entry: Vincular cuenta de Lunch Flow manual_entry: Introducir saldo de la cuenta title: ¿Cómo te gustaría añadirla? diff --git a/config/locales/views/accounts/nb.yml b/config/locales/views/accounts/nb.yml index d398a612f..7cc45f459 100644 --- a/config/locales/views/accounts/nb.yml +++ b/config/locales/views/accounts/nb.yml @@ -28,6 +28,7 @@ nb: method_selector: connected_entry: Koble til konto connected_entry_eu: Koble til EU-konto + link_with_provider: "Koble til %{provider}" manual_entry: Angi kontobalanse title: Hvordan vil du legge den til? title: Hva vil du legge til? diff --git a/config/locales/views/accounts/ro.yml b/config/locales/views/accounts/ro.yml index 14a1b6977..e87bb523c 100644 --- a/config/locales/views/accounts/ro.yml +++ b/config/locales/views/accounts/ro.yml @@ -29,6 +29,7 @@ ro: method_selector: connected_entry: Conectează cont connected_entry_eu: Conectează cont UE + link_with_provider: "Conectează cu %{provider}" lunchflow_entry: Conectează cont Lunch Flow manual_entry: Introdu soldul contului title: Cum dorești să adaugi? diff --git a/config/locales/views/accounts/tr.yml b/config/locales/views/accounts/tr.yml index f0fc734f8..daee9867b 100644 --- a/config/locales/views/accounts/tr.yml +++ b/config/locales/views/accounts/tr.yml @@ -28,6 +28,7 @@ tr: method_selector: connected_entry: Hesabı bağla connected_entry_eu: AB hesabı bağla + link_with_provider: "%{provider} ile bağla" manual_entry: Hesap bakiyesi gir title: Nasıl eklemek istersiniz? title: Ne eklemek istersiniz? diff --git a/config/locales/views/simplefin_items/ca.yml b/config/locales/views/simplefin_items/ca.yml index 29932f3a7..216957650 100644 --- a/config/locales/views/simplefin_items/ca.yml +++ b/config/locales/views/simplefin_items/ca.yml @@ -1,6 +1,12 @@ --- ca: simplefin_items: + new: + title: Connecta SimpleFin + setup_token: Token de configuració + setup_token_placeholder: enganxa el teu token de configuració SimpleFin + connect: Connecta + cancel: Cancel·la create: success: Connexió SimpleFin afegida correctament! Els teus comptes apareixeran en breu mentre es sincronitzen en segon pla. errors: diff --git a/config/locales/views/simplefin_items/de.yml b/config/locales/views/simplefin_items/de.yml index b75cb84d8..3830b99e6 100644 --- a/config/locales/views/simplefin_items/de.yml +++ b/config/locales/views/simplefin_items/de.yml @@ -1,6 +1,12 @@ --- de: simplefin_items: + new: + title: SimpleFin verbinden + setup_token: Setup-Token + setup_token_placeholder: Füge dein SimpleFin-Setup-Token ein + connect: Verbinden + cancel: Abbrechen create: success: SimpleFin-Verbindung erfolgreich hinzugefügt! Deine Konten werden in Kürze angezeigt, sobald sie im Hintergrund synchronisiert wurden. errors: diff --git a/config/locales/views/simplefin_items/en.yml b/config/locales/views/simplefin_items/en.yml index 017eb7b9d..7181520dc 100644 --- a/config/locales/views/simplefin_items/en.yml +++ b/config/locales/views/simplefin_items/en.yml @@ -1,6 +1,12 @@ --- en: simplefin_items: + new: + title: Connect SimpleFin + setup_token: Setup token + setup_token_placeholder: paste your SimpleFin setup token + connect: Connect + cancel: Cancel create: success: SimpleFin connection added successfully! Your accounts will appear shortly as they sync in the background. errors: diff --git a/config/locales/views/simplefin_items/es.yml b/config/locales/views/simplefin_items/es.yml index 2c682a142..e36d3db59 100644 --- a/config/locales/views/simplefin_items/es.yml +++ b/config/locales/views/simplefin_items/es.yml @@ -1,6 +1,12 @@ --- es: simplefin_items: + new: + title: Conectar SimpleFin + setup_token: Token de configuración + setup_token_placeholder: pega tu token de configuración de SimpleFin + connect: Conectar + cancel: Cancelar create: success: ¡Conexión SimpleFin añadida con éxito! Tus cuentas aparecerán en breve mientras se sincronizan en segundo plano. errors: diff --git a/config/locales/views/simplefin_items/ro.yml b/config/locales/views/simplefin_items/ro.yml index a1a6e965c..e817ca6b5 100644 --- a/config/locales/views/simplefin_items/ro.yml +++ b/config/locales/views/simplefin_items/ro.yml @@ -1,6 +1,12 @@ --- ro: simplefin_items: + new: + title: Conectează SimpleFin + setup_token: Token de configurare + setup_token_placeholder: lipește token-ul tău de configurare SimpleFin + connect: Conectează + cancel: Anulează create: success: Conexiunea SimpleFin a fost adăugată cu succes! Conturile tale vor apărea în scurt timp pe măsură ce se sincronizează în fundal. errors: