diff --git a/.erb_lint.yml b/.erb_lint.yml index 25e2184f9..d9521ca07 100644 --- a/.erb_lint.yml +++ b/.erb_lint.yml @@ -40,4 +40,38 @@ linters: - 'border-gray-500' - 'border-gray-700' - 'border-gray-900' - - 'border-white' \ No newline at end of file + - 'border-white' + # Custom @utility tokens (bg-inverse, text-inverse, text-primary, etc.) do + # NOT support Tailwind's `/N` opacity modifier syntax — modifiers like + # `text-inverse/70` silently compile to nothing. Use `opacity-N` on the + # parent element, or migrate the token to `@theme --color-X` in + # design/tokens/sure.tokens.json so Tailwind auto-generates the + # color-mix pipeline. See #1653. + - suggestion: "Custom @utility tokens drop `/N` opacity modifiers silently. Use `opacity-N` instead, or migrate the token to @theme in design/tokens/sure.tokens.json (see #1653)." + deprecated: + - 'text-inverse\/\d+' + - 'bg-inverse\/\d+' + - 'bg-inverse-hover\/\d+' + - 'border-inverse\/\d+' + - 'text-primary\/\d+' + - 'text-secondary\/\d+' + - 'text-subdued\/\d+' + - 'border-primary\/\d+' + - 'border-secondary\/\d+' + - 'border-subdued\/\d+' + - 'border-destructive\/\d+' + - 'border-solid\/\d+' + - 'button-bg-primary\/\d+' + - 'button-bg-primary-hover\/\d+' + - 'button-bg-secondary\/\d+' + - 'button-bg-secondary-hover\/\d+' + - 'button-bg-secondary-strong\/\d+' + - 'button-bg-secondary-strong-hover\/\d+' + - 'button-bg-disabled\/\d+' + - 'button-bg-destructive\/\d+' + - 'button-bg-destructive-hover\/\d+' + - 'button-bg-ghost-hover\/\d+' + - 'button-bg-outline-hover\/\d+' + - 'tab-item-active\/\d+' + - 'tab-item-hover\/\d+' + - 'tab-bg-group\/\d+' diff --git a/.sure-version b/.sure-version index 11a626600..38d939e70 100644 --- a/.sure-version +++ b/.sure-version @@ -1 +1 @@ -0.7.1-alpha.8 +0.7.1-alpha.10 diff --git a/app/assets/tailwind/sure-design-system/_generated.css b/app/assets/tailwind/sure-design-system/_generated.css index 105b788e4..96a966b86 100644 --- a/app/assets/tailwind/sure-design-system/_generated.css +++ b/app/assets/tailwind/sure-design-system/_generated.css @@ -9,11 +9,22 @@ --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; --color-white: #ffffff; --color-black: #0B0B0B; - --color-success: var(--color-green-600); + --color-success: var(--color-green-700); --color-warning: var(--color-yellow-600); --color-destructive: var(--color-red-600); --color-info: var(--color-blue-600); --color-shadow: --alpha(var(--color-black) / 6%); + --color-link: var(--color-blue-600); + --color-tertiary: var(--color-alpha-black-100); + --color-surface: var(--color-gray-50); + --color-surface-hover: var(--color-gray-100); + --color-surface-inset: var(--color-gray-100); + --color-surface-inset-hover: var(--color-gray-200); + --color-container: var(--color-white); + --color-container-hover: var(--color-gray-50); + --color-container-inset: var(--color-gray-50); + --color-container-inset-hover: var(--color-gray-100); + --color-nav-indicator: var(--color-black); --color-gray-25: #FAFAFA; --color-gray-50: #F7F7F7; --color-gray-100: #F0F0F0; @@ -197,11 +208,22 @@ @layer base { [data-theme="dark"] { - --color-success: var(--color-green-500); + --color-success: var(--color-green-400); --color-warning: var(--color-yellow-400); --color-destructive: var(--color-red-400); --color-info: var(--color-blue-500); --color-shadow: --alpha(var(--color-white) / 8%); + --color-link: var(--color-blue-500); + --color-tertiary: var(--color-alpha-white-200); + --color-surface: var(--color-black); + --color-surface-hover: var(--color-gray-800); + --color-surface-inset: var(--color-gray-800); + --color-surface-inset-hover: var(--color-gray-800); + --color-container: var(--color-gray-900); + --color-container-hover: var(--color-gray-800); + --color-container-inset: var(--color-gray-800); + --color-container-inset-hover: var(--color-gray-700); + --color-nav-indicator: var(--color-white); --budget-unused-fill: var(--color-gray-500); --budget-unallocated-fill: var(--color-gray-700); --shadow-xs: 0px 1px 2px 0px --alpha(var(--color-white) / 8%); @@ -212,70 +234,6 @@ } } -@utility bg-surface { - @apply bg-gray-50; - - @variant theme-dark { - @apply bg-black; - } -} - -@utility bg-surface-hover { - @apply bg-gray-100; - - @variant theme-dark { - @apply bg-gray-800; - } -} - -@utility bg-surface-inset { - @apply bg-gray-100; - - @variant theme-dark { - @apply bg-gray-800; - } -} - -@utility bg-surface-inset-hover { - @apply bg-gray-200; - - @variant theme-dark { - @apply bg-gray-800; - } -} - -@utility bg-container { - @apply bg-white; - - @variant theme-dark { - @apply bg-gray-900; - } -} - -@utility bg-container-hover { - @apply bg-gray-50; - - @variant theme-dark { - @apply bg-gray-800; - } -} - -@utility bg-container-inset { - @apply bg-gray-50; - - @variant theme-dark { - @apply bg-gray-800; - } -} - -@utility bg-container-inset-hover { - @apply bg-gray-100; - - @variant theme-dark { - @apply bg-gray-700; - } -} - @utility bg-inverse { @apply bg-gray-800; @@ -336,14 +294,6 @@ } } -@utility text-link { - @apply text-blue-600; - - @variant theme-dark { - @apply text-blue-500; - } -} - @utility shadow-border-xs { box-shadow: var(--shadow-xs), 0px 0px 0px 1px var(--color-alpha-black-50); @@ -400,14 +350,6 @@ } } -@utility border-tertiary { - @apply border-alpha-black-100; - - @variant theme-dark { - @apply border-alpha-white-200; - } -} - @utility border-divider { @apply border-tertiary; } @@ -555,11 +497,3 @@ @apply bg-alpha-black-700; } } - -@utility bg-nav-indicator { - @apply bg-black; - - @variant theme-dark { - @apply bg-white; - } -} diff --git a/app/assets/tailwind/sure-design-system/base.css b/app/assets/tailwind/sure-design-system/base.css index 991cfc4ef..522cdcf37 100644 --- a/app/assets/tailwind/sure-design-system/base.css +++ b/app/assets/tailwind/sure-design-system/base.css @@ -1,6 +1,10 @@ @layer base { button { - @apply cursor-pointer focus-visible:outline-gray-900; + @apply cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-alpha-black-300; + + @variant theme-dark { + @apply focus-visible:ring-alpha-white-300; + } } hr { diff --git a/app/components/DS/button.rb b/app/components/DS/button.rb index a253c04c7..ca5644225 100644 --- a/app/components/DS/button.rb +++ b/app/components/DS/button.rb @@ -22,7 +22,6 @@ class DS::Button < DS::Buttonish def merged_opts merged_opts = opts.dup || {} extra_classes = merged_opts.delete(:class) - href = merged_opts.delete(:href) data = merged_opts.delete(:data) || {} if confirm.present? @@ -33,6 +32,28 @@ class DS::Button < DS::Buttonish data = data.merge(turbo_frame: frame) end + # `content_tag(:button, ...)` defaults to `type="submit"` per the HTML + # spec — meaning a DS::Button rendered inside a form will steal Enter-key + # submission from the first text input. Default to `type="button"` so + # callers must opt into submit behavior explicitly. `button_to` (href + # branch) wraps the button in its own form, so submit there is correct + # and we leave its default alone. + if href.blank? + merged_opts[:type] ||= "button" + end + + # Icon-only buttons have no visible text node, so screen readers fall + # back to announcing "button" with no name. Derive a humanized fallback + # from the icon key so AT users hear *something* meaningful; explicit + # `aria: { label: }` on the caller still wins. + if icon_only? && icon.present? + aria = (merged_opts[:aria] || {}).symbolize_keys + if aria[:label].blank? && merged_opts[:"aria-label"].blank? + aria[:label] = icon.to_s.tr("-_", " ").capitalize + merged_opts[:aria] = aria + end + end + merged_opts.merge( class: class_names(container_classes, extra_classes), data: data diff --git a/app/components/DS/buttonish.rb b/app/components/DS/buttonish.rb index bd8894be6..f1e864511 100644 --- a/app/components/DS/buttonish.rb +++ b/app/components/DS/buttonish.rb @@ -10,7 +10,7 @@ class DS::Buttonish < DesignSystemComponent }, destructive: { container_classes: "text-inverse bg-red-500 theme-dark:bg-red-400 hover:bg-red-600 theme-dark:hover:bg-red-500 disabled:bg-red-200 theme-dark:disabled:bg-red-600", - icon_classes: "fg-white" + icon_classes: "text-inverse" }, outline: { container_classes: "text-primary border border-secondary bg-transparent hover:bg-surface-hover", @@ -43,13 +43,13 @@ class DS::Buttonish < DesignSystemComponent }, md: { container_classes: "px-3 py-2", - icon_container_classes: "inline-flex items-center justify-center w-9 h-9", + icon_container_classes: "inline-flex items-center justify-center w-11 h-11", radius_classes: "rounded-lg", text_classes: "text-sm" }, lg: { container_classes: "px-4 py-3", - icon_container_classes: "inline-flex items-center justify-center w-10 h-10", + icon_container_classes: "inline-flex items-center justify-center w-12 h-12", radius_classes: "rounded-xl", text_classes: "text-base" } diff --git a/app/components/DS/dialog.html.erb b/app/components/DS/dialog.html.erb index e6892b1ce..97bac18d6 100644 --- a/app/components/DS/dialog.html.erb +++ b/app/components/DS/dialog.html.erb @@ -1,5 +1,23 @@ <%= wrapper_element do %> - <%= tag.dialog class: "w-full h-full bg-transparent text-primary theme-dark:backdrop:bg-alpha-black-900 backdrop:bg-overlay pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)] #{(drawer? || responsive?) ? "lg:p-3" : "lg:p-1"}", **merged_opts do %> + <%# `role="dialog"` + `aria-modal="true"` is redundant with `` + in modern browsers, but Safari and screen readers older than the + 2024 WAI-ARIA Mapping still benefit from the explicit role. + `aria-labelledby` is always emitted with the stable `title_id`. When + the header slot rendered an auto-title (the common case), AT + resolves the reference and announces the title. When no title is + rendered (`custom_header: true`, body-only dialogs), the dangling + reference is silently ignored per the WAI-ARIA spec, and callers + can supply `aria-label` / `aria-labelledby` via `**opts` (last-wins) + for an explicit accessible name. The conditional `if has_auto_title?` + gate was a no-op here: the `renders_one :header` slot lambda is + evaluated lazily at slot-render time (after the `` opening + tag attributes are computed), so the flag was never `true` when + this attribute was read. %> + <%= tag.dialog class: "w-full h-full bg-transparent text-primary theme-dark:backdrop:bg-alpha-black-900 backdrop:bg-overlay pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)] #{(drawer? || responsive?) ? "lg:p-3" : "lg:p-1"}", + role: "dialog", + "aria-modal": "true", + "aria-labelledby": title_id, + **merged_opts do %> <%= tag.div class: dialog_outer_classes do %> <%= tag.div class: dialog_inner_classes, data: { DS__dialog_target: "content" } do %>
"> diff --git a/app/components/DS/dialog.rb b/app/components/DS/dialog.rb index 1027f6db0..fe2611339 100644 --- a/app/components/DS/dialog.rb +++ b/app/components/DS/dialog.rb @@ -2,7 +2,11 @@ class DS::Dialog < DesignSystemComponent renders_one :header, ->(title: nil, subtitle: nil, custom_header: false, **opts, &block) do content_tag(:header, class: "px-4 flex flex-col gap-2", **opts) do title_div = content_tag(:div, class: "flex items-center justify-between gap-2") do - title = content_tag(:h2, title, class: class_names("font-medium text-primary", drawer? ? "text-lg" : "")) if title + # `id: title_id` lets the host `` reference the title via + # `aria-labelledby` so AT users hear the title when focus lands + # in the dialog. `content_tag("h#{heading_level}", ...)` builds an + # h2/h3/etc based on the caller's `heading_level:`. + title = content_tag("h#{heading_level}", title, id: title_id, class: class_names("font-medium text-primary", drawer? ? "text-lg" : "")) if title close_icon = close_button unless custom_header safe_join([ title, close_icon ].compact) end @@ -33,7 +37,7 @@ class DS::Dialog < DesignSystemComponent end end - attr_reader :variant, :auto_open, :reload_on_close, :width, :disable_frame, :content_class, :disable_click_outside, :opts, :responsive, :scrollable + attr_reader :variant, :auto_open, :reload_on_close, :width, :disable_frame, :content_class, :disable_click_outside, :opts, :responsive, :scrollable, :heading_level, :title_id VARIANTS = %w[modal drawer].freeze WIDTHS = { @@ -42,8 +46,13 @@ class DS::Dialog < DesignSystemComponent lg: "lg:max-w-[700px]", full: "lg:max-w-full" }.freeze + VALID_HEADING_LEVELS = (1..6).freeze + + def initialize(variant: "modal", auto_open: true, reload_on_close: false, width: "md", frame: nil, disable_frame: false, content_class: nil, disable_click_outside: false, responsive: false, scrollable: true, heading_level: 2, **opts) + unless heading_level.is_a?(Integer) && VALID_HEADING_LEVELS.cover?(heading_level) + raise ArgumentError, "heading_level must be an Integer between 1 and 6, got: #{heading_level.inspect}" + end - def initialize(variant: "modal", auto_open: true, reload_on_close: false, width: "md", frame: nil, disable_frame: false, content_class: nil, disable_click_outside: false, responsive: false, scrollable: true, **opts) @variant = variant.to_sym @auto_open = auto_open @reload_on_close = reload_on_close @@ -54,6 +63,8 @@ class DS::Dialog < DesignSystemComponent @disable_click_outside = disable_click_outside @responsive = responsive @scrollable = scrollable + @heading_level = heading_level + @title_id = "dialog-title-#{SecureRandom.hex(4)}" @opts = opts end diff --git a/app/components/DS/disclosure.html.erb b/app/components/DS/disclosure.html.erb index bf6f61d1d..8253491bb 100644 --- a/app/components/DS/disclosure.html.erb +++ b/app/components/DS/disclosure.html.erb @@ -1,13 +1,14 @@
> <%= tag.summary class: class_names( - "px-3 py-2 rounded-xl cursor-pointer flex items-center justify-between bg-surface" + "px-3 py-2 rounded-xl cursor-pointer flex items-center justify-between bg-surface", + "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-900 theme-dark:focus-visible:outline-white" ) do %> <% if summary_content? %> <%= summary_content %> <% else %>
<% if align == :left %> - <%= helpers.icon "chevron-right", class: "group-open:transform group-open:rotate-90" %> + <%= helpers.icon "chevron-right", class: "group-open:rotate-90 motion-safe:transition-transform motion-safe:duration-150" %> <% end %> <%= tag.span class: class_names("font-medium", align == :left ? "text-sm text-primary" : "text-xs uppercase text-secondary") do %> @@ -16,7 +17,7 @@
<% if align == :right %> - <%= helpers.icon "chevron-down", class: "group-open:transform group-open:rotate-180" %> + <%= helpers.icon "chevron-down", class: "group-open:rotate-180 motion-safe:transition-transform motion-safe:duration-150" %> <% end %> <% end %> <% end %> diff --git a/app/components/DS/filled_icon.html.erb b/app/components/DS/filled_icon.html.erb index 49adba9e1..9721a26b6 100644 --- a/app/components/DS/filled_icon.html.erb +++ b/app/components/DS/filled_icon.html.erb @@ -1,5 +1,8 @@ <%= tag.div style: transparent? ? container_styles : nil, - class: container_classes do %> + class: container_classes, + role: (!aria_hidden && description.present?) ? "img" : nil, + "aria-label": aria_hidden ? nil : description.presence, + "aria-hidden": aria_hidden ? "true" : nil do %> <% if icon %> <%= helpers.icon(icon, size: icon_size, color: "current") %> <% elsif text %> diff --git a/app/components/DS/filled_icon.rb b/app/components/DS/filled_icon.rb index 73113a0bc..19ed2e5fa 100644 --- a/app/components/DS/filled_icon.rb +++ b/app/components/DS/filled_icon.rb @@ -1,5 +1,5 @@ class DS::FilledIcon < DesignSystemComponent - attr_reader :icon, :text, :hex_color, :size, :rounded, :variant + attr_reader :icon, :text, :hex_color, :size, :rounded, :variant, :description, :aria_hidden VARIANTS = %i[default text surface container inverse].freeze @@ -24,13 +24,26 @@ class DS::FilledIcon < DesignSystemComponent } }.freeze - def initialize(variant: :default, icon: nil, text: nil, hex_color: nil, size: "md", rounded: false) + # `description:` makes the icon meaningful — emits `role="img"` + + # `aria-label=description` so AT users hear it. Without `description:`, + # the wrapper defaults to `aria-hidden="true"` (decorative) on the + # assumption that adjacent DOM carries the accessible name. Pass + # `aria_hidden: false` if you want the visual exposed but the name + # already lives in surrounding text (rare). + # + # NOTE on the `:text` variant: only `text.first` is rendered (e.g. + # "Apple" → "A"). The single letter is decorative — relying on AT + # users to infer "Apple" from "A" is broken. Use `description:` to + # surface the full label, or ensure the adjacent text node carries it. + def initialize(variant: :default, icon: nil, text: nil, hex_color: nil, size: "md", rounded: false, description: nil, aria_hidden: nil) @variant = variant.to_sym @icon = icon @text = text @hex_color = hex_color @size = size.to_sym @rounded = rounded + @description = description.presence + @aria_hidden = aria_hidden.nil? ? @description.blank? : aria_hidden end def container_classes diff --git a/app/components/DS/link.html.erb b/app/components/DS/link.html.erb index dae100eaa..f9c4cff5d 100644 --- a/app/components/DS/link.html.erb +++ b/app/components/DS/link.html.erb @@ -10,4 +10,8 @@ <% if icon && icon_position == "right" %> <%= helpers.icon(icon, size: size, color: icon_color) %> <% end %> + + <% if opens_in_new_tab? %> + <%= t("ds.link.opens_in_new_tab", default: "(opens in new tab)") %> + <% end %> <% end %> diff --git a/app/components/DS/link.rb b/app/components/DS/link.rb index 41ea3f3f2..9ca73aacb 100644 --- a/app/components/DS/link.rb +++ b/app/components/DS/link.rb @@ -5,7 +5,13 @@ class DS::Link < DS::Buttonish VARIANTS = VARIANTS.reverse_merge( default: { - container_classes: "", + # Underline + `text-link` so the link is distinguishable by more + # than color alone (WCAG 1.4.1). Focus ring uses the established + # alpha-ring DS pattern (also used by DS::Toggle, DS::Tooltip, + # provider_card, form-field) so theming stays centralized. + container_classes: "text-link underline underline-offset-2 hover:no-underline " \ + "focus-visible:ring-2 focus-visible:ring-alpha-black-300 " \ + "theme-dark:focus-visible:ring-alpha-white-300", icon_classes: "text-secondary" } ).freeze @@ -18,12 +24,48 @@ class DS::Link < DS::Buttonish data = data.merge(turbo_frame: frame) end + # External link hardening: `target="_blank"` without `rel="noopener"` + # exposes window.opener to the new tab (reverse-tabnabbing). Always + # set `noopener noreferrer` when we send the user off-tab. Authors + # can override by passing `rel:` explicitly. + if merged_opts[:target].to_s == "_blank" + merged_opts[:rel] ||= "noopener noreferrer" + end + + # Icon-only links have no visible text node, so screen readers fall + # back to announcing the href. Derive a humanized fallback from the + # icon key so AT users hear *something* meaningful; explicit + # `aria: { label: }` on the caller still wins. Mirrors DS::Button. + # + # When the link also opens in a new tab, fold the cue into the + # generated `aria-label` itself — `aria-label` overrides the + # descendant accessible name, so the sr-only "(opens in new tab)" + # span in the template would otherwise be masked. + if icon_only? && icon.present? + aria = (merged_opts[:aria] || {}).symbolize_keys + if aria[:label].blank? && merged_opts[:"aria-label"].blank? + label = icon.to_s.tr("-_", " ").humanize + if merged_opts[:target].to_s == "_blank" + label = "#{label} #{I18n.t("ds.link.opens_in_new_tab", default: "(opens in new tab)")}" + end + aria[:label] = label + merged_opts[:aria] = aria + end + end + merged_opts.merge( class: class_names(container_classes, extra_classes), data: data ) end + # Render an sr-only suffix when the link opens in a new tab so AT + # users hear "(opens in new tab)" — visual is a separate concern + # (callers can render a `external-link` icon if they want a glyph). + def opens_in_new_tab? + opts[:target].to_s == "_blank" + end + private def container_size_classes super unless variant == :default diff --git a/app/components/DS/menu.html.erb b/app/components/DS/menu.html.erb index ed6490184..27c262a59 100644 --- a/app/components/DS/menu.html.erb +++ b/app/components/DS/menu.html.erb @@ -1,26 +1,16 @@ <%= tag.div data: { controller: "DS--menu", DS__menu_placement_value: placement, DS__menu_offset_value: offset, DS__menu_mobile_fullwidth_value: mobile_fullwidth, testid: testid } do %> <% if variant == :icon %> - <%= render DS::Button.new(variant: "icon", icon: icon_vertical ? "more-vertical" : "more-horizontal", data: { DS__menu_target: "button" }) %> + <%= render DS::Button.new(variant: "icon", icon: icon_vertical ? "more-vertical" : "more-horizontal", aria: { haspopup: "menu", expanded: "false", controls: menu_id }, data: { DS__menu_target: "button" }) %> <% elsif variant == :button %> <%= button %> - <% elsif variant == :avatar %> - <% end %> - <% end %>
diff --git a/app/views/budget_categories/_allocation_progress.erb b/app/views/budget_categories/_allocation_progress.erb index bd162f5e0..0312cd677 100644 --- a/app/views/budget_categories/_allocation_progress.erb +++ b/app/views/budget_categories/_allocation_progress.erb @@ -9,10 +9,10 @@ <% end %> <% if budget.available_to_allocate.negative? %> -

> 100% set

+

<%= t("budget_categories.allocation_progress.over_set") %>

<% else %>

- <%= number_to_percentage(budget.allocated_percent, precision: 0) %> set + <%= t("budget_categories.allocation_progress.percent_set", percent: number_to_percentage(budget.allocated_percent, precision: 0)) %>

<% end %> @@ -34,11 +34,11 @@
<% if budget.available_to_allocate.negative? %>

- Budget exceeded by <%= format_money(budget.available_to_allocate_money.abs) %> + <%= t("budget_categories.allocation_progress.budget_exceeded_html", amount: format_money(budget.available_to_allocate_money.abs)).html_safe %>

<% else %> <%= format_money(budget.available_to_allocate_money) %> - left to allocate + <%= t("budget_categories.allocation_progress.left_to_allocate") %> <% end %>
diff --git a/app/views/budget_categories/_budget_category_form.html.erb b/app/views/budget_categories/_budget_category_form.html.erb index 322dd0b7a..855a0cda8 100644 --- a/app/views/budget_categories/_budget_category_form.html.erb +++ b/app/views/budget_categories/_budget_category_form.html.erb @@ -8,7 +8,7 @@

<%= budget_category.category.name %>

-

<%= budget_category.median_monthly_expense_money.format(precision: 0) %>/m avg

+

<%= t("budget_categories.budget_category_form.monthly_average", amount: budget_category.median_monthly_expense_money.format(precision: 0)) %>

@@ -18,12 +18,12 @@ <%= currency.symbol %> <%= 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: budget_category.subcategory? ? "Shared" : "0", + placeholder: budget_category.subcategory? ? t("budget_categories.budget_category_form.shared_placeholder") : "0", step: currency.step, id: dom_id(budget_category, :budgeted_spending), min: 0, data: { auto_submit_form_target: "auto" }, - title: budget_category.subcategory? ? "Leave empty to share parent's budget" : nil %> + title: budget_category.subcategory? ? t("budget_categories.budget_category_form.shared_title") : nil %>
<% end %> diff --git a/app/views/budget_categories/_uncategorized_budget_category_form.html.erb b/app/views/budget_categories/_uncategorized_budget_category_form.html.erb index ab477232c..49e545cb0 100644 --- a/app/views/budget_categories/_uncategorized_budget_category_form.html.erb +++ b/app/views/budget_categories/_uncategorized_budget_category_form.html.erb @@ -7,7 +7,7 @@

<%= budget_category.category.name %>

-

<%= budget_category.avg_monthly_expense_money.format(precision: 0) %>/m avg

+

<%= t("budget_categories.budget_category_form.monthly_average", amount: budget_category.avg_monthly_expense_money.format(precision: 0)) %>

diff --git a/app/views/budgets/_budget_header.html.erb b/app/views/budgets/_budget_header.html.erb index 9346d6ba7..b1df7cee7 100644 --- a/app/views/budgets/_budget_header.html.erb +++ b/app/views/budgets/_budget_header.html.erb @@ -27,13 +27,13 @@ <% end %>
- <%= render DS::Menu.new(variant: "button") do |menu| %> - <% menu.with_button class: "flex items-center gap-1 hover:bg-alpha-black-25 cursor-pointer rounded-md p-2" do %> + <%= render DS::Popover.new(variant: "button") do |popover| %> + <% popover.with_button class: "flex items-center gap-1 hover:bg-alpha-black-25 cursor-pointer rounded-md p-2" do %> <%= @budget.name %> <%= icon("chevron-down") %> <% end %> - <% menu.with_custom_content do %> + <% popover.with_custom_content do %> <%= render "budgets/picker", family: Current.family, year: budget.start_date.year %> <% end %> <% end %> diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb index 036634e31..4f2979c33 100644 --- a/app/views/categories/_form.html.erb +++ b/app/views/categories/_form.html.erb @@ -35,7 +35,7 @@ diff --git a/app/views/categories/_menu.html.erb b/app/views/categories/_menu.html.erb index e3f8598b6..321f91f9c 100644 --- a/app/views/categories/_menu.html.erb +++ b/app/views/categories/_menu.html.erb @@ -1,7 +1,7 @@ <%# locals: (transaction:, in_split_group: false) %> -<%= render DS::Menu.new(variant: "button") do |menu| %> - <% menu.with_button(class: "block w-full overflow-hidden") do %> +<%= render DS::Popover.new(variant: "button") do |popover| %> + <% popover.with_button(class: "block w-full overflow-hidden") do %> @@ -10,7 +10,7 @@ <% end %> - <% menu.with_custom_content do %> + <% popover.with_custom_content do %> <%= turbo_frame_tag "category_dropdown", src: category_dropdown_path(category_id: transaction.category_id, transaction_id: transaction.id, grouped: in_split_group), loading: :lazy do %>

<%= t(".loading") %>

diff --git a/app/views/category/deletions/new.html.erb b/app/views/category/deletions/new.html.erb index cf06b137d..d594dba7a 100644 --- a/app/views/category/deletions/new.html.erb +++ b/app/views/category/deletions/new.html.erb @@ -16,6 +16,7 @@ <%= render DS::Button.new( variant: "destructive", + type: :submit, text: t(".delete_and_leave_uncategorized", category_name: @category.name), full_width: true, data: { deletion_target: "destructiveSubmitButton" } @@ -23,6 +24,7 @@ <%= render DS::Button.new( text: t(".delete_and_recategorize", category_name: @category.name), + type: :submit, data: { deletion_target: "safeSubmitButton" }, hidden: true, full_width: true diff --git a/app/views/coinstats_items/new.html.erb b/app/views/coinstats_items/new.html.erb index 40b90570b..5d163f86e 100644 --- a/app/views/coinstats_items/new.html.erb +++ b/app/views/coinstats_items/new.html.erb @@ -53,8 +53,7 @@ <% end %>
- <%= form.submit t(".link_wallet_submit"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %> + <%= form.submit t(".link_wallet_submit") %>
<% end %> @@ -90,8 +89,7 @@
- <%= form.submit t(".link_exchange_submit"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %> + <%= form.submit t(".link_exchange_submit") %>
<% end %> @@ -115,11 +113,13 @@
- <%= link_to settings_providers_path, - class: "w-full inline-flex items-center justify-center rounded-lg font-medium whitespace-nowrap rounded-lg hidden md:inline-flex px-3 py-2 text-sm text-inverse bg-inverse hover:bg-inverse-hover disabled:bg-gray-500 theme-dark:disabled:bg-gray-400", - data: { turbo: false } do %> - <%= t(".go_to_settings") %> - <% end %> + <%= render DS::Link.new( + text: t(".go_to_settings"), + href: settings_providers_path, + variant: :primary, + full_width: true, + data: { turbo: false } + ) %>
<% end %> diff --git a/app/views/enable_banking_items/new.html.erb b/app/views/enable_banking_items/new.html.erb index 625579939..2f7b481e9 100644 --- a/app/views/enable_banking_items/new.html.erb +++ b/app/views/enable_banking_items/new.html.erb @@ -53,11 +53,13 @@ <%= t(".reconnect") %> <% end %> <% else %> - <%= link_to select_bank_enable_banking_item_path(item), - class: "inline-flex items-center justify-center rounded-lg px-3 py-1.5 text-xs font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors", - data: { turbo_frame: "modal" } do %> - <%= t(".connect_bank") %> - <% end %> + <%= render DS::Link.new( + text: t(".connect_bank"), + href: select_bank_enable_banking_item_path(item), + variant: :primary, + size: :sm, + data: { turbo_frame: "modal" } + ) %> <% end %> <%= button_to enable_banking_item_path(item), @@ -73,13 +75,13 @@ <%# Add Connection button below the list - only show if we have a valid session to copy credentials from %> <% if item_for_new_connection %>
- <%= button_to new_connection_enable_banking_item_path(item_for_new_connection), - method: :post, - class: "inline-flex items-center gap-2 justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors", - data: { turbo_frame: "modal" } do %> - <%= icon "plus", size: "sm" %> - <%= t(".add_connection") %> - <% end %> + <%= render DS::Button.new( + text: t(".add_connection"), + icon: "plus", + href: new_connection_enable_banking_item_path(item_for_new_connection), + variant: :primary, + data: { turbo_method: :post, turbo_frame: "modal" } + ) %>
<% end %> @@ -104,11 +106,13 @@
- <%= link_to settings_providers_path, - class: "w-full inline-flex items-center justify-center rounded-lg font-medium whitespace-nowrap rounded-lg hidden md:inline-flex px-3 py-2 text-sm text-inverse bg-inverse hover:bg-inverse-hover disabled:bg-gray-500 theme-dark:disabled:bg-gray-400", - data: { turbo: false } do %> - <%= t(".go_to_provider_settings") %> - <% end %> + <%= render DS::Link.new( + text: t(".go_to_provider_settings"), + href: settings_providers_path, + variant: :primary, + full_width: true, + data: { turbo: false } + ) %>
<% end %> diff --git a/app/views/family_merchants/merge.html.erb b/app/views/family_merchants/merge.html.erb index d2fca9c7d..879118d56 100644 --- a/app/views/family_merchants/merge.html.erb +++ b/app/views/family_merchants/merge.html.erb @@ -26,6 +26,7 @@ <%= render DS::Button.new( text: t(".submit"), + type: :submit, full_width: true ) %> <% end %> diff --git a/app/views/holdings/_cost_basis_cell.html.erb b/app/views/holdings/_cost_basis_cell.html.erb index 0b82ca299..4ae265df4 100644 --- a/app/views/holdings/_cost_basis_cell.html.erb +++ b/app/views/holdings/_cost_basis_cell.html.erb @@ -17,8 +17,8 @@ <% else %> <%# Unlocked OR editable context (drawer) - show clickable menu %> - <%= render DS::Menu.new(variant: :button, placement: "bottom-end") do |menu| %> - <% menu.with_button(class: "hover:text-primary cursor-pointer group") do %> + <%= render DS::Popover.new(variant: :button, placement: "bottom-end") do |popover| %> + <% popover.with_button(class: "hover:text-primary cursor-pointer group") do %> <% if holding.avg_cost %>
<%= tag.span format_money(holding.avg_cost), class: "privacy-sensitive" %> @@ -34,7 +34,7 @@
<% end %> <% end %> - <% menu.with_custom_content do %> + <% popover.with_custom_content do %>
@@ -96,7 +96,7 @@
<%= f.submit t(".save"), class: "inline-flex items-center gap-1 px-2 py-1 rounded-md text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover" %> diff --git a/app/views/holdings/show.html.erb b/app/views/holdings/show.html.erb index 153166c2d..e382fda31 100644 --- a/app/views/holdings/show.html.erb +++ b/app/views/holdings/show.html.erb @@ -58,7 +58,7 @@
<% end %>
diff --git a/app/views/ibkr_items/_ibkr_item.html.erb b/app/views/ibkr_items/_ibkr_item.html.erb index 511550b5e..905eda0dd 100644 --- a/app/views/ibkr_items/_ibkr_item.html.erb +++ b/app/views/ibkr_items/_ibkr_item.html.erb @@ -32,7 +32,7 @@ <% elsif ibkr_item.sync_error.present? %>
- <%= render DS::Tooltip.new(text: ibkr_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive") %> + <%= render DS::Tooltip.new(text: ibkr_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive", as: :span) %> <%= tag.span t(".error"), class: "text-destructive" %>
<% else %> diff --git a/app/views/import/configurations/_actual_import.html.erb b/app/views/import/configurations/_actual_import.html.erb new file mode 100644 index 000000000..6b10d8a11 --- /dev/null +++ b/app/views/import/configurations/_actual_import.html.erb @@ -0,0 +1,27 @@ +<%# locals: (import:) %> + +
+ + <%= icon("check-circle", color: "current") %> + +

<%= t(".preconfigured_notice") %>

+
+ +<%= styled_form_with model: @import, url: import_configuration_path(@import), scope: :import, method: :patch, class: "space-y-4" do |form| %> +
+ <%= form.select :date_col_label, import.csv_headers, { include_blank: t(".leave_empty"), label: t(".date_label") }, required: true, disabled: import.complete? %> + <%= form.select :date_format, Family::DATE_FORMATS, { label: t(".date_format_label") }, label: true, required: true, disabled: import.complete? %> +
+ +
+ <%= form.select :amount_col_label, import.csv_headers, { include_blank: t(".leave_empty"), label: t(".amount_label") }, required: true, disabled: import.complete? %> + <%= form.select :signage_convention, [[t(".incomes_are_negative"), "inflows_negative"], [t(".incomes_are_positive"), "inflows_positive"]], { label: t(".signage_convention_label") }, disabled: import.complete? %> +
+ + <%= form.select :account_col_label, import.csv_headers, { include_blank: t(".leave_empty"), label: t(".account_label") }, disabled: import.complete? %> + <%= form.select :name_col_label, import.csv_headers, { include_blank: t(".leave_empty"), label: t(".name_label") }, disabled: import.complete? %> + <%= form.select :category_col_label, import.csv_headers, { include_blank: t(".leave_empty"), label: t(".category_label") }, disabled: import.complete? %> + <%= form.select :notes_col_label, import.csv_headers, { include_blank: t(".leave_empty"), label: t(".notes_label") }, disabled: import.complete? %> + + <%= form.submit t(".apply_configuration"), disabled: import.complete? %> +<% end %> diff --git a/app/views/import/confirms/show.html.erb b/app/views/import/confirms/show.html.erb index 1c89375be..8560b761d 100644 --- a/app/views/import/confirms/show.html.erb +++ b/app/views/import/confirms/show.html.erb @@ -31,8 +31,20 @@
- <%= button_to t("import.confirms.sure_import.publish_button"), publish_import_path(@import), method: :post, class: "btn btn--primary w-full", disabled: !@import.publishable? %> - <%= link_to t("import.confirms.sure_import.cancel"), imports_path, class: "btn btn--ghost w-full text-center" %> + <%= render DS::Button.new( + text: t("import.confirms.sure_import.publish_button"), + href: publish_import_path(@import), + variant: :primary, + full_width: true, + disabled: !@import.publishable?, + data: { turbo_method: :post } + ) %> + <%= render DS::Link.new( + text: t("import.confirms.sure_import.cancel"), + href: imports_path, + variant: :ghost, + full_width: true + ) %>
<% else %> diff --git a/app/views/import/uploads/show.html.erb b/app/views/import/uploads/show.html.erb index 56a5e320b..7cf51d651 100644 --- a/app/views/import/uploads/show.html.erb +++ b/app/views/import/uploads/show.html.erb @@ -109,7 +109,7 @@ <% tabs.with_panel(tab_id: "csv-upload") do %> <%= styled_form_with model: @import, scope: :import, url: import_upload_path(@import), multipart: true, class: "space-y-2", data: { drag_and_drop_import_target: "form" } do |form| %> - <%= form.select :col_sep, Import::SEPARATORS, label: true %> + <%= form.select :col_sep, Import.separator_options, label: true %> <% if @import.type == "TransactionImport" || @import.type == "TradeImport" %> <%= form.select :account_id, @import.family.accounts.visible.alphabetically.pluck(:name, :id), { label: t(".account_optional_label"), include_blank: t(".multi_account_import"), selected: @import.account_id } %> @@ -141,7 +141,7 @@ <% tabs.with_panel(tab_id: "csv-paste") do %> <%= styled_form_with model: @import, scope: :import, url: import_upload_path(@import), multipart: true, class: "space-y-2" do |form| %> - <%= form.select :col_sep, Import::SEPARATORS, label: true %> + <%= form.select :col_sep, Import.separator_options, label: true %> <% if @import.type == "TransactionImport" || @import.type == "TradeImport" %> <%= form.select :account_id, @import.family.accounts.visible.alphabetically.pluck(:name, :id), { label: t(".account_optional_label"), include_blank: t(".multi_account_import"), selected: @import.account_id } %> diff --git a/app/views/imports/_success.html.erb b/app/views/imports/_success.html.erb index c3bc2d1eb..329977a91 100644 --- a/app/views/imports/_success.html.erb +++ b/app/views/imports/_success.html.erb @@ -2,7 +2,7 @@
-
+
<%= icon "check", color: "success" %>
@@ -11,6 +11,39 @@

<%= t(".description") %>

+ <% if import.is_a?(SureImport) %> + <% verification = import_verification_view(import) %> + +
+
+

<%= t(".verification.title") %>

+ <%= t(".verification.status.#{verification.status}", default: verification.status.humanize) %> +
+ +
+
+

<%= t(".verification.checked") %>

+

<%= number_with_delimiter(verification.checked_total) %>

+
+
+

<%= t(".verification.mismatches") %>

+

<%= number_with_delimiter(verification.mismatches_count) %>

+
+
+ + <% if verification.mismatches? %> +
+ <% verification.mismatches_preview.each do |key, counts| %> +
+ <%= key.humanize %> + <%= number_with_delimiter(counts["actual"]) %> / <%= number_with_delimiter(counts["expected"]) %> +
+ <% end %> +
+ <% end %> +
+ <% end %> + <%= render DS::Link.new( text: t(".back_to_dashboard"), variant: "primary", diff --git a/app/views/imports/new.html.erb b/app/views/imports/new.html.erb index 84d235a15..e71d84b6f 100644 --- a/app/views/imports/new.html.erb +++ b/app/views/imports/new.html.erb @@ -31,7 +31,7 @@ <% import_type = params[:type].presence || @pending_import&.type - active_tab = import_type.present? && !import_type.in?(%w[MintImport QifImport SureImport DocumentImport PdfImport]) ? "raw_data" : "financial_tools" + active_tab = import_type.present? && !import_type.in?(%w[MintImport ActualImport QifImport SureImport DocumentImport PdfImport]) ? "raw_data" : "financial_tools" %> <%= render DS::Tabs.new(active_tab: active_tab) do |tabs| %> <% tabs.with_nav do |nav| %> @@ -42,7 +42,7 @@ <% tabs.with_panel(tab_id: "financial_tools") do %>
    - <% if @pending_import.present? && params[:type].present? && params[:type].in?(%w[MintImport QifImport SureImport DocumentImport PdfImport]) %> + <% if @pending_import.present? && params[:type].present? && params[:type].in?(%w[MintImport ActualImport QifImport SureImport DocumentImport PdfImport]) %>
  • <%= link_to import_path(@pending_import), class: "flex items-center justify-between p-4 group cursor-pointer", data: { turbo: false } do %>
    @@ -99,6 +99,16 @@ enabled: true %> <% end %> + <% if params[:type].nil? || params[:type] == "ActualImport" %> + <%= render "imports/import_option", + type: "ActualImport", + icon_name: "wallet", + icon_bg_class: "bg-emerald-500/5", + icon_text_class: "text-emerald-500", + label: t(".import_actual"), + enabled: true %> + <% end %> + <% if params[:type].nil? || params[:type] == "QifImport" %> <%= render "imports/import_option", type: "QifImport", @@ -153,7 +163,7 @@ <% tabs.with_panel(tab_id: "raw_data") do %>
      - <% if @pending_import.present? && params[:type].present? && !params[:type].in?(%w[MintImport QifImport SureImport DocumentImport PdfImport]) %> + <% if @pending_import.present? && params[:type].present? && !params[:type].in?(%w[MintImport ActualImport QifImport SureImport DocumentImport PdfImport]) %>
    • <%= link_to import_path(@pending_import), class: "flex items-center justify-between p-4 group cursor-pointer", data: { turbo: false } do %>
      diff --git a/app/views/indexa_capital_items/_indexa_capital_item.html.erb b/app/views/indexa_capital_items/_indexa_capital_item.html.erb index e6f608e33..7f90af7bd 100644 --- a/app/views/indexa_capital_items/_indexa_capital_item.html.erb +++ b/app/views/indexa_capital_items/_indexa_capital_item.html.erb @@ -34,7 +34,7 @@
      <% elsif indexa_capital_item.sync_error.present? %>
      - <%= render DS::Tooltip.new(text: indexa_capital_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive") %> + <%= render DS::Tooltip.new(text: indexa_capital_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive", as: :span) %> <%= tag.span t(".error"), class: "text-destructive" %>
      <% else %> diff --git a/app/views/indexa_capital_items/select_existing_account.html.erb b/app/views/indexa_capital_items/select_existing_account.html.erb index 7b0f46764..bb6535672 100644 --- a/app/views/indexa_capital_items/select_existing_account.html.erb +++ b/app/views/indexa_capital_items/select_existing_account.html.erb @@ -14,7 +14,13 @@ <%= icon "alert-circle", class: "text-warning mx-auto mb-4", size: "lg" %>

      <%= t("indexa_capital_items.select_existing_account.no_accounts") %>

      <%= t("indexa_capital_items.select_existing_account.connect_hint") %>

      - <%= link_to t("indexa_capital_items.select_existing_account.settings_link"), settings_providers_path, class: "btn btn--primary btn--sm mt-4" %> + <%= render DS::Link.new( + text: t("indexa_capital_items.select_existing_account.settings_link"), + href: settings_providers_path, + variant: :primary, + size: :sm, + class: "mt-4" + ) %>
    <% else %>
    diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 16457cc86..bc48fb234 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -152,7 +152,7 @@ end %> <% if content_for?(:breadcrumbs) %> <%= yield :breadcrumbs %> <% else %> - <%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs %> + <%= render "layouts/shared/breadcrumbs", breadcrumbs: breadcrumbs %> <% end %>
    diff --git a/app/views/layouts/settings.html.erb b/app/views/layouts/settings.html.erb index 1c8a65a79..887789332 100644 --- a/app/views/layouts/settings.html.erb +++ b/app/views/layouts/settings.html.erb @@ -16,7 +16,7 @@ <% if content_for?(:breadcrumbs) %> <%= yield :breadcrumbs %> <% else %> - <%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs %> + <%= render "layouts/shared/breadcrumbs", breadcrumbs: breadcrumbs %> <% end %>
    diff --git a/app/views/layouts/shared/_confirm_dialog.html.erb b/app/views/layouts/shared/_confirm_dialog.html.erb index a25c36f72..cefc5aa13 100644 --- a/app/views/layouts/shared/_confirm_dialog.html.erb +++ b/app/views/layouts/shared/_confirm_dialog.html.erb @@ -17,6 +17,7 @@ <%= render DS::Button.new( text: t(".confirm"), variant: variant, + type: :submit, autofocus: true, full_width: true, value: "confirm", diff --git a/app/views/lunchflow_items/_api_error.html.erb b/app/views/lunchflow_items/_api_error.html.erb index 50050e35a..7a1e2c352 100644 --- a/app/views/lunchflow_items/_api_error.html.erb +++ b/app/views/lunchflow_items/_api_error.html.erb @@ -21,11 +21,12 @@
    - <%= link_to settings_providers_path, - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors", - data: { turbo: false } do %> - <%= t(".check_provider_settings") %> - <% end %> + <%= render DS::Link.new( + text: t(".check_provider_settings"), + href: settings_providers_path, + variant: :primary, + data: { turbo: false } + ) %>
    <% end %> diff --git a/app/views/lunchflow_items/_lunchflow_item.html.erb b/app/views/lunchflow_items/_lunchflow_item.html.erb index a1aec313b..0b0fecc76 100644 --- a/app/views/lunchflow_items/_lunchflow_item.html.erb +++ b/app/views/lunchflow_items/_lunchflow_item.html.erb @@ -35,7 +35,7 @@
<% elsif lunchflow_item.sync_error.present? %>
- <%= render DS::Tooltip.new(text: lunchflow_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive") %> + <%= render DS::Tooltip.new(text: lunchflow_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive", as: :span) %> <%= tag.span t(".error"), class: "text-destructive" %>
<% else %> diff --git a/app/views/lunchflow_items/_setup_required.html.erb b/app/views/lunchflow_items/_setup_required.html.erb index 1773e81ef..f53dce376 100644 --- a/app/views/lunchflow_items/_setup_required.html.erb +++ b/app/views/lunchflow_items/_setup_required.html.erb @@ -20,11 +20,12 @@
- <%= link_to settings_providers_path, - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors", - data: { turbo: false } do %> - <%= t(".go_to_provider_settings") %> - <% end %> + <%= render DS::Link.new( + text: t(".go_to_provider_settings"), + href: settings_providers_path, + variant: :primary, + data: { turbo: false } + ) %>
<% end %> diff --git a/app/views/lunchflow_items/select_accounts.html.erb b/app/views/lunchflow_items/select_accounts.html.erb index 9399bef0f..dc9f5aba5 100644 --- a/app/views/lunchflow_items/select_accounts.html.erb +++ b/app/views/lunchflow_items/select_accounts.html.erb @@ -46,8 +46,11 @@ <%= link_to t(".cancel"), @return_to || new_account_path, class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover", data: { turbo_frame: "_top", action: "DS--dialog#close" } %> - <%= submit_tag t(".link_accounts"), - class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %> + <%= render DS::Button.new( + text: t(".link_accounts"), + variant: :primary, + type: :submit + ) %> diff --git a/app/views/lunchflow_items/select_existing_account.html.erb b/app/views/lunchflow_items/select_existing_account.html.erb index 3dc778517..07f8227eb 100644 --- a/app/views/lunchflow_items/select_existing_account.html.erb +++ b/app/views/lunchflow_items/select_existing_account.html.erb @@ -46,8 +46,11 @@ <%= link_to t(".cancel"), @return_to || accounts_path, class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover", data: { turbo_frame: "_top", action: "DS--dialog#close" } %> - <%= submit_tag t(".link_account"), - class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %> + <%= render DS::Button.new( + text: t(".link_account"), + variant: :primary, + type: :submit + ) %> diff --git a/app/views/mercury_items/_api_error.html.erb b/app/views/mercury_items/_api_error.html.erb index 0f5696b14..7b736eab6 100644 --- a/app/views/mercury_items/_api_error.html.erb +++ b/app/views/mercury_items/_api_error.html.erb @@ -24,11 +24,12 @@
- <%= link_to settings_providers_path, - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors", - data: { turbo: false } do %> - <%= t(".check_provider_settings") %> - <% end %> + <%= render DS::Link.new( + text: t(".check_provider_settings"), + href: settings_providers_path, + variant: :primary, + data: { turbo: false } + ) %>
<% end %> diff --git a/app/views/mercury_items/_mercury_item.html.erb b/app/views/mercury_items/_mercury_item.html.erb index 0159551e8..6485da548 100644 --- a/app/views/mercury_items/_mercury_item.html.erb +++ b/app/views/mercury_items/_mercury_item.html.erb @@ -35,7 +35,7 @@ <% elsif mercury_item.sync_error.present? %>
- <%= render DS::Tooltip.new(text: mercury_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive") %> + <%= render DS::Tooltip.new(text: mercury_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive", as: :span) %> <%= tag.span t(".error"), class: "text-destructive" %>
<% else %> diff --git a/app/views/mercury_items/_setup_required.html.erb b/app/views/mercury_items/_setup_required.html.erb index 5711d968d..3738a1fce 100644 --- a/app/views/mercury_items/_setup_required.html.erb +++ b/app/views/mercury_items/_setup_required.html.erb @@ -22,11 +22,12 @@
- <%= link_to settings_providers_path, - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors", - data: { turbo: false } do %> - <%= t(".go_to_provider_settings") %> - <% end %> + <%= render DS::Link.new( + text: t(".go_to_provider_settings"), + href: settings_providers_path, + variant: :primary, + data: { turbo: false } + ) %>
<% end %> diff --git a/app/views/mercury_items/select_accounts.html.erb b/app/views/mercury_items/select_accounts.html.erb index 5e80783c6..4b48c7720 100644 --- a/app/views/mercury_items/select_accounts.html.erb +++ b/app/views/mercury_items/select_accounts.html.erb @@ -48,8 +48,11 @@ <%= link_to t(".cancel"), @return_to || new_account_path, class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover", data: { turbo_frame: "_top", action: "DS--dialog#close" } %> - <%= submit_tag t(".link_accounts"), - class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %> + <%= render DS::Button.new( + text: t(".link_accounts"), + variant: :primary, + type: :submit + ) %> diff --git a/app/views/mercury_items/select_existing_account.html.erb b/app/views/mercury_items/select_existing_account.html.erb index e66266e61..2641de1a5 100644 --- a/app/views/mercury_items/select_existing_account.html.erb +++ b/app/views/mercury_items/select_existing_account.html.erb @@ -48,8 +48,11 @@ <%= link_to t(".cancel"), @return_to || accounts_path, class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover", data: { turbo_frame: "_top", action: "DS--dialog#close" } %> - <%= submit_tag t(".link_account"), - class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %> + <%= render DS::Button.new( + text: t(".link_account"), + variant: :primary, + type: :submit + ) %> diff --git a/app/views/onboardings/goals.html.erb b/app/views/onboardings/goals.html.erb index 646a892d1..8cb36cd99 100644 --- a/app/views/onboardings/goals.html.erb +++ b/app/views/onboardings/goals.html.erb @@ -46,6 +46,7 @@
<%= render DS::Button.new( text: t("onboardings.goals.submit"), + type: :submit, full_width: true ) %>
diff --git a/app/views/pages/dashboard/_balance_sheet.html.erb b/app/views/pages/dashboard/_balance_sheet.html.erb index b2ff7d632..1c104fa28 100644 --- a/app/views/pages/dashboard/_balance_sheet.html.erb +++ b/app/views/pages/dashboard/_balance_sheet.html.erb @@ -118,10 +118,10 @@ ) %>

- <%= t("pages.dashboard.balance_sheet.no_items", name: classification_group.name) %> + <%= t("pages.dashboard.balance_sheet.no_#{classification_group.classification}") %>

- <%= t("pages.dashboard.balance_sheet.add_accounts", name: classification_group.name) %> + <%= t("pages.dashboard.balance_sheet.add_#{classification_group.classification}_accounts") %>

<% end %> diff --git a/app/views/pages/dashboard/_cashflow_sankey.html.erb b/app/views/pages/dashboard/_cashflow_sankey.html.erb index 5ec8de5ee..201e0c8b9 100644 --- a/app/views/pages/dashboard/_cashflow_sankey.html.erb +++ b/app/views/pages/dashboard/_cashflow_sankey.html.erb @@ -11,21 +11,13 @@ <% if sankey_data[:links].present? %>
-
+ <%= render "pages/dashboard/cashflow_sankey_chart", sankey_data: sankey_data %>
<%= render DS::Dialog.new(id: "cashflow-expanded-dialog", auto_open: false, width: "custom", disable_frame: true, content_class: "!w-[96vw] max-w-[1650px]", data: { action: "close->cashflow-expand#restore" }) do |dialog| %> <% dialog.with_header(title: t("pages.dashboard.cashflow_sankey.title")) %> <% dialog.with_body do %>
-
+ <%= render "pages/dashboard/cashflow_sankey_chart", sankey_data: sankey_data %>
<% end %> <% end %> diff --git a/app/views/pages/dashboard/_cashflow_sankey_chart.html.erb b/app/views/pages/dashboard/_cashflow_sankey_chart.html.erb new file mode 100644 index 000000000..d22b305ce --- /dev/null +++ b/app/views/pages/dashboard/_cashflow_sankey_chart.html.erb @@ -0,0 +1,22 @@ +<%# locals: (sankey_data:) %> +
+
+ <%= render DS::Button.new( + variant: :icon, + icon: "arrow-left", + type: "button", + title: t("pages.dashboard.cashflow_sankey.zoom_out"), + aria: { label: t("pages.dashboard.cashflow_sankey.zoom_out") }, + hidden: true, + data: { + sankey_chart_target: "zoomOutButton", + action: "sankey-chart#zoomOut" + } + ) %> +
+
+
diff --git a/app/views/pages/intro.html.erb b/app/views/pages/intro.html.erb index 7378ccdeb..7c014008e 100644 --- a/app/views/pages/intro.html.erb +++ b/app/views/pages/intro.html.erb @@ -15,7 +15,11 @@ <%= t(".description") %>

- <%= link_to t(".start_chatting"), chats_path, class: "inline-flex items-center gap-2 px-4 py-2 rounded-lg button-bg-primary text-inverse font-medium" %> + <%= render DS::Link.new( + text: t(".start_chatting"), + href: chats_path, + variant: :primary + ) %>
diff --git a/app/views/plaid_items/select_existing_account.html.erb b/app/views/plaid_items/select_existing_account.html.erb index 8b0cde2bc..088d5bf11 100644 --- a/app/views/plaid_items/select_existing_account.html.erb +++ b/app/views/plaid_items/select_existing_account.html.erb @@ -35,8 +35,11 @@ <%= link_to t(".cancel"), accounts_path, class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover", data: { turbo_frame: "_top", action: "DS--dialog#close" } %> - <%= submit_tag t(".link_account"), - class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %> + <%= render DS::Button.new( + text: t(".link_account"), + variant: :primary, + type: :submit + ) %> diff --git a/app/views/properties/address.html.erb b/app/views/properties/address.html.erb index 489ab62b1..a8b873c7c 100644 --- a/app/views/properties/address.html.erb +++ b/app/views/properties/address.html.erb @@ -41,6 +41,7 @@ <%= render DS::Button.new( text: t(".save"), variant: "primary", + type: :submit, ) %> <% end %> diff --git a/app/views/properties/balances.html.erb b/app/views/properties/balances.html.erb index 3cd96041d..9477213f7 100644 --- a/app/views/properties/balances.html.erb +++ b/app/views/properties/balances.html.erb @@ -21,6 +21,7 @@ <%= render DS::Button.new( text: @account.active? ? t(".save") : t(".next"), variant: "primary", + type: :submit, ) %> <% end %> diff --git a/app/views/properties/edit.html.erb b/app/views/properties/edit.html.erb index 51d674f96..428e60059 100644 --- a/app/views/properties/edit.html.erb +++ b/app/views/properties/edit.html.erb @@ -18,6 +18,7 @@ <%= render DS::Button.new( text: @account.active? ? "Save" : "Next", variant: "primary", + type: :submit, ) %> <% end %> diff --git a/app/views/properties/new.html.erb b/app/views/properties/new.html.erb index 32ab6d960..5e790cce0 100644 --- a/app/views/properties/new.html.erb +++ b/app/views/properties/new.html.erb @@ -18,6 +18,7 @@ <%= render DS::Button.new( text: t(".next"), variant: "primary", + type: :submit, ) %> <% end %> diff --git a/app/views/reports/index.html.erb b/app/views/reports/index.html.erb index 55ae1a8bb..f66ce7788 100644 --- a/app/views/reports/index.html.erb +++ b/app/views/reports/index.html.erb @@ -115,13 +115,13 @@ <% if [:monthly, :quarterly, :ytd].include?(@period_type) %> - <%= render DS::Menu.new(variant: "button") do |menu| %> - <% menu.with_button class: "flex items-center gap-1 hover:bg-alpha-black-25 cursor-pointer rounded-md p-2" do %> + <%= render DS::Popover.new(variant: "button") do |popover| %> + <% popover.with_button class: "flex items-center gap-1 hover:bg-alpha-black-25 cursor-pointer rounded-md p-2" do %> <%= @nav[:label] %> <%= icon("chevron-down") %> <% end %> - <% menu.with_custom_content do %> + <% popover.with_custom_content do %> <%= render "reports/period_picker", period_type: @period_type, start_date: @start_date %> <% end %> <% end %> diff --git a/app/views/rules/_category_rule_cta.html.erb b/app/views/rules/_category_rule_cta.html.erb index ff3481f4d..3c7f2ed41 100644 --- a/app/views/rules/_category_rule_cta.html.erb +++ b/app/views/rules/_category_rule_cta.html.erb @@ -13,7 +13,7 @@ <%= f.hidden_field :rule_prompt_dismissed_at, value: Time.current %> <%= tag.div class:"flex gap-2 justify-end" do %> - <%= render DS::Button.new(text: "Dismiss", variant: "secondary") %> + <%= render DS::Button.new(text: "Dismiss", variant: "secondary", type: :submit) %> <% rule_href = new_rule_path(resource_type: "transaction", action_type: "set_transaction_category", action_value: cta[:category_id], name: cta[:merchant_name]) %> <%= render DS::Link.new(text: "Create rule", variant: "primary", href: rule_href, frame: :modal) %> <% end %> diff --git a/app/views/settings/_settings_nav.html.erb b/app/views/settings/_settings_nav.html.erb index f72cbc196..f9e5e975b 100644 --- a/app/views/settings/_settings_nav.html.erb +++ b/app/views/settings/_settings_nav.html.erb @@ -30,6 +30,7 @@ nav_sections = [ { label: t(".ai_prompts_label"), path: settings_ai_prompts_path, icon: "bot" }, { label: t(".llm_usage_label"), path: settings_llm_usage_path, icon: "activity" }, { label: t(".api_keys_label"), path: settings_api_key_path, icon: "key" }, + { label: t(".debug_label", default: "Debug"), path: settings_debug_path, icon: "bug", if: Current.user&.super_admin? }, { label: t(".self_hosting_label"), path: settings_hosting_path, icon: "database", if: self_hosted? }, { label: t(".imports_label"), path: imports_path, icon: "download" }, { label: t(".exports_label"), path: family_exports_path, icon: "upload" }, diff --git a/app/views/settings/debugs/show.html.erb b/app/views/settings/debugs/show.html.erb new file mode 100644 index 000000000..252ec4ed5 --- /dev/null +++ b/app/views/settings/debugs/show.html.erb @@ -0,0 +1,113 @@ +<%= content_for :page_title, t(".page_title") %> + +
+
+

<%= t(".title") %>

+

<%= t(".subtitle") %>

+
+ +
+ <%= form_with url: settings_debug_path, method: :get, class: "grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4 items-end" do |f| %> +
+ <%= f.label :category, t(".filters.category"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.select :category, options_for_select([[t(".filters.all"), ""]] + @categories.map { |value| [value, value] }, params[:category]), {}, class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full" %> +
+
+ <%= f.label :level, t(".filters.level"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.select :level, options_for_select([[t(".filters.all"), ""]] + @levels.map { |value| [value, value] }, params[:level]), {}, class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full" %> +
+
+ <%= f.label :source, t(".filters.source"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.select :source, options_for_select([[t(".filters.all"), ""]] + @sources.map { |value| [value, value] }, params[:source]), {}, class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full" %> +
+
+ <%= f.label :provider_key, t(".filters.provider"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.select :provider_key, options_for_select([[t(".filters.all"), ""]] + @provider_keys.map { |value| [value, value] }, params[:provider_key]), {}, class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full" %> +
+
+ <%= f.label :start_date, t(".filters.start_date"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.date_field :start_date, value: @start_date || params[:start_date], class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full" %> +
+
+ <%= f.label :end_date, t(".filters.end_date"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.date_field :end_date, value: @end_date || params[:end_date], class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full" %> +
+
+ <%= f.label :family_id, t(".filters.family_id"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.text_field :family_id, value: params[:family_id], class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full font-mono" %> +
+
+ <%= f.label :account_id, t(".filters.account_id"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.text_field :account_id, value: params[:account_id], class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full font-mono" %> +
+
+ <%= f.label :user_id, t(".filters.user_id"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.text_field :user_id, value: params[:user_id], class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full font-mono" %> +
+
+ <%= f.label :account_provider_id, t(".filters.account_provider_id"), class: "block text-sm font-medium text-primary mb-1" %> + <%= f.text_field :account_provider_id, value: params[:account_provider_id], class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container-inset text-primary w-full font-mono" %> +
+
+ <%= render DS::Button.new(variant: :primary, size: :md, type: "submit", text: t(".filters.submit"), class: "justify-center") %> + <%= render DS::Link.new(text: t(".filters.reset"), href: settings_debug_path, variant: "ghost") %> +
+ <% end %> +
+ +
+ <% if @debug_log_entries.any? %> +
+ + + + + + + + + + + + + + <% @debug_log_entries.each do |entry| %> + + + + + + + + + + <% end %> + +
<%= t(".table.time") %><%= t(".table.level") %><%= t(".table.category") %><%= t(".table.source") %><%= t(".table.message") %><%= t(".table.context") %><%= t(".table.metadata") %>
<%= l(entry.created_at, format: :long) %><%= entry.level %><%= entry.category %><%= entry.source %><%= entry.message %> +
<%= t(".context.provider", value: entry.provider_key.presence || t(".missing_value")) %>
+
<%= t(".context.family", value: entry.family_id || t(".missing_value")) %>
+
<%= t(".context.account", value: entry.account_id || t(".missing_value")) %>
+
<%= t(".context.user", value: entry.user_id || t(".missing_value")) %>
+
<%= t(".context.account_provider", value: entry.account_provider_id || t(".missing_value")) %>
+
+ <% if entry.metadata.present? %> +
+ <%= t(".table.view_metadata") %> +
<%= JSON.pretty_generate(entry.metadata) %>
+
+ <% else %> + <%= t(".missing_value") %> + <% end %> +
+
+ <% else %> +
<%= t(".empty") %>
+ <% end %> +
+ + <% if @pagy.pages > 1 %> +
+ <%= render "shared/pagination", pagy: @pagy %> +
+ <% end %> +
diff --git a/app/views/settings/preferences/show.html.erb b/app/views/settings/preferences/show.html.erb index 4e52431dd..d2e0fd9a1 100644 --- a/app/views/settings/preferences/show.html.erb +++ b/app/views/settings/preferences/show.html.erb @@ -25,7 +25,7 @@ { label: t(".country") }, { data: { auto_submit_form_target: "auto" } } %> <%= family_form.select :month_start_day, - (1..28).map { |day| [day.ordinalize, day] }, + (1..28).map { |day| [localized_ordinal(day), day] }, { label: t(".month_start_day"), hint: t(".month_start_day_hint") }, { data: { auto_submit_form_target: "auto" } } %> <% if @user.family.uses_custom_month_start? %> @@ -33,7 +33,7 @@ <%= t(".month_start_day_warning") %> <% end %> -

Please note, we are still working on translations for various languages.

+

<%= t(".translations_notice") %>

<% end %> <% end %> @@ -182,7 +182,7 @@
<%= render DS::Button.new(text: t("shared.cancel"), type: :button, variant: :ghost, data: { action: "DS--dialog#close" }) %> - <%= render DS::Button.new(text: t(".save_currencies")) %> + <%= render DS::Button.new(text: t(".save_currencies"), type: :submit) %>
<% end %> <% end %> @@ -206,3 +206,29 @@ <% end %> <% end %> + +<%# Preview features toggle — visible to all users, not just admins. Lives at + the bottom of Preferences as a standalone card (no section header) so the + toggle row is the entire surface. Posts directly to + settings#preferences#update via the Settings::PreferencesController, + matching the auto-submit pattern used on the Appearance page. %> +
+ <%= form_with url: settings_preferences_path, method: :patch, + data: { controller: "auto-submit-form" } do |f| %> + <%# Wrapping the row in
diff --git a/app/views/settings/profiles/show.html.erb b/app/views/settings/profiles/show.html.erb index 245ac27db..5c431449d 100644 --- a/app/views/settings/profiles/show.html.erb +++ b/app/views/settings/profiles/show.html.erb @@ -19,19 +19,19 @@
- <%= render DS::Button.new(text: t(".save"), class: "md:w-auto w-full justify-center") %> + <%= render DS::Button.new(text: t(".save"), type: :submit, class: "md:w-auto w-full justify-center") %>
<% end %> <% end %> <% unless Current.user.ui_layout_intro? %> - <%= settings_section title: family_moniker == "Group" ? t(".group_title", default: "Group") : t(".household_title"), subtitle: t(".household_subtitle", moniker_plural: family_moniker_plural_downcase, moniker: family_moniker_downcase) do %> + <%= settings_section title: Current.family&.moniker == "Group" ? t(".group_title", default: "Group") : t(".household_title"), subtitle: t(".household_subtitle", moniker_plural: family_moniker_plural_downcase, moniker: family_moniker_downcase) do %>
<%= styled_form_with model: Current.user, class: "space-y-4", data: { controller: "auto-submit-form" } do |form| %> <%= form.fields_for :family do |family_fields| %> - <% name_label = family_moniker == "Group" ? t(".group_form_label", default: "Group name") : t(".household_form_label") %> - <% name_placeholder = family_moniker == "Group" ? t(".group_form_input_placeholder", default: "Enter group name") : t(".household_form_input_placeholder") %> + <% name_label = Current.family&.moniker == "Group" ? t(".group_form_label", default: "Group name") : t(".household_form_label") %> + <% name_placeholder = Current.family&.moniker == "Group" ? t(".group_form_input_placeholder", default: "Enter group name") : t(".household_form_input_placeholder") %> <%= family_fields.text_field :name, placeholder: name_placeholder, label: name_label, @@ -50,7 +50,7 @@

<%= user.display_name %>

-

<%= user.role %>

+

<%= t("users.roles.#{user.role}", default: user.role.humanize) %>

<% if Current.user.admin? && user != Current.user %>
diff --git a/app/views/settings/providers/_binance_panel.html.erb b/app/views/settings/providers/_binance_panel.html.erb index 49b8cd0d4..578573188 100644 --- a/app/views/settings/providers/_binance_panel.html.erb +++ b/app/views/settings/providers/_binance_panel.html.erb @@ -93,8 +93,7 @@ type: :password %>
- <%= form.submit t("settings.providers.binance_panel.connect_button"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 transition-colors" %> + <%= form.submit t("settings.providers.binance_panel.connect_button") %>
<% end %> <% end %> diff --git a/app/views/settings/providers/_brex_panel.html.erb b/app/views/settings/providers/_brex_panel.html.erb index 3954c60f3..5b87ad38e 100644 --- a/app/views/settings/providers/_brex_panel.html.erb +++ b/app/views/settings/providers/_brex_panel.html.erb @@ -98,8 +98,7 @@ href: setup_accounts_brex_item_path(item), frame: :modal ) %> - <%= form.submit t("brex_items.provider_panel.update_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %> + <%= form.submit t("brex_items.provider_panel.update_connection") %>
<% end %> @@ -136,8 +135,7 @@ placeholder: t("brex_items.provider_panel.base_url_placeholder") %>
- <%= form.submit t("brex_items.provider_panel.add_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %> + <%= form.submit t("brex_items.provider_panel.add_connection") %>
<% end %> diff --git a/app/views/settings/providers/_coinbase_panel.html.erb b/app/views/settings/providers/_coinbase_panel.html.erb index 546d32626..82cb7d473 100644 --- a/app/views/settings/providers/_coinbase_panel.html.erb +++ b/app/views/settings/providers/_coinbase_panel.html.erb @@ -72,8 +72,7 @@ type: :password %>
- <%= form.submit t("settings.providers.coinbase_panel.connect_button"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 transition-colors" %> + <%= form.submit t("settings.providers.coinbase_panel.connect_button") %>
<% end %> <% end %> diff --git a/app/views/settings/providers/_coinstats_panel.html.erb b/app/views/settings/providers/_coinstats_panel.html.erb index b9e62b071..d545c9952 100644 --- a/app/views/settings/providers/_coinstats_panel.html.erb +++ b/app/views/settings/providers/_coinstats_panel.html.erb @@ -32,8 +32,7 @@ type: :password %>
- <%= form.submit is_new_record ? t("coinstats_items.new.configure") : t("coinstats_items.new.update_configuration"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 transition-colors" %> + <%= form.submit is_new_record ? t("coinstats_items.new.configure") : t("coinstats_items.new.update_configuration") %>
<% end %> diff --git a/app/views/settings/providers/_enable_banking_panel.html.erb b/app/views/settings/providers/_enable_banking_panel.html.erb index b73009f96..9b2fb2381 100644 --- a/app/views/settings/providers/_enable_banking_panel.html.erb +++ b/app/views/settings/providers/_enable_banking_panel.html.erb @@ -90,8 +90,7 @@ disabled: has_authenticated_connections && !is_new_record %>
- <%= form.submit is_new_record ? t("settings.providers.enable_banking_panel.save_and_connect") : t("settings.providers.enable_banking_panel.update_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %> + <%= form.submit is_new_record ? t("settings.providers.enable_banking_panel.save_and_connect") : t("settings.providers.enable_banking_panel.update_connection") %>
<% end %> @@ -158,11 +157,13 @@ <%= t("settings.providers.enable_banking_panel.reconnect") %> <% end %> <% else %> - <%= link_to select_bank_enable_banking_item_path(item), - class: "inline-flex items-center justify-center rounded-lg px-3 py-1.5 text-xs font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors", - data: { turbo_frame: "modal" } do %> - <%= t("settings.providers.enable_banking_panel.connect_bank") %> - <% end %> + <%= render DS::Link.new( + text: t("settings.providers.enable_banking_panel.connect_bank"), + href: select_bank_enable_banking_item_path(item), + variant: :primary, + size: :sm, + data: { turbo_frame: "modal" } + ) %> <% end %> <%= button_to enable_banking_item_path(item), @@ -178,13 +179,13 @@ <%# Add Connection button below the list - only show if we have a valid session to copy credentials from %> <% if item_for_new_connection %>
- <%= button_to new_connection_enable_banking_item_path(item_for_new_connection), - method: :post, - class: "inline-flex items-center gap-2 justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors", - data: { turbo_frame: "modal" } do %> - <%= icon "plus", size: "sm" %> - <%= t("settings.providers.enable_banking_panel.add_connection") %> - <% end %> + <%= render DS::Button.new( + text: t("settings.providers.enable_banking_panel.add_connection"), + icon: "plus", + href: new_connection_enable_banking_item_path(item_for_new_connection), + variant: :primary, + data: { turbo_method: :post, turbo_frame: "modal" } + ) %>
<% end %> diff --git a/app/views/settings/providers/_ibkr_panel.html.erb b/app/views/settings/providers/_ibkr_panel.html.erb index d20d03f31..578c6af34 100644 --- a/app/views/settings/providers/_ibkr_panel.html.erb +++ b/app/views/settings/providers/_ibkr_panel.html.erb @@ -132,7 +132,7 @@ type: :password %>
- <%= form.submit(is_new_record ? t(".save_configuration") : t(".update_configuration"), class: "btn btn--primary") %> + <%= form.submit(is_new_record ? t(".save_configuration") : t(".update_configuration")) %>
<% end %> diff --git a/app/views/settings/providers/_indexa_capital_panel.html.erb b/app/views/settings/providers/_indexa_capital_panel.html.erb index c0fbdcaf1..c751e0feb 100644 --- a/app/views/settings/providers/_indexa_capital_panel.html.erb +++ b/app/views/settings/providers/_indexa_capital_panel.html.erb @@ -53,7 +53,7 @@
<%= form.submit is_new_record ? t("indexa_capital_items.panel.save_button") : t("indexa_capital_items.panel.update_button"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium btn btn--primary" %> + class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium" %>
<% end %> diff --git a/app/views/settings/providers/_kraken_panel.html.erb b/app/views/settings/providers/_kraken_panel.html.erb index 7de8e7831..8490b1c49 100644 --- a/app/views/settings/providers/_kraken_panel.html.erb +++ b/app/views/settings/providers/_kraken_panel.html.erb @@ -93,8 +93,7 @@ value: nil %>
- <%= form.submit t("settings.providers.kraken_panel.update_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %> + <%= form.submit t("settings.providers.kraken_panel.update_connection") %>
<% end %> @@ -134,8 +133,7 @@ value: nil %>
- <%= form.submit t("settings.providers.kraken_panel.add_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %> + <%= form.submit t("settings.providers.kraken_panel.add_connection") %>
<% end %> diff --git a/app/views/settings/providers/_lunchflow_panel.html.erb b/app/views/settings/providers/_lunchflow_panel.html.erb index 9b128f8dd..d6aef9530 100644 --- a/app/views/settings/providers/_lunchflow_panel.html.erb +++ b/app/views/settings/providers/_lunchflow_panel.html.erb @@ -37,8 +37,7 @@ value: lunchflow_item.base_url %>
- <%= form.submit is_new_record ? t("settings.providers.lunchflow_panel.save_and_connect") : t("settings.providers.lunchflow_panel.update_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %> + <%= form.submit is_new_record ? t("settings.providers.lunchflow_panel.save_and_connect") : t("settings.providers.lunchflow_panel.update_connection") %>
<% end %> diff --git a/app/views/settings/providers/_mercury_panel.html.erb b/app/views/settings/providers/_mercury_panel.html.erb index 47a7f8b20..4e711b4c7 100644 --- a/app/views/settings/providers/_mercury_panel.html.erb +++ b/app/views/settings/providers/_mercury_panel.html.erb @@ -78,8 +78,7 @@ href: setup_accounts_mercury_item_path(item), frame: :modal ) %> - <%= form.submit t("mercury_items.provider_panel.update_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %> + <%= form.submit t("mercury_items.provider_panel.update_connection") %> <% end %> @@ -117,8 +116,7 @@

<%= t("mercury_items.provider_panel.sandbox_note_html").html_safe %>

- <%= form.submit t("mercury_items.provider_panel.add_connection"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %> + <%= form.submit t("mercury_items.provider_panel.add_connection") %>
<% end %> diff --git a/app/views/settings/providers/_provider_form.html.erb b/app/views/settings/providers/_provider_form.html.erb index 4a7294a65..a16a15675 100644 --- a/app/views/settings/providers/_provider_form.html.erb +++ b/app/views/settings/providers/_provider_form.html.erb @@ -63,8 +63,7 @@ <% end %>
- <%= form.submit "Save and connect", - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %> + <%= form.submit t(".save_and_connect") %>
<% end %> diff --git a/app/views/settings/providers/_simplefin_panel.html.erb b/app/views/settings/providers/_simplefin_panel.html.erb index b169c5cd9..f5125a2a1 100644 --- a/app/views/settings/providers/_simplefin_panel.html.erb +++ b/app/views/settings/providers/_simplefin_panel.html.erb @@ -25,8 +25,7 @@ type: :password %>
- <%= form.submit t("settings.providers.simplefin_panel.save_and_connect"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %> + <%= form.submit t("settings.providers.simplefin_panel.save_and_connect") %>
<% end %> diff --git a/app/views/settings/providers/_snaptrade_panel.html.erb b/app/views/settings/providers/_snaptrade_panel.html.erb index b99bace2b..ec877bdcd 100644 --- a/app/views/settings/providers/_snaptrade_panel.html.erb +++ b/app/views/settings/providers/_snaptrade_panel.html.erb @@ -38,8 +38,7 @@ type: :password %>
- <%= form.submit is_new_record ? t("providers.snaptrade.save_button") : t("providers.snaptrade.update_button"), - class: "btn btn--primary" %> + <%= form.submit is_new_record ? t("providers.snaptrade.save_button") : t("providers.snaptrade.update_button") %>
<% end %> diff --git a/app/views/settings/providers/_sophtron_panel.html.erb b/app/views/settings/providers/_sophtron_panel.html.erb index e17c8a816..4511d01dc 100644 --- a/app/views/settings/providers/_sophtron_panel.html.erb +++ b/app/views/settings/providers/_sophtron_panel.html.erb @@ -40,8 +40,7 @@ value: sophtron_item.base_url %>
- <%= form.submit is_new_record ? t("sophtron_items.sophtron_panel.save") : t("sophtron_items.sophtron_panel.update"), - class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %> + <%= form.submit is_new_record ? t("sophtron_items.sophtron_panel.save") : t("sophtron_items.sophtron_panel.update") %>
<% end %> diff --git a/app/views/settings/securities/show.html.erb b/app/views/settings/securities/show.html.erb index e0c1c5956..c0482ac98 100644 --- a/app/views/settings/securities/show.html.erb +++ b/app/views/settings/securities/show.html.erb @@ -10,11 +10,11 @@
<% if Current.user.otp_required? %> -

Two-factor authentication is enabled

-

Your account is protected with an additional layer of security.

+

<%= t(".mfa_enabled_status_html") %>

+

<%= t(".mfa_enabled_description") %>

<% else %> -

Two-factor authentication is disabled

-

Enable 2FA to add an extra layer of security to your account.

+

<%= t(".mfa_disabled_status_html") %>

+

<%= t(".mfa_disabled_description") %>

<% end %>
diff --git a/app/views/simplefin_items/_replacement_prompt.html.erb b/app/views/simplefin_items/_replacement_prompt.html.erb index f17e5dc41..4337a8f69 100644 --- a/app/views/simplefin_items/_replacement_prompt.html.erb +++ b/app/views/simplefin_items/_replacement_prompt.html.erb @@ -52,14 +52,15 @@ new_name: new_sfa.name), btn_text: t("simplefin_items.replacement_prompt.relink") ) %> - <%= button_to t("simplefin_items.replacement_prompt.relink"), - link_existing_account_simplefin_items_path( - account_id: sure_account.id, - simplefin_account_id: new_sfa.id - ), - method: :post, - data: { turbo_confirm: confirm.to_data_attribute }, - class: "inline-flex items-center gap-1.5 text-sm font-medium px-3 py-2 rounded-lg text-inverse bg-inverse hover:bg-inverse-hover" %> + <%= render DS::Button.new( + text: t("simplefin_items.replacement_prompt.relink"), + href: link_existing_account_simplefin_items_path( + account_id: sure_account.id, + simplefin_account_id: new_sfa.id + ), + variant: :primary, + data: { turbo_method: :post, turbo_confirm: confirm.to_data_attribute } + ) %> diff --git a/app/views/simplefin_items/_simplefin_item.html.erb b/app/views/simplefin_items/_simplefin_item.html.erb index c6e90e810..d09d9b202 100644 --- a/app/views/simplefin_items/_simplefin_item.html.erb +++ b/app/views/simplefin_items/_simplefin_item.html.erb @@ -52,7 +52,7 @@ <% if has_warnings %>
<% if stats["accounts_skipped"].to_i > 0 %> - <%= render DS::Tooltip.new(text: t(".accounts_skipped_tooltip"), icon: "alert-triangle", size: "sm", color: "warning") %> + <%= render DS::Tooltip.new(text: t(".accounts_skipped_tooltip"), icon: "alert-triangle", size: "sm", color: "warning", as: :span) %> <%= t(".accounts_skipped_label", count: stats["accounts_skipped"].to_i) %> <% end %> @@ -63,14 +63,15 @@ text: (ago ? t(".rate_limited_ago", time: ago) : t(".rate_limited_recently")), icon: "clock", size: "sm", - color: "warning" + color: "warning", + as: :span ) %> <% end %> <% if stats["total_errors"].to_i > 0 || (stats["errors"].is_a?(Array) && stats["errors"].any?) %> <% tooltip_text = simplefin_error_tooltip(stats) %> <% if tooltip_text.present? %> - <%= render DS::Tooltip.new(text: tooltip_text, icon: "alert-octagon", size: "sm", color: "warning") %> + <%= render DS::Tooltip.new(text: tooltip_text, icon: "alert-octagon", size: "sm", color: "warning", as: :span) %> <% end %> <% end %>
@@ -119,7 +120,7 @@ <% elsif simplefin_item.sync_error.present? && !duplicate_only_errors %>
- <%= render DS::Tooltip.new(text: simplefin_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive") %> + <%= render DS::Tooltip.new(text: simplefin_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive", as: :span) %> <%= tag.span t(".error"), class: "text-destructive" %>
<% elsif duplicate_only_errors %> diff --git a/app/views/simplefin_items/edit.html.erb b/app/views/simplefin_items/edit.html.erb index 51f26f39d..a350327bf 100644 --- a/app/views/simplefin_items/edit.html.erb +++ b/app/views/simplefin_items/edit.html.erb @@ -28,7 +28,7 @@ <% if @error_message %> -
+
<%= icon "alert-triangle", size: "sm", class: "text-destructive mt-0.5 flex-shrink-0" %>

<%= @error_message %>

diff --git a/app/views/simplefin_items/new.html.erb b/app/views/simplefin_items/new.html.erb index ade7c448c..d0b3ffd9b 100644 --- a/app/views/simplefin_items/new.html.erb +++ b/app/views/simplefin_items/new.html.erb @@ -9,15 +9,20 @@
<% end %> - <%= form_with model: @simplefin_item, url: simplefin_items_path, method: :post, data: { turbo: true, turbo_frame: "_top" } do |f| %> + <%= styled_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" %> + <%= render DS::Link.new( + text: t(".cancel"), + href: accounts_path, + variant: :secondary, + data: { turbo_frame: "_top", action: "DS--dialog#close" } + ) %> + <%= render DS::Button.new(text: t(".connect"), type: :submit) %>
<% end %> diff --git a/app/views/snaptrade_items/_snaptrade_item.html.erb b/app/views/snaptrade_items/_snaptrade_item.html.erb index f36712ec2..636d09dbe 100644 --- a/app/views/snaptrade_items/_snaptrade_item.html.erb +++ b/app/views/snaptrade_items/_snaptrade_item.html.erb @@ -42,7 +42,7 @@
<% elsif snaptrade_item.sync_error.present? %>
- <%= render DS::Tooltip.new(text: snaptrade_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive") %> + <%= render DS::Tooltip.new(text: snaptrade_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive", as: :span) %> <%= tag.span t(".error"), class: "text-destructive" %>
<% else %> diff --git a/app/views/snaptrade_items/select_existing_account.html.erb b/app/views/snaptrade_items/select_existing_account.html.erb index ab4d49ff2..bf817c98d 100644 --- a/app/views/snaptrade_items/select_existing_account.html.erb +++ b/app/views/snaptrade_items/select_existing_account.html.erb @@ -14,7 +14,13 @@ <%= icon "alert-circle", class: "text-warning mx-auto mb-4", size: "lg" %>

<%= t("snaptrade_items.select_existing_account.no_accounts", default: "No unlinked SnapTrade accounts available.") %>

<%= t("snaptrade_items.select_existing_account.connect_hint", default: "You may need to connect a brokerage first.") %>

- <%= link_to t("snaptrade_items.select_existing_account.settings_link", default: "Go to Provider Settings"), settings_providers_path, class: "btn btn--primary btn--sm mt-4" %> + <%= render DS::Link.new( + text: t("snaptrade_items.select_existing_account.settings_link", default: "Go to Provider Settings"), + href: settings_providers_path, + variant: :primary, + size: :sm, + class: "mt-4" + ) %>
<% else %>
diff --git a/app/views/sophtron_items/_sophtron_item.html.erb b/app/views/sophtron_items/_sophtron_item.html.erb index a8c71d900..d91450a86 100644 --- a/app/views/sophtron_items/_sophtron_item.html.erb +++ b/app/views/sophtron_items/_sophtron_item.html.erb @@ -41,7 +41,7 @@
<% elsif sophtron_item.sync_error.present? %>
- <%= render DS::Tooltip.new(text: sophtron_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive") %> + <%= render DS::Tooltip.new(text: sophtron_item.sync_error, icon: "alert-circle", size: "sm", color: "destructive", as: :span) %> <%= tag.span t(".error"), class: "text-destructive" %>
<% else %> diff --git a/app/views/subscriptions/upgrade.html.erb b/app/views/subscriptions/upgrade.html.erb index fd7d49936..2fbf5839a 100644 --- a/app/views/subscriptions/upgrade.html.erb +++ b/app/views/subscriptions/upgrade.html.erb @@ -48,6 +48,7 @@ <%= render DS::Button.new( text: t("subscriptions.upgrade.contribute_and_support_sure"), variant: "primary", + type: :submit, full_width: true ) %> diff --git a/app/views/tag/deletions/new.html.erb b/app/views/tag/deletions/new.html.erb index c069518ec..dcadf6e1d 100644 --- a/app/views/tag/deletions/new.html.erb +++ b/app/views/tag/deletions/new.html.erb @@ -16,6 +16,7 @@ <%= render DS::Button.new( variant: "destructive", + type: :submit, text: t(".delete_and_leave_uncategorized", tag_name: @tag.name), full_width: true, data: { deletion_target: "destructiveSubmitButton" } @@ -23,6 +24,7 @@ <%= render DS::Button.new( text: t(".delete_and_reassign"), + type: :submit, data: { deletion_target: "safeSubmitButton" }, hidden: true, full_width: true diff --git a/app/views/transactions/_attachments.html.erb b/app/views/transactions/_attachments.html.erb index dba4b464f..b771ca448 100644 --- a/app/views/transactions/_attachments.html.erb +++ b/app/views/transactions/_attachments.html.erb @@ -51,6 +51,7 @@ text: t(".upload"), variant: :primary, size: :sm, + type: :submit, data: { attachment_upload_target: "submitButton" } ) %> diff --git a/app/views/transactions/_list.html.erb b/app/views/transactions/_list.html.erb index 8506bdf85..5d57daa19 100644 --- a/app/views/transactions/_list.html.erb +++ b/app/views/transactions/_list.html.erb @@ -3,6 +3,8 @@ data-controller="bulk-select checkbox-toggle drag-and-drop-import" data-bulk-select-singular-label-value="<%= t(".transaction") %>" data-bulk-select-plural-label-value="<%= t(".transactions") %>" + data-bulk-select-selected-label-value="<%= t("transactions.selection_bar.selected") %>" + data-bulk-select-edit-label-value="<%= t("transactions.selection_bar.edit") %>" class="flex flex-col bg-container rounded-xl shadow-border-xs px-3 py-4 lg:p-4 relative group"> <%= form_with url: imports_path, method: :post, class: "hidden", data: { drag_and_drop_import_target: "form", turbo: false } do |f| %> @@ -29,7 +31,7 @@ action: "bulk-select#togglePageSelection", checkbox_toggle_target: "selectionEntry" } %> -

transaction

+

<%= t(".transaction") %>

diff --git a/app/views/transactions/_transfer_match.html.erb b/app/views/transactions/_transfer_match.html.erb index 53d05a4f4..f2d39531d 100644 --- a/app/views/transactions/_transfer_match.html.erb +++ b/app/views/transactions/_transfer_match.html.erb @@ -2,21 +2,21 @@
" class="flex items-center gap-1"> <% if transaction.transfer.confirmed? %> - is confirmed"> + "> <%= icon "link-2", size: "sm", class: "text-secondary" %> <% elsif transaction.transfer.pending? %> - A/M + <%= t("transactions.transfer_match.auto_matched_short") %> <%= button_to transfer_path(transaction.transfer, transfer: { status: "confirmed" }), method: :patch, class: "text-secondary flex items-center justify-center cursor-pointer", - title: "Confirm match" do %> + title: t("transactions.transfer_match.confirm_match") do %> <%= icon "check", size: "sm", class: "text-secondary hover:text-primary" %> <% end %> @@ -24,7 +24,7 @@ method: :patch, data: { turbo: false }, class: "text-secondary hover:text-primary flex items-center justify-center cursor-pointer", - title: "Reject match" do %> + title: t("transactions.transfer_match.reject_match") do %> <%= icon "x", size: "sm", class: "text-subdued hover:text-primary" %> <% end %> <% end %> diff --git a/app/views/transactions/bulk_updates/new.html.erb b/app/views/transactions/bulk_updates/new.html.erb index 7affac23e..47b38bf3f 100644 --- a/app/views/transactions/bulk_updates/new.html.erb +++ b/app/views/transactions/bulk_updates/new.html.erb @@ -1,27 +1,27 @@ <%= render DS::Dialog.new(variant: "drawer", frame: "bulk_transaction_edit_drawer") do |dialog| %> - <% dialog.with_header(title: "Edit transactions", data: { bulk_select_target: "bulkEditDrawerHeader" }) %> + <% dialog.with_header(title: t(".header_title"), data: { bulk_select_target: "bulkEditDrawerHeader" }) %> <% dialog.with_body do %> <%= styled_form_with url: transactions_bulk_update_path, scope: "bulk_update", class: "h-full flex flex-col justify-between gap-4", data: { turbo_frame: "_top" } do |form| %>
- <%= render DS::Disclosure.new(title: "Overview", open: true) do %> - <%= form.date_field :date, label: "Date", max: Date.current %> + <%= render DS::Disclosure.new(title: t(".overview"), open: true) do %> + <%= form.date_field :date, label: t(".date_label"), max: Date.current %> <% end %> - <%= render DS::Disclosure.new(title: "Transactions", open: true) do %> + <%= render DS::Disclosure.new(title: t(".transactions_section"), open: true) do %>
- <%= form.text_field :name, label: t("transactions.bulk_updates.new.name_label"), placeholder: t("transactions.bulk_updates.new.name_placeholder") %> - <%= form.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: "Select a category", label: "Category", class: "text-subdued" } %> - <%= form.collection_select :merchant_id, Current.family.available_merchants_for(Current.user).alphabetically, :id, :name, { prompt: "Select a merchant", label: "Merchant", class: "text-subdued" } %> - <%= form.select :tag_ids, Current.family.tags.alphabetically.pluck(:name, :id), { include_blank: "None", multiple: true, label: "Tags", include_hidden: false } %> - <%= form.text_area :notes, label: "Notes", placeholder: "Enter a note that will be applied to selected transactions", rows: 5 %> + <%= form.text_field :name, label: t(".name_label"), placeholder: t(".name_placeholder") %> + <%= form.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: t(".category_prompt"), label: t(".category_label"), class: "text-subdued" } %> + <%= form.collection_select :merchant_id, Current.family.available_merchants_for(Current.user).alphabetically, :id, :name, { prompt: t(".merchant_prompt"), label: t(".merchant_label"), class: "text-subdued" } %> + <%= form.select :tag_ids, Current.family.tags.alphabetically.pluck(:name, :id), { include_blank: t(".none"), multiple: true, label: t(".tags_label"), include_hidden: false } %> + <%= form.text_area :notes, label: t(".notes_label"), placeholder: t(".notes_placeholder"), rows: 5 %>
<% end %>
- <%= render DS::Button.new(text: "Cancel", variant: "ghost", data: { action: "click->DS--dialog#close" }) %> - <%= render DS::Button.new(text: "Save", data: { bulk_select_scope_param: "bulk_update", action: "bulk-select#submitBulkRequest" }) %> + <%= render DS::Button.new(text: t(".cancel"), variant: "ghost", data: { action: "click->DS--dialog#close" }) %> + <%= render DS::Button.new(text: t(".save"), type: :submit, data: { bulk_select_scope_param: "bulk_update", action: "bulk-select#submitBulkRequest" }) %>
<% end %> <% end %> diff --git a/app/views/transactions/new.html.erb b/app/views/transactions/new.html.erb index b2273188b..3d612c0a8 100644 --- a/app/views/transactions/new.html.erb +++ b/app/views/transactions/new.html.erb @@ -1,5 +1,5 @@ <%= render DS::Dialog.new(scrollable: false, content_class: "lg:max-h-none lg:overflow-y-auto") do |dialog| %> - <% dialog.with_header(title: "New transaction") %> + <% dialog.with_header(title: t(".new_transaction")) %> <% dialog.with_body do %> <%= render "form", entry: @entry, categories: @categories %> <% end %> diff --git a/app/views/transactions/searches/_form.html.erb b/app/views/transactions/searches/_form.html.erb index c32b1f166..93fda30b3 100644 --- a/app/views/transactions/searches/_form.html.erb +++ b/app/views/transactions/searches/_form.html.erb @@ -17,8 +17,8 @@
- <%= render DS::Menu.new(variant: "button", no_padding: true) do |menu| %> - <% menu.with_button( + <%= render DS::Popover.new(variant: "button", no_padding: true) do |popover| %> + <% popover.with_button( id: "transaction-filters-button", type: "button", text: t(".filter"), @@ -26,7 +26,7 @@ icon: "list-filter" ) %> - <% menu.with_custom_content do %> + <% popover.with_custom_content do %> <%= render "transactions/searches/menu", form: form %> <% end %> <% end %> diff --git a/app/views/transactions/searches/_menu.html.erb b/app/views/transactions/searches/_menu.html.erb index 0f2e9b09a..c424b20ed 100644 --- a/app/views/transactions/searches/_menu.html.erb +++ b/app/views/transactions/searches/_menu.html.erb @@ -37,8 +37,8 @@
- <%= render DS::Button.new(text: t(".cancel"), type: "button", variant: "ghost", data: { action: "DS--menu#close" }) %> - <%= render DS::Button.new(text: t(".apply")) %> + <%= render DS::Button.new(text: t(".cancel"), type: "button", variant: "ghost", data: { action: "DS--popover#close" }) %> + <%= render DS::Button.new(text: t(".apply"), type: :submit) %>
diff --git a/app/views/transactions/show.html.erb b/app/views/transactions/show.html.erb index 701844a9c..342670518 100644 --- a/app/views/transactions/show.html.erb +++ b/app/views/transactions/show.html.erb @@ -28,16 +28,20 @@
- <%= button_to t("transactions.show.merge_duplicate"), - merge_duplicate_transaction_path(@entry.transaction), - method: :post, - class: "btn btn--primary btn--sm", - data: { turbo_frame: "_top" } %> - <%= button_to t("transactions.show.keep_both"), - dismiss_duplicate_transaction_path(@entry.transaction), - method: :post, - class: "btn btn--outline btn--sm", - data: { turbo_frame: "_top" } %> + <%= render DS::Button.new( + text: t("transactions.show.merge_duplicate"), + href: merge_duplicate_transaction_path(@entry.transaction), + variant: :primary, + size: :sm, + data: { turbo_method: :post, turbo_frame: "_top" } + ) %> + <%= render DS::Button.new( + text: t("transactions.show.keep_both"), + href: dismiss_duplicate_transaction_path(@entry.transaction), + variant: :outline, + size: :sm, + data: { turbo_method: :post, turbo_frame: "_top" } + ) %>
diff --git a/app/views/users/_user_menu.html.erb b/app/views/users/_user_menu.html.erb index ddb2bc561..6268defb9 100644 --- a/app/views/users/_user_menu.html.erb +++ b/app/views/users/_user_menu.html.erb @@ -3,19 +3,20 @@ <% intro_mode = local_assigns.fetch(:intro_mode, false) %>
- <%= render DS::Menu.new( - variant: "avatar", + <%# `DS::Popover` (not `DS::Menu`) because the panel includes a + decorative profile header alongside the action items — `role="menu"` + would restrict AT users to menuitem-only navigation and hide the + user-info block. %> + <%= render DS::Popover.new( + variant: intro_mode ? "icon" : "avatar", avatar_url: user.profile_image&.variant(:small)&.url, initials: user.initials, placement: placement, - offset: offset - ) do |menu| %> - <% if intro_mode %> - <% menu.with_button do %> - <%= render DS::Button.new(variant: "icon", icon: "settings", data: { DS__menu_target: "button" }) %> - <% end %> - <% end %> - <%= menu.with_header do %> + offset: offset, + icon: "settings", + aria_label: t(".aria_label", default: "Open account menu") + ) do |popover| %> + <%= popover.with_header do %>
<%= render "settings/user_avatar", avatar_url: user.profile_image&.variant(:small)&.url, initials: user.initials, lazy: true %> @@ -43,21 +44,27 @@ <% end %> <% end %> - <% menu.with_item( - variant: "link", - text: t(".settings"), - icon: "settings", - href: intro_mode ? settings_profile_path : accounts_path(return_to: request.fullpath) - ) %> - <% menu.with_item(variant: "link", text: t(".changelog"), icon: "box", href: changelog_path) %> + <% popover.with_custom_content do %> + <%# `roving: false` keeps these items in the normal Tab order. The parent + `DS::Popover` has no arrow-key roving handler and is not a `role="menu"` + container, so the default `tabindex="-1"` would skip every item. %> + <%= render DS::MenuItem.new( + variant: "link", + roving: false, + text: t(".settings"), + icon: "settings", + href: intro_mode ? settings_profile_path : accounts_path(return_to: request.fullpath) + ) %> + <%= render DS::MenuItem.new(variant: "link", roving: false, text: t(".changelog"), icon: "box", href: changelog_path) %> - <% if self_hosted? && !intro_mode %> - <% menu.with_item(variant: "link", text: t(".feedback"), icon: "megaphone", href: feedback_path) %> + <% if self_hosted? && !intro_mode %> + <%= render DS::MenuItem.new(variant: "link", roving: false, text: t(".feedback"), icon: "megaphone", href: feedback_path) %> + <% end %> + <%= render DS::MenuItem.new(variant: "link", roving: false, text: t(".contact"), icon: "message-square-more", href: "https://discord.gg/36ZGBsxYEK", target: "_blank", rel: "noopener noreferrer") %> + + <%= render DS::MenuItem.new(variant: "divider") %> + + <%= render DS::MenuItem.new(variant: "button", roving: false, text: t(".log_out"), icon: "log-out", href: session_path(Current.session), method: :delete) %> <% end %> - <% menu.with_item(variant: "link", text: t(".contact"), icon: "message-square-more", href: "https://discord.gg/36ZGBsxYEK", target: "_blank", rel: "noopener noreferrer") %> - - <% menu.with_item(variant: "divider") %> - - <% menu.with_item(variant: "button", text: t(".log_out"), icon: "log-out", href: session_path(Current.session), method: :delete) %> <% end %>
diff --git a/charts/sure/Chart.yaml b/charts/sure/Chart.yaml index fa061c2c9..412a3c29e 100644 --- a/charts/sure/Chart.yaml +++ b/charts/sure/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: sure description: Official Helm chart for deploying the Sure Rails app (web + Sidekiq) on Kubernetes with optional HA PostgreSQL (CloudNativePG) and Redis. type: application -version: 0.7.1-alpha.8 -appVersion: "0.7.1-alpha.8" +version: 0.7.1-alpha.10 +appVersion: "0.7.1-alpha.10" kubeVersion: ">=1.25.0-0" diff --git a/charts/sure/templates/_env.tpl b/charts/sure/templates/_env.tpl index e50ab7ce8..e0aba60d5 100644 --- a/charts/sure/templates/_env.tpl +++ b/charts/sure/templates/_env.tpl @@ -48,8 +48,10 @@ The helper always injects: key: ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT {{- end }} {{- if $includeDatabase }} +{{- $railsExtraEnv := (default (dict) $ctx.Values.rails.extraEnv) -}} +{{- $explicitDb := hasKey $railsExtraEnv "DATABASE_URL" -}} {{- $dburl := include "sure.databaseUrl" $ctx -}} -{{- if $dburl }} +{{- if and $dburl (not $explicitDb) }} - name: DB_PASSWORD valueFrom: secretKeyRef: @@ -60,8 +62,10 @@ The helper always injects: {{- end }} {{- end }} {{- if $includeRedis }} +{{- $railsExtraEnv := (default (dict) $ctx.Values.rails.extraEnv) -}} +{{- $explicitRedis := hasKey $railsExtraEnv "REDIS_URL" -}} {{- $redis := include "sure.redisUrl" $ctx -}} -{{- if $redis }} +{{- if and $redis (not $explicitRedis) }} - name: REDIS_PASSWORD valueFrom: secretKeyRef: diff --git a/config/application.rb b/config/application.rb index 1269f1aad..17909aadf 100644 --- a/config/application.rb +++ b/config/application.rb @@ -48,6 +48,11 @@ module Sure config.x.ui = ActiveSupport::OrderedOptions.new default_layout = ENV.fetch("DEFAULT_UI_LAYOUT", "dashboard") config.x.ui.default_layout = default_layout.in?(%w[dashboard intro]) ? default_layout : "dashboard" + + config.x.debug_log = ActiveSupport::OrderedOptions.new + retention_days = ENV.fetch("DEBUG_LOG_RETENTION_DAYS", "90").to_i + config.x.debug_log.retention_days = retention_days.positive? ? retention_days : 90 + # Handle OmniAuth/OIDC errors gracefully (must be before OmniAuth middleware) require_relative "../app/middleware/omniauth_error_handler" config.middleware.use OmniauthErrorHandler diff --git a/config/importmap.rb b/config/importmap.rb index 12bf26d90..308591cbd 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -8,6 +8,7 @@ pin_all_from "app/javascript/controllers", under: "controllers" pin_all_from "app/components", under: "controllers", to: "" pin_all_from "app/javascript/services", under: "services", to: "services" pin_all_from "app/javascript/utils", under: "utils", to: "utils" +pin "utils/sankey_zoom", to: "utils/sankey_zoom.mjs" pin "@github/hotkey", to: "@github--hotkey.js" # @3.1.1 pin "@simonwep/pickr", to: "@simonwep--pickr.js" # @1.9.1 diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index 549789cbf..e116f5753 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -5,3 +5,6 @@ Mime::Type.register "text/csv", :csv Mime::Type.register "application/pdf", :pdf Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx + +# Register .mjs so Propshaft serves ES modules with the correct Content-Type. +Mime::Type.register "text/javascript", :mjs unless Mime::Type.lookup_by_extension(:mjs) diff --git a/config/locales/breadcrumbs/ca.yml b/config/locales/breadcrumbs/ca.yml index c726a4da7..af61405d4 100644 --- a/config/locales/breadcrumbs/ca.yml +++ b/config/locales/breadcrumbs/ca.yml @@ -1,6 +1,87 @@ --- ca: breadcrumbs: + account_sharings: Compartició de comptes + account_statements: Arxiu d'extractes + accounts: Comptes + ai_prompts: Prompts d'IA + api_key: Clau API + api_keys: Claus API + appearance: Aparença + appearances: Aparença + bank_sync: Sincronització bancària + binance_items: Binance + brex_items: Brex + budget_categories: Categories del pressupost + budgets: Pressupostos + categories: Categories + categorize: Categoritza + chats: Xats + coinbase_items: Coinbase + coinstats_items: CoinStats + credit_cards: Targetes de crèdit + cryptos: Cripto + dashboard: Tauler + debug: Depuració + debugs: Depuració + depositories: Comptes d'efectiu + enable_banking_items: Enable Banking exports: Exportacions + family_exports: Exportacions + family_merchants: Comerços + guides: Guies + holdings: Posicions home: Inici + hostings: Self hosting + ibkr_items: Interactive Brokers + impersonation_sessions: Suplantacions imports: Importacions + indexa_capital_items: Indexa Capital + intro: Introducció + investments: Inversions + invitations: Invitacions + invite_codes: Codis d'invitació + kraken_items: Kraken + llm_usage: Ús d'LLM + llm_usages: Ús d'LLM + loans: Préstecs + lunchflow_items: Lunch Flow + merchants: Comerços + mercury_items: Mercury + messages: Missatges + mfa: Autenticació de dos factors + oidc_accounts: Comptes SSO + onboardings: Configuració inicial + other_assets: Altres actius + other_liabilities: Altres passius + payments: Pagaments + pending_duplicate_merges: Revisió de duplicats + plaid_items: Plaid + preferences: Preferències + profile: Informació del perfil + profiles: Informació del perfil + properties: Propietats + providers: Proveïdors + recurring_transactions: Recurrents + registrations: Registre + reports: Informes + rules: Regles + securities: Seguretat + security: Seguretat + self_hosting: Self hosting + sessions: Inici de sessió + simplefin_items: SimpleFIN + snaptrade_items: SnapTrade + sophtron_items: Sophtron + splits: Divisió + sso_identities: Connexions SSO + sso_providers: Proveïdors SSO + subscriptions: Subscripció + tags: Etiquetes + trades: Operacions + transactions: Transaccions + transfer_matches: Coincidències de transferències + transfers: Transferències + users: Usuaris + valuations: Valoracions + vehicles: Vehicles diff --git a/config/locales/breadcrumbs/en.yml b/config/locales/breadcrumbs/en.yml index 1c840acdc..c6f1ba1d8 100644 --- a/config/locales/breadcrumbs/en.yml +++ b/config/locales/breadcrumbs/en.yml @@ -1,8 +1,87 @@ --- en: breadcrumbs: + account_sharings: Account sharing + account_statements: Statement vault + accounts: Accounts + ai_prompts: AI Prompts + api_key: API Key + api_keys: API Keys + appearance: Appearance + appearances: Appearance + bank_sync: Bank Sync + binance_items: Binance + brex_items: Brex + budget_categories: Budget categories + budgets: Budgets + categories: Categories categorize: Categorize + chats: Chats + coinbase_items: Coinbase + coinstats_items: CoinStats + credit_cards: Credit cards + cryptos: Crypto + dashboard: Dashboard + debug: Debug + debugs: Debug + depositories: Cash accounts + enable_banking_items: Enable Banking exports: Exports + family_exports: Exports + family_merchants: Merchants + guides: Guides + holdings: Holdings home: Home + hostings: Self-Hosting + ibkr_items: Interactive Brokers + impersonation_sessions: Impersonations imports: Imports + indexa_capital_items: Indexa Capital + intro: Intro + investments: Investments + invitations: Invitations + invite_codes: Invite codes + kraken_items: Kraken + llm_usage: LLM Usage + llm_usages: LLM Usage + loans: Loans + lunchflow_items: Lunch Flow + merchants: Merchants + mercury_items: Mercury + messages: Messages + mfa: Two-factor authentication + oidc_accounts: SSO accounts + onboardings: Onboarding + other_assets: Other assets + other_liabilities: Other liabilities + payments: Payments + pending_duplicate_merges: Duplicate review + plaid_items: Plaid + preferences: Preferences + profile: Profile Info + profiles: Profile Info + properties: Properties + providers: Providers + recurring_transactions: Recurring + registrations: Sign up + reports: Reports + rules: Rules + securities: Security + security: Security + self_hosting: Self-Hosting + sessions: Sign in + simplefin_items: SimpleFIN + snaptrade_items: SnapTrade + sophtron_items: Sophtron + splits: Split + sso_identities: SSO connections + sso_providers: SSO providers + subscriptions: Subscription + tags: Tags + trades: Trades transactions: Transactions + transfer_matches: Transfer matches + transfers: Transfers + users: Users + valuations: Valuations + vehicles: Vehicles diff --git a/config/locales/breadcrumbs/hu.yml b/config/locales/breadcrumbs/hu.yml index 4210c7cc8..93dcdb312 100644 --- a/config/locales/breadcrumbs/hu.yml +++ b/config/locales/breadcrumbs/hu.yml @@ -1,8 +1,21 @@ --- hu: breadcrumbs: + ai_prompts: AI promptok + api_key: API kulcs + bank_sync: Bankszinkronizáció + budgets: Költségvetések categorize: Kategorizálás + dashboard: Irányítópult exports: Exportálások + guides: Útmutatók home: Kezdőlap imports: Importálások + intro: Bemutató + llm_usage: LLM használat + merchants: Kereskedők + profile: Profil adatok + reports: Jelentések + security: Biztonság + self_hosting: Saját üzemeltetés transactions: Tranzakciók diff --git a/config/locales/countries.ca.yml b/config/locales/countries.ca.yml new file mode 100644 index 000000000..ecb7b82f4 --- /dev/null +++ b/config/locales/countries.ca.yml @@ -0,0 +1,121 @@ +--- +ca: + countries: + AD: Andorra + AE: Emirats Àrabs Units + AF: Afganistan + AL: Albània + AM: Armènia + AO: Angola + AR: Argentina + AT: Àustria + AU: Austràlia + BA: Bòsnia i Hercegovina + BD: Bangla Desh + BE: Bèlgica + BG: Bulgària + BO: Bolívia + BR: Brasil + BY: Bielorússia + CA: Canadà + CD: República Democràtica del Congo + CG: República del Congo + CH: Suïssa + CI: Costa d'Ivori + CL: Xile + CM: Camerun + CN: Xina + CO: Colòmbia + CR: Costa Rica + CU: Cuba + CY: Xipre + CZ: República Txeca + DE: Alemanya + DK: Dinamarca + DO: República Dominicana + DZ: Algèria + EC: Equador + EE: Estònia + EG: Egipte + ES: Espanya + ET: Etiòpia + FI: Finlàndia + FR: França + GB: Regne Unit + GE: Geòrgia + GH: Ghana + GR: Grècia + GT: Guatemala + HK: Hong Kong + HN: Hondures + HR: Croàcia + HT: Haití + HU: Hongria + ID: Indonèsia + IE: Irlanda + IL: Israel + IN: Índia + IQ: Iraq + IR: Iran + IS: Islàndia + IT: Itàlia + JM: Jamaica + JO: Jordània + JP: Japó + KE: Kenya + KH: Cambodja + KP: Corea del Nord + KR: Corea del Sud + KW: Kuwait + KZ: Kazakhstan + LB: Líban + LT: Lituània + LU: Luxemburg + LV: Letònia + MA: Marroc + MD: Moldàvia + ME: Montenegro + MG: Madagascar + MK: Macedònia del Nord + MM: Myanmar (Birmània) + MN: Mongòlia + MT: Malta + MX: Mèxic + MY: Malàisia + NG: Nigèria + NI: Nicaragua + NL: Països Baixos + 'NO': Noruega + NP: Nepal + NZ: Nova Zelanda + PA: Panamà + PE: Perú + PH: Filipines + PK: Pakistan + PL: Polònia + PR: Puerto Rico + PT: Portugal + PY: Paraguai + QA: Qatar + RO: Romania + RS: Sèrbia + RU: Rússia + SA: Aràbia Saudita + SE: Suècia + SG: Singapur + SI: Eslovènia + SK: Eslovàquia + SV: El Salvador + SY: Síria + TH: Tailàndia + TN: Tunísia + TR: Turquia + TW: Taiwan + UA: Ucraïna + UG: Uganda + US: Estats Units + UY: Uruguai + VE: Veneçuela + VN: Vietnam + ZA: Sud-àfrica + ZW: Zimbàbue diff --git a/config/locales/defaults/ca.yml b/config/locales/defaults/ca.yml index 127267ac6..a88f011d3 100644 --- a/config/locales/defaults/ca.yml +++ b/config/locales/defaults/ca.yml @@ -41,7 +41,9 @@ ca: formats: default: "%d-%m-%Y" long: "%d de %B de %Y" + month_year: "%B de %Y" short: "%d de %b" + short_month_year: "%b de %Y" month_names: - - Gener @@ -83,7 +85,7 @@ ca: other: menys de %{count} segons over_x_years: one: més d'%{count} any - other: més de %{count} anys + other: més d'%{count} anys x_days: one: "%{count} dia" other: "%{count} dies" @@ -108,6 +110,8 @@ ca: year: any defaults: brand_name: "%{brand_name}" + common: + close: Tanca product_name: "%{product_name}" errors: format: "%{attribute} %{message}" @@ -122,7 +126,7 @@ ca: greater_than: ha de ser més gran que %{count} greater_than_or_equal_to: ha de ser més gran o igual a %{count} in: ha d'estar entre %{count} - inclusion: no està inclós a la llista + inclusion: no està inclòs a la llista invalid: no és vàlid less_than: ha de ser menor que %{count} less_than_or_equal_to: ha de ser menor o igual a %{count} @@ -148,13 +152,17 @@ ca: header: one: No s'ha pogut desar aquest/a %{model} perquè hi ha %{count} error other: No s'ha pogut desar aquest/a %{model} perquè hi ha hagut %{count} errors + global: + expand: Desplega helpers: select: - prompt: Si us plau tria + default_label: Selecciona... + prompt: Tria + search_placeholder: Cerca submit: - create: Crear %{model} - submit: Guardar %{model} - update: Actualitzar %{model} + create: Crea %{model} + submit: Desa %{model} + update: Actualitza %{model} number: currency: format: diff --git a/config/locales/doorkeeper.ca.yml b/config/locales/doorkeeper.ca.yml index 0b7a5f4aa..3f137996e 100644 --- a/config/locales/doorkeeper.ca.yml +++ b/config/locales/doorkeeper.ca.yml @@ -46,7 +46,7 @@ ca: callback_url: URL de retorn confidential: Confidencial? confidentiality: - 'no': No + 'no': 'No' 'yes': Sí name: Nom new: Nova aplicació @@ -68,6 +68,7 @@ ca: authorize: Autoritza deny: Denega error: + go_back: Torna enrere title: S'ha produït un error form_post: title: Envia aquest formulari @@ -76,6 +77,8 @@ ca: prompt: Autoritzes %{client_name} a utilitzar el teu compte? title: Autorització requerida show: + authorization_code_label: 'Codi d''autorització:' + copy_instructions: Copia aquest codi i enganxa'l a l'aplicació. title: Codi d'autorització authorized_applications: buttons: diff --git a/config/locales/doorkeeper.hu.yml b/config/locales/doorkeeper.hu.yml index d3c382282..4038b4776 100644 --- a/config/locales/doorkeeper.hu.yml +++ b/config/locales/doorkeeper.hu.yml @@ -64,12 +64,15 @@ hu: deny: 'Elutasítás' error: title: 'Hiba történt' + go_back: 'Vissza' new: title: 'Engedélyezés szükséges' prompt: 'Engedélyezed, hogy %{client_name} hozzáférjen a fiókodhoz?' able_to: 'Az alkalmazás a következőkre lesz jogosult' show: title: 'Engedélyezési kód' + authorization_code_label: 'Engedélyezési kód:' + copy_instructions: 'Másold ki ezt a kódot, és illeszd be az alkalmazásba.' form_post: title: 'Küldd el ezt az űrlapot' authorized_applications: diff --git a/config/locales/mailers/invitation_mailer/ca.yml b/config/locales/mailers/invitation_mailer/ca.yml index e00247801..64274f354 100644 --- a/config/locales/mailers/invitation_mailer/ca.yml +++ b/config/locales/mailers/invitation_mailer/ca.yml @@ -2,4 +2,4 @@ ca: invitation_mailer: invite_email: - subject: "%{inviter} t'ha convidat a unir-te al seu grup familiar a %{product_name}!" + subject: "%{inviter} t'ha convidat a unir-te al seu compte de %{product_name}!" diff --git a/config/locales/mailers/pdf_import_mailer/ca.yml b/config/locales/mailers/pdf_import_mailer/ca.yml new file mode 100644 index 000000000..1170cd293 --- /dev/null +++ b/config/locales/mailers/pdf_import_mailer/ca.yml @@ -0,0 +1,5 @@ +--- +ca: + pdf_import_mailer: + next_steps: + subject: S'ha analitzat el teu document PDF - %{product_name} diff --git a/config/locales/models/account/ca.yml b/config/locales/models/account/ca.yml index bc22cd01f..43c7f9960 100644 --- a/config/locales/models/account/ca.yml +++ b/config/locales/models/account/ca.yml @@ -1,12 +1,25 @@ --- ca: + account_order: + balance_asc: + label: Saldo (de menor a major) + label_short: Saldo ↑ + balance_desc: + label: Saldo (de major a menor) + label_short: Saldo ↓ + name_asc: + label: Nom (A-Z) + label_short: Nom ↑ + name_desc: + label: Nom (Z-A) + label_short: Nom ↓ activerecord: attributes: account: balance: Saldo - currency: Moneda - family: Família - family_id: Família + currency: Divisa + family: "%{moniker}" + family_id: "%{moniker}" name: Nom subtype: Subtipus models: @@ -15,8 +28,7 @@ ca: account/depository: Compte bancari account/investment: Inversió account/loan: Préstec - account/other_asset: Altres actius - account/other_liability: Altres passius + account/other_asset: Altre actiu + account/other_liability: Altre passiu account/property: Immoble account/vehicle: Vehicle - diff --git a/config/locales/models/account/en.yml b/config/locales/models/account/en.yml index e4c882b9c..df47d3302 100644 --- a/config/locales/models/account/en.yml +++ b/config/locales/models/account/en.yml @@ -1,5 +1,18 @@ --- en: + account_order: + balance_asc: + label: Balance (Low to High) + label_short: Balance ↑ + balance_desc: + label: Balance (High to Low) + label_short: Balance ↓ + name_asc: + label: Name (A-Z) + label_short: Name ↑ + name_desc: + label: Name (Z-A) + label_short: Name ↓ activerecord: attributes: account: diff --git a/config/locales/models/account/hu.yml b/config/locales/models/account/hu.yml index c1fcbbd6f..7966b9b53 100644 --- a/config/locales/models/account/hu.yml +++ b/config/locales/models/account/hu.yml @@ -15,7 +15,7 @@ hu: account/depository: Bankszámla account/investment: Befektetés account/loan: Kölcsön - account/other_asset: Egyéb eszköz + account/other_asset: Egyéb vagyon account/other_liability: Egyéb kötelezettség account/property: Ingatlan account/vehicle: Jármű diff --git a/config/locales/models/account_statement/ca.yml b/config/locales/models/account_statement/ca.yml new file mode 100644 index 000000000..f264559e8 --- /dev/null +++ b/config/locales/models/account_statement/ca.yml @@ -0,0 +1,30 @@ +--- +ca: + activerecord: + attributes: + account_statement: + account: Compte + account_last4_hint: Quatre últims dígits del compte + account_name_hint: Pista del nom del compte + closing_balance: Saldo final + content_sha256: Resum del contingut + currency: Divisa + filename: Nom del fitxer + institution_name_hint: Pista de la institució + opening_balance: Saldo inicial + original_file: Fitxer de l'extracte + period_end_on: Final del període + period_start_on: Inici del període + errors: + models: + account_statement: + attributes: + checksum: + duplicate_statement_file: ja s'ha pujat per a aquesta família + content_sha256: + duplicate_statement_file: ja s'ha pujat per a aquesta família + original_file: + invalid_format: ha de ser un fitxer PDF, CSV o XLSX + too_large: és massa gran. La mida màxima és %{max_mb}MB + period_end_on: + on_or_after_start: ha de ser igual o posterior a l'inici del període diff --git a/config/locales/models/account_statement/hu.yml b/config/locales/models/account_statement/hu.yml new file mode 100644 index 000000000..6ae639f88 --- /dev/null +++ b/config/locales/models/account_statement/hu.yml @@ -0,0 +1,30 @@ +--- +hu: + activerecord: + attributes: + account_statement: + account: Számla + account_last4_hint: Számla utolsó négy számjegye + account_name_hint: Számlanév-tipp + closing_balance: Záró egyenleg + content_sha256: Tartalom-összefoglaló + currency: Pénznem + filename: Fájlnév + institution_name_hint: Intézménynév-tipp + opening_balance: Nyitóegyenleg + original_file: Kimutatásfájl + period_end_on: Időszak vége + period_start_on: Időszak kezdete + errors: + models: + account_statement: + attributes: + checksum: + duplicate_statement_file: már fel lett töltve ennél a háztartásnál + content_sha256: + duplicate_statement_file: már fel lett töltve ennél a háztartásnál + original_file: + invalid_format: csak PDF, CSV vagy XLSX fájl lehet + too_large: túl nagy. A maximális méret %{max_mb} MB + period_end_on: + on_or_after_start: nem lehet korábbi, mint az időszak kezdete diff --git a/config/locales/models/address/ca.yml b/config/locales/models/address/ca.yml index d879be675..e43482fad 100644 --- a/config/locales/models/address/ca.yml +++ b/config/locales/models/address/ca.yml @@ -9,4 +9,3 @@ ca: postal_code: Codi postal region: Regió format: "%{line1} %{line2}, %{locality}, %{region} %{postal_code} %{country}" - diff --git a/config/locales/models/api_key/ca.yml b/config/locales/models/api_key/ca.yml new file mode 100644 index 000000000..95e88eb7d --- /dev/null +++ b/config/locales/models/api_key/ca.yml @@ -0,0 +1,8 @@ +--- +ca: + activerecord: + errors: + models: + api_key: + cannot_destroy_demo_key: No es pot eliminar la clau API de monitoratge de + demostració diff --git a/config/locales/models/api_key/hu.yml b/config/locales/models/api_key/hu.yml new file mode 100644 index 000000000..78f98c066 --- /dev/null +++ b/config/locales/models/api_key/hu.yml @@ -0,0 +1,7 @@ +--- +hu: + activerecord: + errors: + models: + api_key: + cannot_destroy_demo_key: "A demo felügyeleti API-kulcs nem törölhető" diff --git a/config/locales/models/brex_item/ca.yml b/config/locales/models/brex_item/ca.yml new file mode 100644 index 000000000..ce59c6867 --- /dev/null +++ b/config/locales/models/brex_item/ca.yml @@ -0,0 +1,14 @@ +--- +ca: + activerecord: + attributes: + brex_item: + base_url: URL base + name: Nom de la connexió + token: Token + errors: + models: + brex_item: + attributes: + base_url: + official_hosts_only: ha de ser buit, https://api.brex.com o https://api-staging.brex.com diff --git a/config/locales/models/brex_item/hu.yml b/config/locales/models/brex_item/hu.yml new file mode 100644 index 000000000..0386c1a44 --- /dev/null +++ b/config/locales/models/brex_item/hu.yml @@ -0,0 +1,14 @@ +--- +hu: + activerecord: + attributes: + brex_item: + base_url: Alap URL + name: Kapcsolat neve + token: Token + errors: + models: + brex_item: + attributes: + base_url: + official_hosts_only: üres kell legyen, vagy https://api.brex.com, vagy https://api-staging.brex.com diff --git a/config/locales/models/category/ca.yml b/config/locales/models/category/ca.yml index 310293577..ffa650927 100644 --- a/config/locales/models/category/ca.yml +++ b/config/locales/models/category/ca.yml @@ -2,6 +2,28 @@ ca: models: category: + defaults: + entertainment: Oci + fees: Comissions + food_and_drink: Menjar i begudes + gifts_and_donations: Regals i donacions + groceries: Alimentació + healthcare: Salut + home_improvement: Millora de la llar + income: Ingressos + insurance: Assegurances + loan_payments: Pagaments de préstecs + mortgage_rent: Hipoteca / Lloguer + personal_care: Cura personal + savings_and_investments: Estalvis i inversions + services: Serveis + shopping: Compres + sports_and_fitness: Esport i fitness + subscriptions: Subscripcions + taxes: Impostos + transportation: Transport + travel: Viatges + utilities: Subministraments + investment_contributions: Contribucions d'inversió other_investments: Altres inversions uncategorized: Sense categoria - investment_contributions: Contribucions d'inversió diff --git a/config/locales/models/category/en.yml b/config/locales/models/category/en.yml index 749f80860..7216b8a42 100644 --- a/config/locales/models/category/en.yml +++ b/config/locales/models/category/en.yml @@ -5,3 +5,25 @@ en: uncategorized: Uncategorized other_investments: Other Investments investment_contributions: Investment Contributions + defaults: + income: Income + food_and_drink: Food & Drink + groceries: Groceries + shopping: Shopping + transportation: Transportation + travel: Travel + entertainment: Entertainment + healthcare: Healthcare + personal_care: Personal Care + home_improvement: Home Improvement + mortgage_rent: Mortgage / Rent + utilities: Utilities + subscriptions: Subscriptions + insurance: Insurance + sports_and_fitness: Sports & Fitness + gifts_and_donations: Gifts & Donations + taxes: Taxes + loan_payments: Loan Payments + services: Services + fees: Fees + savings_and_investments: Savings & Investments diff --git a/config/locales/models/category/hu.yml b/config/locales/models/category/hu.yml index 2a02c4149..605ead1cf 100644 --- a/config/locales/models/category/hu.yml +++ b/config/locales/models/category/hu.yml @@ -5,3 +5,25 @@ hu: uncategorized: Kategorizálatlan other_investments: Egyéb befektetések investment_contributions: Befektetési befizetések + defaults: + income: Bevétel + food_and_drink: Étel és ital + groceries: Élelmiszer + shopping: Vásárlás + transportation: Közlekedés + travel: Utazás + entertainment: Szórakozás + healthcare: Egészségügy + personal_care: Személyes gondozás + home_improvement: Lakásfelújítás + mortgage_rent: Jelzálog / Bérleti díj + utilities: Rezsi + subscriptions: Előfizetések + insurance: Biztosítás + sports_and_fitness: Sport és fitnesz + gifts_and_donations: Ajándékok és adományok + taxes: Adók + loan_payments: Hitelrészletek + services: Szolgáltatások + fees: Díjak + savings_and_investments: Megtakarítások és befektetések diff --git a/config/locales/models/category_import/ca.yml b/config/locales/models/category_import/ca.yml new file mode 100644 index 000000000..9b7124b3f --- /dev/null +++ b/config/locales/models/category_import/ca.yml @@ -0,0 +1,8 @@ +--- +ca: + activerecord: + errors: + models: + category_import: + missing_columns: 'Falten columnes obligatòries: %{columns}' + own_parent: La categoria '%{name}' no pot ser el seu propi pare diff --git a/config/locales/models/category_import/hu.yml b/config/locales/models/category_import/hu.yml new file mode 100644 index 000000000..474990177 --- /dev/null +++ b/config/locales/models/category_import/hu.yml @@ -0,0 +1,8 @@ +--- +hu: + activerecord: + errors: + models: + category_import: + own_parent: "A(z) '%{name}' kategória nem lehet saját maga szülője" + missing_columns: "Hiányzó kötelező oszlopok: %{columns}" diff --git a/config/locales/models/chat/ca.yml b/config/locales/models/chat/ca.yml new file mode 100644 index 000000000..7bb662ddb --- /dev/null +++ b/config/locales/models/chat/ca.yml @@ -0,0 +1,11 @@ +--- +ca: + chat: + errors: + default: No s'ha pogut generar una resposta. Torna-ho a provar. + misconfigured: El proveïdor d'IA no està configurat correctament. Contacta amb + el teu administrador. + rate_limited: El proveïdor d'IA té un límit de peticions ara mateix. Torna-ho + a provar d'aquí a uns minuts. + temporarily_unavailable: El proveïdor d'IA no està disponible temporalment. + Torna-ho a provar d'aquí a uns minuts. diff --git a/config/locales/models/coinbase_account/ca.yml b/config/locales/models/coinbase_account/ca.yml new file mode 100644 index 000000000..3379622a3 --- /dev/null +++ b/config/locales/models/coinbase_account/ca.yml @@ -0,0 +1,5 @@ +--- +ca: + coinbase: + processor: + paid_via: Pagat amb %{method} diff --git a/config/locales/models/coinstats_item/ca.yml b/config/locales/models/coinstats_item/ca.yml index 2aadcea9b..d6d9f697e 100644 --- a/config/locales/models/coinstats_item/ca.yml +++ b/config/locales/models/coinstats_item/ca.yml @@ -4,7 +4,7 @@ ca: coinstats_item: syncer: calculating_balances: S'estan calculant els saldos... - checking_configuration: S'està comprovant la configuració del moneder... - importing_wallets: S'estan important moneders de CoinStats... - processing_holdings: S'estan processant les participacions... - wallets_need_setup: "%{count} moneders necessiten configuració..." + checking_configuration: S'està comprovant la configuració del compte de CoinStats... + importing_wallets: S'estan important comptes de cripto des de CoinStats... + processing_holdings: S'estan processant les posicions... + wallets_need_setup: "%{count} comptes de cripto necessiten configuració..." diff --git a/config/locales/models/import/ca.yml b/config/locales/models/import/ca.yml index 56ecfa5c6..ffee0098d 100644 --- a/config/locales/models/import/ca.yml +++ b/config/locales/models/import/ca.yml @@ -3,7 +3,11 @@ ca: activerecord: attributes: import: - currency: Moneda + col_sep: Separador de columnes + col_seps: + comma: Coma (,) + semicolon: Punt i coma (;) + currency: Divisa number_format: Format numèric errors: models: @@ -11,4 +15,5 @@ ca: attributes: raw_file_str: invalid_csv_format: no és un format CSV vàlid - + duplicate_headers: 'Les capçaleres del CSV es normalitzen en columnes duplicades: + %{columns}' diff --git a/config/locales/models/import/en.yml b/config/locales/models/import/en.yml index 0c24706dd..1ff592eba 100644 --- a/config/locales/models/import/en.yml +++ b/config/locales/models/import/en.yml @@ -3,6 +3,10 @@ en: activerecord: attributes: import: + col_sep: Column separator + col_seps: + comma: Comma (,) + semicolon: Semicolon (;) currency: Currency number_format: Number Format errors: diff --git a/config/locales/models/import/hu.yml b/config/locales/models/import/hu.yml index 051c6adc3..f56aa9371 100644 --- a/config/locales/models/import/hu.yml +++ b/config/locales/models/import/hu.yml @@ -8,6 +8,7 @@ hu: errors: models: import: + duplicate_headers: "A CSV fejlécek duplikált oszlopokra normalizálódnak: %{columns}" attributes: raw_file_str: invalid_csv_format: nem érvényes CSV formátum diff --git a/config/locales/models/indexa_capital_item/ca.yml b/config/locales/models/indexa_capital_item/ca.yml new file mode 100644 index 000000000..be3abb1b1 --- /dev/null +++ b/config/locales/models/indexa_capital_item/ca.yml @@ -0,0 +1,8 @@ +--- +ca: + activerecord: + errors: + models: + indexa_capital_item: + credentials_required: Cal la variable d'entorn INDEXA_API_TOKEN o bé les + credencials d'usuari/document/contrasenya diff --git a/config/locales/models/indexa_capital_item/hu.yml b/config/locales/models/indexa_capital_item/hu.yml new file mode 100644 index 000000000..d416d4d39 --- /dev/null +++ b/config/locales/models/indexa_capital_item/hu.yml @@ -0,0 +1,7 @@ +--- +hu: + activerecord: + errors: + models: + indexa_capital_item: + credentials_required: "Az INDEXA_API_TOKEN környezeti változó vagy felhasználónév/dokumentum/jelszó hitelesítő adatok megadása kötelező" diff --git a/config/locales/models/period/ca.yml b/config/locales/models/period/ca.yml new file mode 100644 index 000000000..f63df2d4a --- /dev/null +++ b/config/locales/models/period/ca.yml @@ -0,0 +1,54 @@ +--- +ca: + period: + all_time: + comparison_label: vs. inici + label: Sempre + label_short: Tot + current_month: + comparison_label: vs. inici de mes + label: Mes en curs + label_short: MTD + current_week: + comparison_label: vs. inici de setmana + label: Setmana en curs + label_short: STD + current_year: + comparison_label: vs. inici d'any + label: Any en curs + label_short: YTD + custom: + label: Període personalitzat + label_short: Personalitzat + last_10_years: + comparison_label: vs. fa 10 anys + label: Últims 10 anys + label_short: 10A + last_30_days: + comparison_label: vs. últims 30 dies + label: Últims 30 dies + label_short: 30D + last_365_days: + comparison_label: vs. fa 1 any + label: Últims 365 dies + label_short: 365D + last_5_years: + comparison_label: vs. fa 5 anys + label: Últims 5 anys + label_short: 5A + last_7_days: + comparison_label: vs. setmana anterior + label: Últims 7 dies + label_short: 7D + last_90_days: + comparison_label: vs. trimestre anterior + label: Últims 90 dies + label_short: 90D + last_day: + comparison_label: vs. ahir + label: Últim dia + label_short: 1D + last_month: + comparison_label: vs. mes anterior + label: Mes anterior + label_short: MA diff --git a/config/locales/models/period/en.yml b/config/locales/models/period/en.yml new file mode 100644 index 000000000..96e3bb21c --- /dev/null +++ b/config/locales/models/period/en.yml @@ -0,0 +1,54 @@ +--- +en: + period: + last_day: + label_short: "1D" + label: "Last Day" + comparison_label: "vs. yesterday" + current_week: + label_short: "WTD" + label: "Current Week" + comparison_label: "vs. start of week" + last_7_days: + label_short: "7D" + label: "Last 7 Days" + comparison_label: "vs. last week" + current_month: + label_short: "MTD" + label: "Current Month" + comparison_label: "vs. start of month" + last_month: + label_short: "LM" + label: "Last Month" + comparison_label: "vs. last month" + last_30_days: + label_short: "30D" + label: "Last 30 Days" + comparison_label: "vs. last 30 days" + last_90_days: + label_short: "90D" + label: "Last 90 Days" + comparison_label: "vs. last quarter" + current_year: + label_short: "YTD" + label: "Current Year" + comparison_label: "vs. start of year" + last_365_days: + label_short: "365D" + label: "Last 365 Days" + comparison_label: "vs. 1 year ago" + last_5_years: + label_short: "5Y" + label: "Last 5 Years" + comparison_label: "vs. 5 years ago" + last_10_years: + label_short: "10Y" + label: "Last 10 Years" + comparison_label: "vs. 10 years ago" + all_time: + label_short: "All" + label: "All Time" + comparison_label: "vs. beginning" + custom: + label_short: "Custom" + label: "Custom Period" diff --git a/config/locales/models/period/hu.yml b/config/locales/models/period/hu.yml new file mode 100644 index 000000000..cbc946af0 --- /dev/null +++ b/config/locales/models/period/hu.yml @@ -0,0 +1,54 @@ +--- +hu: + period: + last_day: + label_short: "1N" + label: "Tegnap óta" + comparison_label: "vs. tegnap" + current_week: + label_short: "HE" + label: "Jelenlegi hét" + comparison_label: "vs. hét eleje" + last_7_days: + label_short: "7N" + label: "Utóbbi 7 nap" + comparison_label: "vs. előző hét" + current_month: + label_short: "HÓE" + label: "Jelenlegi hónap" + comparison_label: "vs. hónap eleje" + last_month: + label_short: "EHÓ" + label: "Előző hónap" + comparison_label: "vs. előző hónap" + last_30_days: + label_short: "30N" + label: "Utóbbi 30 nap" + comparison_label: "vs. utóbbi 30 nap" + last_90_days: + label_short: "90N" + label: "Utóbbi 90 nap" + comparison_label: "vs. előző negyedév" + current_year: + label_short: "ÉE" + label: "Jelenlegi év" + comparison_label: "vs. év eleje" + last_365_days: + label_short: "365N" + label: "Utóbbi 365 nap" + comparison_label: "vs. 1 évvel ezelőtt" + last_5_years: + label_short: "5É" + label: "Utóbbi 5 év" + comparison_label: "vs. 5 évvel ezelőtt" + last_10_years: + label_short: "10É" + label: "Utóbbi 10 év" + comparison_label: "vs. 10 évvel ezelőtt" + all_time: + label_short: "Mind" + label: "Teljes időszak" + comparison_label: "vs. kezdet" + custom: + label_short: "Egyéni" + label: "Egyéni időszak" diff --git a/config/locales/models/plaid_account/ca.yml b/config/locales/models/plaid_account/ca.yml new file mode 100644 index 000000000..29125eb3d --- /dev/null +++ b/config/locales/models/plaid_account/ca.yml @@ -0,0 +1,7 @@ +--- +ca: + activerecord: + errors: + models: + plaid_account: + no_balance: El compte de Plaid ha de tenir un saldo actual o disponible diff --git a/config/locales/models/plaid_account/hu.yml b/config/locales/models/plaid_account/hu.yml new file mode 100644 index 000000000..ef9407c16 --- /dev/null +++ b/config/locales/models/plaid_account/hu.yml @@ -0,0 +1,7 @@ +--- +hu: + activerecord: + errors: + models: + plaid_account: + no_balance: "A Plaid-számlának rendelkeznie kell aktuális vagy elérhető egyenleggel" diff --git a/config/locales/models/provider_warnings/ca.yml b/config/locales/models/provider_warnings/ca.yml index a78bd889d..d972ab171 100644 --- a/config/locales/models/provider_warnings/ca.yml +++ b/config/locales/models/provider_warnings/ca.yml @@ -1,4 +1,7 @@ --- ca: provider_warnings: - limited_investment_data: "Les dades d'inversió d'aquest proveïdor són limitades. Les etiquetes d'activitat (Compra, Venda, Dividend) no estan disponibles, cosa que pot afectar la precisió del pressupost. Considereu crear regles per excloure o categoritzar les transaccions d'inversió." + limited_investment_data: Les dades d'inversió d'aquest proveïdor són limitades. + Les etiquetes d'activitat (Compra, Venda, Dividend) no estan disponibles, cosa + que pot afectar la precisió del pressupost. Considera crear regles per excloure + o categoritzar les transaccions d'inversió. diff --git a/config/locales/models/recurring_transaction/ca.yml b/config/locales/models/recurring_transaction/ca.yml new file mode 100644 index 000000000..6fd1c3ed1 --- /dev/null +++ b/config/locales/models/recurring_transaction/ca.yml @@ -0,0 +1,7 @@ +--- +ca: + activerecord: + errors: + models: + recurring_transaction: + merchant_or_name_required: Cal indicar un comerç o un nom diff --git a/config/locales/models/recurring_transaction/hu.yml b/config/locales/models/recurring_transaction/hu.yml new file mode 100644 index 000000000..16e833a50 --- /dev/null +++ b/config/locales/models/recurring_transaction/hu.yml @@ -0,0 +1,7 @@ +--- +hu: + activerecord: + errors: + models: + recurring_transaction: + merchant_or_name_required: "Kereskedőt vagy nevet kötelező megadni" diff --git a/config/locales/models/rule/ca.yml b/config/locales/models/rule/ca.yml new file mode 100644 index 000000000..639de6ed1 --- /dev/null +++ b/config/locales/models/rule/ca.yml @@ -0,0 +1,9 @@ +--- +ca: + activerecord: + errors: + models: + rule: + duplicate_actions: La regla no pot tenir accions duplicades %{types} + min_actions: ha de tenir com a mínim una acció + nested_conditions: Les condicions compostes no es poden imbricar diff --git a/config/locales/models/rule/hu.yml b/config/locales/models/rule/hu.yml new file mode 100644 index 000000000..cb50ca38f --- /dev/null +++ b/config/locales/models/rule/hu.yml @@ -0,0 +1,9 @@ +--- +hu: + activerecord: + errors: + models: + rule: + min_actions: "legalább egy műveletet kötelező megadni" + duplicate_actions: "A szabálynak nem lehetnek duplikált műveletei: %{types}" + nested_conditions: "Összetett feltételek nem ágyazhatók egymásba" diff --git a/config/locales/models/rule_import/ca.yml b/config/locales/models/rule_import/ca.yml new file mode 100644 index 000000000..b0567f267 --- /dev/null +++ b/config/locales/models/rule_import/ca.yml @@ -0,0 +1,9 @@ +--- +ca: + activerecord: + errors: + models: + rule_import: + invalid_json: 'JSON no vàlid a les condicions o accions: %{message}' + min_actions: La regla ha de tenir com a mínim una acció + unsupported_resource_type: 'Tipus de recurs no compatible: %{resource_type}' diff --git a/config/locales/models/rule_import/hu.yml b/config/locales/models/rule_import/hu.yml new file mode 100644 index 000000000..a74c31546 --- /dev/null +++ b/config/locales/models/rule_import/hu.yml @@ -0,0 +1,9 @@ +--- +hu: + activerecord: + errors: + models: + rule_import: + unsupported_resource_type: "Nem támogatott erőforrástípus: %{resource_type}" + invalid_json: "Érvénytelen JSON a feltételekben vagy műveletekben: %{message}" + min_actions: "A szabálynak legalább egy művelete kell legyen" diff --git a/config/locales/models/simplefin_account/ca.yml b/config/locales/models/simplefin_account/ca.yml new file mode 100644 index 000000000..76763c4c5 --- /dev/null +++ b/config/locales/models/simplefin_account/ca.yml @@ -0,0 +1,7 @@ +--- +ca: + activerecord: + errors: + models: + simplefin_account: + no_balance: El compte de SimpleFIN ha de tenir un saldo actual o disponible diff --git a/config/locales/models/simplefin_account/hu.yml b/config/locales/models/simplefin_account/hu.yml new file mode 100644 index 000000000..2e61ef2f1 --- /dev/null +++ b/config/locales/models/simplefin_account/hu.yml @@ -0,0 +1,7 @@ +--- +hu: + activerecord: + errors: + models: + simplefin_account: + no_balance: "A SimpleFin-számlának rendelkeznie kell aktuális vagy elérhető egyenleggel" diff --git a/config/locales/models/sophtron_account/ca.yml b/config/locales/models/sophtron_account/ca.yml new file mode 100644 index 000000000..30ff9f50c --- /dev/null +++ b/config/locales/models/sophtron_account/ca.yml @@ -0,0 +1,7 @@ +--- +ca: + activerecord: + errors: + models: + sophtron_account: + no_balance: El compte de Sophtron ha de tenir un saldo actual o disponible diff --git a/config/locales/models/sophtron_account/hu.yml b/config/locales/models/sophtron_account/hu.yml new file mode 100644 index 000000000..62e97a274 --- /dev/null +++ b/config/locales/models/sophtron_account/hu.yml @@ -0,0 +1,7 @@ +--- +hu: + activerecord: + errors: + models: + sophtron_account: + no_balance: "A Sophtron-számlának rendelkeznie kell aktuális vagy elérhető egyenleggel" diff --git a/config/locales/models/sso_provider/ca.yml b/config/locales/models/sso_provider/ca.yml new file mode 100644 index 000000000..bed818f12 --- /dev/null +++ b/config/locales/models/sso_provider/ca.yml @@ -0,0 +1,14 @@ +--- +ca: + activerecord: + errors: + models: + sso_provider: + attributes: + settings: + metadata_url_invalid: L'URL de metadades de l'IdP ha de ser un URL vàlid + saml_cert_required: Cal el certificat de l'IdP o l'empremta del certificat + quan no s'utilitza l'URL de metadades + saml_url_required: Per als proveïdors SAML cal l'URL de metadades de + l'IdP o l'URL d'SSO de l'IdP + sso_url_invalid: L'URL d'SSO de l'IdP ha de ser un URL vàlid diff --git a/config/locales/models/sso_provider/hu.yml b/config/locales/models/sso_provider/hu.yml new file mode 100644 index 000000000..f66acd0f3 --- /dev/null +++ b/config/locales/models/sso_provider/hu.yml @@ -0,0 +1,12 @@ +--- +hu: + activerecord: + errors: + models: + sso_provider: + attributes: + settings: + saml_url_required: "SAML-szolgáltatókhoz kötelező megadni az IdP metaadat URL-jét vagy az IdP SSO URL-jét" + saml_cert_required: "Ha nem metaadat URL-t használsz, kötelező megadni az IdP tanúsítványt vagy a tanúsítvány ujjlenyomatát" + metadata_url_invalid: "Az IdP metaadat URL-nek érvényes URL-nek kell lennie" + sso_url_invalid: "Az IdP SSO URL-nek érvényes URL-nek kell lennie" diff --git a/config/locales/models/time_series/value/ca.yml b/config/locales/models/time_series/value/ca.yml index 9990ae475..02ccaf3b4 100644 --- a/config/locales/models/time_series/value/ca.yml +++ b/config/locales/models/time_series/value/ca.yml @@ -7,4 +7,3 @@ ca: attributes: value: must_be_a_money_or_numeric: ha de ser un Money o un valor numèric - diff --git a/config/locales/models/transaction/ca.yml b/config/locales/models/transaction/ca.yml new file mode 100644 index 000000000..4cb3f500e --- /dev/null +++ b/config/locales/models/transaction/ca.yml @@ -0,0 +1,11 @@ +--- +ca: + activerecord: + errors: + models: + transaction: + attributes: + attachments: + invalid_format: el fitxer %{index} té un format no compatible (%{file_format}) + too_large: el fitxer %{index} és massa gran (màxim %{max_mb}MB) + too_many: no es poden superar %{max} fitxers per transacció diff --git a/config/locales/models/transfer/ca.yml b/config/locales/models/transfer/ca.yml index 75f00b76c..ca846488a 100644 --- a/config/locales/models/transfer/ca.yml +++ b/config/locales/models/transfer/ca.yml @@ -15,9 +15,13 @@ ca: han d'estar dins d'un marge de 4 dies must_have_opposite_amounts: Les transaccions de transferència han de tenir imports oposats - must_have_single_currency: La transferència ha de tenir una sola moneda + must_have_single_currency: La transferència ha de tenir una sola divisa outflow_cannot_be_in_multiple_transfers: La transacció de sortida no pot formar part de múltiples transferències + different_accounts: Han de ser de comptes diferents + opposite_amounts: Han de tenir imports oposats + same_family: Han de ser de la mateixa família + within_days: Han d'estar dins de %{count} dies transfer: name: Transferència a %{to_account} payment_name: Pagament a %{to_account} diff --git a/config/locales/models/transfer/hu.yml b/config/locales/models/transfer/hu.yml index 9911b4615..e5677e476 100644 --- a/config/locales/models/transfer/hu.yml +++ b/config/locales/models/transfer/hu.yml @@ -4,6 +4,10 @@ hu: errors: models: transfer: + different_accounts: "Különböző számlákról kell lennie" + same_family: "Ugyanazon a háztartáson belül kell lennie" + opposite_amounts: "Ellentétes összegekkel kell rendelkeznie" + within_days: "%{count} napon belül kell lennie" attributes: base: inflow_cannot_be_in_multiple_transfers: A beérkező tranzakció nem szerepelhet több átutalásban diff --git a/config/locales/models/user/ca.yml b/config/locales/models/user/ca.yml index 0bcd625f9..33d47cbb9 100644 --- a/config/locales/models/user/ca.yml +++ b/config/locales/models/user/ca.yml @@ -4,8 +4,8 @@ ca: attributes: user: email: Correu electrònic - family: Família - family_id: Família + family: "%{moniker}" + family_id: "%{moniker}" first_name: Nom last_name: Cognom password: Contrasenya @@ -16,7 +16,6 @@ ca: attributes: base: cannot_deactivate_admin_with_other_users: L'administrador no pot eliminar - el compte mentre hi hagi altres usuaris. Elimina tots els membres - primer. + el compte mentre hi hagi altres usuaris. Elimina primer tots els membres. profile_image: invalid_file_size: la mida del fitxer ha de ser inferior a %{max_megabytes}MB diff --git a/config/locales/views/account_sharings/ca.yml b/config/locales/views/account_sharings/ca.yml new file mode 100644 index 000000000..2b932320e --- /dev/null +++ b/config/locales/views/account_sharings/ca.yml @@ -0,0 +1,30 @@ +--- +ca: + account_sharings: + show: + exclude_from_finances: Exclou dels meus pressupostos i informes + finance_toggle_description: Compta aquest compte al teu patrimoni net, pressupostos + i informes + include_in_finances: Inclou als meus pressupostos i informes + member: Membre + no_members: Encara no hi ha altres membres amb qui compartir aquest compte + owner_label: 'Propietari: %{name}' + permission: Permís + permissions: + full_control: Control total + full_control_description: Pot veure, editar i gestionar transaccions + read_only: Només visualització + read_only_description: Només pot veure les dades del compte + read_write: Pot anotar + read_write_description: Pot categoritzar, etiquetar i afegir notes + save: Desa la configuració de compartició + shared: Compartit + shared_with_count: + one: Compartit amb 1 membre + other: Compartit amb %{count} membres + subtitle: Controla qui pot veure i interactuar amb aquest compte + title: Compartició de comptes + update: + finance_toggle_success: Preferència d'inclusió a les finances actualitzada + not_owner: Només el propietari del compte pot gestionar la compartició + success: Configuració de compartició actualitzada diff --git a/config/locales/views/account_statements/ca.yml b/config/locales/views/account_statements/ca.yml new file mode 100644 index 000000000..84f732424 --- /dev/null +++ b/config/locales/views/account_statements/ca.yml @@ -0,0 +1,119 @@ +--- +ca: + account_statements: + account_tab: + coverage_description: Mesos històrics coberts amb extractes pujats i comprovacions + de saldo. + coverage_range: "%{start} - %{end}" + coverage_title: Cobertura d'extractes + empty: Encara no hi ha extractes enllaçats a aquest compte. + open_inbox: Safata d'entrada + statements_title: Extractes + year_label: Any de cobertura + balance: + unknown: Desconegut + coverage: + status: + ambiguous: Ambigu + covered: Cobert + duplicate: Duplicat + mismatched: No coincideix + missing: Falta + not_expected: No previst + create: + duplicates: + one: S'ha omès 1 extracte duplicat. + other: S'han omès %{count} extractes duplicats. + invalid_file_type: Puja un extracte en PDF, CSV o XLSX dins del límit de mida. + no_files: Selecciona com a mínim un fitxer d'extracte. + success: + one: 1 extracte pujat. + other: "%{count} extractes pujats." + destroy: + failure: No s'ha pogut eliminar l'extracte. + success: Extracte eliminat. + form: + account_upload: Puja l'extracte + files_hint: PDF, CSV o XLSX. Màxim %{max_size}MB per fitxer. + files_label: Fitxers d'extracte + inbox_upload: Puja + index: + account_label: Compte + confidence: Coincidència %{confidence} + empty_linked: Encara no hi ha extractes enllaçats. + empty_unmatched: La safata sense aparellar està buida. + leave_unmatched: Deixa sense aparellar + linked_title: Extractes enllaçats + no_suggestion: Sense suggeriment + storage_used: Emmagatzematge utilitzat + title: Arxiu d'extractes + unmatched_title: Safata sense aparellar + upload_description: Puja extractes a la safata, o tria un compte per enllaçar-los + immediatament. + upload_title: Puja extractes + link: + no_account: Tria un compte abans d'enllaçar aquest extracte. + success: Extracte enllaçat a %{account}. + period: + unknown: Període desconegut + reconciliation: + checks: + closing_balance: Saldo final + opening_balance: Saldo inicial + period_movement: Moviment del període + unknown_check: Comprovació desconeguda + matched: Coincideix + mismatched: No coincideix + unavailable: No comprovat + reject: + success: Coincidència d'extracte rebutjada. + show: + account_label: Compte + account_last4_hint: Últims quatre dígits del compte + account_name_hint: Pista del nom del compte + closing_balance: Saldo final + currency: Divisa + delete: Elimina + difference: Diferència + download: Descarrega + institution_name_hint: Pista de la institució + ledger_amount: Llibre de Sure + link_suggestion: Suggeriment d'enllaç + linked_to: Enllaçat a %{account}. + linking_title: Enllaç del compte + metadata_title: Metadades de l'extracte + no_suggestion: Encara no hi ha cap suggeriment de compte. + opening_balance: Saldo inicial + period_end_on: Final del període + period_start_on: Inici del període + reconciliation_title: Conciliació + reconciliation_unavailable: Afegeix un període d'extracte i un saldo inicial + o final, i comprova que Sure tingui historial de saldos per a aquestes dates. + reject: Rebutja + save: Desa l'extracte + statement_amount: Extracte + suggested_account: El compte suggerit és %{account} (confiança %{confidence}). + title: Extracte + unknown_value: Desconegut + unlink: Desenllaça + unmatched_account: Safata sense aparellar + status: + linked: Enllaçat + rejected: Rebutjat + unmatched: Sense aparellar + table: + account: Compte + actions: Accions + download: Descarrega + file: Fitxer + link_suggestion: Suggeriment d'enllaç + period: Període + reconciliation: Conciliació + reject: Rebutja el suggeriment + suggestion: Suggeriment + unlink: Desenllaça + view: Visualitza + unlink: + success: Extracte mogut de nou a la safata sense aparellar. + update: + success: Extracte actualitzat. diff --git a/config/locales/views/account_statements/hu.yml b/config/locales/views/account_statements/hu.yml new file mode 100644 index 000000000..0a3fc5966 --- /dev/null +++ b/config/locales/views/account_statements/hu.yml @@ -0,0 +1,116 @@ +--- +hu: + account_statements: + account_tab: + coverage_title: Kimutatás lefedettség + coverage_description: Feltöltött kimutatásokkal és egyenlegellenőrzésekkel lefedett korábbi hónapok. + coverage_range: "%{start} - %{end}" + empty: Még nincs ehhez a számlához kapcsolt kimutatás. + open_inbox: Beérkező + statements_title: Kimutatások + year_label: Lefedési év + balance: + unknown: Ismeretlen + coverage: + status: + ambiguous: Kétértelmű + covered: Lefedett + duplicate: Duplikált + mismatched: Eltérő + missing: Hiányzó + not_expected: Nem várt + create: + duplicates: + one: 1 duplikált kimutatás ki lett hagyva. + other: "%{count} duplikált kimutatás ki lett hagyva." + invalid_file_type: PDF, CSV vagy XLSX kimutatást tölts fel a méretkorláton belül. + no_files: Válassz legalább egy kimutatásfájlt. + success: + one: 1 kimutatás feltöltve. + other: "%{count} kimutatás feltöltve." + destroy: + failure: A kimutatást nem sikerült törölni. + success: Kimutatás törölve. + form: + account_upload: Kimutatás feltöltése + files_hint: PDF, CSV vagy XLSX. Maximum %{max_size} MB fájlonként. + files_label: Kimutatásfájlok + inbox_upload: Feltöltés + index: + account_label: Számla + confidence: "%{confidence} egyezés" + empty_linked: Még nincs kapcsolt kimutatás. + empty_unmatched: A kimutatás beérkező üres. + leave_unmatched: Hagyja párosítatlanul + linked_title: Kapcsolt kimutatások + no_suggestion: Nincs javaslat + storage_used: Felhasznált tárhely + title: Kimutatástár + unmatched_title: Párosítatlan beérkező + upload_description: Töltsd fel a kimutatásokat a beérkezőbe, vagy válassz számlát az azonnali összekapcsoláshoz. + upload_title: Kimutatások feltöltése + link: + no_account: Válassz számlát, mielőtt összekapcsolod ezt a kimutatást. + success: "Kimutatás összekapcsolva ezzel a számlával: %{account}." + period: + unknown: Az időszak ismeretlen + reconciliation: + checks: + closing_balance: Záró egyenleg + opening_balance: Nyitóegyenleg + period_movement: Időszaki mozgás + unknown_check: Ismeretlen ellenőrzés + matched: Egyezik + mismatched: Eltérő + unavailable: Nem ellenőrzött + reject: + success: Kimutatás-egyezési javaslat elutasítva. + show: + account_label: Számla + account_last4_hint: Számla utolsó négy számjegye + account_name_hint: Számlanév-tipp + closing_balance: Záró egyenleg + currency: Pénznem + delete: Törlés + difference: Különbség + download: Letöltés + institution_name_hint: Intézménynév-tipp + ledger_amount: Sure főkönyv + linked_to: "Összekapcsolva ezzel a számlával: %{account}." + linking_title: Számlakapcsolat + link_suggestion: Kapcsolati javaslat + metadata_title: Kimutatás metaadatok + no_suggestion: Még nincs számlajavaslat. + opening_balance: Nyitóegyenleg + period_end_on: Időszak vége + period_start_on: Időszak kezdete + reconciliation_title: Egyeztetés + reconciliation_unavailable: Adj meg egy kimutatási időszakot és nyitó- vagy záróegyenleget, majd győződj meg arról, hogy a Sure rendelkezik egyenlegelőzményekkel ezekre a dátumokra. + reject: Elutasítás + save: Kimutatás mentése + statement_amount: Kimutatás + suggested_account: A javasolt számla %{account} (%{confidence} bizonyossággal). + title: Kimutatás + unlink: Szétkapcsolás + unmatched_account: Párosítatlan beérkező + unknown_value: Ismeretlen + status: + linked: Összekapcsolt + rejected: Elutasított + unmatched: Párosítatlan + table: + account: Számla + actions: Műveletek + download: Letöltés + file: Fájl + link_suggestion: Kapcsolati javaslat + period: Időszak + reconciliation: Egyeztetés + reject: Javaslat elutasítása + suggestion: Javaslat + unlink: Szétkapcsolás + view: Megtekintés + unlink: + success: Kimutatás visszahelyezve a párosítatlan beérkezőbe. + update: + success: Kimutatás frissítve. diff --git a/config/locales/views/accounts/ca.yml b/config/locales/views/accounts/ca.yml index 47ea78944..ed1919ea0 100644 --- a/config/locales/views/accounts/ca.yml +++ b/config/locales/views/accounts/ca.yml @@ -3,31 +3,41 @@ ca: account: entries: destroy: - success: Èxit + success: Entrada eliminada correctament. accounts: account: + change_simplefin_account: Canvia el compte de SimpleFIN + complete_setup: Completa la configuració + default_label: Per defecte + delete: Elimina el compte + disable: Desactiva el compte + edit: Edita + enable: Activa el compte link_lunchflow: Enllaça amb Lunch Flow link_provider: Enllaça amb proveïdor + remove_default: Treu com a predeterminat + set_default: Estableix com a predeterminat + sharing: Compartició troubleshoot: Resolució de problemes unlink_provider: Desenllaça del proveïdor chart: data_not_available: Dades no disponibles per al període seleccionat confirm_unlink: confirm_button: Confirma i desenllaça - description_html: Estàs a punt de desenllaçar %{account_name} de - %{provider_name}. Això el convertirà en un compte manual. + description_html: Estàs a punt de desenllaçar %{account_name} + de %{provider_name}. Això el convertirà en un compte manual. title: Vols desenllaçar el compte del proveïdor? - warning_can_delete: Després de desenllaçar-lo, podràs eliminar el compte - si és necessari - warning_manual_updates: Hauràs d'afegir transaccions i actualitzar saldos - manualment - warning_no_sync: El compte ja no sincronitzarà automàticament amb el teu proveïdor + warning_can_delete: Després de desenllaçar-lo, podràs eliminar el compte si + és necessari + warning_manual_updates: Hauràs d'afegir transaccions i actualitzar saldos manualment + warning_no_sync: El compte ja no es sincronitzarà automàticament amb el teu proveïdor warning_title: Això significa warning_transactions_kept: Totes les transaccions i saldos existents es conservaran create: success: Compte %{type} creat destroy: - cannot_delete_linked: No es pot eliminar un compte enllaçat. Si us plau, desenllaça'l primer. + cannot_delete_linked: No es pot eliminar un compte enllaçat. Desenllaça'l primer. + failed: No s'ha pogut eliminar el recurs. Torna-ho a provar més tard. success: El compte %{type} s'ha programat per a l'eliminació empty: empty_message: Afegeix un compte mitjançant connexió, importació o introducció @@ -36,16 +46,17 @@ ca: no_accounts: Encara no hi ha cap compte form: additional_details: Detalls addicionals - balance: Saldo actual - institution_domain_label: Domini de l'institució + balance: 'Saldo a la data:' + institution_domain_label: Domini de la institució institution_domain_placeholder: p. ex., chase.com - institution_name_label: Nom de l'institució + institution_name_label: Nom de la institució institution_name_placeholder: p. ex., Chase Bank name_label: Nom del compte name_placeholder: Exemple de nom de compte notes_label: Notes - notes_placeholder: Emmagatzema informació addicional com números de compte, codis de sortida, - IBAN, números de ruta, etc. + notes_placeholder: Emmagatzema informació addicional com números de compte, + codis de sortida, IBAN, números de ruta, etc. + opening_balance_date_label: Data del saldo inicial index: accounts: Comptes manual_accounts: @@ -53,6 +64,10 @@ ca: new_account: Nou compte sync: Sincronitza-ho tot new: + container: + close: Tanca + navigate: Navega + select: Selecciona import_accounts: Importa comptes method_selector: connected_entry: Enllaça el compte @@ -62,11 +77,15 @@ ca: manual_entry: Introdueix el saldo del compte title: Com vols afegir-lo? title: Què vols afegir? + not_authorized: No tens permís per gestionar aquest compte select_provider: already_linked: Aquest compte ja està enllaçat a un proveïdor description: Tria quin proveïdor vols utilitzar per enllaçar %{account_name} no_providers: Actualment no hi ha cap proveïdor configurat title: Selecciona un proveïdor per enllaçar + set_default: + depository_only: Només els comptes d'efectiu i de targeta de crèdit es poden + establir com a predeterminats. show: activity: amount: Import @@ -77,17 +96,27 @@ ca: entry: entrada filter: Filtra new: Nou + new_activity: Nova activitat new_balance: Nou saldo + new_trade: Nova operació new_transaction: Nova transacció + new_transfer: Nova transferència no_entries: No s'han trobat entrades pending: Pendent search: placeholder: Cerca entrades per nom + search_placeholder: Cerca entrades per nom status: Estat title: Activitat chart: balance: Saldo owed: Import degut + header: + complete_setup: Completa la configuració + limited_fx_history_warning: L'historial de tipus de canvi només està disponible + a partir del %{date}. Les transaccions anteriors a aquesta data utilitzen + conversions de divisa aproximades — això pot passar quan el proveïdor de FX + només ofereix una finestra històrica limitada. menu: confirm_accept: Elimina "%{name}" confirm_body_html: "

En eliminar aquest compte, s'esborrarà l'historial @@ -97,9 +126,19 @@ ca: restaurar la informació del compte perquè hauràs d'afegir-lo com un compte nou.

" confirm_title: Vols eliminar el compte? + delete_account: Elimina el compte edit: Edita import: Importa transaccions + import_trades: Importa operacions + import_transactions: Importa transaccions manage: Gestiona els comptes + sharing: Compartició + statements: Extractes + tabs: + activity: Activitat + holdings: Posicions + overview: Resum + statements: Extractes sidebar: configure_providers: Configura els teus proveïdors aquí. missing_data: Falten dades històriques @@ -114,8 +153,26 @@ ca: all: Tots assets: Actius debts: Deutes + subtype_regions: + au: Austràlia + ca: Canadà + eu: Europa + generic: General + in: Índia + uk: Regne Unit + us: Estats Units sync_all: syncing: Sincronitzant comptes... + tax_treatment_descriptions: + tax_advantaged: Beneficis fiscals especials amb condicions + tax_deferred: Aportacions deduïbles, tributació en retirar + tax_exempt: Aportacions després d'impostos, guanys no tributats + taxable: Guanys tributats en realitzar-se + tax_treatments: + tax_advantaged: Amb avantatge fiscal + tax_deferred: Tributació diferida + tax_exempt: Exempt d'impostos + taxable: Subjecte a impostos types: credit_card: Targeta de crèdit crypto: Cripto @@ -123,12 +180,22 @@ ca: investment: Inversió loan: Préstec other_asset: Altre actiu - other_liability: Altra passiu + other_liability: Altre passiu property: Propietat vehicle: Vehicle + types_plural: + credit_card: Targetes de crèdit + crypto: Cripto + depository: Efectiu + investment: Inversions + loan: Préstecs + other_asset: Altres actius + other_liability: Altres passius + property: Propietats + vehicle: Vehicles unlink: - error: "No s'ha pogut desenllaçar el compte: %{error}" - generic_error: S'ha produït un error inesperat. Si us plau, torna-ho a intentar. + error: 'No s''ha pogut desenllaçar el compte: %{error}' + generic_error: S'ha produït un error inesperat. Torna-ho a intentar. not_linked: El compte no està enllaçat a cap proveïdor success: El compte s'ha desenllaçat correctament. Ara és un compte manual. update: diff --git a/config/locales/views/accounts/en.yml b/config/locales/views/accounts/en.yml index f927e3424..a18a3de41 100644 --- a/config/locales/views/accounts/en.yml +++ b/config/locales/views/accounts/en.yml @@ -142,6 +142,16 @@ en: credit_card: Credit Card loan: Loan other_liability: Other Liability + types_plural: + depository: Cash + investment: Investments + crypto: Crypto + property: Properties + vehicle: Vehicles + other_asset: Other Assets + credit_card: Credit Cards + loan: Loans + other_liability: Other Liabilities tax_treatments: taxable: Taxable tax_deferred: Tax-Deferred diff --git a/config/locales/views/accounts/hu.yml b/config/locales/views/accounts/hu.yml index 49d72fb98..6041d3d91 100644 --- a/config/locales/views/accounts/hu.yml +++ b/config/locales/views/accounts/hu.yml @@ -1,8 +1,13 @@ --- hu: + account: + entries: + destroy: + success: "Tétel sikeresen törölve." accounts: not_authorized: "Nincs jogosultságod ennek a számlának a kezeléséhez" account: + complete_setup: Beállítás befejezése edit: Szerkesztés link_lunchflow: Összekapcsolás a Lunch Flow-val link_provider: Összekapcsolás szolgáltatóval @@ -52,6 +57,10 @@ hu: syncing: "Számlák szinkronizálása..." new: import_accounts: Számlák importálása + container: + select: Kiválasztás + navigate: Navigálás + close: Bezárás method_selector: connected_entry: Számla összekapcsolása connected_entry_eu: EU-s számla összekapcsolása @@ -62,6 +71,11 @@ hu: title: Mit szeretnél hozzáadni? show: limited_fx_history_warning: "Az árfolyam-előzmények csak %{date} dátumtól érhetők el. Az ezt megelőző tranzakciókhoz közelítő árfolyamok kerülnek alkalmazásra – ez akkor fordulhat elő, ha a devizaárfolyam-szolgáltató csak korlátozott előzményadatokat kínál." + tabs: + activity: Tevékenység + holdings: Portfólió + overview: Áttekintés + statements: Kimutatások activity: amount: Összeg balance: Egyenleg @@ -80,20 +94,26 @@ hu: pending: Függőben lévő search: placeholder: Tételek keresése név alapján + search_placeholder: Tételek keresése név alapján status: Állapot title: Tevékenység chart: balance: Egyenleg owed: Tartozás összege + header: + complete_setup: Beállítás befejezése menu: confirm_accept: '"%{name}" törlése' confirm_body_html: "

A számla törlésével törlöd az értéktörténetét is, ami hatással van az összesített fiókodra. Ez közvetlenül befolyásolja a nettó vagyonszámítást és a számlagrafikonokat.


A törlés után a számla adatait nem lehet visszaállítani – ha szükséges, új számlaként kell hozzáadni.

" confirm_title: Törlöd a számlát? + delete_account: Számla törlése edit: Szerkesztés import: Tranzakciók importálása import_trades: Ügyletek importálása import_transactions: Tranzakciók importálása manage: Számlák kezelése + sharing: Megosztás + statements: Kimutatások update: success: "%{type} számla frissítve" sidebar: @@ -102,9 +122,9 @@ hu: configure_providers: Konfiguráld itt a szolgáltatóidat. tabs: all: Összes - assets: Eszközök + assets: Vagyon debts: Kötelezettségek - new_asset: Új eszköz + new_asset: Új vagyonelem new_debt: Új kötelezettség new_account: Új számla new_account_group: "Új %{account_group}" @@ -114,10 +134,20 @@ hu: crypto: Kripto property: Ingatlan vehicle: Jármű - other_asset: Egyéb eszköz + other_asset: Egyéb vagyon credit_card: Hitelkártya loan: Hitel other_liability: Egyéb kötelezettség + types_plural: + depository: Készpénz + investment: Befektetések + crypto: Kripto + property: Ingatlanok + vehicle: Járművek + other_asset: Egyéb vagyon + credit_card: Hitelkártyák + loan: Hitelek + other_liability: Egyéb kötelezettségek tax_treatments: taxable: Adóköteles tax_deferred: Halasztott adózású @@ -134,6 +164,7 @@ hu: ca: Kanada au: Ausztrália eu: Európa + in: India generic: Általános confirm_unlink: title: Leválasztod a számlát a szolgáltatóról? diff --git a/config/locales/views/admin/invitations/ca.yml b/config/locales/views/admin/invitations/ca.yml new file mode 100644 index 000000000..0d12897a7 --- /dev/null +++ b/config/locales/views/admin/invitations/ca.yml @@ -0,0 +1,8 @@ +--- +ca: + admin: + invitations: + destroy: + success: Invitació eliminada. + destroy_all: + success: S'han eliminat totes les invitacions d'aquesta família. diff --git a/config/locales/views/admin/sso_providers/ca.yml b/config/locales/views/admin/sso_providers/ca.yml index 3906fd918..41ba67d6a 100644 --- a/config/locales/views/admin/sso_providers/ca.yml +++ b/config/locales/views/admin/sso_providers/ca.yml @@ -5,8 +5,8 @@ ca: create: success: El proveïdor SSO s'ha creat correctament. destroy: - confirm: Estàs segur que vols eliminar aquest proveïdor? Aquesta acció no es - pot desfer. + confirm: Segur que vols eliminar aquest proveïdor? Aquesta acció no es pot + desfer. success: El proveïdor SSO s'ha eliminat correctament. edit: description: Actualitza la configuració per a %{label} @@ -18,99 +18,130 @@ ca: cancel: Cancel·la client_id_help: ID del client OAuth del teu proveïdor d'identitat client_id_label: ID del client - client_id_placeholder: el-teu-id-client + client_id_placeholder: el-teu-id-de-client client_secret_help: Secret del client OAuth (xifrat a la base de dades) - client_secret_help_existing: " - deixa en blanc per mantenir l'existent" + client_secret_help_existing: Deixa-ho en blanc per mantenir el secret existent client_secret_label: Secret del client - client_secret_placeholder_existing: "••••••••••••••••" - client_secret_placeholder_new: el-teu-secret-client + client_secret_placeholder_existing: "••••••••" + client_secret_placeholder_new: el-teu-secret-de-client copy_button: Copia - default_role_help: Rol assignat als usuaris creats mitjançant aprovisionament + create_provider: Crea el proveïdor + default_role_help: Rol assignat als usuaris creats mitjançant l'aprovisionament de comptes SSO just-in-time (JIT). Per defecte és Membre. default_role_label: Rol per defecte per a nous usuaris - enabled_help: Els usuaris poden iniciar sessió amb aquest proveïdor quan està - habilitat - enabled_label: Habilita aquest proveïdor - errors_title: "%{count} error ha prohibit que aquest proveïdor s' desa:" - groups_help: Llista separada per comes dels noms de grups del IdP. Usa * per coincidir - amb tots els grups. - icon_help: Nom de la icona Lucide (opcional) - icon_label: Icona - icon_placeholder: p. ex., key, google, github - idp_cert_fingerprint: Emprempta del certificat (alternativa) + enabled_help: Els usuaris podran iniciar sessió amb aquest proveïdor quan + estigui activat + enabled_label: Activa aquest proveïdor + errors_title: + one: "%{count} error ha impedit desar aquest proveïdor:" + other: "%{count} errors han impedit desar aquest proveïdor:" + groups_help: Llista separada per comes amb els noms dels grups del IdP. Fes + servir * per fer coincidir tots els grups. + guest_groups: Grups de convidats + icon_help: Nom de la icona Lucide per al botó d'inici de sessió + icon_label: Icona (opcional) + icon_placeholder: p. ex., key, shield + idp_cert_fingerprint: Empremta del certificat (alternativa) idp_certificate: Certificat del IdP - idp_certificate_help: Certificat X.509 en format PEM. Obligatori si no s'utilitza - l'URL de metadades. + idp_certificate_help: Certificat X.509 en format PEM. Obligatori si no fas + servir l'URL de metadades. idp_metadata_url: URL de metadades del IdP - idp_metadata_url_help: URL a les metadades SAML del teu IdP. Si es proporciona, - altres configuracions SAML es configuraran automàticament. + idp_metadata_url_help: URL de les metadades SAML del teu IdP. Si la indiques, + la resta de paràmetres SAML es configuraran automàticament. idp_slo_url: URL SLO del IdP (opcional) idp_sso_url: URL SSO del IdP - issuer_help: URL emisor OIDC (validarà el punt final .well-known/openid-configuration) - issuer_label: Emisor - issuer_placeholder: https://accounts.google.com + issuer_help: URL de l'emissor OIDC (valida .well-known/openid-configuration) + issuer_label: URL de l'emissor + issuer_placeholder: https://el-teu-idp.exemple.com/realms/el-teu-realm label_help: Text del botó que es mostra als usuaris - label_label: Etiqueta + label_label: Etiqueta del botó label_placeholder: p. ex., Inicia sessió amb Keycloak - manual_saml_config: Configuració manual (si no s'utilitza l'URL de metadades) - manual_saml_help: Només utilitza aquesta configuració si el teu IdP no proporciona + manual_saml_config: Configuració manual (si no fas servir URL de metadades) + manual_saml_help: Fes servir aquesta configuració només si el teu IdP no proporciona una URL de metadades. member_groups: Grups de membres - name_help: Identificador únic (només minúscules, números, subratllats) + name_help: Identificador únic (només minúscules, números i guions baixos) name_id_email: Adreça de correu electrònic (per defecte) name_id_format: Format NameID name_id_persistent: Persistent name_id_transient: Transient name_id_unspecified: No especificat name_label: Nom - name_placeholder: p. ex., openid_connect, keycloak, authentik + name_placeholder: p. ex., keycloak, authentik oauth_configuration: Configuració OAuth/OIDC - prompt_consent: Força consentiment (autoritzar de nou) + prompt_consent: Força el consentiment (torna a autoritzar) prompt_default: Per defecte (decideix el IdP) - prompt_help: Controla com el IdP demana a l'usuari durant l'autenticació. - prompt_label: Prompt d'autenticació - prompt_login: Força inici de sessió (torna a autenticar) - prompt_none: Sense prompt (autenticació silenciosa) - prompt_select_account: Selecció de compte (triar compte) - provisioning_title: Proveïment d'usuaris - redirect_uri_help: URL de callback per configurar al teu proveïdor d'identitat - redirect_uri_label: URI de redirecció - redirect_uri_placeholder: https://teudomini.com/auth/openid_connect/callback + prompt_help: Controla com el IdP demana l'autenticació a l'usuari. + prompt_label: Indicador d'autenticació + prompt_login: Força l'inici de sessió (torna a autenticar) + prompt_none: Sense indicador (autenticació silenciosa) + prompt_select_account: Selecció de compte (tria el compte) + provisioning_title: Aprovisionament d'usuaris + redirect_uri_help: Configura aquesta URL al teu proveïdor d'identitat + redirect_uri_label: URL de retorn + redirect_uri_placeholder: https://elteudomini.com/auth/openid_connect/callback role_admin: Administrador - role_mapping_help: Mapa els grups/claims del IdP als rols de l'aplicació. Als usuaris - se'ls assigna el rol més alt que coincideix. Deixa en blanc per utilitzar el rol per defecte - de dalt. - role_mapping_title: Mapa de grups a rols (Opcional) + role_guest: Convidat + role_mapping_help: Mapeja els grups/claims del IdP als rols de l'aplicació. + Als usuaris se'ls assigna el rol més alt que coincideixi. Deixa-ho en blanc + per utilitzar el rol per defecte de dalt. + role_mapping_title: Mapatge de grups a rols (opcional) role_member: Membre role_super_admin: Super administrador saml_configuration: Configuració SAML - scopes_help: Llista separada per espais d'àmbits OIDC. Deixa en blanc per defecte - (openid email profile). Afegeix 'groups' per recuperar claims de grup. + saml_sp_callback_url_help: Configura aquesta URL com a URL del servei consumidor + d'assercions al teu IdP + saml_sp_callback_url_label: URL de retorn del SP (URL ACS) + scopes_help: Llista separada per espais amb els àmbits OIDC. Deixa-ho en blanc + per als valors per defecte (openid email profile). Afegeix 'groups' per + recuperar els claims de grup. scopes_label: Àmbits personalitzats - strategy_help: L'estratègia d'autenticació a utilitzar + strategy_github: GitHub + strategy_google_oauth2: Google OAuth2 + strategy_help: L'estratègia d'autenticació que cal utilitzar strategy_label: Estratègia + strategy_openid_connect: OpenID Connect + strategy_saml: SAML 2.0 submit: Desa el proveïdor super_admin_groups: Grups de super administradors test_connection: Prova la connexió + update_provider: Actualitza el proveïdor index: add_provider: Afegeix proveïdor - description: Gestiona proveïdors d'autenticació d'inici de sessió únic per a la teva instància + configuration_mode: Mode de configuració + configured_providers: Proveïdors configurats + db_backed_providers: Proveïdors basats en base de dades + db_backed_providers_description: Carrega els proveïdors des de la base de + dades en lloc de la configuració YAML + db_backed_providers_help_html: Defineix AUTH_PROVIDERS_SOURCE=db per activar els proveïdors + basats en base de dades. Això permet fer canvis sense reiniciar el servidor. + delete: Elimina + description: Gestiona proveïdors d'autenticació d'inici de sessió únic per + a la teva instància. + disable: Desactiva + disabled: Desactivat + edit: Edita + enable: Activa + enabled: Activat env_configured: Entorn/YAML legacy_providers_notice: Aquests proveïdors estan configurats mitjançant variables - d'entorn o YAML i no es poden gestionar mitjançant aquesta interfície. Per gestionar-los - aquí, migrant-los a proveïdors basats en base de dades activant AUTH_PROVIDERS_SOURCE=db - i recreant-los a la interfície d'usuari. - legacy_providers_title: Proveïdors configurats a l'entorn - no_providers_message: Comença afegint el teu primer proveïdor SSO. + d'entorn o YAML i no es poden gestionar des d'aquesta interfície. Per gestionar-los + aquí, migra'ls a proveïdors basats en base de dades activant AUTH_PROVIDERS_SOURCE=db + i recreant-los a la interfície. + legacy_providers_title: Proveïdors configurats per entorn + no_providers_message: Encara no hi ha proveïdors SSO configurats. no_providers_title: No hi ha proveïdors SSO - note: Els canvis als proveïdors SSO requereixen un reinici del servidor per fer efecte. - Alternativament, activa la bandera de característica AUTH_PROVIDERS_SOURCE=db per carregar - proveïdors de la base de dades de manera dinàmica. + note: Els canvis als proveïdors SSO requereixen un reinici del servidor per + fer efecte. Alternativament, activa la bandera de característica AUTH_PROVIDERS_SOURCE=db + per carregar els proveïdors des de la base de dades de manera dinàmica. + page_title: Proveïdors SSO + restart_required: Els canvis requereixen un reinici del servidor per fer efecte. table: actions: Accions disabled: Desactivat - enabled: Actiu - issuer: Emisor + enabled: Activat + issuer: Emissor name: Nom status: Estat strategy: Estratègia @@ -119,8 +150,8 @@ ca: description: Configura un nou proveïdor d'autenticació d'inici de sessió únic title: Afegeix proveïdor SSO toggle: - confirm_disable: Estàs segur que vols desactivar aquest proveïdor? - confirm_enable: Estàs segur que vols activar aquest proveïdor? + confirm_disable: Segur que vols desactivar aquest proveïdor? + confirm_enable: Segur que vols activar aquest proveïdor? success_disabled: El proveïdor SSO s'ha desactivat correctament. success_enabled: El proveïdor SSO s'ha activat correctament. update: diff --git a/config/locales/views/admin/sso_providers/en.yml b/config/locales/views/admin/sso_providers/en.yml index f563c38a7..bca7ac709 100644 --- a/config/locales/views/admin/sso_providers/en.yml +++ b/config/locales/views/admin/sso_providers/en.yml @@ -93,7 +93,9 @@ en: submit: "Save Provider" create_provider: "Create Provider" update_provider: "Update Provider" - errors_title: "%{count} error prohibited this provider from being saved:" + errors_title: + one: "An error prohibited this provider from being saved:" + other: "%{count} errors prohibited this provider from being saved:" provisioning_title: "User Provisioning" default_role_label: "Default Role for New Users" default_role_help: "Role assigned to users created via just-in-time (JIT) SSO account provisioning. Defaults to Member." diff --git a/config/locales/views/admin/sso_providers/hu.yml b/config/locales/views/admin/sso_providers/hu.yml index c3f0d3497..e08bfcb7b 100644 --- a/config/locales/views/admin/sso_providers/hu.yml +++ b/config/locales/views/admin/sso_providers/hu.yml @@ -4,12 +4,25 @@ hu: unauthorized: "Nincs jogosultságod ehhez a területhez." sso_providers: index: + page_title: "SSO-szolgáltatók" title: "SSO-szolgáltatók" description: "Az egyszeri bejelentkezési hitelesítési szolgáltatók kezelése a példányodhoz" + restart_required: "A módosítások érvénybe lépéséhez szerver-újraindítás szükséges." + configured_providers: "Konfigurált szolgáltatók" add_provider: "Szolgáltató hozzáadása" no_providers_title: "Nincsenek SSO-szolgáltatók" no_providers_message: "Kezdd az első SSO-szolgáltató hozzáadásával." note: "Az SSO-szolgáltatók módosításaihoz szerver-újraindítás szükséges. Alternatívaként engedélyezd az AUTH_PROVIDERS_SOURCE=db feature flag-et, hogy a szolgáltatók dinamikusan töltődjenek be az adatbázisból." + enabled: "Engedélyezve" + disabled: "Letiltva" + edit: "Szerkesztés" + enable: "Engedélyezés" + disable: "Letiltás" + delete: "Törlés" + configuration_mode: "Konfigurációs mód" + db_backed_providers: "Adatbázis-alapú szolgáltatók" + db_backed_providers_description: "Szolgáltatók betöltése az adatbázisból YAML konfiguráció helyett" + db_backed_providers_help_html: "Állítsd be az AUTH_PROVIDERS_SOURCE=db értéket az adatbázis-alapú szolgáltatók engedélyezéséhez. Ez lehetővé teszi a módosításokat szerver-újraindítás nélkül." table: name: "Név" strategy: "Stratégia" @@ -44,6 +57,10 @@ hu: oauth_configuration: "OAuth/OIDC konfiguráció" strategy_label: "Stratégia" strategy_help: "A használandó hitelesítési stratégia" + strategy_openid_connect: "OpenID Connect" + strategy_saml: "SAML 2.0" + strategy_google_oauth2: "Google OAuth2" + strategy_github: "GitHub" name_label: "Név" name_placeholder: "pl.: openid_connect, keycloak, authentik" name_help: "Egyedi azonosító (csak kisbetűk, számok és aláhúzás)" @@ -69,9 +86,13 @@ hu: redirect_uri_label: "Átirányítási URI" redirect_uri_placeholder: "https://a-te-domainedet.com/auth/openid_connect/callback" redirect_uri_help: "Visszahívási URL, amelyet konfigurálni kell az identitásszolgáltatódban" + saml_sp_callback_url_label: "SP visszahívási URL (ACS URL)" + saml_sp_callback_url_help: "Ezt az URL-t kell megadni az Assertion Consumer Service URL-ként az IdP-ben" copy_button: "Másolás" cancel: "Mégse" submit: "Szolgáltató mentése" + create_provider: "Szolgáltató létrehozása" + update_provider: "Szolgáltató frissítése" errors_title: "%{count} hiba akadályozta meg a szolgáltató mentését:" provisioning_title: "Felhasználói kiépítés" default_role_label: "Alapértelmezett szerepkör az új felhasználókhoz" diff --git a/config/locales/views/admin/users/ca.yml b/config/locales/views/admin/users/ca.yml index e0fa5149a..adb977c85 100644 --- a/config/locales/views/admin/users/ca.yml +++ b/config/locales/views/admin/users/ca.yml @@ -3,26 +3,58 @@ ca: admin: users: index: - description: Gestiona els rols d'usuari per a la teva instància. Els super administradors poden accedir - a la configuració de proveïdors SSO i la gestió d'usuaris. + description: Gestiona els rols d'usuari per a la teva instància. Els super + administradors poden accedir a la configuració de proveïdors SSO i a la + gestió d'usuaris. + family_summary: "%{members} membres · %{accounts} comptes · %{transactions} + transaccions" + filters: + role: Rol + role_all: Tots els rols + submit: Filtra + trial_all: Tots + trial_expiring_soon: Caduca en 7 dies + trial_status: Estat de la prova + trial_trialing: En prova + invitations: + delete: Elimina + delete_all: Elimina-ho tot + expires: Caduca %{date} + pending_label: Convidat (pendent) + no_subscription: Sense subscripció no_users: No s'han trobat usuaris. + not_available: n/d role_descriptions: - admin: Administrador familiar. Pot accedir a configuracions avançades com claus API, - importacions i prompts d'IA. + admin: Administrador familiar. Pot accedir a configuracions avançades com + claus API, importacions i prompts d'IA. + guest: Experiència centrada en l'assistent amb permisos restringits intencionadament + per a fluxos d'introducció. member: Accés bàsic d'usuari. Pot gestionar els seus propis comptes, transaccions i configuracions. - super_admin: Administrador d'instància. Pot gestionar proveïdors SSO, rols d'usuari - i personificar usuaris per suport. - role_descriptions_title: Descripcions de rols + super_admin: Administrador d'instància. Pot gestionar proveïdors SSO, rols + d'usuari i personificar usuaris per donar suport. + role_descriptions_title: Descripcions dels rols roles: admin: Administrador + guest: Convidat member: Membre super_admin: Super administrador - section_title: Usuaris + section_title: Famílies / Grups + summary: + trials_expiring_7_days: Proves que caduquen en els pròxims 7 dies + table: + family_accounts: Comptes familiars + family_transactions: Transaccions familiars + last_login: Últim inici de sessió + never: Mai + role: Rol + session_count: Nombre de sessions + trial_ends_at: Fi de la prova + user: Usuari title: Gestió d'usuaris + trial_ends_at: Fi de la prova + unnamed_family: Família/grup sense nom you: "(Tu)" - trial_ends_at: Fi de prova - not_available: n/a update: failure: No s'ha pogut actualitzar el rol d'usuari. - success: El rol d'usuari s'ha actualitzat correctament. + success: Rol d'usuari actualitzat correctament. diff --git a/config/locales/views/beta/ca.yml b/config/locales/views/beta/ca.yml new file mode 100644 index 000000000..9484728c3 --- /dev/null +++ b/config/locales/views/beta/ca.yml @@ -0,0 +1,5 @@ +--- +ca: + beta: + not_enabled: Aquesta funció està en beta. Activa les funcions beta a Configuració + → Preferències per provar-la. diff --git a/config/locales/views/binance_items/ca.yml b/config/locales/views/binance_items/ca.yml new file mode 100644 index 000000000..c33580047 --- /dev/null +++ b/config/locales/views/binance_items/ca.yml @@ -0,0 +1,81 @@ +--- +ca: + binance_item: + syncer: + accounts_need_setup: + one: "%{count} compte necessita configuració" + other: "%{count} comptes necessiten configuració" + calculating_balances: Calculant saldos... + checking_configuration: Comprovant la configuració del compte... + checking_credentials: Comprovant credencials... + credentials_invalid: Credencials de l'API no vàlides. Revisa la teva clau API + i el secret. + importing_accounts: Important comptes des de Binance... + processing_accounts: Processant dades del compte... + binance_items: + binance_item: + delete: Elimina + deletion_in_progress: Eliminant... + import_accounts_menu: Importa compte + no_accounts_message: El teu portafoli de Binance apareixerà aquí després de + sincronitzar. + no_accounts_title: No s'han trobat comptes + provider_name: Binance + reconnect: Les credencials necessiten actualització + setup_action: Importa compte + setup_description: Selecciona quins portafolis de Binance vols seguir. + setup_needed: Compte a punt per importar + stale_rate_warning: El saldo és aproximat — el tipus de canvi exacte per a %{date} + no estava disponible. S'actualitzarà a la propera sincronització. + status: Darrera sincronització fa %{timestamp} + status_never: Mai sincronitzat + status_with_summary: Darrera sincronització fa %{timestamp} - %{summary} + sync_status: + all_synced: + one: "%{count} compte sincronitzat" + other: "%{count} comptes sincronitzats" + no_accounts: No s'han trobat comptes + partial_sync: "%{linked_count} sincronitzats, %{unlinked_count} necessiten + configuració" + syncing: Sincronitzant... + update_credentials: Actualitza les credencials + complete_account_setup: + no_accounts: No hi ha comptes per importar + none_selected: No s'ha seleccionat cap compte + success: + one: S'ha importat %{count} compte + other: S'han importat %{count} comptes + create: + default_name: Binance + success: S'ha connectat correctament a Binance! El teu compte s'està sincronitzant. + destroy: + success: S'ha programat la connexió Binance per a la seva eliminació. + link_existing_account: + errors: + invalid_binance_account: Compte Binance no vàlid + only_manual: Només els comptes manuals es poden enllaçar a Binance + success: S'ha enllaçat correctament al compte Binance + select_existing_account: + cancel: Cancel·la + check_provider_health: Comprova que les teves credencials de l'API de Binance + siguin vàlides + currently_linked_to: 'Actualment enllaçat a: %{account_name}' + link: Enllaça + no_accounts_found: No s'han trobat comptes Binance. + title: Enllaça compte Binance + wait_for_sync: Espera que Binance acabi la sincronització + setup_accounts: + accounts_count: + one: "%{count} compte disponible" + other: "%{count} comptes disponibles" + cancel: Cancel·la + creating: Important... + import_selected: Importa els seleccionats + instructions: Selecciona els portafolis de Binance que vols importar. Només + es mostren els portafolis amb saldos. + no_accounts: Tots els comptes s'han importat. + select_all: Selecciona-ho tot + subtitle: Selecciona quins portafolis vols seguir + title: Importa compte Binance + update: + success: La configuració de Binance s'ha actualitzat correctament. diff --git a/config/locales/views/brex_items/ca.yml b/config/locales/views/brex_items/ca.yml new file mode 100644 index 000000000..cbe5595c7 --- /dev/null +++ b/config/locales/views/brex_items/ca.yml @@ -0,0 +1,308 @@ +--- +ca: + brex_items: + account_metadata: + provider: Brex + separator: " • " + api_error: + common_issues: 'Problemes habituals:' + expired_credentials: Genera un nou token API des de Brex. + expired_credentials_label: 'Credencials caducades:' + heading: No s'ha pogut connectar a Brex + invalid_token: Revisa el teu token API a la configuració del proveïdor. + invalid_token_label: 'Token API no vàlid:' + network: Comprova la teva connexió a internet. + network_label: 'Problema de xarxa:' + permissions: Assegura't que el teu token té els permisos necessaris només de + lectura per a comptes i transaccions. + permissions_label: 'Permisos insuficients:' + service: L'API de Brex pot estar temporalment no disponible. + service_label: 'Servei caigut:' + settings_link: Revisa la configuració del proveïdor + title: Error de connexió Brex + brex_item: + accounts_need_setup: Els comptes necessiten configuració + delete: Elimina la connexió + deletion_in_progress: eliminació en curs... + error: Error + no_accounts_description: Aquesta connexió encara no té comptes enllaçats. + no_accounts_title: No hi ha comptes + setup_action: Configura els nous comptes + setup_description: "%{linked} de %{total} comptes enllaçats. Tria els tipus + de compte per als teus nous comptes Brex importats." + setup_needed: Nous comptes a punt per configurar + status: Sincronitzat fa %{timestamp} + status_never: Mai sincronitzat + status_with_summary: Darrera sincronització fa %{timestamp} - %{summary} + syncing: Sincronitzant... + total: Total + unlinked: Sense enllaç + complete_account_setup: + all_skipped: S'han omès tots els comptes. No s'ha creat cap compte. + creation_failed: 'No s''han pogut crear els comptes: %{error}' + creation_failed_count: No s'han pogut crear %{count} compte(s). + no_accounts: No hi ha comptes per configurar. + partial_skipped: S'han creat correctament %{created_count} compte(s); s'han + omès %{skipped_count} compte(s). + partial_success: S'han creat correctament %{created_count} compte(s), però %{failed_count} + compte(s) han fallat. + success: S'han creat correctament %{count} compte(s). + unexpected_error: S'ha produït un error inesperat. + create: + success: La connexió Brex s'ha creat correctament + default_card_name: Targeta Brex + default_cash_name: Brex Cash %{id} + default_connection_name: Connexió Brex + destroy: + success: La connexió Brex s'ha eliminat + entries: + default_name: Transacció Brex + errors: + unexpected_error: S'ha produït un error inesperat. Torna-ho a provar més tard. + index: + title: Connexions Brex + institution_summary: + count: + one: "%{count} entitat" + other: "%{count} entitats" + none: No hi ha entitats connectades + one: "%{name}" + kinds: + card: Targeta + cash: Efectiu + link_accounts: + all_already_linked: + one: El compte seleccionat (%{names}) ja està enllaçat + other: 'Tots els %{count} comptes seleccionats ja estan enllaçats: %{names}' + api_error: 'Error de l''API: %{message}' + invalid_account_names: + one: No es pot enllaçar un compte sense nom + other: No es poden enllaçar %{count} comptes sense nom + invalid_account_type: Tipus de compte Brex no admès + link_failed: No s'han pogut enllaçar els comptes + no_accounts_selected: Selecciona almenys un compte + no_api_token: No s'ha trobat el token API de Brex. Configura'l a la configuració + del proveïdor. + partial_invalid: S'han enllaçat correctament %{created_count} compte(s), %{already_linked_count} + compte(s) ja estaven enllaçats, %{invalid_count} compte(s) tenien noms no + vàlids + partial_success: 'S''han enllaçat correctament %{created_count} compte(s). %{already_linked_count} + compte(s) ja estaven enllaçats: %{already_linked_names}' + select_connection: Tria una connexió Brex abans d'enllaçar comptes. + success: + one: S'ha enllaçat correctament %{count} compte + other: S'han enllaçat correctament %{count} comptes + link_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + api_error: 'Error de l''API: %{message}' + invalid_account_name: No es pot enllaçar un compte sense nom + missing_parameters: Falten paràmetres obligatoris + no_account_specified: No s'ha especificat cap compte + no_api_token: No s'ha trobat el token API de Brex. Configura'l a la configuració + del proveïdor. + provider_account_already_linked: Aquest compte Brex ja està enllaçat a un altre + compte + provider_account_not_found: No s'ha trobat el compte Brex + select_connection: Tria una connexió Brex abans d'enllaçar comptes. + success: S'ha enllaçat correctament %{account_name} amb Brex + loading: + loading_message: Carregant comptes Brex... + loading_title: Carregant + provider_connection: + default_description: Connecta't al teu compte Brex + default_name: Brex + description: Connecta amb %{name} + name: Brex - %{name} + provider_panel: + accounts_link: Comptes + add_connection: Afegeix connexió Brex + base_url_label: URL base (opcional) + base_url_placeholder: https://api.brex.com + configured_html: Configurat i a punt per utilitzar. Visita la pestanya %{accounts_link} + per gestionar i configurar comptes. + connection_name_label: Nom de la connexió + connection_name_placeholder: Compte corrent d'empresa + default_connection_name: Connexió Brex + disconnect_confirm: Vols desconnectar %{name}? + disconnect_label: Desconnecta %{name} + encryption_warning: + message: Configura les claus de xifrat d'Active Record abans d'afegir tokens + de Brex en producció. Sense claus de xifrat, Sure emmagatzema les credencials + i les instantànies del proveïdor Brex en text pla com altres registres de + proveïdors. + title: El xifrat de la base de dades no està configurat + instructions: + copy_token_html: Copia el token i afegeix-lo com a connexió amb nom a continuació. + Sure emmagatzema el token només per sincronitzar aquesta família. + create_token: 'Crea un token API amb aquests permisos només de lectura: accounts.cash.readonly, + accounts.card.readonly, transactions.cash.readonly, transactions.card.readonly' + open_tokens: Ves a la configuració de tokens API/desenvolupador de Brex per + a l'empresa que vols connectar + sign_in_html: Visita %{link} i inicia sessió al compte que vols connectar + keep_token_placeholder: Deixa-ho en blanc per mantenir el token actual + not_configured: No configurat + sandbox_note_html: Utilitza una connexió amb nom separada per a cada empresa/token + API de Brex que vulguis sincronitzar. Deixa l'URL base en blanc per a producció. + El staging està limitat a les proves aprovades per Brex i no funciona amb tokens + de clients. + setup_accounts: Configura comptes + setup_title: 'Instruccions de configuració:' + sync: Sincronitza + token_label: Token + token_placeholder: Enganxa el token aquí + update_connection: Actualitza la connexió + select_accounts: + accounts_selected: comptes seleccionats + api_error: 'Error de l''API: %{message}' + cancel: Cancel·la + configure_name_in_brex: No es pot importar — configura el nom del compte a Brex + description: Selecciona els comptes que vols enllaçar al teu compte de %{product_name}. + link_accounts: Enllaça els comptes seleccionats + no_accounts_found: No s'han trobat comptes. Comprova la configuració del teu + token API. + no_api_token: No s'ha trobat el token API de Brex. Configura'l a la configuració + del proveïdor. + no_credentials_configured: Primer, configura el teu token API de Brex a la configuració + del proveïdor. + no_name_placeholder: "(Sense nom)" + select_connection: Tria una connexió Brex a la configuració del proveïdor. + title: Selecciona comptes Brex + unexpected_error: S'ha produït un error inesperat. Torna-ho a provar més tard. + select_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + all_accounts_already_linked: Tots els comptes Brex ja estan enllaçats + api_error: 'Error de l''API: %{message}' + cancel: Cancel·la + configure_name_in_brex: No es pot importar — configura el nom del compte a Brex + description: Selecciona un compte Brex per enllaçar-lo amb aquest compte. Les + transaccions es sincronitzaran i deduplicaran automàticament. + link_account: Enllaça compte + no_account_specified: No s'ha especificat cap compte + no_accounts_found: No s'han trobat comptes Brex. Comprova la configuració del + teu token API. + no_api_token: No s'ha trobat el token API de Brex. Configura'l a la configuració + del proveïdor. + no_credentials_configured: Primer, configura el teu token API de Brex a la configuració + del proveïdor. + no_name_placeholder: "(Sense nom)" + select_connection: Tria una connexió Brex a la configuració del proveïdor. + title: Enllaça %{account_name} amb Brex + unexpected_error: S'ha produït un error inesperat. Torna-ho a provar més tard. + setup_accounts: + account_type_label: 'Tipus de compte:' + account_types: + credit_card: Targeta de crèdit + depository: Compte corrent o d'estalvis + investment: Compte d'inversió + loan: Préstec o hipoteca + other_asset: Altre actiu + skip: Omet aquest compte + all_accounts_linked: Tots els teus comptes Brex ja s'han configurat. + api_error: 'Error de l''API: %{message}' + balance: Saldo + cancel: Cancel·la + choose_account_type: 'Tria el tipus de compte correcte per a cada compte Brex:' + create_accounts: Crea comptes + creating_accounts: Creant comptes... + fetch_failed: No s'han pogut obtenir els comptes + historical_data_range: 'Rang de dades històriques:' + no_accounts_to_setup: No hi ha comptes per configurar + no_api_token: No s'ha trobat el token API de Brex. Configura'l a la configuració + del proveïdor. + subtitle: Tria els tipus de compte correctes per als teus comptes importats + subtype_labels: + credit_card: '' + depository: 'Subtipus de compte:' + investment: 'Tipus d''inversió:' + loan: 'Tipus de préstec:' + other_asset: '' + subtype_messages: + credit_card: Les targetes de crèdit es configuraran automàticament com a comptes + de targeta de crèdit. + other_asset: No calen opcions addicionals per a altres actius. + subtypes: + depository: + cd: Certificat de dipòsit + checking: Compte corrent + hsa: Compte d'estalvi per a salut + money_market: Mercat monetari + savings: Estalvis + investment: + 401k: 401(k) + 403b: 403(b) + 529_plan: Pla 529 + angel: Inversió àngel + brokerage: Corredoria + hsa: Compte d'estalvi per a salut + ira: IRA tradicional + mutual_fund: Fons d'inversió + pension: Pensió + retirement: Jubilació + roth_401k: Roth 401(k) + roth_ira: IRA Roth + tsp: Pla d'estalvis de jubilació (TSP) + loan: + auto: Préstec d'automòbil + mortgage: Hipoteca + other: Altre préstec + student: Préstec d'estudis + sync_start_date_help: Selecciona fins on vols sincronitzar l'historial de transaccions. + Hi ha un màxim de 3 anys d'historial disponible. + sync_start_date_label: 'Comença a sincronitzar transaccions des de:' + title: Configura els teus comptes Brex + setup_required: + description: Abans d'enllaçar comptes Brex, has de configurar el teu token API + de Brex. + heading: Token API no configurat + settings_link: Ves a la configuració del proveïdor + setup_steps: 'Passos de configuració:' + steps: + enter_token: Introdueix el teu token API de Brex + find_section_html: Localitza la secció Brex + open_settings_html: Ves a Configuració > Proveïdors + return_to_link: Torna aquí per enllaçar els teus comptes + title: Cal configurar Brex + statuses: + ACTIVE: Actiu + CLOSED: Tancat + FROZEN: Congelat + active: Actiu + closed: Tancat + frozen: Congelat + subtype_select: + placeholder: + subtype: Selecciona el subtipus + type: Selecciona el tipus + sync: + success: Sincronització iniciada + sync_status: + all_synced: + one: "%{count} compte sincronitzat" + other: "%{count} comptes sincronitzats" + no_accounts: No s'han trobat comptes + partial_setup: "%{synced} sincronitzats, %{pending} necessiten configuració" + syncer: + account_processing_failed: + one: "%{count} compte Brex ha fallat durant el processament." + other: "%{count} comptes Brex han fallat durant el processament." + account_sync_failed: + one: "%{count} sincronització de compte Brex no s'ha pogut programar." + other: "%{count} sincronitzacions de compte Brex no s'han pogut programar." + accounts_failed: + one: "%{count} compte Brex no s'ha pogut importar." + other: "%{count} comptes Brex no s'han pogut importar." + accounts_need_setup: + one: "%{count} compte necessita configuració..." + other: "%{count} comptes necessiten configuració..." + calculating_balances: Calculant saldos... + checking_account_configuration: Comprovant la configuració dels comptes... + credentials_invalid: Token API de Brex no vàlid o permisos del compte incorrectes + failed: La sincronització ha fallat. Torna-ho a provar o contacta amb el suport. + import_failed: La importació de Brex ha fallat. + importing_accounts: Important comptes des de Brex... + processing_transactions: Processant transaccions... + transactions_failed: + one: "%{count} compte Brex ha tingut errors d'importació de transaccions." + other: "%{count} comptes Brex han tingut errors d'importació de transaccions." + update: + success: La connexió Brex s'ha actualitzat diff --git a/config/locales/views/brex_items/hu.yml b/config/locales/views/brex_items/hu.yml new file mode 100644 index 000000000..6d182321a --- /dev/null +++ b/config/locales/views/brex_items/hu.yml @@ -0,0 +1,277 @@ +--- +hu: + brex_items: + default_connection_name: Brex kapcsolat + account_metadata: + provider: Brex + separator: " • " + kinds: + cash: Készpénz + card: Kártya + statuses: + ACTIVE: Aktív + active: Aktív + CLOSED: Lezárt + closed: Lezárt + frozen: Befagyasztott + FROZEN: Befagyasztott + create: + success: Brex kapcsolat sikeresen létrehozva + default_card_name: Brex kártya + default_cash_name: "Brex készpénz %{id}" + destroy: + success: Brex kapcsolat eltávolítva + index: + title: Brex kapcsolatok + institution_summary: + none: Nincs csatlakoztatott intézmény + one: "%{name}" + count: + one: "%{count} intézmény" + other: "%{count} intézmény" + sync_status: + no_accounts: Nem találhatók számlák + all_synced: + one: "%{count} számla szinkronizálva" + other: "%{count} számla szinkronizálva" + partial_setup: "%{synced} szinkronizálva, %{pending} beállítást igényel" + api_error: + common_issues: "Gyakori problémák:" + expired_credentials: Generálj új API-tokent a Brex-ből. + expired_credentials_label: "Lejárt hitelesítő adatok:" + heading: Nem sikerült csatlakozni a Brex-hez + invalid_token: Ellenőrizd az API-tokenedet a Szolgáltatói beállításokban. + invalid_token_label: "Érvénytelen API-token:" + network: Ellenőrizd az internetkapcsolatodat. + network_label: "Hálózati probléma:" + permissions: Győződj meg róla, hogy a token rendelkezik a szükséges csak olvasható fiók- és tranzakciós hatókörökkel. + permissions_label: "Elégtelen jogosultságok:" + service: A Brex API ideiglenesen nem elérhető. + service_label: "Szolgáltatás leállása:" + settings_link: Szolgáltatói beállítások ellenőrzése + title: Brex kapcsolódási hiba + errors: + unexpected_error: Váratlan hiba történt. Kérlek próbáld újra később. + entries: + default_name: Brex tranzakció + loading: + loading_message: Brex számlák betöltése... + loading_title: Betöltés + link_accounts: + all_already_linked: + one: "A kiválasztott számla (%{names}) már össze van kapcsolva" + other: "Mind a(z) %{count} kiválasztott számla már össze van kapcsolva: %{names}" + api_error: "API hiba: %{message}" + invalid_account_names: + one: "Nem lehet összekapcsolni üres nevű számlát" + other: "Nem lehet összekapcsolni %{count} üres nevű számlát" + invalid_account_type: Nem támogatott Brex számlatípus + link_failed: Nem sikerült összekapcsolni a számlákat + no_accounts_selected: Kérlek válassz legalább egy számlát + no_api_token: Brex API-token nem található. Kérlek állítsd be a Szolgáltatói beállításokban. + partial_invalid: "%{created_count} számla sikeresen összekapcsolva, %{already_linked_count} már össze volt kapcsolva, %{invalid_count} számla nevei érvénytelenek" + partial_success: "%{created_count} számla sikeresen összekapcsolva. %{already_linked_count} már össze volt kapcsolva: %{already_linked_names}" + select_connection: Válassz Brex kapcsolatot a számlák összekapcsolása előtt. + success: + one: "%{count} számla sikeresen összekapcsolva" + other: "%{count} számla sikeresen összekapcsolva" + brex_item: + accounts_need_setup: Számlák beállítást igényelnek + delete: Kapcsolat törlése + deletion_in_progress: törlés folyamatban... + error: Hiba + no_accounts_description: Ehhez a kapcsolathoz még nincsenek összekapcsolt számlák. + no_accounts_title: Nincsenek számlák + setup_action: Új számlák beállítása + setup_description: "%{linked} / %{total} számla összekapcsolva. Válaszd ki az újonnan importált Brex számlák típusait." + setup_needed: Új számlák beállításra várnak + status: "Szinkronizálva %{timestamp} ezelőtt" + status_never: Még nem szinkronizált + status_with_summary: "Utolsó szinkronizálás %{timestamp} ezelőtt - %{summary}" + syncing: Szinkronizálás... + total: Összesen + unlinked: Nincs összekapcsolva + provider_panel: + accounts_link: Számlák + add_connection: Brex kapcsolat hozzáadása + base_url_label: Alap URL (opcionális) + base_url_placeholder: https://api.brex.com + configured_html: "Konfigurálva és használatra kész. Látogass el a %{accounts_link} fülre a számlák kezeléséhez és beállításához." + connection_name_label: Kapcsolat neve + connection_name_placeholder: Üzleti folyószámla + default_connection_name: Brex kapcsolat + disconnect_label: "%{name} szétkapcsolása" + disconnect_confirm: "%{name} szétkapcsolása?" + encryption_warning: + title: Az adatbázis-titkosítás nincs konfigurálva + message: Állítsd be az Active Record titkosítási kulcsokat, mielőtt Brex tokeneket adsz hozzá az éles környezetben. Titkosítási kulcsok nélkül a Sure a Brex szolgáltatói hitelesítő adatokat és pillanatfelvételeket más szolgáltatói rekordokhoz hasonlóan titkosítatlanul tárolja. + instructions: + copy_token_html: "Másold ki a tokent és add hozzá alább megnevezett kapcsolatként. A Sure csak a token nevű szinkronizáláshoz tárolja azt ehhez a háztartáshoz." + create_token: "Hozz létre API-tokent ezekkel a csak olvasható hatókörökkel: accounts.cash.readonly, accounts.card.readonly, transactions.cash.readonly, transactions.card.readonly" + open_tokens: Menj a csatlakoztatni kívánt vállalat Brex fejlesztői/API-token beállításaiba + sign_in_html: "Látogass el ide: %{link}, és lépj be a csatlakoztatni kívánt fiókba" + keep_token_placeholder: Hagyd üresen az aktuális token megtartásához + not_configured: Nincs beállítva + sandbox_note_html: "Minden szinkronizálni kívánt Brex vállalathoz/API-tokenhez használj külön megnevezett kapcsolatot. Az Alap URL-t hagyd üresen az éles környezethez. A tesztkörnyezet csak a Brex által jóváhagyott tesztelésre korlátozódik, és nem működik ügyfél tokenekkel." + setup_accounts: Számlák beállítása + setup_title: "Beállítási utasítások:" + sync: Szinkronizálás + token_label: Token + token_placeholder: Illeszt be tokent ide + update_connection: Kapcsolat frissítése + provider_connection: + default_description: Csatlakozás Brex fiókhoz + default_name: Brex + description: "Csatlakozás ezzel: %{name}" + name: "Brex - %{name}" + select_accounts: + accounts_selected: kiválasztott számla + api_error: "API hiba: %{message}" + cancel: Mégse + configure_name_in_brex: Nem importálható — kérlek állítsd be a számla nevét a Brex-ben + description: "Válaszd ki azokat a számlákat, amelyeket össze szeretnél kapcsolni a(z) %{product_name} fiókkal." + link_accounts: Kiválasztott számlák összekapcsolása + no_accounts_found: Nem találhatók számlák. Kérlek ellenőrizd az API-token konfigurációdat. + no_api_token: Brex API-token nem található. Kérlek állítsd be a Szolgáltatói beállításokban. + no_credentials_configured: Kérlek előbb állítsd be a Brex API-tokenedet a Szolgáltatói beállításokban. + no_name_placeholder: "(Nincs név)" + select_connection: Válassz Brex kapcsolatot a Szolgáltatói beállításokban. + title: Brex számlák kiválasztása + unexpected_error: Váratlan hiba történt. Kérlek próbáld újra később. + select_existing_account: + account_already_linked: Ez a számla már össze van kapcsolva egy szolgáltatóval + all_accounts_already_linked: Minden Brex számla már össze van kapcsolva + api_error: "API hiba: %{message}" + cancel: Mégse + configure_name_in_brex: Nem importálható — kérlek állítsd be a számla nevét a Brex-ben + description: Válassz egy Brex számlát, amelyet ehhez a számlához szeretnél kapcsolni. A tranzakciók automatikusan szinkronizálásra és deduplikálásra kerülnek. + link_account: Számla összekapcsolása + no_account_specified: Nem lett megadva számla + no_accounts_found: Nem találhatók Brex számlák. Kérlek ellenőrizd az API-token konfigurációdat. + no_api_token: Brex API-token nem található. Kérlek állítsd be a Szolgáltatói beállításokban. + no_credentials_configured: Kérlek előbb állítsd be a Brex API-tokenedet a Szolgáltatói beállításokban. + no_name_placeholder: "(Nincs név)" + select_connection: Válassz Brex kapcsolatot a Szolgáltatói beállításokban. + title: "%{account_name} összekapcsolása a Brex-szel" + unexpected_error: Váratlan hiba történt. Kérlek próbáld újra később. + setup_required: + description: A Brex számlák összekapcsolása előtt be kell állítanod a Brex API-tokenedet. + heading: Az API-token nincs beállítva + settings_link: Szolgáltatói beállítások megnyitása + setup_steps: "Beállítási lépések:" + steps: + enter_token: Add meg a Brex API-tokenedet + find_section_html: "Keresd meg a Brex részt" + open_settings_html: "Menj a Beállítások > Szolgáltatók menübe" + return_to_link: Térj vissza ide a számlák összekapcsolásához + title: Brex beállítás szükséges + subtype_select: + placeholder: + subtype: Altípus kiválasztása + type: Típus kiválasztása + link_existing_account: + account_already_linked: Ez a számla már össze van kapcsolva egy szolgáltatóval + api_error: "API hiba: %{message}" + invalid_account_name: Nem lehet összekapcsolni üres nevű számlát + missing_parameters: Hiányzó kötelező paraméterek + no_account_specified: Nem lett megadva számla + no_api_token: Brex API-token nem található. Kérlek állítsd be a Szolgáltatói beállításokban. + provider_account_already_linked: Ez a Brex számla már össze van kapcsolva egy másik számlával + provider_account_not_found: Brex számla nem található + select_connection: Válassz Brex kapcsolatot a számlák összekapcsolása előtt. + success: "%{account_name} sikeresen összekapcsolva a Brex-szel" + setup_accounts: + account_type_label: "Számla típusa:" + all_accounts_linked: "Minden Brex számlád már be van állítva." + api_error: "API hiba: %{message}" + fetch_failed: "Nem sikerült lekérni a számlákat" + no_accounts_to_setup: "Nincs beállítandó számla" + no_api_token: Brex API-token nem található. Kérlek állítsd be a Szolgáltatói beállításokban. + account_types: + skip: Számla kihagyása + depository: Folyó- vagy megtakarítási számla + credit_card: Hitelkártya + investment: Befektetési számla + loan: Hitel vagy jelzálog + other_asset: Egyéb vagyon + subtype_labels: + depository: "Számla altípusa:" + credit_card: "" + investment: "Befektetés típusa:" + loan: "Hitel típusa:" + other_asset: "" + subtype_messages: + credit_card: "A hitelkártyák automatikusan hitelkártya számlákként lesznek beállítva." + other_asset: "Az egyéb vagyonelemekhez nincs szükség további beállításokra." + subtypes: + depository: + checking: Folyószámla + savings: Megtakarítási számla + hsa: Egészségügyi megtakarítási számla + cd: Lekötött betét + money_market: Pénzpiaci számla + investment: + brokerage: Brókeri számla + pension: Nyugdíjalap + retirement: Nyugdíj-megtakarítás + "401k": "401(k)" + roth_401k: "Roth 401(k)" + "403b": "403(b)" + tsp: Thrift Savings Plan + "529_plan": "529 Terv" + hsa: Egészségügyi megtakarítási számla + mutual_fund: Befektetési alap + ira: Hagyományos IRA + roth_ira: Roth IRA + angel: Angyal befektető + loan: + mortgage: Jelzálog + student: Diákhitel + auto: Autóhitel + other: Egyéb hitel + balance: Egyenleg + cancel: Mégse + choose_account_type: "Válaszd ki a megfelelő számlatípust minden Brex számlához:" + create_accounts: Számlák létrehozása + creating_accounts: Számlák létrehozása... + historical_data_range: "Előzmények időtartama:" + subtitle: Válaszd ki az importált számlák helyes típusait + sync_start_date_help: "Válaszd ki, milyen messzire szeretnél visszamenni a tranzakciós előzmények szinkronizálásában. Maximum 3 év előzmény érhető el." + sync_start_date_label: "Tranzakciók szinkronizálásának kezdete:" + title: Brex számlák beállítása + complete_account_setup: + all_skipped: "Minden számla ki lett hagyva. Nem jött létre számla." + creation_failed: "Nem sikerült létrehozni a számlákat: %{error}" + creation_failed_count: "%{count} számla létrehozása sikertelen." + no_accounts: "Nincs beállítandó számla." + partial_skipped: "%{created_count} számla sikeresen létrehozva; %{skipped_count} számla ki lett hagyva." + partial_success: "%{created_count} számla sikeresen létrehozva, de %{failed_count} számla sikertelen volt." + success: "%{count} számla sikeresen létrehozva." + unexpected_error: Váratlan hiba történt. + sync: + success: Szinkronizálás elindítva + syncer: + account_processing_failed: + one: "%{count} Brex számla feldolgozása sikertelen volt." + other: "%{count} Brex számla feldolgozása sikertelen volt." + account_sync_failed: + one: "%{count} Brex számla szinkronizálása nem ütemezható." + other: "%{count} Brex számla szinkronizálása nem ütemezható." + accounts_need_setup: + one: "%{count} számla beállítást igényel..." + other: "%{count} számla beállítást igényel..." + accounts_failed: + one: "%{count} Brex számla importálása sikertelen volt." + other: "%{count} Brex számla importálása sikertelen volt." + calculating_balances: Egyenlegek kiszámítása... + checking_account_configuration: Számlakonfiguráció ellenőrzése... + credentials_invalid: Érvénytelen Brex API-token vagy számlajogosultságok + failed: A szinkronizálás sikertelen volt. Kérlek próbáld újra, vagy lépj kapcsolatba a támogatással. + import_failed: Brex importálás sikertelen. + importing_accounts: Számlák importálása a Brex-ből... + processing_transactions: Tranzakciók feldolgozása... + transactions_failed: + one: "%{count} Brex számlánál tranzakciós importálási hibák léptek fel." + other: "%{count} Brex számlánál tranzakciós importálási hibák léptek fel." + update: + success: Brex kapcsolat frissítve diff --git a/config/locales/views/budgets/ca.yml b/config/locales/views/budgets/ca.yml index 6f3d53e3d..c1131fece 100644 --- a/config/locales/views/budgets/ca.yml +++ b/config/locales/views/budgets/ca.yml @@ -1,21 +1,102 @@ --- ca: + budget_categories: + allocation_progress: + budget_exceeded_html: 'Pressupost superat en %{amount}' + left_to_allocate: per assignar + over_set: "> 100 % assignat" + percent_set: "%{percent} assignat" + budget_category_form: + monthly_average: "%{amount}/mes (mitjana)" + shared_placeholder: Compartit + shared_title: Deixa-ho buit per compartir el pressupost de la categoria pare + confirm_button: + confirm: Confirma + index: + description: Ajusta els pressupostos per categoria per establir límits de despesa. + Els fons no assignats es marcaran automàticament com a sense categoritzar. + title: Edita els pressupostos per categoria + no_categories: + new_category: Nova categoria + no_categories_message: Encara no has creat ni assignat cap categoria de despesa + a les teves transaccions. + oops: Vaja! + use_defaults: Usa els valors per defecte (recomanat) + show: + budgeted: Pressupostat + category: Categoria + left: restant + monthly_average_spending: Despesa mensual mitjana + monthly_median_spending: Despesa mensual mediana + no_transactions: No s'han trobat transaccions per a aquest període pressupostari. + overspent: per sobre + overview: Resum + recent_transactions: Transaccions recents + spending: Despesa de %{date} + status: Estat + view_all_transactions: Veure totes les transaccions de la categoria budgets: + actuals_summary: + expenses: Despeses + income: Ingressos + budget_donut: + new_budget: Nou pressupost + of_budget: de %{amount} + spent: Gastat + unused: Sense utilitzar + budget_header: + today: Avui + budget_nav: + categories: Categories + setup: Configuració + budgeted_summary: + budgeted: Pressupostat + earned: "%{amount} guanyats" + expected_income: Ingressos esperats + left: "%{amount} restants" + over: "%{amount} per sobre" + spent: "%{amount} gastats" + copy_previous: + already_initialized: Aquest pressupost ja s'ha configurat + no_source: No s'ha trobat cap pressupost anterior per copiar + success: Pressupost copiat de %{source_name} + copy_previous_prompt: + copy_button: Copia de %{source_name} + description: Pots copiar el teu pressupost de %{source_name} o començar de zero. + fresh_button: Comença de zero + title: Configura el teu pressupost + edit: + autosuggest_description: Es basarà en l'historial de transaccions. La IA pot + equivocar-se, verifica-ho abans de continuar. + autosuggest_title: Suggereix automàticament el pressupost d'ingressos i despeses + budgeted_spending: Despesa pressupostada + continue: Continua + expected_income: Ingressos esperats + setup_description: Introdueix els teus ingressos mensuals i la despesa planificada + a sota per configurar el teu pressupost. + setup_title: Configura el teu pressupost + name: + custom_range: "%{start} - %{end_date}" + month_year: "%{month}" + over_allocation_warning: + fix_allocations: Corregeix les assignacions + over_allocated_message: Has assignat per sobre del teu pressupost. Corregeix + les assignacions. show: categories: - amount: Quantitat + amount: Import edit: Edita title: Categories - on_track_categories: - short_title: En bon cami - title: En bon cami - over_budget_categories: - short_title: Sobre pressupost - title: Sobre pressupost filter: all: Totes - on_track: En bon cami - over_budget: Sobre pressupost + on_track: Sota control + over_budget: Pressupost superat + on_track_categories: + short_title: Sota control + title: Sota control + over_budget_categories: + short_title: Pressupost superat + title: Pressupost superat tabs: actual: Real budgeted: Pressupostat diff --git a/config/locales/views/budgets/en.yml b/config/locales/views/budgets/en.yml index af53f4f2f..04f745c61 100644 --- a/config/locales/views/budgets/en.yml +++ b/config/locales/views/budgets/en.yml @@ -8,6 +8,9 @@ en: unused: "Unused" budget_header: today: "Today" + budget_nav: + categories: Categories + setup: Setup over_allocation_warning: over_allocated_message: "You have over-allocated your budget. Please fix your allocations." fix_allocations: "Fix allocations" @@ -60,6 +63,15 @@ en: no_source: "No previous budget found to copy from" already_initialized: "This budget has already been set up" budget_categories: + allocation_progress: + budget_exceeded_html: 'Budget exceeded by %{amount}' + left_to_allocate: left to allocate + over_set: "> 100% set" + percent_set: "%{percent} set" + budget_category_form: + monthly_average: "%{amount}/m avg" + shared_placeholder: Shared + shared_title: Leave empty to share parent's budget confirm_button: confirm: "Confirm" no_categories: diff --git a/config/locales/views/budgets/hu.yml b/config/locales/views/budgets/hu.yml index 109ca752a..0d0fc5312 100644 --- a/config/locales/views/budgets/hu.yml +++ b/config/locales/views/budgets/hu.yml @@ -1,6 +1,34 @@ --- hu: budgets: + budget_donut: + spent: "Elköltve" + new_budget: "Új költségvetés" + of_budget: "%{amount}-ból/ből" + unused: "Felhasználatlan" + budget_header: + today: "Ma" + over_allocation_warning: + over_allocated_message: "Túllépted a költségvetési keretét. Kérjük, javítsd az elosztásokat." + fix_allocations: "Elosztások javítása" + actuals_summary: + income: "Bevétel" + expenses: "Kiadások" + budgeted_summary: + expected_income: "Várható bevétel" + budgeted: "Tervezett" + earned: "%{amount} megkeresve" + over: "%{amount} túllépve" + left: "%{amount} maradt" + spent: "%{amount} elköltve" + edit: + setup_title: "Állítsd be a költségvetésed" + setup_description: "Add meg a havi bevételeidet és tervezett kiadásaidat a költségvetés beállításához." + budgeted_spending: "Tervezett kiadások" + expected_income: "Várható bevétel" + autosuggest_title: "Bevételi és kiadási keret automatikus javaslata" + autosuggest_description: "Ez a tranzakcióelőzmények alapján készül. Az AI hibázhat, ellenőrizd folytatás előtt." + continue: "Folytatás" name: custom_range: "%{start} - %{end_date}" month_year: "%{month}" @@ -31,3 +59,27 @@ hu: success: "Költségvetés átmásolva innen: %{source_name}" no_source: "Nem található korábbi költségvetés a másoláshoz" already_initialized: "Ez a költségvetés már be van állítva" + budget_categories: + confirm_button: + confirm: "Megerősítés" + no_categories: + oops: "Hoppá!" + no_categories_message: "Még nem hoztál létre kiadási kategóriákat, és nem rendeltél egyet sem a tranzakcióidhoz." + use_defaults: "Alapértelmezések használata (ajánlott)" + new_category: "Új kategória" + index: + title: "Kategóriakereteid szerkesztése" + description: "Állítsd be a kategóriakereteket a kiadási limitek meghatározásához. A fel nem osztott összegek automatikusan kategorizálatlanként kerülnek hozzárendelésre." + show: + category: "Kategória" + overview: "Áttekintés" + spending: "%{date} kiadásai" + status: "Állapot" + overspent: "túllépve" + left: "maradt" + budgeted: "Tervezett" + monthly_average_spending: "Havi átlagos kiadás" + monthly_median_spending: "Havi mediánkiadás" + recent_transactions: "Legutóbbi tranzakciók" + view_all_transactions: "Összes kategória tranzakció megtekintése" + no_transactions: "Nem találhatók tranzakciók erre a költségvetési időszakra." diff --git a/config/locales/views/categories/ca.yml b/config/locales/views/categories/ca.yml index 877e1c665..f57ac01e7 100644 --- a/config/locales/views/categories/ca.yml +++ b/config/locales/views/categories/ca.yml @@ -4,21 +4,31 @@ ca: bootstrap: success: Categories per defecte creades correctament category: - delete: Elimina categoria - edit: Edita categoria + delete: Elimina la categoria + edit: Edita la categoria create: success: Categoria creada correctament destroy: success: Categoria eliminada correctament + destroy_all: + success: Totes les categories eliminades edit: - edit: Edita categoria + edit: Edita la categoria form: + color: Color + icon: Icona + name_label: Nom + parent_category_label: Categoria pare (opcional) placeholder: Nom de la categoria + auto_adjust: ajusta'l automàticament. + poor_contrast: Contrast insuficient; tria un color més fosc o + unassigned: "(sense assignar)" index: bootstrap: Utilitza les predeterminades (recomanat) categories: Categories categories_expenses: Categories de despesa categories_incomes: Categories d'ingressos + delete_all: Elimina-les totes empty: No s'han trobat categories new: Nova categoria menu: @@ -27,8 +37,16 @@ ca: new_category: Nova categoria update: success: Categoria actualitzada correctament + virtual: + payment: Pagament + trade: Operació + transfer: Transferència category: dropdowns: show: bootstrap: Genera categories per defecte empty: No s'han trobat categories + expense: despesa + income: ingrés + match_transfer: Fes coincidir amb transferència/pagament + one_time: "%{type} puntual" diff --git a/config/locales/views/categories/en.yml b/config/locales/views/categories/en.yml index 37c8c2568..0422c07cf 100644 --- a/config/locales/views/categories/en.yml +++ b/config/locales/views/categories/en.yml @@ -19,7 +19,8 @@ en: parent_category_label: "Parent category (optional)" color: Color icon: Icon - poor_contrast: "Poor contrast, choose darker color or" + auto_adjust: auto-adjust. + poor_contrast: "Poor contrast, choose a darker color or" destroy_all: success: All categories deleted index: diff --git a/config/locales/views/categories/hu.yml b/config/locales/views/categories/hu.yml index bff8ce2d6..a10c00072 100644 --- a/config/locales/views/categories/hu.yml +++ b/config/locales/views/categories/hu.yml @@ -14,11 +14,20 @@ hu: edit: Kategória szerkesztése form: placeholder: Kategória neve + name_label: Név + unassigned: "(nincs hozzárendelve)" + parent_category_label: "Szülőkategória (nem kötelező)" + color: Szín + icon: Ikon + poor_contrast: "Gyenge kontraszt, válassz sötétebb színt vagy" + destroy_all: + success: Összes kategória törölve index: bootstrap: Alapértelmezések használata (ajánlott) categories: Kategóriák categories_expenses: Kiadás kategóriák categories_incomes: Bevétel kategóriák + delete_all: Összes törlése empty: Nem található kategória new: Új kategória menu: @@ -27,8 +36,16 @@ hu: new_category: Új kategória update: success: Kategória sikeresen frissítve + virtual: + transfer: Átutalás + payment: Fizetés + trade: Ügylet category: dropdowns: show: bootstrap: Alapértelmezett kategóriák létrehozása empty: Nem található kategória + match_transfer: "Átutalás/fizetés párosítása" + one_time: "Egyszeri %{type}" + income: "bevétel" + expense: "kiadás" diff --git a/config/locales/views/category/dropdowns/ca.yml b/config/locales/views/category/dropdowns/ca.yml index c77fc6255..6cfdb1b6c 100644 --- a/config/locales/views/category/dropdowns/ca.yml +++ b/config/locales/views/category/dropdowns/ca.yml @@ -3,9 +3,9 @@ ca: category: dropdowns: row: - delete: Elimina categoria - edit: Edita categoria + delete: Elimina la categoria + edit: Edita la categoria show: - clear: Neteja categoria + clear: Esborra la categoria no_categories: No s'han trobat categories search_placeholder: Cerca diff --git a/config/locales/views/chats/ca.yml b/config/locales/views/chats/ca.yml index 1e6971c16..e3d25e036 100644 --- a/config/locales/views/chats/ca.yml +++ b/config/locales/views/chats/ca.yml @@ -1,8 +1,54 @@ --- ca: + assistant_messages: + assistant_message: + assistant_reasoning: Raonament de l'assistent + tool_calls: + arguments: 'Arguments:' + function: 'Funció:' + tool_calls: Crides a eines chats: - demo_banner_message: "Estàs utilitzant un LLM Qwen3 de pesos oberts amb crèdits proporcionats - per Cloudflare Workers AI. Els resultats poden variar ja que el codi es va provar - principalment amb `gpt-4.1` però els teus tokens no van a cap altre lloc per ser entrenats! 🤖" - demo_banner_title: Mode de demostració - thinking: "Treballant ..." + ai_consent: + available_description: El xat amb IA pot respondre preguntes financeres i oferir-te + anàlisis basades en les teves dades. Per utilitzar aquesta funcionalitat l'has + d'activar explícitament. + disable_note: Desactiva-ho en qualsevol moment. Totes les dades enviades als + nostres proveïdors de LLM són anonimitzades. + enable_button: Activa els xats d'IA + title: Activa els xats d'IA + unavailable_description_html: Per utilitzar l'assistent d'IA, has d'establir + la variable d'entorn OPENAI_ACCESS_TOKEN o configurar-la a la configuració de self hosting + de la teva instància. + ai_greeting: + commands_hint_html: Pots utilitzar / per accedir a les ordres + evaluate_portfolio: Avalua la cartera d'inversió + greeting: Hola %{name}! Sóc una IA / model de llenguatge gran que et pot ajudar + amb les teves finances. Tinc accés al web i a les dades del teu compte. + questions_intro: 'Aquí tens algunes preguntes que pots fer:' + spending_insights: Mostra anàlisi de la despesa + there: '' + unusual_patterns: Troba patrons inusuals + chat: + delete_chat: Elimina el xat + edit_chat_title: Edita el títol del xat + chat_nav: + all_chats: Tots els xats + delete_chat: Elimina el xat + edit_chat_title: Edita el títol del xat + start_new_chat: Inicia un xat nou + demo_banner_message: "Estàs utilitzant LLM amb crèdits proporcionats per Cloudflare + Workers AI. Els resultats poden variar, ja que el codi s'ha provat amb `gpt-4.1`, + però els teus tokens no s'envien enlloc més per entrenar-los! 🤖" + demo_banner_title: Mode demostració actiu + destroy: + notice: Xat eliminat correctament + error: + retry: Torna-ho a provar + index: + chats: Xats + new_chat: Nou xat + thinking: Pensant... + update: + success: Xat actualitzat diff --git a/config/locales/views/chats/hu.yml b/config/locales/views/chats/hu.yml index 3995ec692..6e4830ac1 100644 --- a/config/locales/views/chats/hu.yml +++ b/config/locales/views/chats/hu.yml @@ -4,3 +4,41 @@ hu: demo_banner_title: "Demo mód aktív" demo_banner_message: "LLM-eket használsz a Cloudflare Workers AI által biztosított krediteken keresztül. Az eredmények változhatnak, mivel a kódot `gpt-4.1`-en tesztelték, de a tokenjeid nem kerülnek sehova tanítás céljából! 🤖" thinking: "Gondolkodás..." + ai_greeting: + greeting: "Szia, %{name}! Egy AI/nagy nyelvi modell vagyok, aki segíthet pénzügyeid kezelésében. Hozzáférhetek az internethez és a fiókadataidhoz." + there: "ott" + commands_hint_html: "Használd a / jelet a parancsok eléréséhez" + questions_intro: "Íme néhány kérdés, amit feltehetsz:" + evaluate_portfolio: "Befektetési portfólió értékelése" + spending_insights: "Kiadási statisztikák megtekintése" + unusual_patterns: "Szokatlan minták keresése" + chat: + edit_chat_title: "Csevegés nevének szerkesztése" + delete_chat: "Csevegés törlése" + chat_nav: + all_chats: "Összes csevegés" + start_new_chat: "Új csevegés indítása" + edit_chat_title: "Csevegés nevének szerkesztése" + delete_chat: "Csevegés törlése" + error: + retry: "Újrapróbálás" + destroy: + notice: "A csevegés sikeresen törölve" + index: + chats: "Csevegések" + new_chat: "Új csevegés" + update: + success: "Csevegés frissítve" + ai_consent: + title: "AI-csevegések engedélyezése" + available_description: "Az AI-csevegés pénzügyi kérdésekre tud válaszolni és az adataid alapján elemzéseket nyújtani. A funkció használatához explicit engedélyezés szükséges." + unavailable_description_html: "Az AI-asszisztens használatához be kell állítanod az OPENAI_ACCESS_TOKEN környezeti változót, vagy konfigurálnod kell az önálló üzemeltetési beállításokban." + enable_button: "AI-csevegések engedélyezése" + disable_note: "Bármikor letiltható. Az LLM-szolgáltatóknak küldött összes adat anonimizált." + assistant_messages: + assistant_message: + assistant_reasoning: "Asszisztens gondolkodása" + tool_calls: + tool_calls: "Eszközhívások" + function: "Függvény:" + arguments: "Argumentumok:" diff --git a/config/locales/views/coinbase_items/ca.yml b/config/locales/views/coinbase_items/ca.yml new file mode 100644 index 000000000..2cdb8cf9d --- /dev/null +++ b/config/locales/views/coinbase_items/ca.yml @@ -0,0 +1,83 @@ +--- +ca: + coinbase_item: + syncer: + accounts_need_setup: + one: "%{count} compte necessita configuració" + other: "%{count} comptes necessiten configuració" + calculating_balances: Calculant saldos... + checking_configuration: Comprovant la configuració del compte... + checking_credentials: Comprovant credencials... + credentials_invalid: Credencials de l'API no vàlides. Revisa la teva clau API + i el secret. + importing_accounts: Important comptes des de Coinbase... + processing_accounts: Processant dades del compte... + coinbase_items: + coinbase_item: + delete: Elimina + deletion_in_progress: Eliminant... + import_wallets_menu: Importa carteres + more_wallets_available: + one: "%{count} cartera més disponible per importar" + other: "%{count} carteres més disponibles per importar" + no_accounts_message: Les teves carteres de Coinbase apareixeran aquí després + de sincronitzar. + no_accounts_title: No s'han trobat comptes + provider_name: Coinbase + reconnect: Les credencials necessiten actualització + setup_action: Importa carteres + setup_description: Selecciona quines carteres de Coinbase vols seguir. + setup_needed: Carteres a punt per importar + status: Darrera sincronització fa %{timestamp} + status_never: Mai sincronitzat + status_with_summary: Darrera sincronització fa %{timestamp} - %{summary} + sync_status: + all_synced: + one: "%{count} compte sincronitzat" + other: "%{count} comptes sincronitzats" + no_accounts: No s'han trobat comptes + partial_sync: "%{linked_count} sincronitzats, %{unlinked_count} necessiten + configuració" + syncing: Sincronitzant... + update_credentials: Actualitza les credencials + complete_account_setup: + no_accounts: No hi ha carteres per importar + none_selected: No s'ha seleccionat cap cartera + success: + one: S'ha importat %{count} cartera + other: S'han importat %{count} carteres + create: + default_name: Coinbase + success: S'ha connectat correctament a Coinbase! Els teus comptes s'estan sincronitzant. + destroy: + success: S'ha programat la connexió Coinbase per a la seva eliminació. + link_existing_account: + errors: + invalid_coinbase_account: Compte Coinbase no vàlid + only_manual: Només els comptes manuals es poden enllaçar a Coinbase + success: S'ha enllaçat correctament al compte Coinbase + select_existing_account: + balance: Saldo + cancel: Cancel·la + check_provider_health: Comprova que les teves credencials de l'API de Coinbase + siguin vàlides + currently_linked_to: 'Actualment enllaçat a: %{account_name}' + link: Enllaça + no_accounts_found: No s'han trobat comptes Coinbase. + title: Enllaça compte Coinbase + wait_for_sync: Espera que Coinbase acabi la sincronització + setup_accounts: + accounts_count: + one: "%{count} cartera disponible" + other: "%{count} carteres disponibles" + cancel: Cancel·la + creating: Important... + import_selected: Importa les seleccionades + instructions: Selecciona les carteres que vols importar. Les carteres no seleccionades + quedaran disponibles si les vols afegir més tard. + no_accounts: Totes les carteres s'han importat. + select_all: Selecciona-ho tot + subtitle: Selecciona quines carteres vols seguir + title: Importa carteres Coinbase + update: + success: La configuració de Coinbase s'ha actualitzat correctament. diff --git a/config/locales/views/coinstats_items/ca.yml b/config/locales/views/coinstats_items/ca.yml index 66140452a..9694cfc41 100644 --- a/config/locales/views/coinstats_items/ca.yml +++ b/config/locales/views/coinstats_items/ca.yml @@ -3,59 +3,86 @@ ca: coinstats_items: coinstats_item: delete: Elimina - deletion_in_progress: S'estan esborrant les dades de la cartera de criptomonedes... - no_wallets_message: Actualment no hi ha carteres de criptomonedes connectades a CoinStats. - no_wallets_title: No hi ha carteres de criptomonedes connectades + deletion_in_progress: S'estan eliminant les dades de la cartera de cripto... + no_wallets_message: Actualment no hi ha carteres de cripto connectades a CoinStats. + no_wallets_title: No hi ha carteres de cripto connectades provider_name: CoinStats - reconnect: Torna a connectar - status: Sincronitzat per última vegada %{timestamp} fa + reconnect: Reconnecta + status: Darrera sincronització fa %{timestamp} status_never: Mai sincronitzat - status_with_summary: Sincronitzat per última vegada %{timestamp} fa • %{summary} + status_with_summary: Darrera sincronització fa %{timestamp} • %{summary} sync_status: all_synced: - one: "%{count} cartera de criptomonedes sincronitzada" - other: "%{count} carteres de criptomonedes sincronitzades" - no_accounts: No s'han trobat carteres de criptomonedes - partial_sync: "%{linked_count} carteres de criptomonedes sincronitzades, %{unlinked_count} necessiten configuració" + one: "%{count} cartera de cripto sincronitzada" + other: "%{count} carteres de cripto sincronitzades" + no_accounts: No s'han trobat carteres de cripto + partial_sync: "%{linked_count} carteres de cripto sincronitzades, %{unlinked_count} + necessiten configuració" syncing: Sincronitzant... - update_api_key: Actualitzar clau API + update_api_key: Actualitza la clau API create: default_name: Connexió CoinStats errors: - validation_failed: "La validació ha fallat: %{message}." + validation_failed: 'La validació ha fallat: %{message}.' success: La connexió amb el proveïdor CoinStats s'ha configurat correctament. destroy: - success: La connexió amb el proveïdor CoinStats està programada per a la seva eliminació. + success: La connexió amb el proveïdor CoinStats està programada per a la seva + eliminació. + link_exchange: + error: 'No s''ha pogut enllaçar l''exchange: %{message}.' + failed: No s'ha pogut enllaçar l'exchange. + invalid_exchange: L'exchange seleccionat ja no està admès. + missing_params: Cal l'exchange i les credencials. + success: S'ha enllaçat l'exchange %{name}. link_wallet: - error: "L'enllaç de la cartera de criptomonedes ha fallat: %{message}." + error: 'L''enllaç de la cartera de criptomonedes ha fallat: %{message}.' failed: L'enllaç de la cartera de criptomonedes ha fallat. - missing_params: "Falten els paràmetres requerits: adreça i blockchain." + missing_params: 'Falten els paràmetres requerits: adreça i blockchain.' success: "%{count} cartera(s) de criptomonedes enllaçades correctament." new: address_label: Adreça - address_placeholder: Requerit + address_placeholder: Obligatori api_key_label: Clau API - api_key_placeholder: Requerit - blockchain_fetch_error: No s'han pogut carregar els Blockchains. Torna a intentar-ho més tard. + api_key_placeholder: Obligatori + blockchain_fetch_error: No s'han pogut carregar les blockchains. Torna-ho a + provar més tard. blockchain_label: Blockchain - blockchain_placeholder: Requerit - blockchain_select_blank: Selecciona un Blockchain + blockchain_placeholder: Obligatori + blockchain_select_blank: Selecciona una blockchain configure: Configura default_name: Connexió CoinStats - go_to_settings: Anar a la configuració del proveïdor - link: Enllaça una cartera de criptomonedes - not_configured_message: Per enllaçar una cartera de criptomonedes, primer has de configurar la connexió amb el proveïdor CoinStats. + exchange_label: Exchange + exchange_select_blank: Selecciona un exchange + go_to_settings: Ves a la configuració del proveïdor + link_exchange_description: Utilitza una clau API d'exchange només de lectura + perquè CoinStats pugui sincronitzar saldos i transaccions de Bitvavo, Binance + i altres exchanges admesos. + link_exchange_note: Si el teu exchange requereix activació de la clau API o + confirmació per correu, completa aquest pas abans d'enllaçar-lo aquí. + link_exchange_submit: Enllaça l'exchange + link_exchange_title: Enllaça l'API de l'exchange + link_wallet_description: Fes el seguiment d'una cartera autocustodiada o d'una + sola adreça on-chain a través de CoinStats. + link_wallet_submit: Enllaça la cartera de cripto + link_wallet_title: Enllaça l'adreça de la cartera + not_configured_message: Per enllaçar una cartera de cripto o un exchange, primer + has de configurar la connexió amb el proveïdor CoinStats. not_configured_step1_html: Ves a Configuració → Proveïdors not_configured_step2_html: Localitza el proveïdor CoinStats - not_configured_step3_html: Segueix les instruccions de configuració proporcionades per completar la configuració del proveïdor + not_configured_step3_html: Segueix les instruccions de configuració + proporcionades per completar la configuració del proveïdor not_configured_title: La connexió amb el proveïdor CoinStats no està configurada - setup_instructions: "Instruccions de configuració:" - step1_html: Ves al Panell de l'API Pública de CoinStats per obtenir una clau API. + setup_instructions: 'Instruccions de configuració:' + step1_html: Visita el panell de l'API pública de CoinStats + per obtenir una clau API. step2: Introdueix la teva clau API a continuació i fes clic a Configura. - step3_html: Després d'una connexió reeixida, ves a la pestanya Comptes per configurar les carteres de criptomonedes. - title: Enllaça una cartera de criptomonedes amb CoinStats - update_configuration: Torna a configurar + step3_html: Després d'una connexió correcta, ves a la pestanya Comptes per configurar els teus comptes + de cripto. + title: Enllaça cripto amb CoinStats + update_configuration: Reconfigura update: errors: - validation_failed: "La validació ha fallat: %{message}." - success: La connexió amb el proveïdor CoinStats s'ha actualitzat correctament. \ No newline at end of file + validation_failed: 'La validació ha fallat: %{message}.' + success: La connexió amb el proveïdor CoinStats s'ha actualitzat correctament. diff --git a/config/locales/views/components/ca.yml b/config/locales/views/components/ca.yml index c5dcbeb11..adc046526 100644 --- a/config/locales/views/components/ca.yml +++ b/config/locales/views/components/ca.yml @@ -1,5 +1,98 @@ --- ca: + UI: + account: + activity_date: + balance_tooltip: Saldo al final del dia, després de totes les transaccions + i ajustos + no_balance_data: No hi ha dades de saldo per a aquesta data + activity_feed: + toggle_selection_checkboxes: Commuta la selecció + balance_reconciliation: + labels: + adjustments: Ajustos + buys: Compres + change_in_brokerage_cash: Variació de l'efectiu del broker + change_in_holdings_market: Variació de les posicions (preu de mercat) + change_in_holdings_trades: Variació de les posicions (compres/vendes) + charges: Càrrecs + end_balance: Saldo final + end_principal: Capital final + end_value: Valor final + final_balance: Saldo final del dia + final_principal: Capital final del dia + final_value: Valor final del dia + market_changes: Variacions de mercat + net_cash_flow: Flux net d'efectiu + net_principal_change: Variació neta del capital + net_value_change: Variació neta del valor + payments: Pagaments + sells: Vendes + start_balance: Saldo inicial + start_principal: Capital inicial + start_value: Valor inicial + tooltips: + adjustments: Conciliacions manuals o altres ajustos + adjustments_asset: Ajustos de valor manuals o taxacions + buys: Compres de cripto durant el dia + change_in_brokerage_cash: Variació neta de l'efectiu per dipòsits, retirades + i operacions + change_in_holdings_market: Variació del valor de les posicions per moviments + del preu de mercat + change_in_holdings_trades: Impacte sobre les posicions per compres i vendes + de valors + charges: Nous càrrecs realitzats durant el dia + end_balance: Saldo calculat després de totes les transaccions + end_balance_investment: Saldo calculat després de tota l'activitat + end_principal: Capital calculat després de totes les transaccions + end_value: Valor calculat després de tots els canvis + final_balance: Saldo final del compte del dia + final_balance_credit: Saldo deutor final del dia + final_balance_crypto: Valor final de les posicions cripto del dia + final_balance_investment: Valor final de la cartera del dia + final_principal: Capital final del préstec del dia + final_value: Valor final de l'actiu del dia + market_changes: Variacions de valor pels moviments del preu de mercat + net_cash_flow: Variació neta del saldo per totes les transaccions del dia + net_principal_change: Pagaments de capital i nous préstecs durant el dia + net_value_change: Totes les variacions de valor incloent millores i depreciació + payments: Pagaments fets a la targeta durant el dia + sells: Vendes de cripto durant el dia + start_balance: Saldo del compte a l'inici del dia + start_balance_credit: Saldo deutor a l'inici del dia + start_balance_crypto: Valor de les posicions cripto a l'inici del dia + start_balance_investment: Valor total de la cartera a l'inici del dia + start_principal: Saldo del capital a l'inici del dia + start_value: Valor de l'actiu a l'inici del dia + chart: + no_data_available: No hi ha dades disponibles + title: + balance: Saldo + cash_value: Valor de l'efectiu + debt_balance: Saldo del deute + estimated_property_value: Valor estimat de l'immoble + estimated_vehicle_value: Valor estimat del vehicle + holdings_value: Valor de les posicions + remaining_principal_balance: Capital pendent + total_account_value: Valor total del compte + views: + cash: Efectiu + holdings: Posicions + total_value: Valor total + vs_available_history: vs. historial disponible + ds: + alert: + variants: + destructive: Error + error: Error + info: Informació + success: Èxit + warning: Avís + dialog: + close: Tanca + pill: + aria_label: "%{label}" + default_label: Experimental provider_sync_summary: accounts: institutions: 'Institucions: %{count}' @@ -20,8 +113,8 @@ ca: rate_limited: Sota límit de %{time_ago} recently: recentment stale_pending: - one: "%{count} transacció pendent obsoleta (exclòs dels pressupostos)" - other: "%{count} transaccions pendents obsoletes (exclòs dels pressupostos)" + one: "%{count} transacció pendent obsoleta (exclosa dels pressupostos)" + other: "%{count} transaccions pendents obsoletes (excloses dels pressupostos)" stale_pending_count: one: "%{count} transacció" other: "%{count} transaccions" @@ -34,6 +127,7 @@ ca: title: Estat view_data_quality: Veure detalls de qualitat de dades view_duplicate_suggestions: Veure duplicades suggerides + view_error_details: Veure detalls de l'error view_reconciled: Veure transaccions conciliades view_stale_pending: Veure comptes afectats view_stale_unmatched: Veure transaccions que necessiten revisió @@ -42,10 +136,25 @@ ca: processed: 'Processat: %{count}' title: Posicions last_sync: 'Última sincronització: fa %{time_ago}' + skip_reasons: + excluded: Excloses + import_locked: Importació CSV + protected: Protegides + user_modified: Modificades per l'usuari title: Resum de sincronització - transactions: + trades: + fetching: Recuperant activitats del broker... imported: 'Importat: %{count}' + skipped: 'Omès: %{count}' + title: Operacions + transactions: + fetching: Recuperant del broker... + imported: 'Importat: %{count}' + protected: + one: "%{count} entrada protegida (no sobreescrita)" + other: "%{count} entrades protegides (no sobreescrites)" seen: 'Vist: %{count}' skipped: 'Omès: %{count}' title: Transaccions updated: 'Actualitzat: %{count}' + view_protected: Veure entrades protegides diff --git a/config/locales/views/components/en.yml b/config/locales/views/components/en.yml index 1f3bff829..e0dfca1ab 100644 --- a/config/locales/views/components/en.yml +++ b/config/locales/views/components/en.yml @@ -4,8 +4,75 @@ en: account: activity_feed: toggle_selection_checkboxes: Toggle selection + balance_reconciliation: + labels: + adjustments: Adjustments + buys: Buys + change_in_brokerage_cash: Change in brokerage cash + change_in_holdings_market: Change in holdings (market price activity) + change_in_holdings_trades: Change in holdings (buys/sells) + charges: Charges + end_balance: End balance + end_principal: End principal + end_value: End value + final_balance: Final balance + final_principal: Final principal + final_value: Final value + market_changes: Market changes + net_cash_flow: Net cash flow + net_principal_change: Net principal change + net_value_change: Net value change + payments: Payments + sells: Sells + start_balance: Start balance + start_principal: Start principal + start_value: Start value + tooltips: + adjustments: Manual reconciliations or other adjustments + adjustments_asset: Manual value adjustments or appraisals + buys: Crypto purchases during the day + change_in_brokerage_cash: Net change in cash from deposits, withdrawals, and trades + change_in_holdings_market: Change in holdings value from market price movements + change_in_holdings_trades: Impact on holdings from buying and selling securities + charges: New charges made during the day + end_balance: The calculated balance after all transactions + end_balance_investment: The calculated balance after all activity + end_principal: The calculated principal after all transactions + end_value: The calculated value after all changes + final_balance: The final account balance for the day + final_balance_credit: The final balance owed for the day + final_balance_crypto: The final crypto holdings value for the day + final_balance_investment: The final portfolio value for the day + final_principal: The final principal balance for the day + final_value: The final asset value for the day + market_changes: Value changes from market price movements + net_cash_flow: Net change in balance from all transactions during the day + net_principal_change: Principal payments and new borrowing during the day + net_value_change: All value changes including improvements and depreciation + payments: Payments made to the card during the day + sells: Crypto sales during the day + start_balance: The account balance at the beginning of this day + start_balance_credit: The balance owed at the beginning of this day + start_balance_crypto: The crypto holdings value at the beginning of this day + start_balance_investment: The total portfolio value at the beginning of this day + start_principal: The principal balance at the beginning of this day + start_value: The asset value at the beginning of this day chart: no_data_available: "No data available" + title: + balance: Balance + cash_value: Cash value + debt_balance: Debt balance + estimated_property_value: Estimated property value + estimated_vehicle_value: Estimated vehicle value + holdings_value: Holdings value + remaining_principal_balance: Remaining principal balance + total_account_value: Total account value + views: + cash: Cash + holdings: Holdings + total_value: Total value + vs_available_history: vs. available history activity_date: balance_tooltip: "The end of day balance, after all transactions and adjustments" no_balance_data: "No balance data available for this date" @@ -17,8 +84,17 @@ en: warning: Warning error: Error destructive: Error + pill: + aria_label: "%{label}" + default_label: Preview dialog: close: Close + popover: + avatar_default_label: Open menu + tooltip: + trigger_label: More info + link: + opens_in_new_tab: (opens in new tab) provider_sync_summary: title: Sync summary last_sync: "Last sync: %{time_ago} ago" diff --git a/config/locales/views/components/es.yml b/config/locales/views/components/es.yml index 4587a0088..639beff3f 100644 --- a/config/locales/views/components/es.yml +++ b/config/locales/views/components/es.yml @@ -63,4 +63,8 @@ es: other: "%{count} transacciones" data_warnings: "Avisos de datos: %{count}" notices: "Avisos: %{count}" - view_data_quality: Ver detalles de calidad de datos \ No newline at end of file + view_data_quality: Ver detalles de calidad de datos + ds: + pill: + aria_label: "%{label}" + default_label: Experimental \ No newline at end of file diff --git a/config/locales/views/components/hu.yml b/config/locales/views/components/hu.yml index c0145c036..7eaea51d6 100644 --- a/config/locales/views/components/hu.yml +++ b/config/locales/views/components/hu.yml @@ -1,5 +1,24 @@ --- hu: + UI: + account: + activity_feed: + toggle_selection_checkboxes: Kijelölés be-/kikapcsolása + chart: + no_data_available: "Nincs elérhető adat" + activity_date: + balance_tooltip: "A nap végi egyenleg, az összes tranzakció és korrekció után" + no_balance_data: "Erre a dátumra nincs elérhető egyenlegadat" + ds: + alert: + variants: + info: Információ + success: Siker + warning: Figyelmeztetés + error: Hiba + destructive: Hiba + dialog: + close: Bezárás provider_sync_summary: title: Szinkronizálás összegzése last_sync: "Utolsó szinkronizálás: %{time_ago} ezelőtt" diff --git a/config/locales/views/credit_cards/ca.yml b/config/locales/views/credit_cards/ca.yml index 9f6ad0003..6ac6a7515 100644 --- a/config/locales/views/credit_cards/ca.yml +++ b/config/locales/views/credit_cards/ca.yml @@ -20,6 +20,7 @@ ca: annual_fee: Quota anual apr: TAE available_credit: Crèdit disponible + edit_account_details: Edita els detalls del compte expiration_date: Data de caducitat minimum_payment: Pagament mínim unknown: Desconegut diff --git a/config/locales/views/credit_cards/hu.yml b/config/locales/views/credit_cards/hu.yml index e037fc0ee..be82b379d 100644 --- a/config/locales/views/credit_cards/hu.yml +++ b/config/locales/views/credit_cards/hu.yml @@ -20,6 +20,7 @@ hu: annual_fee: Éves díj apr: THM available_credit: Rendelkezésre álló hitelkeret + edit_account_details: Számlaadatok szerkesztése expiration_date: Lejárati dátum minimum_payment: Minimális törlesztőrészlet unknown: Ismeretlen diff --git a/config/locales/views/cryptos/ca.yml b/config/locales/views/cryptos/ca.yml index 597bd3cbe..fb41ce5bc 100644 --- a/config/locales/views/cryptos/ca.yml +++ b/config/locales/views/cryptos/ca.yml @@ -3,5 +3,20 @@ ca: cryptos: edit: edit: Edita %{account} + form: + subtype_label: Tipus de compte + subtype_none: Cap + subtype_prompt: Selecciona el tipus de compte + tax_treatment_hint: La majoria de les criptomonedes es tenen en comptes subjectes + a impostos. Selecciona una altra opció si es tenen en un compte amb avantatges + fiscals. + tax_treatment_label: Tractament fiscal new: title: Introdueix el saldo del compte + subtypes: + exchange: + long: Exchange de cripto + short: Exchange + wallet: + long: Cartera de cripto + short: Cartera diff --git a/config/locales/views/depositories/ca.yml b/config/locales/views/depositories/ca.yml index 59d4cb0de..8f4327d69 100644 --- a/config/locales/views/depositories/ca.yml +++ b/config/locales/views/depositories/ca.yml @@ -8,3 +8,21 @@ ca: subtype_prompt: Selecciona el tipus de compte new: title: Introdueix el saldo del compte + subtypes: + cd: + long: Certificat de dipòsit + short: CD + checking: + long: Corrent + short: Corrent + hsa: + long: Compte d'estalvi per a salut + short: HSA + money_market: + long: Mercat monetari + short: MM + savings: + long: Estalvis + short: Estalvis + types_plural: + depository: Comptes corrents i estalvis diff --git a/config/locales/views/depositories/en.yml b/config/locales/views/depositories/en.yml index 081d14679..99cc944d1 100644 --- a/config/locales/views/depositories/en.yml +++ b/config/locales/views/depositories/en.yml @@ -8,3 +8,19 @@ en: subtype_prompt: Select account type new: title: Enter account balance + subtypes: + cd: + long: Certificate of Deposit + short: CD + checking: + long: Checking + short: Checking + hsa: + long: Health Savings Account + short: HSA + money_market: + long: Money Market + short: MM + savings: + long: Savings + short: Savings diff --git a/config/locales/views/enable_banking_items/ca.yml b/config/locales/views/enable_banking_items/ca.yml index a2ee3c9bf..432240782 100644 --- a/config/locales/views/enable_banking_items/ca.yml +++ b/config/locales/views/enable_banking_items/ca.yml @@ -2,52 +2,131 @@ ca: enable_banking_items: authorize: - authorization_failed: No s'ha pogut iniciar l'autorització - bank_required: Si us plau, selecciona un banc. - invalid_redirect: L'URL d'autorització rebuta no és vàlida. Si us plau, torna-ho - a provar o contacta amb l'assistència. - redirect_uri_not_allowed: Redirecció no permesa. Si us plau, configura `%{callback_url}` - a la configuració de l'aplicació Enable Banking. - unexpected_error: S'ha produït un error inesperat. Si us plau, torna-ho a provar. + authorization_failed: 'No s''ha pogut iniciar l''autorització: %{message}' + bank_required: Selecciona un banc. + decoupled_not_supported: Aquest banc utilitza un mètode d'autenticació amb dispositiu + separat que encara no està admès. Afegeix aquest compte manualment. + invalid_redirect: L'URL d'autorització rebuda no és vàlida. Torna-ho a provar. + redirect_uri_not_allowed: Redirecció no permesa. Configura `%{callback_url}` + a la configuració de la teva aplicació Enable Banking. + unexpected_error: S'ha produït un error inesperat. Torna-ho a provar. callback: authorization_error: L'autorització ha fallat invalid_callback: Paràmetres de callback no vàlids. item_not_found: Connexió no trobada. session_failed: No s'ha pogut completar l'autorització - success: S'ha connectat correctament amb el teu banc. Les teves comptes s'estan sincronitzant. - unexpected_error: S'ha produït un error inesperat. Si us plau, torna-ho a provar. + success: T'has connectat correctament al teu banc. Els teus comptes s'estan + sincronitzant. + unexpected_error: S'ha produït un error inesperat. Torna-ho a provar. complete_account_setup: - all_skipped: S'han omès tots els comptes. Pots configurar-los més tard a la pàgina - de comptes. + all_skipped: S'han omès tots els comptes. Pots configurar-los més tard a la + pàgina de comptes. no_accounts: No hi ha comptes disponibles per configurar. success: S'han creat correctament %{count} comptes! create: success: La configuració d'Enable Banking s'ha fet amb èxit. destroy: success: La connexió d'Enable Banking s'ha posat a la cua per a l'eliminació. + enable_banking_item: + delete: Elimina + deletion_in_progress: Eliminació en curs + last_synced: Darrera sincronització fa %{time} + never_synced: Mai sincronitzat + no_accounts_found: No s'han trobat comptes + no_accounts_found_description: No s'han trobat comptes a Enable Banking. Torna + a sincronitzar. + provider_name: Enable Banking + reconnect: Reconnecta + set_up_accounts: Configura comptes + setup_needed: Cal configuració + setup_needed_description: + one: 1 compte importat d'Enable Banking necessita configuració + other: "%{count} comptes importats d'Enable Banking necessiten configuració" + syncing: Sincronitzant... + update: Actualitza + errors: + api_error: S'ha produït un error de comunicació amb el banc. + network_unreachable: El servei bancari està temporalment inaccessible. Torna-ho + a provar més tard. + session_invalid: La sessió ha caducat. Torna a connectar el teu banc. + unexpected: S'ha produït un error inesperat durant la sincronització. link_accounts: - already_linked: Els comptes seleccionats ja estan vinculats. - link_failed: No s'ha pogut vincular els comptes + already_linked: Els comptes seleccionats ja estan enllaçats. + link_failed: No s'han pogut enllaçar els comptes no_accounts_selected: No s'han seleccionat comptes. - no_session: No hi ha connexió activa d'Enable Banking. Si us plau, connecta't a un banc primer. - success: S'han vinculat correctament %{count} comptes. + no_session: No hi ha cap connexió activa d'Enable Banking. Primer connecta't + a un banc. + success: S'han enllaçat correctament %{count} comptes. link_existing_account: errors: - invalid_enable_banking_account: S'ha seleccionat un compte d'Enable Banking no vàlid - only_manual: Només es poden vincular comptes manuals - success: Compte vinculat correctament a Enable Banking + invalid_enable_banking_account: S'ha seleccionat un compte d'Enable Banking + no vàlid + only_manual: Només els comptes manuals es poden enllaçar + success: El compte s'ha enllaçat correctament a Enable Banking new: - link_enable_banking_title: Vincula Enable Banking + add_connection: Afegeix connexió + configured: Configurat + connect_bank: Connecta el banc + connected_bank: Banc connectat + connection: Connexió + go_to_provider_settings: Ves a la configuració del proveïdor + link_enable_banking_title: Enllaça Enable Banking + not_configured: Connexió d'Enable Banking no configurada + not_configured_description: Abans d'enllaçar comptes d'Enable Banking, has de + configurar la teva connexió d'Enable Banking. + ready_to_connect: A punt per connectar un banc + reconnect: Reconnecta + remove: Elimina + remove_confirm: Segur que vols eliminar aquesta connexió? + session_expired: La sessió ha caducat — cal tornar a autoritzar + session_expires: La sessió caduca + setup_step_1_html: Ves a Configuració → Proveïdors + setup_step_2_html: Localitza la secció Enable Banking + setup_step_3: Introdueix les teves credencials d'Enable Banking + setup_step_4: Torna aquí per enllaçar els teus comptes + setup_steps_title: 'Passos de configuració:' + sync: Sincronitza + unknown: Desconegut reauthorize: - invalid_redirect: L'URL d'autorització rebuta no és vàlida. Si us plau, torna-ho - a provar o contacta amb l'assistència. + invalid_redirect: L'URL d'autorització rebuda no és vàlida. Torna-ho a provar. reauthorization_failed: La reautorització ha fallat select_bank: + beta_label: Beta cancel: Cancel·la - check_country: Si us plau, revisa els teus codis de país. - credentials_required: Si us plau, configura les teves credencials d'Enable Banking primer. + check_country: Revisa la configuració del codi de país. + credentials_required: Primer configura les teves credencials d'Enable Banking. description: Selecciona el banc al qual vols connectar els teus comptes. - no_banks: No hi ha bancs disponibles per aquest país/regió. + no_banks: No hi ha bancs disponibles per a aquest país/regió. + no_search_results: Cap banc coincideix amb la teva cerca. + search_label: Cerca el teu banc + search_placeholder: Cerca el teu banc... title: Selecciona el teu banc + select_existing_account: + all_linked: Sembla que tots els comptes d'Enable Banking ja estan enllaçats. + balance: Saldo + cancel: Cancel·la + link: Enllaça + title: Enllaça compte d'Enable Banking + try_after_sync: Si acabes de connectar o sincronitzar, torna-ho a provar després + que la sincronització acabi. + unlink_to_move: Per enllaçar un compte diferent, primer desenllaça'l del menú + d'accions del compte. + setup_accounts: + account_type_label: 'Tipus de compte:' + balance: Saldo + cancel: Cancel·la + choose_account_type: 'Tria el tipus de compte correcte per a cada compte d''Enable + Banking:' + create_accounts: Crea comptes + creating_accounts: Creant comptes... + header_subtitle: Tria els tipus de compte correctes per als teus comptes importats + historical_data_range: 'Rang de dades històriques:' + psd2_savings_notice: 'Nota: alguns comptes d''estalvi regulats francesos (Livret + A, PEL, LEP, LDDS) tenen accés limitat o nul a través de l''Open Banking (PSD2). + Si manca un compte d''estalvi, pots afegir-lo manualment.' + sync_start_date_help: Selecciona fins on vols sincronitzar l'historial de transaccions. + Hi ha un màxim de 2 anys d'historial disponible. + sync_start_date_label: 'Comença a sincronitzar transaccions des de:' + title: Configura els teus comptes d'Enable Banking update: success: La configuració d'Enable Banking s'ha actualitzat. diff --git a/config/locales/views/enable_banking_items/hu.yml b/config/locales/views/enable_banking_items/hu.yml index d96307af5..79a3282f0 100644 --- a/config/locales/views/enable_banking_items/hu.yml +++ b/config/locales/views/enable_banking_items/hu.yml @@ -39,8 +39,53 @@ hu: errors: only_manual: Csak manuális számlákat lehet összekapcsolni invalid_enable_banking_account: Érvénytelen Enable Banking-számla választva + enable_banking_item: + deletion_in_progress: Törlés folyamatban + provider_name: Enable Banking + syncing: Szinkronizálás... + reconnect: Újracsatlakozás + last_synced: Utoljára szinkronizálva %{time} ezelőtt + never_synced: Még nem szinkronizált + update: Frissítés + delete: Törlés + setup_needed: Beállítás szükséges + setup_needed_description: + one: 1 Enable Banking-ből importált számla beállítása szükséges + other: "%{count} Enable Banking-ből importált számla beállítása szükséges" + set_up_accounts: Számlák beállítása + no_accounts_found: Nem található számla + no_accounts_found_description: Nem található számla az Enable Banking-ből. Próbálj újra szinkronizálni. + select_existing_account: + title: Enable Banking-számla összekapcsolása + all_linked: Úgy tűnik, minden Enable Banking-számla már össze van kapcsolva. + try_after_sync: Ha most csatlakoztál vagy szinkronizáltál, próbálj újra a szinkronizálás befejezése után. + unlink_to_move: Másik számla összekapcsolásához először válaszd le a számlán a műveletek menüből. + balance: Egyenleg + link: Összekapcsolás + cancel: Mégse new: link_enable_banking_title: Enable Banking összekapcsolása + session_expired: A munkamenet lejárt – újraengedélyezés szükséges + connected_bank: Csatlakoztatott bank + session_expires: "Munkamenet lejárata" + unknown: Ismeretlen + connection: Kapcsolat + configured: Konfigurálva + ready_to_connect: Kész egy bank csatlakoztatására + sync: Szinkronizálás + reconnect: Újracsatlakozás + connect_bank: Bank csatlakoztatása + remove_confirm: Biztosan el szeretnéd távolítani ezt a kapcsolatot? + remove: Eltávolítás + add_connection: Kapcsolat hozzáadása + not_configured: Az Enable Banking kapcsolat nincs konfigurálva + not_configured_description: Mielőtt Enable Banking-számlákat kapcsolnál össze, konfigurálnod kell az Enable Banking kapcsolatot. + setup_steps_title: "Beállítási lépések:" + setup_step_1_html: "Menj a Beállítások → Szolgáltatók menübe" + setup_step_2_html: "Keresd meg az Enable Banking részt" + setup_step_3: Add meg az Enable Banking hitelesítő adatait + setup_step_4: Térj vissza ide a számlák összekapcsolásához + go_to_provider_settings: Ugrás a szolgáltató beállításaihoz reauthorize: invalid_redirect: A kapott engedélyezési URL érvénytelen. Kérjük, próbáld újra. reauthorization_failed: Az újraengedélyezés sikertelen @@ -56,6 +101,17 @@ hu: search_placeholder: Keresd meg a bankod... title: Válaszd ki a bankod setup_accounts: + title: Enable Banking-számlák beállítása + header_subtitle: Válaszd ki a megfelelő számlatípusokat az importált számlákhoz + choose_account_type: "Válaszd ki az egyes Enable Banking-számlák megfelelő számlatípusát:" + historical_data_range: "Historikus adatok tartománya:" + sync_start_date_label: "Tranzakciók szinkronizálásának kezdete:" + sync_start_date_help: Válaszd meg, milyen messzire nyúljon vissza a tranzakciótörténet szinkronizálása. Legfeljebb 2 év előzmény érhető el. + account_type_label: "Számlatípus:" + balance: Egyenleg + create_accounts: Számlák létrehozása + creating_accounts: Számlák létrehozása... + cancel: Mégse psd2_savings_notice: "Megjegyzés: Egyes szabályozott francia megtakarítási számlákhoz (Livret A, PEL, LEP, LDDS) korlátozott vagy semmilyen hozzáférés nem áll rendelkezésre az Open Banking (PSD2) révén. Ha egy megtakarítási számla hiányzik, manuálisan is hozzáadhatod." update: success: Az Enable Banking konfiguráció frissítve. diff --git a/config/locales/views/entries/ca.yml b/config/locales/views/entries/ca.yml index 4ece9e3aa..5e9e0d459 100644 --- a/config/locales/views/entries/ca.yml +++ b/config/locales/views/entries/ca.yml @@ -10,5 +10,16 @@ ca: title: No s'han trobat entrades loading: loading: Carregant entrades... + protection: + description: Les teves edicions a aquesta entrada no se sobreescriuran amb la + sincronització del proveïdor. + locked_fields_label: 'Camps bloquejats:' + title: Protegida de la sincronització + tooltip: Protegida de la sincronització + unlock_button: Permet que la sincronització l'actualitzi + unlock_confirm: Vols permetre que la sincronització actualitzi aquesta entrada? + Els teus canvis es poden sobreescriure a la pròxima sincronització. + unlock: + success: Entrada desbloquejada. Pot ser actualitzada a la pròxima sincronització. update: success: Entrada actualitzada diff --git a/config/locales/views/family_exports/ca.yml b/config/locales/views/family_exports/ca.yml index 9056ea5c6..04a517f20 100644 --- a/config/locales/views/family_exports/ca.yml +++ b/config/locales/views/family_exports/ca.yml @@ -3,29 +3,46 @@ ca: family_exports: access_denied: Accés denegat create: - success: Exportació iniciada. Podràs descarregar-la aviat. - delete_confirmation: Estàs segur que vols eliminar aquesta exportació? Aquesta acció no es pot desfer. - delete_failed_confirmation: Estàs segur que vols eliminar aquesta exportació fallida? + success: Exportació iniciada. La podràs descarregar aviat. + delete_confirmation: Segur que vols eliminar aquesta exportació? Aquesta acció + no es pot desfer. + delete_failed_confirmation: Segur que vols eliminar aquesta exportació fallida? destroy: - success: Exportació eliminada amb èxit - export_not_ready: L'exportació no està llesta per descarregar + success: Exportació eliminada correctament + export_not_ready: L'exportació no està a punt per descarregar exporting: Exportant... index: - title: Exportacions new: Nova exportació - table: title: Exportacions + new: + accounts_and_balances: Tots els comptes i saldos + cancel: Cancel·la + categories_tags_rules: Categories, etiquetes i regles + dialog_subtitle: Descarrega totes les teves dades financeres + dialog_title: Exporta les teves dades + export_data: Exporta les dades + investment_trades: Operacions d'inversió + note_description: Aquesta exportació inclou totes les teves dades, però només + se'n pot importar de nou una part mitjançant la funció d'importació CSV. Donem + suport a la importació de comptes, transaccions (amb categoria i etiquetes) + i operacions. La resta de dades del compte no es poden importar i són només + per als teus registres. + note_label: Nota + transaction_history: Historial de transaccions + whats_included: 'Què s''inclou:' + table: + empty: Encara no hi ha exportacions. header: + actions: Accions date: Data filename: Nom del fitxer status: Estat - actions: Accions row: - status: - in_progress: En curs - complete: Completat - failed: Error actions: delete: Elimina - download: Descarregar - empty: Encara no hi ha exportacions. + download: Descarrega + status: + complete: Completat + failed: Error + in_progress: En curs + title: Exportacions diff --git a/config/locales/views/family_exports/hu.yml b/config/locales/views/family_exports/hu.yml index 626a42e4e..35f49accb 100644 --- a/config/locales/views/family_exports/hu.yml +++ b/config/locales/views/family_exports/hu.yml @@ -10,6 +10,18 @@ hu: success: Az export sikeresen törölve export_not_ready: Az export még nem áll készen a letöltésre exporting: Exportálás folyamatban... + new: + dialog_title: Adataid exportálása + dialog_subtitle: Töltsd le az összes pénzügyi adatodat + whats_included: "Mi kerül bele:" + accounts_and_balances: Összes számla és egyenleg + transaction_history: Tranzakciótörténet + investment_trades: Befektetési ügyletek + categories_tags_rules: Kategóriák, címkék és szabályok + note_label: Megjegyzés + note_description: Ez az export tartalmazza az összes adatodat, de csak egy részük importálható vissza a CSV importálás funkcióval. Számlák, tranzakciók (kategóriával és címkékkel) és kereskedések importálása támogatott. Más számlaadat nem importálható, csak nyilvántartás céljából szerepel. + cancel: Mégse + export_data: Adatok exportálása index: title: Exportok new: Új export diff --git a/config/locales/views/holdings/ca.yml b/config/locales/views/holdings/ca.yml index ea6b8e0dd..899da5016 100644 --- a/config/locales/views/holdings/ca.yml +++ b/config/locales/views/holdings/ca.yml @@ -2,23 +2,28 @@ ca: holdings: cash: - brokerage_cash: Efectiu de broker + brokerage_cash: Efectiu del broker cost_basis_cell: cancel: Cancel·la - or_per_share_label: 'O entra per acció:' + or_per_share_label: 'O introdueix per acció:' overwrite_confirm_body: Això reemplaçarà el cost base actual de %{current}. overwrite_confirm_title: Reemplaça el cost base? per_share: per acció save: Desa - set_cost_basis_header: Estableix el cost base per %{ticker} (%{qty} accions) + set: Estableix + set_cost_basis_header: Estableix el cost base per a %{ticker} (%{qty} accions) total_cost_basis_label: Cost base total unknown: "--" cost_basis_sources: - calculated: Des de les operacions + calculated: A partir de les operacions manual: Establert per l'usuari - provider: Des del proveïdor + provider: Del proveïdor destroy: + cannot_delete: No pots eliminar aquesta posició success: Posició eliminada + errors: + security_collision: 'No es pot reassignar: ja tens una posició per a %{ticker} + a %{date}.' holding: no_cost_basis: Sense cost base per_share: per acció @@ -28,38 +33,84 @@ ca: average_cost: Cost mitjà holdings: Posicions name: Nom - new_holding: Nova transacció + new_holding: Nova activitat no_holdings: No hi ha posicions per mostrar. return: Rendiment total weight: Pes missing_price_tooltip: - description: Aquesta inversió té valors que falten i no hem pogut calcular-ne - el rendiment o el valor. + description: Aquesta inversió té valors que falten i no se n'han pogut calcular + el rendiment ni el valor. missing_data: Falten dades + remap_security: + security_not_found: No s'ha pogut trobar el valor seleccionat. + success: Valor actualitzat correctament. + reset_security: + success: Valor restablert al del proveïdor. show: avg_cost_label: Cost mitjà - cost_basis_locked_description: El cost base establert manualment no canviarà + book_value_label: Valor comptable + cancel: Cancel·la + cost_basis_locked_description: El cost base establert manualment no es modificarà amb les sincronitzacions. cost_basis_locked_label: El cost base està bloquejat current_market_price_label: Preu de mercat actual delete: Elimina delete_subtitle: Això eliminarà la posició i totes les operacions associades d'aquest compte. Aquesta acció no es pot desfer. - delete_title: Elimina posició + delete_title: Elimina la posició + edit_security: Edita el valor history: Historial + last_price_update: Última actualització de preu + market_data_label: Dades de mercat + market_data_sync_button: Actualitza + market_value_label: Valor de mercat + never: Mai + no_security_provider: Proveïdor de valors no configurat. No es poden cercar + valors. + no_trade_history: No hi ha historial d'operacions per a aquesta posició. + originally: era %{ticker} overview: Resum - portfolio_weight_label: Pes al portafolis + portfolio_weight_label: Pes a la cartera + provider_disabled_warning: Actualitzacions de preu en pausa — el proveïdor %{provider} + està desactivat. Canvia a un altre proveïdor o torna'l a activar a Configuració. + provider_sent: 'El proveïdor ha enviat: %{ticker}' + remap_security: Desa + reset_confirm_body: Això canviarà el valor de %{current} a %{original} i mourà + totes les operacions associades. + reset_confirm_title: Restablir el valor al del proveïdor? + reset_to_provider: Restableix al del proveïdor + search_security: Cerca valor + search_security_placeholder: Cerca per símbol o nom + security_label: Valor + security_remapped_label: Valor reassignat settings: Configuració - ticker_label: Ticker + shares_label: Accions + switch_provider_button: Canvia + switch_provider_description: "%{provider} està desactivat. Cerca aquest valor + en un altre proveïdor activat." + switch_provider_label: Canvia de proveïdor + syncing: Sincronitzant... + ticker_label: Símbol total_return_label: Rendiment total trade_history_entry: "%{qty} accions de %{security} a %{price}" + truncated_history_warning: L'historial de preus només està disponible a partir + del %{date}. Les dates anteriors no tenen dades del proveïdor seleccionat + — això pot passar quan l'actiu es va llistar després de la data de l'operació, + o quan el proveïdor només ofereix una finestra històrica limitada al seu pla + actual. unknown: Desconegut - unlock_confirm_body: Això permetrà que el cost base s'actualitzi per sincronitzacions - del proveïdor o càlculs d'operacions. - unlock_confirm_title: Desbloqueja el cost base? + unlock_confirm_body: Això permetrà que el cost base s'actualitzi per les sincronitzacions + del proveïdor o pels càlculs d'operacions. + unlock_confirm_title: Desbloquejar el cost base? unlock_cost_basis: Desbloqueja + sync_prices: + provider_error: No s'han pogut obtenir els preus més recents. Torna-ho a provar + d'aquí a uns minuts. + success: Dades de mercat sincronitzades correctament. + unavailable: La sincronització de dades de mercat no està disponible per a valors + sense connexió. unlock_cost_basis: - success: El cost base s'ha desbloquejat. Pot actualitzar-se en la següent sincronització. + success: Cost base desbloquejat. Pot actualitzar-se a la propera sincronització. update: error: Valor de cost base no vàlid. success: Cost base desat. diff --git a/config/locales/views/holdings/hu.yml b/config/locales/views/holdings/hu.yml index d8b6067a4..c685e9803 100644 --- a/config/locales/views/holdings/hu.yml +++ b/config/locales/views/holdings/hu.yml @@ -5,6 +5,7 @@ hu: brokerage_cash: Brókeri készpénz destroy: success: Pozíció törölve + cannot_delete: Ez a pozíció nem törölhető update: success: Bekerülési érték mentve. error: Érvénytelen bekerülési érték. @@ -27,6 +28,7 @@ hu: provider: Szolgáltatótól cost_basis_cell: unknown: "--" + set: Megadás set_cost_basis_header: "Bekerülési érték megadása: %{ticker} (%{qty} részvény)" total_cost_basis_label: Teljes bekerülési érték or_per_share_label: "Vagy add meg részvényenként:" diff --git a/config/locales/views/ibkr_items/ca.yml b/config/locales/views/ibkr_items/ca.yml new file mode 100644 index 000000000..7cf62c8ba --- /dev/null +++ b/config/locales/views/ibkr_items/ca.yml @@ -0,0 +1,101 @@ +--- +ca: + ibkr_items: + complete_account_setup: + none_created: No s'ha creat cap compte. + none_selected: No s'ha seleccionat cap compte. + success: + one: S'ha creat correctament %{count} compte d'Interactive Brokers. + other: S'han creat correctament %{count} comptes d'Interactive Brokers. + create: + success: Interactive Brokers s'ha configurat correctament. + defaults: + name: Interactive Brokers + destroy: + success: S'ha programat la connexió Interactive Brokers per a la seva eliminació. + ibkr_item: + accounts_need_setup: Els comptes necessiten configuració + accounts_need_setup_description: Alguns comptes d'IBKR necessiten ser enllaçats + a comptes de Sure. + delete: Elimina + deletion_in_progress: Eliminació en curs + error: Error + flex_web_service: Flex Web Service + never_synced: Mai sincronitzat. + no_accounts_discovered: Encara no s'han descobert comptes d'IBKR. + no_accounts_discovered_description: Executa una sincronització després de configurar + la teva consulta Flex per descobrir comptes. + requires_update: Les credencials necessiten atenció + setup_accounts: Configura comptes + synced: Sincronitzat fa %{time}. %{summary}. + syncing: Sincronitzant + link_existing_account: + already_linked: Aquest compte d'Interactive Brokers ja està enllaçat. + failed: No s'ha pogut enllaçar el compte d'Interactive Brokers. + not_found: No s'ha trobat el compte o la configuració d'Interactive Brokers. + only_manual_investment: Només els comptes d'inversió manuals es poden enllaçar + a Interactive Brokers. + success: S'ha enllaçat correctament al compte d'Interactive Brokers. + select_accounts: + not_configured: Interactive Brokers no està configurat. + select_existing_account: + balance: Saldo + cancel: Cancel·la + link: Enllaça + no_accounts_available: Encara no hi ha comptes d'Interactive Brokers sense enllaçar + disponibles. + run_sync_hint: Executa una sincronització des de Configuració > Proveïdors després + d'actualitzar la teva consulta Flex. + title: Enllaça compte d'Interactive Brokers + wait_for_sync: Espera que la sincronització de descobriment de comptes acabi. + setup_accounts: + available_accounts: + account_id: 'ID del compte: %{account_id}' + account_summary: "%{account_type} • Saldo: %{balance}" + account_type_investment: Inversió + title: Comptes disponibles + buttons: + back_to_settings: Torna a la configuració + cancel: Cancel·la + create_selected_accounts: Crea els comptes seleccionats + done: Fet + link: Enllaça + refresh: Actualitza + dialog_title: Configura els teus comptes d'Interactive Brokers + info_box: + items: + item_1: Posicions amb preus i quantitats actuals + item_2: Cost base per posició + item_3: Operacions, dividends, comissions i dipòsits o retirades d'efectiu + title: Importació de la consulta Flex d'IBKR + warning: L'activitat històrica està limitada a la finestra de l'informe de + la consulta Flex + link_existing: + description: O enllaça un compte d'IBKR descobert a un compte d'inversió manual + existent. + manual_account_option: "%{name} (%{balance})" + select_prompt: Selecciona un compte... + linked_accounts: + linked_to_html: 'Enllaçat a: %{account}' + title: Ja enllaçats + page_title: Configura els comptes d'Interactive Brokers + status: + fetching_accounts: Obtenint comptes d'Interactive Brokers... + no_accounts_found_description: Sure no ha pogut trobar cap compte d'IBKR a + l'últim informe Flex. + no_accounts_found_title: No s'han trobat comptes. + subtitle: Selecciona quins comptes de broker d'IBKR vols enllaçar. + sync_status: + all_linked: + one: 1 compte enllaçat + other: "%{count} comptes enllaçats" + no_accounts: Encara no s'han descobert comptes d'IBKR + partial: "%{linked} enllaçats, %{unlinked} necessiten configuració" + update: + success: La configuració d'Interactive Brokers s'ha actualitzat correctament. + providers: + ibkr: + connection_description: Connecta un informe de Flex Web Service d'Interactive + Brokers + institution_name: Interactive Brokers + name: Interactive Brokers diff --git a/config/locales/views/ibkr_items/hu.yml b/config/locales/views/ibkr_items/hu.yml new file mode 100644 index 000000000..d24742859 --- /dev/null +++ b/config/locales/views/ibkr_items/hu.yml @@ -0,0 +1,92 @@ +--- +hu: + providers: + ibkr: + name: Interactive Brokers + connection_description: Csatlakozás egy Interactive Brokers Flex Web Service jelentéshez + institution_name: Interactive Brokers + ibkr_items: + defaults: + name: Interactive Brokers + ibkr_item: + deletion_in_progress: Törlés folyamatban + flex_web_service: Flex Web Service + syncing: Szinkronizálás + requires_update: A hitelesítő adatok figyelmet igényelnek + error: Hiba + synced: Szinkronizálva %{time} ezelőtt. %{summary}. + never_synced: Még nem szinkronizált. + setup_accounts: Számlák beállítása + delete: Törlés + accounts_need_setup: A számlák beállítást igényelnek + accounts_need_setup_description: Az IBKR-ből importált néhány számlát össze kell kapcsolni a Sure-számlákkal. + no_accounts_discovered: Még nem találhatók IBKR-számlák. + no_accounts_discovered_description: Futtass egy szinkronizálást a Flex-lekérdezés konfigurálása után a számlák felderítéséhez. + setup_accounts: + page_title: Interactive Brokers-számlák beállítása + dialog_title: Interactive Brokers-számlák beállítása + subtitle: Válaszd ki, melyik IBKR brókerszámlákat szeretnéd összekapcsolni. + info_box: + title: IBKR Flex Query importálás + items: + item_1: Pozíciók aktuális árakkal és mennyiségekkel + item_2: Bekerülési érték pozíciónként + item_3: Ügyletek, osztalékok, jutalékok és készpénzbefizetések vagy -kifizetések + warning: A historikus tevékenység a Flex Query jelentési ablakára korlátozódik + status: + fetching_accounts: Számlák lekérése az Interactive Brokers-től... + no_accounts_found_title: Nem található számla. + no_accounts_found_description: A Sure nem talált IBKR-számlákat a legutóbbi Flex-jelentésben. + available_accounts: + title: Elérhető számlák + account_type_investment: Befektetés + account_summary: "%{account_type} • Egyenleg: %{balance}" + account_id: "Számlaazonosító: %{account_id}" + link_existing: + description: Vagy kapcsolj össze egy felderített IBKR-számlát egy meglévő manuális befektetési számlával. + manual_account_option: "%{name} (%{balance})" + select_prompt: Válassz számlát... + linked_accounts: + title: Már összekapcsolt + linked_to_html: "Összekapcsolva: %{account}" + buttons: + refresh: Frissítés + cancel: Mégse + back_to_settings: Vissza a beállításokhoz + create_selected_accounts: Kijelölt számlák létrehozása + link: Összekapcsolás + done: Kész + sync_status: + no_accounts: Még nem találhatók IBKR-számlák + all_linked: + one: 1 számla összekapcsolva + other: "%{count} számla összekapcsolva" + partial: "%{linked} összekapcsolt, %{unlinked} beállítást igényel" + select_existing_account: + title: Interactive Brokers-számla összekapcsolása + no_accounts_available: Még nem érhető el összekapcsolatlan Interactive Brokers-számla. + run_sync_hint: "Futtass szinkronizálást a Beállítások > Szolgáltatók menüből a Flex-lekérdezés frissítése után." + wait_for_sync: Várd meg, amíg a számlafelderítési szinkronizálás befejeződik. + balance: Egyenleg + link: Összekapcsolás + cancel: Mégse + create: + success: Az Interactive Brokers sikeresen konfigurálva. + update: + success: Az Interactive Brokers konfigurációja sikeresen frissítve. + destroy: + success: Az Interactive Brokers kapcsolat törlési sorba került. + select_accounts: + not_configured: Az Interactive Brokers nincs konfigurálva. + link_existing_account: + not_found: A számla vagy az Interactive Brokers konfiguráció nem található. + only_manual_investment: Csak manuális befektetési számlák kapcsolhatók össze az Interactive Brokers-szel. + already_linked: Ez az Interactive Brokers-számla már össze van kapcsolva. + success: Sikeresen összekapcsolva az Interactive Brokers-számlával. + failed: Nem sikerült összekapcsolni az Interactive Brokers-számlával. + complete_account_setup: + success: + one: Sikeresen létrehozva %{count} Interactive Brokers-számla. + other: Sikeresen létrehozva %{count} Interactive Brokers-számla. + none_selected: Nem lett számla kijelölve. + none_created: Nem lett számla létrehozva. diff --git a/config/locales/views/impersonation_sessions/ca.yml b/config/locales/views/impersonation_sessions/ca.yml index ca1a23e07..71932d26d 100644 --- a/config/locales/views/impersonation_sessions/ca.yml +++ b/config/locales/views/impersonation_sessions/ca.yml @@ -13,3 +13,13 @@ ca: success: Has sortit de la sessió reject: success: Sol·licitud rebutjada + super_admin_bar: + impersonating: Personificant + jobs: Tasques + join: Uneix-te + join_a_session: Uneix-te a una sessió + leave: Surt + request_impersonation: Sol·licita personificació + super_admin: Super administrador + terminate: Finalitza + uuid_placeholder: UUID diff --git a/config/locales/views/impersonation_sessions/hu.yml b/config/locales/views/impersonation_sessions/hu.yml index 17025d85f..d8a1a672d 100644 --- a/config/locales/views/impersonation_sessions/hu.yml +++ b/config/locales/views/impersonation_sessions/hu.yml @@ -13,3 +13,13 @@ hu: success: Kilépés a munkamenetből megtörtént reject: success: Kérés elutasítva + super_admin_bar: + super_admin: Super Admin + jobs: Feladatok + impersonating: Megszemélyesítés + leave: Kilépés + terminate: Befejezés + join_a_session: Csatlakozás munkamenethez + join: Csatlakozás + uuid_placeholder: UUID + request_impersonation: Megszemélyesítés kérése diff --git a/config/locales/views/imports/ca.yml b/config/locales/views/imports/ca.yml index 8de803977..723d6471e 100644 --- a/config/locales/views/imports/ca.yml +++ b/config/locales/views/imports/ca.yml @@ -3,19 +3,51 @@ ca: import: cleans: show: + all_rows: Totes les files + data_cleaned: Les teves dades s'han netejat description: Edita les teves dades a la taula de sota. Les cel·les vermelles són invàlides. + error_rows: Files amb errors errors_notice: Hi ha errors a les teves dades. Passa el cursor per sobre de l'error per veure'n els detalls. errors_notice_mobile: Hi ha errors a les teves dades. Toca la icona d'error per veure'n els detalls. + next_step: Pas següent + not_configured: Configura la teva importació abans de continuar. title: Neteja les teves dades configurations: + account_import: + apply_configuration: Aplica la configuració + balance: Saldo + balance_date: Data del saldo + currency: Divisa + date_format: Format de data + default: Per defecte + entity_type: Tipus d'entitat + leave_empty: Deixa-ho buit + name: Nom + select_format: Selecciona el format + actual_import: + account_label: Compte (opcional) + amount_label: Import + apply_configuration: Aplica la configuració + category_label: Categoria (opcional) + date_format_label: Format de data + date_label: Data + incomes_are_negative: Els ingressos són negatius + incomes_are_positive: Els ingressos són positius + leave_empty: Deixa-ho buit + name_label: Beneficiari (opcional) + notes_label: Notes (opcional) + preconfigured_notice: Hem preconfigurat la teva importació d'Actual Budget. + Continua al pas següent. + signage_convention_label: Convenció de signes category_import: button_label: Continua description: Puja un fitxer CSV senzill (com el que generem quan exportes les teves dades). Automàticament maparem les columnes per tu. - instructions: Selecciona continuar per analitzar el teu CSV i passar al pas de neteja. + instructions: Selecciona continuar per analitzar el teu CSV i passar al pas + de neteja. mint_import: date_format_label: Format de data rule_import: @@ -28,13 +60,65 @@ ca: description: Selecciona les columnes que corresponen a cada camp del teu CSV. title: Configura la teva importació trade_import: + account_label: Compte + apply_configuration: Aplica la configuració + buys_are_negative: Les compres tenen quantitat negativa + buys_are_positive: Les compres tenen quantitat positiva + currency_label: Divisa date_format_label: Format de data + date_label: Data + default: Per defecte + format_label: Format + leave_empty: Deixa-ho buit + name_label: Nom + no_security_provider_warning: El proveïdor de preus de valors no està configurat. + Les teves importacions d'operacions funcionaran, però Sure no recuperarà + l'historial de preus. Ves a la configuració per configurar-ho. + note_label: Nota + price_label: Preu + quantity_label: Quantitat + select_column: Selecciona la columna + select_format: Selecciona el format + stock_exchange_code_label: Codi de borsa + ticker_label: Ticker transaction_import: + account_label: Compte + amount_label: Import + amount_type_label: Tipus d'import + amount_type_strategy_label: Estratègia del tipus d'import + apply_configuration: Aplica la configuració + as_amount_type_column: com a columna del tipus d'import + as_identifier_value: com a valor identificador + category_label: Categoria + currency_label: Divisa date_format_label: Format de data + date_label: Data + default: Per defecte + expense_outflow: Despesa (sortida) + format_label: Format + income_inflow: Ingrés (entrada) + incomes_are_negative: Els ingressos són negatius + incomes_are_positive: Els ingressos són positius + leave_empty: Deixa-ho buit + name_label: Nom + notes_label: Notes + rows_to_skip_label: Omet les primeres n files + select_column: Selecciona la columna + select_convention: Selecciona la convenció + select_format: Selecciona el format + select_strategy: Selecciona l'estratègia + select_type: Selecciona el tipus + select_value: Selecciona el valor + set: Estableix + tags_label: Etiquetes + treat_as_html: Tracta «%{value}» com a + update: + success: Importació configurada correctament. confirms: mappings: create_account: Crea un compte csv_mapping_label: "%{mapping} al CSV" + next: Següent no_accounts: Encara no tens cap compte. Crea un compte que puguem utilitzar per a les files (sense assignar) del teu CSV o torna al pas de Neteja i proporciona un nom de compte que puguem utilitzar. @@ -43,75 +127,347 @@ ca: unassigned_account: Necessites crear un nou compte per a les files sense assignar? show: account_mapping_description: Assigna tots els comptes del teu fitxer importat - als comptes existents de Maybe. També pots afegir nous comptes o deixar-los + als comptes existents. També pots afegir nous comptes o deixar-los sense categoria. account_mapping_title: Assigna els teus comptes account_type_mapping_description: Assigna tots els tipus de compte del teu - fitxer importat als de Maybe + fitxer importat als existents account_type_mapping_title: Assigna els teus tipus de compte category_mapping_description: Assigna totes les categories del teu fitxer - importat a les categories existents de Maybe. També pots afegir-ne de noves + importat a les categories existents. També pots afegir-ne de noves o deixar-les sense categoria. category_mapping_title: Assigna les teves categories + invalid_data: Hi ha dades invàlides; edita-les fins que es resolguin tots + els errors tag_mapping_description: Assigna totes les etiquetes del teu fitxer importat - a les etiquetes existents de Maybe. També pots afegir-ne de noves o deixar-les + a les etiquetes existents. També pots afegir-ne de noves o deixar-les sense categoria. tag_mapping_title: Assigna les teves etiquetes - uploads: + sure_import: + cancel: Cancel·la + description: Revisa les dades que s'importaran del teu fitxer d'exportació. + empty_summary: No s'han trobat registres importables en aquest fitxer. Pot + estar buit, o les línies no coincideixen amb el format d'exportació esperat + (cada línia ha de ser un objecte JSON amb les claus «type» i «data», amb + tipus admesos per aquesta importació). + publish_button: Inicia la importació + summary: Resum de la importació + title: Confirma la teva importació + qif_category_selections: show: + categories_found: + one: 1 categoria trobada + other: "%{count} categories trobades" + categories_heading: Categories + category_name_col: Nom de la categoria + description: Revisa el format de data detectat i tria quines categories i + etiquetes del teu fitxer QIF vols importar a %{product_name}. + empty_state_primary: No s'han trobat categories ni etiquetes en aquest fitxer + QIF. + empty_state_secondary: Totes les transaccions s'importaran sense categories + ni etiquetes. + split_badge: dividida + split_warning_description: Aquest fitxer QIF conté transaccions dividides. + Les divisions encara no estan suportades, així que cada transacció dividida + s'importarà com una sola transacció amb el seu import complet i sense categoria. + El detall individual de cada divisió no es conservarà. + split_warning_title: Transaccions dividides detectades + submit: Continua per revisar + tag_name_col: Nom de l'etiqueta + tags_found: + one: 1 etiqueta trobada + other: "%{count} etiquetes trobades" + tags_heading: Etiquetes + title: Configura i selecciona + transactions_col: Transaccions + txn_count: + one: 1 trans. + other: "%{count} trans." + update: + success: Categories i etiquetes desades. + uploads: + handle_qif_upload: + qif_uploaded: Fitxer QIF pujat correctament. + show: + account_optional_label: Compte (opcional) + browse: Explora + copy_paste_tab: Copia i enganxa + csv_file_prompt: per afegir aquí el teu fitxer CSV + csv_invalid: Ha de ser un CSV vàlid amb capçaleres i com a mínim una fila + de dades description: Enganxa o puja el teu fitxer CSV a continuació. Revisa les instruccions de la taula abans de començar. + download_sample_csv: Descarrega un CSV d'exemple + drop_csv_subtitle: El teu fitxer es pujarà automàticament + drop_csv_title: Deixa anar el CSV per pujar-lo instructions_1: A sota hi ha un exemple de CSV amb columnes disponibles per importar. instructions_2: El teu CSV ha de tenir una fila d'encapçalament instructions_3: Pots posar el nom que vulguis a les columnes. Les maparàs en un pas posterior. instructions_4: Les columnes marcades amb un asterisc (*) són obligatòries. - instructions_5: Sense comes, símbols de moneda ni parèntesis als números. + instructions_5: Sense comes, símbols de divisa ni parèntesis als números. + multi_account_import: Importació multicompte + paste_csv_placeholder: Enganxa aquí el contingut del teu fitxer CSV + qif_account_label: Compte + qif_account_placeholder: Selecciona un compte… + qif_description: Selecciona el compte al qual pertany aquest fitxer QIF i + puja la teva exportació .qif de Quicken. + qif_file_hint: només fitxers .qif + qif_file_prompt: per afegir aquí el teu fitxer QIF + qif_submit: Puja QIF + qif_title: Puja el fitxer QIF title: Importa les teves dades + to_see_format: per veure el format CSV requerit + upload_csv_button: Puja CSV + upload_csv_tab: Puja CSV + sure_import: + browse: Explora + browse_hint: per afegir aquí el teu fitxer all.ndjson + description: Puja el fitxer all.ndjson de la teva exportació de dades per + restaurar els teus comptes, transaccions, categories i més. + drop_subtitle: El teu fitxer es pujarà automàticament + drop_title: Deixa anar el NDJSON per pujar-lo + hint_html: Puja el fitxer all.ndjson del teu ZIP d'exportació + de dades + ndjson_invalid: Ha de ser un NDJSON vàlid amb com a mínim un registre + title: Importa des d'una exportació + upload_button: Puja NDJSON + update: + qif_uploaded: Fitxer QIF pujat correctament. imports: + apply_template: + no_template_found: No s'ha trobat cap plantilla; configura manualment la teva + importació. + template_applied: Plantilla aplicada. + column_labels: + account: Compte + amount: Import + category: Categoria + category_color: Color + category_icon: Icona Lucide + category_parent: Categoria pare + currency: Divisa + date: Data + entity_type: Tipus + exchange: Borsa + name: Nom + notes: Notes + price: Preu + qty: Quantitat + tags: Etiquetes + ticker: Ticker + create: + csv_uploaded: CSV pujat correctament. + document_provider_not_configured: No hi ha cap magatzem vectorial configurat per + a la pujada de documents. + document_too_large: El fitxer del document és massa gran. La mida màxima és + %{max_size}MB. + document_upload_failed: No hem pogut pujar el document al magatzem vectorial. + Torna-ho a provar. + document_uploaded: Document pujat correctament. + file_too_large: El fitxer és massa gran. La mida màxima és %{max_size}MB. + invalid_document_file_type: Tipus de fitxer de document no vàlid per a l'arxiu + vectorial actiu. + invalid_file_type: Tipus de fitxer no vàlid. Puja un fitxer CSV. + invalid_ndjson_file_type: Tipus o format de fitxer no vàlid. Puja un fitxer + d'exportació .ndjson o .json vàlid. + invalid_pdf: El fitxer pujat no és un PDF vàlid. + ndjson_uploaded: Fitxer NDJSON pujat correctament. + pdf_processing: El teu PDF s'està processant. Rebràs un correu electrònic quan + l'anàlisi estigui completa. + pdf_too_large: El fitxer PDF és massa gran. La mida màxima és %{max_size}MB. + date_format: + description: El format de data s'ha detectat automàticament del teu fitxer. + Canvia'l si les dates no es veuen correctament. + error_description: Cap dels formats de data suportats ha pogut analitzar les + dates d'aquest fitxer. Comprova que el fitxer contingui entrades de data vàlides. + error_title: No s'ha pogut detectar el format de data + heading: Format de data + preview: Primera data analitzada + destroy: + deleted: La teva importació s'ha eliminat. + document_types: + bank_statement: Extracte bancari + contract: Contracte + credit_card_statement: Extracte de targeta de crèdit + financial_document: Document financer + investment_statement: Extracte d'inversions + other: Altre document + unknown: Document desconegut + empty: + message: No s'ha trobat cap importació. + errors: + custom_column_requires_inflow: Les importacions amb columna personalitzada requereixen + seleccionar una columna d'entrada + failure: + description: Comprova el format del fitxer, els errors i que tots els camps + obligatoris estiguin omplerts, i torna-ho a provar. + title: Importació fallida + try_again: Torna-ho a provar + importing: + back_to_dashboard: Tornar al tauler + check_status: Comprova l'estat + description: La teva importació està en curs. Consulta el menú d'importacions + per veure l'estat o clica «Comprova l'estat» per actualitzar la pàgina. Pots + continuar utilitzant l'aplicació. + title: Importació en curs index: - title: Importacions new: Nova importació + title: Importacions + mapping_labels: + account: Compte + account_type: Tipus de compte + category: Categoria + tag: Etiqueta + new: + coming_soon: Properament + description: Importa des d'una eina financera o puja fitxers de dades sense + processar. + import_accounts: Importa comptes + import_actual: Importa des d'Actual Budget + import_categories: Importa categories + import_file: Importa document + import_file_description: Anàlisi amb IA per a PDFs i pujada de fitxers cercables + import_mint: Importa des de Mint + import_portfolio: Importa inversions + import_qif: Importa des de Quicken (QIF) + import_rules: Importa regles + import_sure: Importa des de Sure + import_sure_description: Fitxer .ndjson d'exportació completa + import_transactions: Importa transaccions + import_ynab: Importa des de YNAB + requires_account: Importa comptes primer per desbloquejar aquesta opció. + resume: Reprèn %{type} + sources: Fonts + tab_financial_tools: Eines financeres i fitxers + tab_raw_data: Dades sense processar + title: Nova importació + pdf_import: + back_to_dashboard: Tornar al tauler + back_to_imports: Tornar a les importacions + check_status: Comprova l'estat + complete_description: Hem analitzat el teu PDF i això és el que hem trobat. + complete_title: Document analitzat + create_account: Crea un compte + delete_import: Elimina la importació + document_type_label: Tipus de document + email_sent_notice: T'hem enviat un correu electrònic amb els passos següents. + failed_description: No hem pogut processar el teu document PDF. Torna-ho a provar + o contacta amb el suport. + failed_title: El processament ha fallat + no_accounts: No hi ha comptes disponibles. Crea un compte primer. + processing_description: Estem analitzant el teu document amb IA. Pot trigar + un moment. Rebràs un correu electrònic quan l'anàlisi estigui completa. + processing_failed_generic: 'El processament ha fallat: %{error}' + processing_failed_with_message: "%{message}" + processing_title: Processant el teu PDF + publish_transactions: + one: Publica %{count} transacció + other: Publica %{count} transaccions + ready_for_review_description: Hem extret %{count} transaccions del teu extracte. + Revisa-les i publica-les per afegir-les al teu compte. + ready_for_review_title: A punt per revisar + review_transactions: Revisa les transaccions + save_account: Desa + select_account: Importa al compte + select_account_hint: Tria a quin compte vols importar aquestes transaccions. + select_account_placeholder: Selecciona un compte... + select_account_to_continue: Selecciona un compte a dalt per continuar. + summary_label: Resum + transactions_extracted: Transaccions extretes + transactions_extracted_count: + one: "%{count} transacció" + other: "%{count} transaccions" + try_again: Torna-ho a provar + unknown_document_type: Desconegut + unknown_state_description: Aquesta importació es troba en un estat inesperat. + Torna a les importacions. + unknown_state_title: Estat desconegut + publish: + max_rows_exceeded: La teva importació supera el límit màxim de %{max} files. + started: La teva importació s'ha iniciat en segon pla. + ready: + back_to_imports: Tornar a les importacions + description: Aquí tens un resum dels nous elements que s'afegiran al teu compte + un cop publiquis aquesta importació. + empty_summary: No s'han trobat registres importables en aquest fitxer. Pot estar + buit, o les línies no coincideixen amb el format d'exportació esperat (cada + línia ha de ser un objecte JSON amb les claus «type» i «data», amb tipus admesos + per aquesta importació). + publish_import: Publica la importació + summary_count_label: Quantitat + summary_item_label: Element + title: Confirma les teves dades d'importació + revert: + started: La importació s'està revertint en segon pla. + revert_failure: + description: Torna-ho a provar + title: La reversió de la importació ha fallat + try_again: Torna-ho a provar + show: + finalize_mappings: Finalitza els teus mapatges abans de continuar. + finalize_upload: Finalitza la pujada del fitxer. + steps: + clean: Neteja + configure: Configuració + confirm: Confirma + map: Mapatge + progress: Pas %{step} de %{total} + select: Selecciona + upload: Pujada + success: + back_to_dashboard: Tornar al tauler + description: Les teves dades importades s'han afegit correctament a l'aplicació + i ja es poden utilitzar. + title: Importació correcta table: - title: Imports + empty: Encara no hi ha importacions. header: + actions: Accions date: Data operation: Operació status: Estat - actions: Accions row: + actions: + confirm_revert: Això eliminarà les transaccions que s'han importat, però + encara podràs revisar i tornar a importar les teves dades en qualsevol + moment. + delete: Elimina + revert: Reverteix + view: Veure status: - in_progress: En curs - uploading: Processant files - reverting: Revertint - revert_failed: Reversió fallida complete: Completat failed: Error - actions: - revert: Revertir - confirm_revert: Això suprimirà les transaccions que s'han importat, però encara podràs revisar i tornar a importar les teves dades en qualsevol moment. - delete: Elimina - view: Veure - empty: Encara no hi ha importacions. - new: - description: Pots importar manualment diversos tipus de dades via CSV o utilitzar - una de les nostres plantilles d'importació com Mint. - import_accounts: Importa comptes - import_categories: Importa categories - import_mint: Importa des de Mint - import_portfolio: Importa inversions - import_rules: Importa regles - import_transactions: Importa transaccions - resume: Reprèn %{type} - sources: Fonts - title: Nova importació CSV - ready: - description: Aquí tens un resum dels nous elements que s'afegiran al teu compte - un cop publiquis aquesta importació. - title: Confirma les teves dades d'importació - summary_item_label: Element - summary_count_label: Quantitat - empty_summary: No s'han trobat registres importables en aquest fitxer. Pot estar buit, o les línies no coincideixen amb el format d'exportació esperat (cada línia ha de ser un objecte JSON amb les claus «type» i «data», amb tipus admesos per aquesta importació). - publish_import: Publicar la importació - back_to_imports: Tornar a les importacions + in_progress: En curs + revert_failed: Reversió fallida + reverting: Revertint + uploading: Processant files + type_labels: + account_import: Compte + actual_import: Actual + category_import: Categoria + document_import: Document + mint_import: Mint + pdf_import: PDF + qif_import: QIF + rule_import: Regla + sure_import: Sure + trade_import: Operació + transaction_import: Transacció + title: Importacions + type_labels: + account_import: Importació de comptes + actual_import: Importació d'Actual + category_import: Importació de categories + document_import: Importació de documents + mint_import: Importació de Mint + pdf_import: Importació PDF + qif_import: Importació QIF + rule_import: Importació de regles + sure_import: Importació Sure + trade_import: Importació d'operacions + transaction_import: Importació de transaccions + update: + account_saved: Compte desat. + invalid_account: No s'ha trobat el compte. diff --git a/config/locales/views/imports/en.yml b/config/locales/views/imports/en.yml index a45792793..270b7d2f6 100644 --- a/config/locales/views/imports/en.yml +++ b/config/locales/views/imports/en.yml @@ -112,6 +112,20 @@ en: instructions: Select continue to parse your CSV and move on to the clean step. mint_import: date_format_label: Date format + actual_import: + preconfigured_notice: We have pre-configured your Actual Budget import for you. Please proceed to the next step. + leave_empty: Leave empty + date_label: Date + date_format_label: Date format + amount_label: Amount + signage_convention_label: Signage convention + incomes_are_negative: Incomes are negative + incomes_are_positive: Incomes are positive + account_label: Account (optional) + name_label: Payee (optional) + category_label: Category (optional) + notes_label: Notes (optional) + apply_configuration: Apply configuration rule_import: description: Configure your rule import. Rules will be created or updated based on the CSV data. @@ -203,6 +217,22 @@ en: account: "Account" category: "Category" tag: "Tag" + dry_run_resources: + transactions: "Transactions" + balances: "Balances" + accounts: "Accounts" + categories: "Categories" + tags: "Tags" + rules: "Rules" + merchants: "Merchants" + recurring_transactions: "Recurring Transactions" + transfers: "Transfers" + rejected_transfers: "Rejected Transfers" + trades: "Trades" + holdings: "Holdings" + valuations: "Valuations" + budgets: "Budgets" + budget_categories: "Budget Categories" column_labels: date: "Date" amount: "Amount" @@ -241,6 +271,16 @@ en: title: Import successful description: Your imported data has been successfully added to the app and is now ready for use. back_to_dashboard: Back to dashboard + verification: + title: Readback verification + checked: Checked + mismatches: Mismatches + status: + not_verified: Not verified + matched: Matched + mismatch: Mismatch + failed: Failed + reverted: Reverted importing: title: Import in progress description: "Your import is in progress. Check the imports menu for status updates or click 'Check Status' to refresh the page for updates. Feel free to continue using the app." @@ -261,6 +301,7 @@ en: trade_import: "Trade import" account_import: "Account import" mint_import: "Mint import" + actual_import: "Actual import" qif_import: "QIF import" category_import: "Category import" rule_import: "Rule import" @@ -293,6 +334,7 @@ en: trade_import: "Trade" account_import: "Account" mint_import: "Mint" + actual_import: "Actual" qif_import: "QIF" category_import: "Category" rule_import: "Rule" @@ -321,6 +363,7 @@ en: import_accounts: Import accounts import_categories: Import categories import_mint: Import from Mint + import_actual: Import from Actual Budget import_portfolio: Import investments import_rules: Import rules import_transactions: Import transactions diff --git a/config/locales/views/imports/hu.yml b/config/locales/views/imports/hu.yml index 4f0f11b7b..8221e18fe 100644 --- a/config/locales/views/imports/hu.yml +++ b/config/locales/views/imports/hu.yml @@ -2,6 +2,8 @@ hu: import: qif_category_selections: + update: + success: "Kategóriák és címkék mentve." show: title: "Konfigurálás és kiválasztás" description: "Ellenőrizd az automatikusan felismert dátumformátumot, majd válaszd ki, mely kategóriákat és címkéket szeretnéd beimportálni a QIF fájlodból a %{product_name} alkalmazásba." @@ -27,13 +29,80 @@ hu: submit: Tovább az áttekintéshez cleans: show: + not_configured: "Kérjük, konfiguráld az importálást a folytatás előtt." description: Szerkeszd az adatokat az alábbi táblázatban. A piros cellák érvénytelen adatokat tartalmaznak. errors_notice: Hibák vannak az adataidban. Vidd az egeret a hiba fölé a részletekért. errors_notice_mobile: Hibák vannak az adataidban. Koppints a hibajelzőre a részletekért. title: Adatok megtisztítása + data_cleaned: Az adataid megtisztítva + next_step: Következő lépés + all_rows: Összes sor + error_rows: Hibasorok configurations: update: success: Az importálás konfigurálása sikeresen megtörtént. + account_import: + leave_empty: Hagyd üresen + default: Alapértelmezett + entity_type: Entitástípus + name: Név + balance: Egyenleg + currency: Pénznem + balance_date: Egyenleg dátuma + date_format: Dátumformátum + select_format: Formátum kiválasztása + apply_configuration: Konfiguráció alkalmazása + transaction_import: + date_label: Dátum + select_column: Oszlop kiválasztása + select_format: Formátum kiválasztása + amount_label: Összeg + default: Alapértelmezett + currency_label: Pénznem + format_label: Formátum + amount_type_strategy_label: Összeg típusának stratégiája + select_strategy: Stratégia kiválasztása + set: Beállítás + as_amount_type_column: összeg típusa oszlopként + select_value: Érték kiválasztása + as_identifier_value: azonosítóértékként + treat_as_html: "Kezeld a \"%{value}\" értéket így:" + income_inflow: Bevétel (beérkező) + expense_outflow: Kiadás (kimenő) + select_type: Típus kiválasztása + leave_empty: Hagyd üresen + account_label: Számla + name_label: Név + category_label: Kategória + tags_label: Címkék + notes_label: Megjegyzések + apply_configuration: Konfiguráció alkalmazása + incomes_are_positive: A bevételek pozitívak + incomes_are_negative: A bevételek negatívak + amount_type_label: Összeg típusa + select_convention: Egyezmény kiválasztása + date_format_label: Dátumformátum + rows_to_skip_label: Első n sor kihagyása + trade_import: + select_column: Oszlop kiválasztása + date_label: Dátum + quantity_label: Mennyiség + buys_are_positive: A vételek pozitív mennyiségűek + buys_are_negative: A vételek negatív mennyiségűek + default: Alapértelmezett + currency_label: Pénznem + format_label: Formátum + select_format: Formátum kiválasztása + ticker_label: Tőzsdei szimbólum + leave_empty: Hagyd üresen + stock_exchange_code_label: Tőzsde kódja + price_label: Ár + account_label: Számla + name_label: Név + note_label: Megjegyzés + no_security_provider_warning: Az értékpapír-árszolgáltató nincs konfigurálva. Az ügyletek importálása működni fog, de a Sure nem tölti fel a korábbi árfolyamadatokat. Kérjük, menj a beállításokhoz és konfiguráld. + date_format_label: Dátumformátum + apply_configuration: Konfiguráció alkalmazása category_import: button_label: Folytatás description: Tölts fel egy egyszerű CSV fájlt (például olyat, amit az adatexportáláskor generálunk). Az oszlopokat automatikusan leképezzük neked. @@ -47,11 +116,6 @@ hu: show: description: Válaszd ki, melyik oszlopok felelnek meg a CSV egyes mezőinek. title: Importálás konfigurálása - trade_import: - date_format_label: Dátumformátum - transaction_import: - date_format_label: Dátumformátum - rows_to_skip_label: Első n sor kihagyása confirms: sure_import: title: Importálás megerősítése @@ -67,7 +131,9 @@ hu: no_accounts: Még nincs egyetlen számlád sem. Kérjük, hozz létre egy számlát a CSV-ben nem hozzárendelt sorokhoz, vagy lépj vissza a Megtisztítás lépéshez, és adj meg egy használható számlanevet. rows_label: Sorok unassigned_account: Új számlát kell létrehoznod a nem hozzárendelt sorokhoz? + next: Tovább show: + invalid_data: "Érvénytelen adatok találhatók, kérjük szerkeszd, amíg minden hibát ki nem javítasz" account_mapping_description: Rendeld hozzá az importált fájl számláit a Maybe meglévő számláihoz. Új számlákat is hozzáadhatsz, vagy hagyhatod őket kategorizálatlanul. account_mapping_title: Számlák hozzárendelése account_type_mapping_description: Rendeld hozzá az importált fájl számlatípusait a Maybe típusaihoz. @@ -77,7 +143,20 @@ hu: tag_mapping_description: Rendeld hozzá az importált fájl címkéit a Maybe meglévő címkéihez. Új címkéket is hozzáadhatsz, vagy hagyhatod őket kategorizálatlanul. tag_mapping_title: Címkék hozzárendelése uploads: + update: + qif_uploaded: "QIF fájl sikeresen feltöltve." show: + csv_invalid: "Érvényes CSV szükséges fejlécekkel és legalább egy adatsorral" + drop_csv_title: Húzd ide a CSV fájlt a feltöltéshez + drop_csv_subtitle: A fájl automatikusan feltöltődik + upload_csv_tab: CSV feltöltése + copy_paste_tab: Másolás és beillesztés + account_optional_label: Számla (nem kötelező) + multi_account_import: Több számlás importálás + upload_csv_button: CSV feltöltése + paste_csv_placeholder: Illeszd be ide a CSV fájl tartalmát + download_sample_csv: Minta CSV letöltése + to_see_format: a szükséges CSV formátum megtekintéséhez qif_title: QIF fájl feltöltése qif_description: Válaszd ki azt a számlát, amelyhez ez a QIF fájl tartozik, majd töltsd fel a Quickenből exportált .qif fájlodat. qif_account_label: Számla @@ -105,6 +184,58 @@ hu: hint_html: Töltsd fel az all.ndjson fájlt az adatexport ZIP archívumból ndjson_invalid: Érvényes NDJSON szükséges, legalább egy rekorddal imports: + mapping_labels: + account_type: "Számlatípus" + account: "Számla" + category: "Kategória" + tag: "Címke" + column_labels: + date: "Dátum" + amount: "Összeg" + name: "Név" + currency: "Pénznem" + category: "Kategória" + tags: "Címkék" + account: "Számla" + notes: "Megjegyzések" + qty: "Mennyiség" + ticker: "Tőzsdei szimbólum" + exchange: "Tőzsde" + price: "Ár" + entity_type: "Típus" + category_parent: "Szülőkategória" + category_color: "Szín" + category_icon: "Lucide ikon" + update: + account_saved: "Számla mentve." + invalid_account: "Számla nem található." + publish: + started: "Az importálás a háttérben elindult." + max_rows_exceeded: "Az importálás meghaladja a maximális %{max} soros korlátot." + revert: + started: "Az importálás visszavonása a háttérben folyamatban van." + apply_template: + template_applied: "Sablon alkalmazva." + no_template_found: "Nem található sablon, kérjük konfiguráld manuálisan az importálást." + destroy: + deleted: "Az importálás törölve." + failure: + title: Az importálás sikertelen + description: Kérjük, ellenőrizd a fájlformátumot, az esetleges hibákat és hogy minden kötelező mező ki van töltve, majd próbáld újra. + try_again: Újrapróbálkozás + success: + title: Importálás sikeres + description: Az importált adatok sikeresen hozzáadásra kerültek az alkalmazáshoz, és most már használhatók. + back_to_dashboard: Vissza az irányítópultra + importing: + title: Importálás folyamatban + description: "Az importálás folyamatban van. Az állapotfrissítéseket az importálások menüben ellenőrizheted, vagy kattints az 'Állapot ellenőrzése' gombra az oldal frissítéséhez. Nyugodtan folytasd az alkalmazás használatát." + check_status: Állapot ellenőrzése + back_to_dashboard: Vissza az irányítópultra + revert_failure: + title: Az importálás visszavonása sikertelen + description: Kérjük, próbáld újra + try_again: Újrapróbálkozás date_format: heading: Dátumformátum description: "A dátumformátum automatikusan lett felismerve a fájlból. Módosítsd, ha a dátumok helytelenül jelennek meg." @@ -129,6 +260,9 @@ hu: map: Leképezés confirm: Megerősítés select: Kiválasztás + progress: "%{step}. lépés / %{total}" + empty: + message: Nem található importálás. index: title: Importálások new: Új importálás @@ -239,3 +373,21 @@ hu: unknown_state_description: Ez az importálás váratlan állapotban van. Kérjük, térj vissza az importálásokhoz. processing_failed_with_message: "%{message}" processing_failed_generic: "Feldolgozási hiba: %{error}" + ready_for_review_title: Felülvizsgálatra kész + ready_for_review_description: "%{count} tranzakciót vontunk ki a kimutatásodból. Ellenőrizd és tedd közzé, hogy hozzáadódjon a számládhoz." + transactions_extracted: Kinyert tranzakciók + transactions_extracted_count: + one: "%{count} tranzakció" + other: "%{count} tranzakció" + select_account: Importálás számlára + select_account_placeholder: Válassz számlát... + select_account_hint: Válaszd ki, melyik számlára szeretnéd importálni ezeket a tranzakciókat. + no_accounts: Nincs elérhető számla. Kérjük, először hozz létre egyet. + create_account: Számla létrehozása + save_account: Mentés + publish_transactions: + one: "%{count} tranzakció közzététele" + other: "%{count} tranzakció közzététele" + review_transactions: Tranzakciók áttekintése + select_account_to_continue: A folytatáshoz kérjük, válassz fentebb számlát. + unknown_document_type: Ismeretlen diff --git a/config/locales/views/indexa_capital_items/ca.yml b/config/locales/views/indexa_capital_items/ca.yml new file mode 100644 index 000000000..e8daf63ac --- /dev/null +++ b/config/locales/views/indexa_capital_items/ca.yml @@ -0,0 +1,249 @@ +--- +ca: + indexa_capital_items: + complete_account_setup: + all_skipped: S'han omès tots els comptes. No s'ha creat cap compte. + creation_failed: 'No s''han pogut crear els comptes: %{error}' + no_accounts: No hi ha comptes per configurar. + success: S'han creat correctament %{count} compte(s). + create: + success: La connexió Indexa Capital s'ha creat correctament + destroy: + success: La connexió Indexa Capital s'ha eliminat + errors: + provider_not_configured: El proveïdor Indexa Capital no està configurat + index: + title: Connexions Indexa Capital + indexa_capital_item: + accounts_need_setup: Els comptes necessiten configuració + delete: Elimina la connexió + deletion_in_progress: eliminació en curs... + error: Error + more_accounts_available: + one: "%{count} compte més disponible" + other: "%{count} comptes més disponibles" + no_accounts_description: Aquesta connexió encara no té comptes enllaçats. + no_accounts_title: No hi ha comptes + provider_name: Indexa Capital + requires_update: La connexió necessita actualització + setup_action: Configura els nous comptes + setup_description: "%{linked} de %{total} comptes enllaçats. Tria els tipus + de compte per als teus nous comptes Indexa Capital importats." + setup_needed: Nous comptes a punt per configurar + status: Sincronitzat fa %{timestamp} — %{summary} + status_never: Mai sincronitzat + syncing: Sincronitzant... + total: Total + unlinked: Sense enllaç + update_credentials: Actualitza les credencials + institution_summary: + count: + one: "%{count} entitat" + other: "%{count} entitats" + none: No hi ha entitats connectades + link_accounts: + all_already_linked: + one: El compte seleccionat (%{names}) ja està enllaçat + other: 'Tots els %{count} comptes seleccionats ja estan enllaçats: %{names}' + api_error: 'Error de l''API: %{message}' + invalid_account_names: + one: No es pot enllaçar un compte sense nom + other: No es poden enllaçar %{count} comptes sense nom + link_failed: No s'han pogut enllaçar els comptes + no_accounts_selected: Selecciona almenys un compte + no_api_key: No s'han trobat les credencials d'Indexa Capital. Configura-les a + la configuració del proveïdor. + partial_invalid: S'han enllaçat correctament %{created_count} compte(s), %{already_linked_count} + ja estaven enllaçats, %{invalid_count} compte(s) tenien noms no vàlids + partial_success: 'S''han enllaçat correctament %{created_count} compte(s). %{already_linked_count} + compte(s) ja estaven enllaçats: %{already_linked_names}' + success: + one: S'ha enllaçat correctament %{count} compte + other: S'han enllaçat correctament %{count} comptes + link_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + api_error: 'Error de l''API: %{message}' + invalid_account_name: No es pot enllaçar un compte sense nom + missing_parameters: Falten paràmetres obligatoris + no_api_key: No s'han trobat les credencials d'Indexa Capital. Configura-les a + la configuració del proveïdor. + provider_account_already_linked: Aquest compte Indexa Capital ja està enllaçat + a un altre compte + provider_account_not_found: No s'ha trobat el compte Indexa Capital + success: S'ha enllaçat correctament %{account_name} amb Indexa Capital + loading: + loading_message: Carregant comptes d'Indexa Capital... + loading_title: Carregant + panel: + alternative_auth: O utilitza l'autenticació amb nom d'usuari/contrasenya... + field_descriptions: 'Descripció dels camps:' + fields: + api_token: + description: El teu token API només de lectura del panell d'Indexa Capital + label: Token API + placeholder_new: Enganxa el teu token API aquí + placeholder_update: Introdueix un nou token API per actualitzar + document: + description: El teu document/ID d'Indexa Capital + label: ID del document + placeholder_new: Enganxa l'ID del document aquí + placeholder_update: Introdueix un nou ID de document per actualitzar + password: + description: La teva contrasenya d'Indexa Capital + label: Contrasenya + placeholder_new: Enganxa la contrasenya aquí + placeholder_update: Introdueix una nova contrasenya per actualitzar + username: + description: El teu nom d'usuari/correu electrònic d'Indexa Capital + label: Nom d'usuari + placeholder_new: Enganxa el nom d'usuari aquí + placeholder_update: Introdueix un nou nom d'usuari per actualitzar + optional: "(opcional)" + optional_with_default: "(opcional, per defecte %{default_value})" + required: "(obligatori)" + save_button: Desa la configuració + setup_instructions: 'Instruccions de configuració:' + step_1: Visita el teu panell d'Indexa Capital per generar un token API només + de lectura + step_2: Enganxa el teu token API a continuació i fes clic a Desa + step_3: Després d'una connexió correcta, ves a la pestanya Comptes per configurar + nous comptes + update_button: Actualitza la configuració + preload_accounts: + no_credentials_configured: Primer, configura les teves credencials d'Indexa Capital + a la configuració del proveïdor. + select_accounts: + accounts_selected: comptes seleccionats + api_error: 'Error de l''API: %{message}' + cancel: Cancel·la + configure_name_in_provider: No es pot importar — configura el nom del compte + a Indexa Capital + description: Selecciona els comptes que vols enllaçar al teu compte de %{product_name}. + link_accounts: Enllaça els comptes seleccionats + no_accounts_found: No s'han trobat comptes. Comprova les teves credencials d'Indexa Capital. + no_api_key: Les credencials d'Indexa Capital no estan configurades. Configura-les + a la configuració. + no_credentials_configured: Primer, configura les teves credencials d'Indexa Capital + a la configuració del proveïdor. + no_name_placeholder: "(Sense nom)" + title: Selecciona comptes Indexa Capital + select_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + all_accounts_already_linked: Tots els comptes Indexa Capital ja estan enllaçats + api_error: 'Error de l''API: %{message}' + balance_label: 'Saldo:' + cancel: Cancel·la + cancel_button: Cancel·la + configure_name_in_provider: No es pot importar — configura el nom del compte + a Indexa Capital + connect_hint: Connecta un compte Indexa Capital per habilitar la sincronització + automàtica. + description: Selecciona un compte Indexa Capital per enllaçar-lo amb aquest compte. + Les transaccions es sincronitzaran i deduplicaran automàticament. + header: Enllaça amb Indexa Capital + link_account: Enllaça compte + link_button: Enllaça aquest compte + linking_to: 'Enllaçant a:' + no_account_specified: No s'ha especificat cap compte + no_accounts: No s'han trobat comptes Indexa Capital sense enllaçar. + no_accounts_found: No s'han trobat comptes Indexa Capital. Comprova les teves + credencials. + no_api_key: Les credencials d'Indexa Capital no estan configurades. Configura-les + a la configuració. + no_credentials_configured: Primer, configura les teves credencials d'Indexa Capital + a la configuració del proveïdor. + no_name_placeholder: "(Sense nom)" + settings_link: Ves a la configuració del proveïdor + subtitle: Tria un compte Indexa Capital + title: Enllaça %{account_name} amb Indexa Capital + setup_accounts: + account_type_label: 'Tipus de compte:' + account_types: + credit_card: Targeta de crèdit + crypto: Compte de criptomonedes + depository: Compte corrent o d'estalvis + investment: Compte d'inversió + loan: Préstec o hipoteca + other_asset: Altre actiu + skip: Omet aquest compte + accounts_count: + one: "%{count} compte disponible" + other: "%{count} comptes disponibles" + all_accounts_linked: Tots els teus comptes Indexa Capital ja s'han configurat. + api_error: 'Error de l''API: %{message}' + balance: Saldo + cancel: Cancel·la + choose_account_type: 'Tria el tipus de compte correcte per a cada compte Indexa Capital:' + create_accounts: Crea comptes + creating: Creant comptes... + creating_accounts: Creant comptes... + fetch_failed: No s'han pogut obtenir els comptes + historical_data_range: 'Rang de dades històriques:' + import_selected: Importa els comptes seleccionats + instructions: Selecciona els comptes que vols importar des d'Indexa Capital. + Pots triar diversos comptes. + no_accounts: No s'han trobat comptes sense enllaçar d'aquesta connexió Indexa Capital. + no_accounts_to_setup: No hi ha comptes per configurar + no_api_key: Les credencials d'Indexa Capital no estan configurades. Revisa la + configuració de la connexió. + select_all: Selecciona-ho tot + subtitle: Tria els tipus de compte correctes per als teus comptes importats + subtype_labels: + credit_card: '' + crypto: '' + depository: 'Subtipus de compte:' + investment: 'Tipus d''inversió:' + loan: 'Tipus de préstec:' + other_asset: '' + subtype_messages: + credit_card: Les targetes de crèdit es configuraran automàticament com a comptes + de targeta de crèdit. + crypto: Els comptes de criptomonedes es configuraran per fer el seguiment + de posicions i transaccions. + other_asset: No calen opcions addicionals per a altres actius. + subtypes: + depository: + cd: Certificat de dipòsit + checking: Compte corrent + hsa: Compte d'estalvi per a salut + money_market: Mercat monetari + savings: Estalvis + investment: + 401k: 401(k) + 403b: 403(b) + 529_plan: Pla 529 + angel: Inversió àngel + brokerage: Corredoria + hsa: Compte d'estalvi per a salut + ira: IRA tradicional + mutual_fund: Fons d'inversió + pension: Pensió + retirement: Jubilació + roth_401k: Roth 401(k) + roth_ira: IRA Roth + tsp: Pla d'estalvis de jubilació (TSP) + loan: + auto: Préstec d'automòbil + mortgage: Hipoteca + other: Altre préstec + student: Préstec d'estudis + sync_start_date_help: Selecciona fins on vols sincronitzar l'historial de transaccions. + sync_start_date_label: 'Comença a sincronitzar transaccions des de:' + title: Configura els teus comptes Indexa Capital + sync: + status: + calculating: Calculant saldos... + checking_setup: Comprovant la configuració dels comptes... + importing: Important comptes des d'Indexa Capital... + importing_data: Important dades del compte... + needs_setup: "%{count} comptes necessiten configuració..." + processing: Processant posicions i activitats... + success: Sincronització iniciada + sync_status: + no_accounts: No s'han trobat comptes + synced: + one: "%{count} compte sincronitzat" + other: "%{count} comptes sincronitzats" + synced_with_setup: "%{linked} sincronitzats, %{unlinked} necessiten configuració" + update: + success: La connexió Indexa Capital s'ha actualitzat diff --git a/config/locales/views/indexa_capital_items/hu.yml b/config/locales/views/indexa_capital_items/hu.yml index be7bf5ff5..defbd74fe 100644 --- a/config/locales/views/indexa_capital_items/hu.yml +++ b/config/locales/views/indexa_capital_items/hu.yml @@ -180,7 +180,7 @@ hu: investment: "Befektetési számla" crypto: "Kriptovaluta számla" loan: "Hitel vagy jelzálog" - other_asset: "Egyéb eszköz" + other_asset: "Egyéb vagyon" subtype_labels: depository: "Számla altípusa:" credit_card: "" @@ -190,7 +190,7 @@ hu: other_asset: "" subtype_messages: credit_card: "A hitelkártyák automatikusan hitelkártya számlákként lesznek beállítva." - other_asset: "Az egyéb eszközökhöz nincs szükség további beállításokra." + other_asset: "Az egyéb vagyonelemekhez nincs szükség további beállításokra." crypto: "A kriptovaluta számlák pozíciók és tranzakciók nyomon követésére lesznek beállítva." subtypes: depository: diff --git a/config/locales/views/investments/ca.yml b/config/locales/views/investments/ca.yml index a7a0cd9b9..3325ed665 100644 --- a/config/locales/views/investments/ca.yml +++ b/config/locales/views/investments/ca.yml @@ -10,9 +10,181 @@ ca: title: Introdueix el saldo del compte show: chart_title: Valor total + subtypes: + 401k: + long: 401(k) + short: 401(k) + 403b: + long: 403(b) + short: 403(b) + 457b: + long: 457(b) + short: 457(b) + 529_plan: + long: Pla 529 d'estalvi per a l'educació + short: Pla 529 + angel: + long: Inversió àngel + short: Àngel + apy: + long: Atal Pension Yojana + short: APY + brokerage: + long: Compte de broker + short: Broker + corporate_bond: + long: Bo corporatiu + short: Bo corporatiu + fd: + long: Dipòsit a termini fix + short: FD + g_sec: + long: Valors governamentals (G-Secs) + short: G-Sec + gold: + long: Or (físic o digital) + short: Or + gold_etf: + long: ETF d'or + short: ETF d'or + gold_mf: + long: Fons mutu d'or + short: MF d'or + hsa: + long: Compte d'estalvi sanitari + short: HSA + indian_equity: + long: Renda variable índia + short: Renda variable índia + indian_etf: + long: ETF indi + short: ETF indi + indian_stocks: + long: Accions índies (Demat) + short: Accions índies + infrastructure_bond: + long: Bo d'infraestructures + short: Bo d'infraestr. + ira: + long: IRA tradicional + short: IRA + isa: + long: Compte d'estalvi individual + short: ISA + kvp: + long: Kisan Vikas Patra + short: KVP + life_insurance: + long: Assegurança de vida + short: Assegurança de vida + lira: + long: Compte de jubilació bloquejat + short: LIRA + lisa: + long: ISA vitalícia + short: LISA + mutual_fund: + long: Fons d'inversió + short: Fons d'inversió + nps: + long: Sistema nacional de pensions + short: NPS + nsc: + long: Certificat nacional d'estalvi + short: NSC + other: + long: Altra inversió + short: Altres + pea: + long: Plan d'Épargne en Actions + short: PEA + pension: + long: Pensió + short: Pensió + pillar_3a: + long: Pensió privada (Pilar 3a) + short: Pilar 3a + pomis: + long: Pla mensual de l'oficina de correus + short: POMIS + ppf: + long: Fons provident públic + short: PPF + rd: + long: Dipòsit recurrent + short: RD + resp: + long: Pla registrat d'estalvi per a l'educació + short: RESP + retirement: + long: Compte de jubilació + short: Jubilació + riester: + long: Riester-Rente + short: Riester + roth_401k: + long: Roth 401(k) + short: Roth 401(k) + roth_ira: + long: Roth IRA + short: Roth IRA + rrif: + long: Fons registrat d'ingressos de jubilació + short: RRIF + rrsp: + long: Pla registrat d'estalvi per a la jubilació + short: RRSP + scss: + long: Pla d'estalvi per a gent gran + short: SCSS + sdl: + long: Préstecs de desenvolupament estatal (SDL) + short: SDL + sep_ira: + long: SEP IRA + short: SEP IRA + sgb: + long: Bo sobirà d'or + short: SGB + simple_ira: + long: SIMPLE IRA + short: SIMPLE IRA + sipp: + long: Pensió personal autoinvertida + short: SIPP + smsf: + long: Fons de superannuació autogestionat + short: SMSF + ssy: + long: Sukanya Samriddhi Yojana + short: SSY + super: + long: Superannuació + short: Super + tax_free_bond: + long: Bo exempt d'impostos + short: Bo exempt + tfsa: + long: Compte d'estalvi lliure d'impostos + short: TFSA + trust: + long: Fideïcomís + short: Fideïcomís + tsp: + long: Thrift Savings Plan + short: TSP + ugma: + long: Compte custodi UGMA + short: UGMA + utma: + long: Compte custodi UTMA + short: UTMA + workplace_pension_uk: + long: Pensió laboral + short: Pensió value_tooltip: cash: Efectiu holdings: Posicions - total: Saldo del portafolis - total_value_tooltip: El saldo total del portafolis és la suma de l'efectiu de + total: Saldo de la cartera + total_value_tooltip: El saldo total de la cartera és la suma de l'efectiu del broker (disponible per operar) i el valor de mercat actual de les teves posicions. diff --git a/config/locales/views/investments/hu.yml b/config/locales/views/investments/hu.yml index 90b4c0e63..7bca28675 100644 --- a/config/locales/views/investments/hu.yml +++ b/config/locales/views/investments/hu.yml @@ -107,6 +107,75 @@ hu: angel: short: Angyal long: Angyal-befektetés + nps: + short: NPS + long: Nemzeti Nyugdíjrendszer + apy: + short: APY + long: Atal Pension Yojana + indian_stocks: + short: Indiai részvények + long: Indiai részvények (Demat) + indian_equity: + short: Indiai tőke + long: Indiai tőke + indian_etf: + short: Indiai ETF + long: Indiai ETF + life_insurance: + short: Életbiztosítás + long: Életbiztosítás + ppf: + short: PPF + long: Közszféra megtakarítási alap + ssy: + short: SSY + long: Sukanya Samriddhi Yojana + nsc: + short: NSC + long: Nemzeti megtakarítási igazolás + scss: + short: SCSS + long: Idősek megtakarítási rendszere + fd: + short: FD + long: Lekötött betét + rd: + short: RD + long: Ismétlődő betét + pomis: + short: POMIS + long: Postai havi jövedelmi program + kvp: + short: KVP + long: Kisan Vikas Patra + gold_etf: + short: Arany ETF + long: Arany ETF + gold_mf: + short: Arany befektetési alap + long: Arany befektetési alap + sgb: + short: SGB + long: Szuverén aranykötvény + g_sec: + short: G-Sec + long: Állampapírok + sdl: + short: SDL + long: Állami fejlesztési kötvények + corporate_bond: + short: Vállalati kötvény + long: Vállalati kötvény + infrastructure_bond: + short: Infrastrukturális kötvény + long: Infrastrukturális kötvény + tax_free_bond: + short: Adómentes kötvény + long: Adómentes kötvény + gold: + short: Arany + long: Arany (fizikai vagy digitális) trust: short: Bizalmi alap long: Bizalmi alap diff --git a/config/locales/views/invitation_mailer/ca.yml b/config/locales/views/invitation_mailer/ca.yml index da59026b1..31f2f8295 100644 --- a/config/locales/views/invitation_mailer/ca.yml +++ b/config/locales/views/invitation_mailer/ca.yml @@ -3,6 +3,6 @@ ca: invitation_mailer: invite_email: accept_button: Accepta la invitació - body: "%{inviter} t'ha convidat a unir-te a la família %{family} a %{product_name}!" + body: "%{inviter} t'ha convidat a unir-te a %{family} (%{moniker}) a %{product_name}!" expiry_notice: Aquesta invitació caducarà en %{days} dies greeting: Benvingut/da a %{product_name}! diff --git a/config/locales/views/invitations/ca.yml b/config/locales/views/invitations/ca.yml index e065d17d4..5c11e701b 100644 --- a/config/locales/views/invitations/ca.yml +++ b/config/locales/views/invitations/ca.yml @@ -1,7 +1,14 @@ --- ca: invitations: + accept_choice: + create_account: Crea un compte nou + joined_household: T'has unit a la llar. + message: "%{inviter} t'ha convidat a unir-te com a %{role}." + sign_in_existing: Ja tinc un compte + title: Uneix-te a %{family} create: + existing_user_added: S'ha afegit l'usuari a la teva llar. failure: No s'ha pogut enviar la invitació success: Invitació enviada correctament destroy: @@ -12,8 +19,9 @@ ca: email_label: Correu electrònic email_placeholder: Introdueix el correu electrònic role_admin: Administrador/a + role_guest: Convidat/da role_label: Rol role_member: Membre - submit: Envia invitació - subtitle: Envia una invitació per unir-te al teu compte familiar a %{product_name} + submit: Envia la invitació + subtitle: Envia una invitació perquè s'uneixi al teu compte de %{product_name} title: Convida algú diff --git a/config/locales/views/invite_codes/ca.yml b/config/locales/views/invite_codes/ca.yml index e9485d61d..26633cd4f 100644 --- a/config/locales/views/invite_codes/ca.yml +++ b/config/locales/views/invite_codes/ca.yml @@ -1,6 +1,10 @@ --- ca: invite_codes: + create: + success: Codi generat + destroy: + success: Codi eliminat index: invite_code_description: Genera un nou codi per veure'l aquí. Els codis generats que s'hagin utilitzat ja no es mostraran. diff --git a/config/locales/views/invite_codes/hu.yml b/config/locales/views/invite_codes/hu.yml index 6f276d2a9..3474d5bd9 100644 --- a/config/locales/views/invite_codes/hu.yml +++ b/config/locales/views/invite_codes/hu.yml @@ -1,6 +1,10 @@ --- hu: invite_codes: + create: + success: "Kód létrehozva" + destroy: + success: "Kód törölve" index: invite_code_description: Generálj új kódot, hogy az megjelenjen itt. A már felhasznált generált kódok nem jelennek meg tovább. no_invite_codes: Nincs megjeleníthető kód diff --git a/config/locales/views/kraken_items/ca.yml b/config/locales/views/kraken_items/ca.yml new file mode 100644 index 000000000..1bbe2c645 --- /dev/null +++ b/config/locales/views/kraken_items/ca.yml @@ -0,0 +1,95 @@ +--- +ca: + kraken_item: + syncer: + accounts_need_setup: + one: "%{count} compte necessita configuració" + other: "%{count} comptes necessiten configuració" + calculating_balances: Calculant saldos... + checking_configuration: Comprovant la configuració del compte... + checking_credentials: Comprovant credencials... + credentials_invalid: Credencials de l'API de Kraken no vàlides. Revisa la teva + clau API i el secret. + importing_accounts: Important comptes des de Kraken... + processing_accounts: Processant dades del compte... + kraken_items: + complete_account_setup: + no_accounts: No hi ha comptes per importar + none_selected: No s'ha seleccionat cap compte + success: + one: S'ha importat %{count} compte + other: S'han importat %{count} comptes + create: + default_name: Kraken + success: S'ha connectat correctament a Kraken. El teu compte de l'exchange s'està + sincronitzant. + destroy: + success: S'ha programat la connexió Kraken per a la seva eliminació. + kraken_item: + delete: Elimina + deletion_in_progress: Eliminant... + import_accounts_menu: Importa compte + no_accounts_message: El teu compte de l'exchange Kraken apareixerà aquí després + de sincronitzar. + no_accounts_title: No s'han trobat comptes + provider_name: Kraken + reconnect: Les credencials necessiten actualització + setup_action: Importa compte + setup_description: Importa aquesta connexió Kraken com a compte d'exchange de + cripto. + setup_needed: Compte a punt per importar + stale_rate_warning: El saldo és aproximat perquè el tipus de canvi exacte per + a %{date} no estava disponible. S'actualitzarà a la propera sincronització. + status: Darrera sincronització fa %{timestamp} + status_never: Mai sincronitzat + status_with_summary: Darrera sincronització fa %{timestamp} - %{summary} + sync_status: + all_synced: + one: "%{count} compte sincronitzat" + other: "%{count} comptes sincronitzats" + no_accounts: No s'han trobat comptes + partial_sync: "%{linked_count} sincronitzats, %{unlinked_count} necessiten + configuració" + syncing: Sincronitzant... + link_accounts: + select_connection: Tria una connexió Kraken abans d'enllaçar comptes. + link_existing_account: + errors: + invalid_kraken_account: Compte Kraken no vàlid + kraken_account_already_linked: Aquest compte Kraken ja està enllaçat + only_manual: Només els comptes manuals d'exchange de cripto sense un enllaç + de proveïdor existent es poden enllaçar a Kraken + select_connection: Tria una connexió Kraken abans d'enllaçar comptes. + success: S'ha enllaçat correctament al compte Kraken + provider_connection: + default_description: Enllaça amb un compte de l'exchange Kraken + default_name: Kraken + description: Enllaça amb %{name} + name: Kraken - %{name} + select_accounts: + no_credentials_configured: Afegeix les credencials de l'API de Kraken abans + de configurar els comptes. + select_connection: Tria una connexió Kraken a la configuració del proveïdor. + select_existing_account: + cancel: Cancel·la + check_provider_health: Comprova que les teves credencials de l'API de Kraken + siguin vàlides. + link: Enllaça + no_accounts_found: No s'han trobat comptes Kraken. + title: Enllaça compte Kraken + wait_for_sync: Espera que Kraken acabi la sincronització. + setup_accounts: + accounts_count: + one: "%{count} compte disponible" + other: "%{count} comptes disponibles" + cancel: Cancel·la + creating: Important... + import_selected: Importa els seleccionats + instructions: Kraken importa un compte d'exchange de cripto combinat per a aquesta + connexió, només amb posicions i execucions d'operacions al comptat. + no_accounts: Tots els comptes Kraken s'han importat. + select_all: Selecciona-ho tot + subtitle: Selecciona el compte de l'exchange per fer-ne el seguiment + title: Importa compte Kraken + update: + success: La connexió Kraken s'ha actualitzat correctament. diff --git a/config/locales/views/kraken_items/hu.yml b/config/locales/views/kraken_items/hu.yml new file mode 100644 index 000000000..be4ef5d0f --- /dev/null +++ b/config/locales/views/kraken_items/hu.yml @@ -0,0 +1,85 @@ +--- +hu: + kraken_items: + provider_connection: + default_name: Kraken + default_description: Kapcsolódás Kraken tőzsdei számlához + name: "Kraken - %{name}" + description: "Kapcsolódás ehhez: %{name}" + create: + default_name: Kraken + success: Sikeresen csatlakoztatva a Krakenhez. A tőzsdei számlád szinkronizálása folyamatban van. + update: + success: Kraken kapcsolat sikeresen frissítve. + destroy: + success: Kraken kapcsolat törlése ütemezve. + select_accounts: + select_connection: Válassz Kraken kapcsolatot a Szolgáltatói beállításokban. + no_credentials_configured: Add meg a Kraken API hitelesítő adatokat a számlák beállítása előtt. + link_accounts: + select_connection: Válassz Kraken kapcsolatot a számlák összekapcsolása előtt. + select_existing_account: + title: Kraken számla összekapcsolása + no_accounts_found: Nem találhatók Kraken számlák. + wait_for_sync: Várd meg, amíg a Kraken befejezi a szinkronizálást. + check_provider_health: Ellenőrizd, hogy a Kraken API hitelesítő adataid érvényesek-e. + link: Összekapcsolás + cancel: Mégse + link_existing_account: + success: Sikeresen összekapcsolva Kraken számlával + select_connection: Válassz Kraken kapcsolatot a számlák összekapcsolása előtt. + errors: + only_manual: Csak olyan manuális kriptopiaci számlák kapcsolhatók a Krakenhez, amelyekhez még nincs meglévő szolgáltatói kapcsolat + invalid_kraken_account: Érvénytelen Kraken számla + kraken_account_already_linked: Ez a Kraken számla már össze van kapcsolva + setup_accounts: + title: Kraken számla importálása + subtitle: Válaszd ki a nyomon követendő tőzsdei számlát + instructions: A Kraken egy kombinált kriptotőzsdei számlát importál ehhez a kapcsolathoz, csak portfólióelemekkel és azonnali ügyletteljesítésekkel. + no_accounts: Minden Kraken számla importálva lett. + accounts_count: + one: "%{count} elérhető számla" + other: "%{count} elérhető számla" + select_all: Összes kijelölése + import_selected: Kijelöltek importálása + cancel: Mégse + creating: Importálás... + complete_account_setup: + success: + one: "%{count} számla importálva" + other: "%{count} számla importálva" + none_selected: Nincs kijelölt számla + no_accounts: Nincs importálható számla + kraken_item: + provider_name: Kraken + syncing: Szinkronizálás... + reconnect: A hitelesítő adatok frissítést igényelnek + deletion_in_progress: Törlés folyamatban... + sync_status: + no_accounts: Nem találhatók számlák + all_synced: + one: "%{count} számla szinkronizálva" + other: "%{count} számla szinkronizálva" + partial_sync: "%{linked_count} szinkronizálva, %{unlinked_count} beállítást igényel" + status: "Utolsó szinkronizálás %{timestamp} ezelőtt" + status_with_summary: "Utolsó szinkronizálás %{timestamp} ezelőtt - %{summary}" + status_never: Még nem szinkronizált + delete: Törlés + no_accounts_title: Nem találhatók számlák + no_accounts_message: A Kraken tőzsdei számlád szinkronizálás után jelenik meg itt. + setup_needed: Számla importálásra kész + setup_description: Importáld ezt a Kraken kapcsolatot kriptotőzsdei számlaként. + setup_action: Számla importálása + import_accounts_menu: Számla importálása + stale_rate_warning: "Az egyenleg közelítő értékű, mert a(z) %{date} pontos árfolyama nem volt elérhető. A következő szinkronizáláskor frissül." + kraken_item: + syncer: + checking_credentials: Hitelesítő adatok ellenőrzése... + credentials_invalid: Érvénytelen Kraken API hitelesítő adatok. Kérlek ellenőrizd az API-kulcsodat és a titkos kulcsodat. + importing_accounts: Számlák importálása a Krakenből... + checking_configuration: Számlakonfiguráció ellenőrzése... + accounts_need_setup: + one: "%{count} számla beállítást igényel" + other: "%{count} számla beállítást igényel" + processing_accounts: Számlaadat-feldolgozás... + calculating_balances: Egyenlegek kiszámítása... diff --git a/config/locales/views/layout/ca.yml b/config/locales/views/layout/ca.yml index d2981ad51..f7bf5a2b4 100644 --- a/config/locales/views/layout/ca.yml +++ b/config/locales/views/layout/ca.yml @@ -2,24 +2,28 @@ ca: layouts: application: - privacy_mode: Alternar mode de privadesa - skip_to_main: Saltar al contingut principal nav: assistant: Assistent budgets: Pressupostos home: Inici reports: Informes transactions: Transaccions + privacy_mode: Commuta el mode de privadesa + skip_to_main: Salta al contingut principal auth: existing_account: Ja tens un compte? - no_account: Nou a %{product_name}? + no_account: Ets nou a %{product_name}? sign_in: Inicia sessió sign_up: Crea un compte shared: + confirm_dialog: + are_you_sure: Segur que vols continuar? + cannot_be_undone: Aquesta acció no es pot desfer. + confirm: Confirma footer: - privacy_policy: Política de privacitat - terms_of_service: Termes del servei + privacy_policy: Política de privadesa + terms_of_service: Condicions del servei trial: - open_demo: Demo oberta + contribute: Contribueix data_deleted_in_days: Les dades s'eliminaran en %{days} dies - contribute: Contribuir \ No newline at end of file + open_demo: Demostració oberta diff --git a/config/locales/views/layout/hu.yml b/config/locales/views/layout/hu.yml index 7a0d252b4..299aaac90 100644 --- a/config/locales/views/layout/hu.yml +++ b/config/locales/views/layout/hu.yml @@ -19,6 +19,10 @@ hu: footer: privacy_policy: Adatvédelmi irányelvek terms_of_service: Felhasználási feltételek + confirm_dialog: + are_you_sure: Biztosan? + cannot_be_undone: Ez a művelet nem vonható vissza. + confirm: Megerősítés trial: open_demo: Demo megnyitása data_deleted_in_days: Az adatok törlődnek %{days} nap múlva diff --git a/config/locales/views/loans/ca.yml b/config/locales/views/loans/ca.yml index 74a8f1a52..c22103a32 100644 --- a/config/locales/views/loans/ca.yml +++ b/config/locales/views/loans/ca.yml @@ -7,7 +7,10 @@ ca: initial_balance: Saldo inicial del préstec interest_rate: Tipus d'interès interest_rate_placeholder: '5.25' - rate_type: Tipus d'interès + none: Cap + rate_type: Modalitat del tipus + subtype_none: Cap + subtype_prompt: Selecciona el tipus de préstec term_months: Termini (mesos) term_months_placeholder: '360' new: @@ -23,6 +26,7 @@ ca: unknown: Desconegut tabs: overview: + edit_loan_details: Edita els detalls del préstec interest_rate: Tipus d'interès monthly_payment: Quota mensual not_applicable: No aplicable diff --git a/config/locales/views/loans/hu.yml b/config/locales/views/loans/hu.yml index 79cf3f8e2..3a2141329 100644 --- a/config/locales/views/loans/hu.yml +++ b/config/locales/views/loans/hu.yml @@ -10,6 +10,7 @@ hu: rate_type: Kamat típusa term_months: Futamidő (hónap) term_months_placeholder: '360' + none: Nincs subtype_prompt: Válassz hiteltípust subtype_none: Nincs new: @@ -23,3 +24,14 @@ hu: term: Futamidő type: Típus unknown: Ismeretlen + tabs: + overview: + interest_rate: Kamatláb + monthly_payment: Havi törlesztőrészlet + not_applicable: N/A + original_principal: Eredeti tőkeösszeg + remaining_principal: Fennmaradó tőkeösszeg + term: Futamidő + type: Típus + unknown: Ismeretlen + edit_loan_details: "Hitel adatainak szerkesztése" diff --git a/config/locales/views/lunchflow_items/ca.yml b/config/locales/views/lunchflow_items/ca.yml index 525e285ee..0df27fcba 100644 --- a/config/locales/views/lunchflow_items/ca.yml +++ b/config/locales/views/lunchflow_items/ca.yml @@ -1,9 +1,22 @@ --- ca: lunchflow_items: + api_error: + check_provider_settings: Revisa la configuració del proveïdor + common_issues: 'Problemes habituals:' + expired_credentials_desc: Genera una nova clau API des de Lunch Flow + expired_credentials_label: Credencials caducades + invalid_api_key_desc: Revisa la teva clau API a la configuració del proveïdor + invalid_api_key_label: Clau API no vàlida + network_issue_desc: Comprova la teva connexió a internet + network_issue_label: Problema de xarxa + service_down_desc: L'API de Lunch Flow pot estar temporalment no disponible + service_down_label: Servei caigut + title: Error de connexió Lunch Flow + unable_to_connect: No s'ha pogut connectar a Lunch Flow complete_account_setup: all_skipped: S'han omès tots els comptes. No s'ha creat cap compte. - creation_failed: "No s'han pogut crear els comptes: %{error}" + creation_failed: 'No s''han pogut crear els comptes: %{error}' no_accounts: No hi ha comptes per configurar. success: S'han creat correctament %{count} compte(s). create: @@ -15,80 +28,88 @@ ca: link_accounts: all_already_linked: one: El compte seleccionat (%{names}) ja està enllaçat - other: "Tots els %{count} comptes seleccionats ja estan enllaçats: %{names}" - api_error: "Error d'API: %{message}" + other: 'Tots els %{count} comptes seleccionats ja estan enllaçats: %{names}' + api_error: 'Error de l''API: %{message}' invalid_account_names: one: No es pot enllaçar un compte sense nom other: No es poden enllaçar %{count} comptes sense nom link_failed: No s'han pogut enllaçar els comptes - no_accounts_selected: Si us plau, selecciona almenys un compte - no_api_key: No hi ha clau API + no_accounts_selected: Selecciona almenys un compte + no_api_key: La clau API de Lunch Flow no està configurada. Configura-la a la + configuració. + no_credentials_configured: Configura primer la teva clau API de Lunch Flow a + la configuració del proveïdor. partial_invalid: S'han enllaçat correctament %{created_count} compte(s), %{already_linked_count} ja estaven enllaçats, %{invalid_count} compte(s) tenien noms no vàlids - partial_success: "S'han enllaçat correctament %{created_count} compte(s). %{already_linked_count} - compte(s) ja estaven enllaçats: %{already_linked_names}" + partial_success: 'S''han enllaçat correctament %{created_count} compte(s). %{already_linked_count} + compte(s) ja estaven enllaçats: %{already_linked_names}' success: one: S'ha enllaçat correctament %{count} compte other: S'han enllaçat correctament %{count} comptes link_existing_account: account_already_linked: Aquest compte ja està enllaçat a un proveïdor - api_error: "Error d'API: %{message}" + api_error: 'Error de l''API: %{message}' invalid_account_name: No es pot enllaçar un compte sense nom lunchflow_account_already_linked: Aquest compte de Lunch Flow ja està enllaçat a un altre compte lunchflow_account_not_found: No s'ha trobat el compte de Lunch Flow - missing_parameters: Falten els paràmetres requerits - no_api_key: No hi ha clau API + missing_parameters: Falten paràmetres obligatoris + no_api_key: La clau API de Lunch Flow no està configurada. Configura-la a la + configuració. success: S'ha enllaçat correctament %{account_name} amb Lunch Flow loading: loading_message: Carregant comptes de Lunch Flow... loading_title: Carregant lunchflow_item: accounts_need_setup: Els comptes necessiten configuració - delete: Eliminar connexió - deletion_in_progress: s'està eliminant... + delete: Elimina la connexió + deletion_in_progress: eliminació en curs... error: Error no_accounts_description: Aquesta connexió encara no té comptes enllaçats. no_accounts_title: No hi ha comptes - setup_action: Configurar nous comptes - setup_description: "%{linked} de %{total} comptes enllaçats. Tria els tipus de comptes - per als teus comptes de Lunch Flow importats recentment." - setup_needed: Nous comptes preparats per a la configuració - status: Sincronitzat %{timestamp} fa + setup_action: Configura els nous comptes + setup_description: "%{linked} de %{total} comptes enllaçats. Tria els tipus + de compte per als teus nous comptes Lunch Flow importats." + setup_needed: Nous comptes a punt per configurar + status: Sincronitzat fa %{timestamp} status_never: Mai sincronitzat - status_with_summary: Sincronitzat per última vegada %{timestamp} fa • %{summary} + status_with_summary: Darrera sincronització fa %{timestamp} • %{summary} syncing: Sincronitzant... total: Total unlinked: Sense enllaç select_accounts: accounts_selected: comptes seleccionats - api_error: "Error d'API: %{message}" + api_error: 'Error de l''API: %{message}' cancel: Cancel·la - configure_name_in_lunchflow: No es pot importar - si us plau, configura el nom del compte a - Lunchflow - description: Selecciona els comptes que vols enllaçar amb el teu compte de %{product_name}. + configure_name_in_lunchflow: No es pot importar — configura el nom del compte + a Lunch Flow + description: Selecciona els comptes que vols enllaçar al teu compte de %{product_name}. link_accounts: Enllaça els comptes seleccionats - no_accounts_found: No s'han trobat comptes. Si us plau, comprova la configuració de la teva clau API. - no_api_key: La clau API de Lunch Flow no està configurada. Configura-la a Configuració. - no_credentials_configured: Primer, configura la teva clau API de Lunch Flow a - Configuració de proveïdors. + no_accounts_found: No s'han trobat comptes. Comprova la configuració de la teva + clau API. + no_api_key: La clau API de Lunch Flow no està configurada. Configura-la a la + configuració. + no_credentials_configured: Configura primer la teva clau API de Lunch Flow a + la configuració del proveïdor. no_name_placeholder: "(Sense nom)" title: Selecciona comptes de Lunch Flow select_existing_account: account_already_linked: Aquest compte ja està enllaçat a un proveïdor all_accounts_already_linked: Tots els comptes de Lunch Flow ja estan enllaçats - api_error: "Error d'API: %{message}" + api_error: 'Error de l''API: %{message}' cancel: Cancel·la - configure_name_in_lunchflow: No es pot importar - si us plau, configura el nom del compte a - Lunchflow - description: Selecciona un compte de Lunch Flow per enllaçar-lo amb aquest compte. Les transaccions - se sincronitzaran i deduplicaran automàticament. + configure_name_in_lunchflow: No es pot importar — configura el nom del compte + a Lunch Flow + description: Selecciona un compte de Lunch Flow per enllaçar-lo amb aquest compte. + Les transaccions es sincronitzaran i deduplicaran automàticament. link_account: Enllaça compte no_account_specified: No s'ha especificat cap compte - no_accounts_found: No s'han trobat comptes de Lunch Flow. Si us plau, comprova la configuració de la teva clau API. - no_api_key: La clau API de Lunch Flow no està configurada. Configura-la a Configuració. - no_credentials_configured: Primer, configura la teva clau API de Lunch Flow a - Configuració de proveïdors. + no_accounts_found: No s'han trobat comptes de Lunch Flow. Comprova la configuració + de la teva clau API. + no_api_key: La clau API de Lunch Flow no està configurada. Configura-la a la + configuració. + no_credentials_configured: Configura primer la teva clau API de Lunch Flow a + la configuració del proveïdor. no_name_placeholder: "(Sense nom)" title: Enllaça %{account_name} amb Lunch Flow setup_accounts: @@ -97,62 +118,75 @@ ca: credit_card: Targeta de crèdit depository: Compte corrent o d'estalvis investment: Compte d'inversió - loan: Prèstec o hipoteca - other_asset: Alt actiu + loan: Préstec o hipoteca + other_asset: Altre actiu skip: Omet aquest compte all_accounts_linked: Tots els teus comptes de Lunch Flow ja s'han configurat. - api_error: "Error d'API: %{message}" + api_error: 'Error de l''API: %{message}' balance: Saldo cancel: Cancel·la - choose_account_type: 'Tria el tipus de compte correcte per a cada compte de Lunch Flow:' - create_accounts: Crear comptes + choose_account_type: 'Tria el tipus de compte correcte per a cada compte de + Lunch Flow:' + create_accounts: Crea comptes creating_accounts: Creant comptes... fetch_failed: No s'han pogut obtenir els comptes historical_data_range: 'Rang de dades històriques:' no_accounts_to_setup: No hi ha comptes per configurar - no_api_key: La clau API de Lunch Flow no està configurada. Si us plau, comprova la configuració + no_api_key: La clau API de Lunch Flow no està configurada. Revisa la configuració de la connexió. - subtitle: Tria els tipus de comptes correctes per als teus comptes importats + subtitle: Tria els tipus de compte correctes per als teus comptes importats subtype_labels: - credit_card: Targeta de crèdit + credit_card: '' depository: 'Subtipus de compte:' - investment: "Tipus d'inversió:" - loan: "Tipus de préstec:" - other_asset: Alt actiu + investment: 'Tipus d''inversió:' + loan: 'Tipus de préstec:' + other_asset: '' subtype_messages: - credit_card: Les targetes de crèdit es configuraran automàticament com a comptes de targeta de crèdit. - other_asset: No calen opcions addicionals per als Altres Actius. + credit_card: Les targetes de crèdit es configuraran automàticament com a comptes + de targeta de crèdit. + other_asset: No calen opcions addicionals per a altres actius. subtypes: depository: - cd: Certificat de Dipòsit + cd: Certificat de dipòsit checking: Compte corrent - hsa: Compte d'estalvis de salut - money_market: Fons mercant - savings: Compte d'estalvis + hsa: Compte d'estalvi per a salut + money_market: Mercat monetari + savings: Estalvis investment: 401k: 401(k) 403b: 403(b) 529_plan: Pla 529 - angel: Àngel + angel: Inversió àngel brokerage: Corredoria - hsa: Compte d'estalvis de salut + hsa: Compte d'estalvi per a salut ira: IRA tradicional - mutual_fund: Fons comú d'inversió - pension: Jubilació + mutual_fund: Fons d'inversió + pension: Pensió retirement: Jubilació - roth_401k: 401(k) Roth + roth_401k: Roth 401(k) roth_ira: IRA Roth - tsp: Pla d'estalvis de retirada (TSP) + tsp: Pla d'estalvis de jubilació (TSP) loan: - auto: Prèstec de vehicle + auto: Préstec d'automòbil mortgage: Hipoteca - other: Alt préstec - student: Prèstec estudiantil + other: Altre préstec + student: Préstec d'estudis sync_start_date_help: Selecciona fins on vols sincronitzar l'historial de transaccions. - Està disponible un màxim de 3 anys d'historial. - sync_start_date_label: 'Començar a sincronitzar transaccions des de:' + Hi ha un màxim de 3 anys d'historial disponible. + sync_start_date_label: 'Comença a sincronitzar transaccions des de:' title: Configura els teus comptes de Lunch Flow + setup_required: + api_key_description: Abans d'enllaçar comptes Lunch Flow, has de configurar + la teva clau API de Lunch Flow. + api_key_not_configured: Clau API no configurada + go_to_provider_settings: Ves a la configuració del proveïdor + setup_step_1_html: Ves a Configuració → Proveïdors + setup_step_2_html: Localitza la secció Lunch Flow + setup_step_3: Introdueix la teva clau API de Lunch Flow + setup_step_4: Torna aquí per enllaçar els teus comptes + setup_steps_title: 'Passos de configuració:' + title: Cal configurar Lunch Flow sync: - success: S'ha iniciat la sincronització + success: Sincronització iniciada update: success: La connexió amb Lunch Flow s'ha actualitzat diff --git a/config/locales/views/lunchflow_items/hu.yml b/config/locales/views/lunchflow_items/hu.yml index 8527a8dc5..ebbc76dc2 100644 --- a/config/locales/views/lunchflow_items/hu.yml +++ b/config/locales/views/lunchflow_items/hu.yml @@ -1,6 +1,29 @@ --- hu: lunchflow_items: + api_error: + title: Lunch Flow kapcsolódási hiba + unable_to_connect: Nem sikerült csatlakozni a Lunch Flow-hoz + common_issues: "Gyakori problémák:" + invalid_api_key_label: Érvénytelen API-kulcs + invalid_api_key_desc: Ellenőrizd az API-kulcsodat a Szolgáltatói beállításokban + expired_credentials_label: Lejárt hitelesítő adatok + expired_credentials_desc: Generálj új API-kulcsot a Lunch Flow-ban + network_issue_label: Hálózati probléma + network_issue_desc: Ellenőrizd az internetkapcsolatodat + service_down_label: Szolgáltatás leállása + service_down_desc: A Lunch Flow API ideiglenesen nem érhető el + check_provider_settings: Szolgáltatói beállítások ellenőrzése + setup_required: + title: Lunch Flow beállítás szükséges + api_key_not_configured: Az API-kulcs nincs beállítva + api_key_description: A Lunch Flow számlák összekapcsolása előtt be kell állítanod a Lunch Flow API-kulcsodat. + setup_steps_title: "Beállítási lépések:" + setup_step_1_html: "Menj a Beállítások → Szolgáltatók menübe" + setup_step_2_html: "Keresd meg a Lunch Flow részt" + setup_step_3: Add meg a Lunch Flow API-kulcsodat + setup_step_4: Térj vissza ide a számlák összekapcsolásához + go_to_provider_settings: Szolgáltatói beállítások megnyitása create: success: Lunch Flow kapcsolat sikeresen létrehozva destroy: @@ -86,7 +109,7 @@ hu: credit_card: Hitelkártya investment: Befektetési számla loan: Hitel vagy jelzálog - other_asset: Egyéb eszköz + other_asset: Egyéb vagyon subtype_labels: depository: "Számla altípusa:" credit_card: "" @@ -95,7 +118,7 @@ hu: other_asset: "" subtype_messages: credit_card: "A hitelkártyák automatikusan hitelkártya számlákként lesznek beállítva." - other_asset: "Az egyéb eszközökhöz nincs szükség további beállításokra." + other_asset: "Az egyéb vagyonelemekhez nincs szükség további beállításokra." subtypes: depository: checking: Folyószámla diff --git a/config/locales/views/merchants/ca.yml b/config/locales/views/merchants/ca.yml index 96de7b12e..5ac3254f1 100644 --- a/config/locales/views/merchants/ca.yml +++ b/config/locales/views/merchants/ca.yml @@ -9,20 +9,37 @@ ca: unlinked_success: El comerç s'ha eliminat de les teves transaccions edit: title: Edita el comerç + enhance: + already_running: La millora ja està en curs. Espera que acabi. + success: S'ha iniciat la millora de comerços del proveïdor. Aviat es milloraran + els comerços i es fusionaran els duplicats. + family_merchant: + delete: Elimina + edit: Edita form: name_placeholder: Nom del comerç + website_hint: Introdueix el lloc web del comerç per mostrar-ne automàticament + el logotip + website_placeholder: Lloc web (p. ex., starbucks.com) index: empty: Encara no hi ha comerços - family_empty: Encara no hi ha comerços familiars - family_title: Comerços familiars + enhance_button: Millora amb IA + enhance_info: + one: A %{count} comerç del proveïdor li falta informació del lloc web. Millora + amb IA per detectar llocs web, mostrar logotips i fusionar comerços duplicats. + other: A %{count} comerços del proveïdor els falta informació del lloc web. + Millora amb IA per detectar llocs web, mostrar logotips i fusionar comerços + duplicats. + family_empty: Encara no hi ha comerços + family_title: Els teus comerços merge: Fusiona comerços new: Nou comerç - provider_empty: Encara no hi ha comerços del proveïdor vinculats a aquesta família - provider_info: Aquests comerços es van detectar automàticament mitjançant les teves connexions - bancàries o IA. Pots editar-los per crear la teva pròpia còpia, o eliminar-los per desvincular-los - de les teves transaccions. - provider_read_only: Els comerços del proveïdor se sincronitzen automàticament - amb les institucions connectades. No es poden editar aquí. + provider_empty: Encara no hi ha comerços del proveïdor vinculats + provider_info: Aquests comerços es van detectar automàticament mitjançant les + teves connexions bancàries o l'IA. Pots editar-los per crear-ne una còpia + pròpia, o eliminar-los per desvincular-los de les teves transaccions. + provider_read_only: Els comerços del proveïdor se sincronitzen des de les teves + institucions connectades. No es poden editar aquí. provider_title: Comerços del proveïdor table: actions: Accions @@ -30,8 +47,9 @@ ca: source: Origen title: Comerços unlinked_info: Aquests comerços s'han eliminat recentment de les teves transaccions. - Desapareixeran d'aquesta llista després de 30 dies a menys que s'assignin novament a una transacció. - unlinked_title: Recently unlinked + Desapareixeran d'aquesta llista al cap de 30 dies si no s'assignen novament + a una transacció. + unlinked_title: Desvinculats recentment merchant: confirm_accept: Elimina el comerç confirm_body: Segur que vols eliminar aquest comerç? Si l'elimines, es desvincularan @@ -40,29 +58,31 @@ ca: delete: Elimina el comerç edit: Edita el comerç merge: - description: Select a target merchant and the merchants to merge into it. All - transactions from merged merchants will be reassigned to the target. - select_target: Select target merchant... - sources_hint: Selected merchants will be merged into the target. Family merchants - will be deleted, provider merchants will be unlinked. - sources_label: Merchants to merge - submit: Merge selected - target_label: Merge into (target) - title: Merge merchants + description: Selecciona un comerç de destinació i els comerços que hi vols fusionar. + Totes les transaccions dels comerços fusionats es reassignaran a la destinació. + select_target: Selecciona el comerç de destinació... + sources_hint: Els comerços seleccionats es fusionaran amb el de destinació. + Els comerços de la família s'eliminaran, els del proveïdor es desvincularan. + sources_label: Comerços per fusionar + submit: Fusiona els seleccionats + target_label: Fusiona amb (destinació) + title: Fusiona comerços new: title: Nou comerç perform_merge: - invalid_merchants: Invalid merchants selected - no_merchants_selected: No merchants selected to merge - success: Successfully merged %{count} merchants - target_not_found: Target merchant not found + invalid_merchants: Comerços seleccionats no vàlids + no_merchants_selected: No s'ha seleccionat cap comerç per fusionar + success: + one: S'ha fusionat correctament %{count} comerç + other: S'han fusionat correctament %{count} comerços + target_not_found: No s'ha trobat el comerç de destinació provider_merchant: - edit: Edit - remove: Remove - remove_confirm_body: Are you sure you want to remove %{name}? This will unlink - all associated transactions from this merchant but will not delete the merchant - itself. - remove_confirm_title: Remove merchant? + edit: Edita + remove: Elimina + remove_confirm_body: Segur que vols eliminar %{name}? Això desvincularà totes + les transaccions associades d'aquest comerç, però no eliminarà el comerç en + si. + remove_confirm_title: Vols eliminar el comerç? update: - converted_success: Merchant converted and updated successfully + converted_success: Comerç convertit i actualitzat correctament success: Comerç actualitzat correctament diff --git a/config/locales/views/merchants/hu.yml b/config/locales/views/merchants/hu.yml index 7d22880cb..f6979411c 100644 --- a/config/locales/views/merchants/hu.yml +++ b/config/locales/views/merchants/hu.yml @@ -34,6 +34,9 @@ hu: merchant: Kereskedő actions: Műveletek source: Forrás + family_merchant: + edit: Szerkesztés + delete: Törlés merchant: confirm_accept: Kereskedő törlése confirm_body: Biztosan törlöd ezt a kereskedőt? A törlés megszünteti az összes kapcsolódó tranzakció hozzárendelését, ami hatással lehet a jelentéseidre. diff --git a/config/locales/views/mercury_items/ca.yml b/config/locales/views/mercury_items/ca.yml new file mode 100644 index 000000000..0f8636dd4 --- /dev/null +++ b/config/locales/views/mercury_items/ca.yml @@ -0,0 +1,233 @@ +--- +ca: + mercury_items: + api_error: + check_provider_settings: Revisa la configuració del proveïdor + common_issues: 'Problemes habituals:' + expired_credentials_desc: Genera un nou token API des de Mercury + expired_credentials_label: Credencials caducades + insufficient_permissions_desc: Assegura't que el teu token té accés només de + lectura + insufficient_permissions_label: Permisos insuficients + invalid_api_token_desc: Revisa el teu token API a la configuració del proveïdor + invalid_api_token_label: Token API no vàlid + network_issue_desc: Comprova la teva connexió a internet + network_issue_label: Problema de xarxa + service_down_desc: L'API de Mercury pot estar temporalment no disponible + service_down_label: Servei caigut + title: Error de connexió Mercury + unable_to_connect: No s'ha pogut connectar a Mercury + complete_account_setup: + all_skipped: S'han omès tots els comptes. No s'ha creat cap compte. + creation_failed: 'No s''han pogut crear els comptes: %{error}' + no_accounts: No hi ha comptes per configurar. + success: S'han creat correctament %{count} compte(s). + create: + success: La connexió Mercury s'ha creat correctament + destroy: + success: La connexió Mercury s'ha eliminat + index: + title: Connexions Mercury + link_accounts: + all_already_linked: + one: El compte seleccionat (%{names}) ja està enllaçat + other: 'Tots els %{count} comptes seleccionats ja estan enllaçats: %{names}' + api_error: 'Error de l''API: %{message}' + invalid_account_names: + one: No es pot enllaçar un compte sense nom + other: No es poden enllaçar %{count} comptes sense nom + link_failed: No s'han pogut enllaçar els comptes + no_accounts_selected: Selecciona almenys un compte + no_api_token: No s'ha trobat el token API de Mercury. Configura'l a la configuració + del proveïdor. + partial_invalid: S'han enllaçat correctament %{created_count} compte(s), %{already_linked_count} + ja estaven enllaçats, %{invalid_count} compte(s) tenien noms no vàlids + partial_success: 'S''han enllaçat correctament %{created_count} compte(s). %{already_linked_count} + compte(s) ja estaven enllaçats: %{already_linked_names}' + select_connection: Tria una connexió Mercury abans d'enllaçar comptes. + success: + one: S'ha enllaçat correctament %{count} compte + other: S'han enllaçat correctament %{count} comptes + link_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + api_error: 'Error de l''API: %{message}' + invalid_account_name: No es pot enllaçar un compte sense nom + mercury_account_already_linked: Aquest compte Mercury ja està enllaçat a un + altre compte + mercury_account_not_found: No s'ha trobat el compte Mercury + missing_parameters: Falten paràmetres obligatoris + no_api_token: No s'ha trobat el token API de Mercury. Configura'l a la configuració + del proveïdor. + select_connection: Tria una connexió Mercury abans d'enllaçar comptes. + success: S'ha enllaçat correctament %{account_name} amb Mercury + loading: + loading_message: Carregant comptes Mercury... + loading_title: Carregant + mercury_item: + accounts_need_setup: Els comptes necessiten configuració + delete: Elimina la connexió + deletion_in_progress: eliminació en curs... + error: Error + no_accounts_description: Aquesta connexió encara no té comptes enllaçats. + no_accounts_title: No hi ha comptes + setup_action: Configura els nous comptes + setup_description: "%{linked} de %{total} comptes enllaçats. Tria els tipus + de compte per als teus nous comptes Mercury importats." + setup_needed: Nous comptes a punt per configurar + status: Sincronitzat fa %{timestamp} + status_never: Mai sincronitzat + status_with_summary: Darrera sincronització fa %{timestamp} - %{summary} + syncing: Sincronitzant... + total: Total + unlinked: Sense enllaç + mercury_item_selection_error_payload: + select_connection: Tria una connexió Mercury abans de carregar comptes. + provider_connection: + default_description: Connecta't al teu banc a través de Mercury + default_name: Mercury + description: Connecta amb %{name} + name: Mercury - %{name} + provider_panel: + add_connection: Afegeix connexió Mercury + base_url_label: URL base (opcional) + base_url_placeholder: https://api.mercury.com/api/v1 (per defecte) + connection_name_label: Nom de la connexió + connection_name_placeholder: Compte corrent d'empresa + default_connection_name: Connexió Mercury + disconnect_confirm: Vols desconnectar %{name}? + instructions: + copy_token_html: Copia el token sencer (incloent el prefix + secret-token:) i afegeix-lo com a connexió amb nom a continuació + create_token: Crea un nou token API amb accés "només de lectura" + open_tokens: Ves a Configuració > Desenvolupador > Tokens API + sign_in_html: Visita %{link} i inicia sessió al compte que vols connectar + whitelist_ip_html: "Important: afegeix l'adreça IP del teu + servidor a la llista blanca del token" + keep_token_placeholder: Deixa-ho en blanc per mantenir el token actual + sandbox_note_html: Utilitza una connexió amb nom separada per a cada inici de + sessió/token API de Mercury que vulguis sincronitzar. Per a proves en sandbox, + utilitza https://api-sandbox.mercury.com/api/v1 com a URL base. + Mercury requereix llistes blanques d'IP — assegura't d'afegir la teva IP al + panell de Mercury. + setup_accounts: Configura comptes + setup_title: 'Instruccions de configuració:' + sync: Sincronitza + token_label: Token + token_placeholder: Enganxa el token aquí + update_connection: Actualitza la connexió + render_mercury_item_selection_failure: + no_credentials_configured: Primer, configura el teu token API de Mercury a la + configuració del proveïdor. + select_connection: Tria una connexió Mercury a la configuració del proveïdor. + select_accounts: + accounts_selected: comptes seleccionats + api_error: 'Error de l''API: %{message}' + cancel: Cancel·la + configure_name_in_mercury: No es pot importar — configura el nom del compte + a Mercury + description: Selecciona els comptes que vols enllaçar al teu compte de %{product_name}. + link_accounts: Enllaça els comptes seleccionats + no_accounts_found: No s'han trobat comptes. Comprova la configuració del teu + token API. + no_api_token: El token API de Mercury no està configurat. Configura'l a la configuració. + no_credentials_configured: Primer, configura el teu token API de Mercury a la + configuració del proveïdor. + no_name_placeholder: "(Sense nom)" + select_connection: Tria una connexió Mercury a la configuració del proveïdor. + title: Selecciona comptes Mercury + select_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + all_accounts_already_linked: Tots els comptes Mercury ja estan enllaçats + api_error: 'Error de l''API: %{message}' + cancel: Cancel·la + configure_name_in_mercury: No es pot importar — configura el nom del compte + a Mercury + description: Selecciona un compte Mercury per enllaçar-lo amb aquest compte. + Les transaccions es sincronitzaran i deduplicaran automàticament. + link_account: Enllaça compte + no_account_specified: No s'ha especificat cap compte + no_accounts_found: No s'han trobat comptes Mercury. Comprova la configuració + del teu token API. + no_api_token: El token API de Mercury no està configurat. Configura'l a la configuració. + no_credentials_configured: Primer, configura el teu token API de Mercury a la + configuració del proveïdor. + no_name_placeholder: "(Sense nom)" + select_connection: Tria una connexió Mercury a la configuració del proveïdor. + title: Enllaça %{account_name} amb Mercury + setup_accounts: + account_type_label: 'Tipus de compte:' + account_types: + credit_card: Targeta de crèdit + depository: Compte corrent o d'estalvis + investment: Compte d'inversió + loan: Préstec o hipoteca + other_asset: Altre actiu + skip: Omet aquest compte + all_accounts_linked: Tots els teus comptes Mercury ja s'han configurat. + api_error: 'Error de l''API: %{message}' + balance: Saldo + cancel: Cancel·la + choose_account_type: 'Tria el tipus de compte correcte per a cada compte Mercury:' + create_accounts: Crea comptes + creating_accounts: Creant comptes... + fetch_failed: No s'han pogut obtenir els comptes + historical_data_range: 'Rang de dades històriques:' + no_accounts_to_setup: No hi ha comptes per configurar + no_api_token: El token API de Mercury no està configurat. Revisa la configuració + de la connexió. + subtitle: Tria els tipus de compte correctes per als teus comptes importats + subtype_labels: + credit_card: '' + depository: 'Subtipus de compte:' + investment: 'Tipus d''inversió:' + loan: 'Tipus de préstec:' + other_asset: '' + subtype_messages: + credit_card: Les targetes de crèdit es configuraran automàticament com a comptes + de targeta de crèdit. + other_asset: No calen opcions addicionals per a altres actius. + subtypes: + depository: + cd: Certificat de dipòsit + checking: Compte corrent + hsa: Compte d'estalvi per a salut + money_market: Mercat monetari + savings: Estalvis + investment: + 401k: 401(k) + 403b: 403(b) + 529_plan: Pla 529 + angel: Inversió àngel + brokerage: Corredoria + hsa: Compte d'estalvi per a salut + ira: IRA tradicional + mutual_fund: Fons d'inversió + pension: Pensió + retirement: Jubilació + roth_401k: Roth 401(k) + roth_ira: IRA Roth + tsp: Pla d'estalvis de jubilació (TSP) + loan: + auto: Préstec d'automòbil + mortgage: Hipoteca + other: Altre préstec + student: Préstec d'estudis + sync_start_date_help: Selecciona fins on vols sincronitzar l'historial de transaccions. + Hi ha un màxim de 3 anys d'historial disponible. + sync_start_date_label: 'Comença a sincronitzar transaccions des de:' + title: Configura els teus comptes Mercury + setup_required: + api_token_description: Abans d'enllaçar comptes Mercury, has de configurar el + teu token API de Mercury. + api_token_not_configured: Token API no configurat + go_to_provider_settings: Ves a la configuració del proveïdor + setup_step_1_html: Ves a Configuració > Proveïdors + setup_step_2_html: Localitza la secció Mercury + setup_step_3: Introdueix el teu token API de Mercury + setup_step_4: Torna aquí per enllaçar els teus comptes + setup_steps_title: 'Passos de configuració:' + title: Cal configurar Mercury + sync: + success: Sincronització iniciada + update: + success: La connexió Mercury s'ha actualitzat diff --git a/config/locales/views/mercury_items/hu.yml b/config/locales/views/mercury_items/hu.yml index 8bf7271a7..011e8a4d7 100644 --- a/config/locales/views/mercury_items/hu.yml +++ b/config/locales/views/mercury_items/hu.yml @@ -1,6 +1,31 @@ --- hu: mercury_items: + api_error: + title: Mercury kapcsolati hiba + unable_to_connect: Nem sikerült csatlakozni a Mercury-hoz + common_issues: "Gyakori problémák:" + invalid_api_token_label: Érvénytelen API token + invalid_api_token_desc: Ellenőrizd az API tokenedet a Szolgáltatói beállításokban + expired_credentials_label: Lejárt hitelesítő adatok + expired_credentials_desc: Generálj új API tokent a Mercury-ban + insufficient_permissions_label: Elégtelen jogosultságok + insufficient_permissions_desc: Győződj meg róla, hogy a tokened csak olvasási hozzáféréssel rendelkezik + network_issue_label: Hálózati hiba + network_issue_desc: Ellenőrizd az internetkapcsolatodat + service_down_label: Szolgáltatás nem elérhető + service_down_desc: A Mercury API átmenetileg nem elérhető + check_provider_settings: Szolgáltatói beállítások ellenőrzése + setup_required: + title: Mercury beállítás szükséges + api_token_not_configured: Az API token nincs beállítva + api_token_description: Mielőtt Mercury-számlákat kapcsolnál össze, be kell állítanod a Mercury API tokenedet. + setup_steps_title: "Beállítási lépések:" + setup_step_1_html: "Menj a Beállítások > Szolgáltatók menübe" + setup_step_2_html: "Keresd meg a Mercury részt" + setup_step_3: Add meg a Mercury API tokenedet + setup_step_4: Térj vissza ide a számlák összekapcsolásához + go_to_provider_settings: Ugrás a szolgáltatói beállításokhoz create: success: Mercury kapcsolat sikeresen létrehozva destroy: @@ -121,7 +146,7 @@ hu: credit_card: Hitelkártya investment: Befektetési számla loan: Hitel vagy jelzálog - other_asset: Egyéb eszköz + other_asset: Egyéb vagyon subtype_labels: depository: "Számla altípusa:" credit_card: "" @@ -130,7 +155,7 @@ hu: other_asset: "" subtype_messages: credit_card: "A hitelkártyák automatikusan hitelkártya számlákként lesznek beállítva." - other_asset: "Az egyéb eszközökhöz nincs szükség további beállításokra." + other_asset: "Az egyéb vagyonelemekhez nincs szükség további beállításokra." subtypes: depository: checking: Folyószámla @@ -176,3 +201,8 @@ hu: success: Szinkronizálás elindítva update: success: Mercury kapcsolat frissítve + mercury_item_selection_error_payload: + select_connection: Válassz Mercury kapcsolatot a számlák betöltése előtt. + render_mercury_item_selection_failure: + select_connection: Válassz Mercury kapcsolatot a Szolgáltatói beállításokban. + no_credentials_configured: Kérlek előbb állítsd be a Mercury API tokenedet a Szolgáltatói beállításokban. diff --git a/config/locales/views/messages/ca.yml b/config/locales/views/messages/ca.yml new file mode 100644 index 000000000..1eaca20ef --- /dev/null +++ b/config/locales/views/messages/ca.yml @@ -0,0 +1,6 @@ +--- +ca: + messages: + chat_form: + disclaimer: Les respostes de la IA són només informatives. No són consells financers! + placeholder: Pregunta el que vulguis ... diff --git a/config/locales/views/messages/hu.yml b/config/locales/views/messages/hu.yml new file mode 100644 index 000000000..df1edc25e --- /dev/null +++ b/config/locales/views/messages/hu.yml @@ -0,0 +1,6 @@ +--- +hu: + messages: + chat_form: + placeholder: "Kérdezz bármit..." + disclaimer: "Az AI-válaszok csak tájékoztató jellegűek. Nem pénzügyi tanácsadás!" diff --git a/config/locales/views/mfa/ca.yml b/config/locales/views/mfa/ca.yml index 18cb4ffe5..e53541c1a 100644 --- a/config/locales/views/mfa/ca.yml +++ b/config/locales/views/mfa/ca.yml @@ -13,27 +13,36 @@ ca: create: invalid_code: Codi de verificació invàlid. Torna-ho a provar. disable: - success: L'autenticació en dos passos s'ha desactivat + success: L'autenticació de dos factors s'ha desactivat new: code_label: Codi de verificació code_placeholder: Introdueix el codi de 6 dígits - description: Millora la seguretat del teu compte activant l'autenticació en - dos passos - page_title: Configuració de l'autenticació en dos passos + description: Millora la seguretat del teu compte activant l'autenticació de + dos factors + page_title: Configuració de l'autenticació de dos factors scan_description: Utilitza una app d'autenticació com Google Authenticator o 1Password per escanejar aquest codi QR scan_title: 1. Escaneja el codi QR secret_description: Si no pots escanejar el codi QR, introdueix aquesta clau manualment a la teva app d'autenticació secret_title: Codi d'entrada manual - title: Activa l'autenticació en dos passos + title: Activa l'autenticació de dos factors verify_button: Verifica i activa 2FA verify_description: Introdueix el codi de 6 dígits de la teva app d'autenticació verify_title: 2. Introdueix el codi de verificació verify: description: Introdueix el codi de la teva app d'autenticació per continuar - page_title: Verifica l'autenticació en dos passos - title: Autenticació en dos passos + or: o + page_title: Verifica l'autenticació de dos factors + title: Autenticació de dos factors verify_button: Verifica + webauthn_button: Utilitza una clau d'accés o de seguretat + webauthn_unsupported: Aquest navegador no admet claus d'accés ni de seguretat. verify_code: invalid_code: Codi d'autenticació invàlid. Torna-ho a provar. + verify_webauthn: + invalid_credential: No s'ha pogut verificar aquesta clau d'accés o de seguretat. + Torna-ho a provar. + webauthn_options: + unavailable: No hi ha claus d'accés ni de seguretat disponibles per a aquest + compte. diff --git a/config/locales/views/oidc_accounts/ca.yml b/config/locales/views/oidc_accounts/ca.yml index 06ad64409..568f549a9 100644 --- a/config/locales/views/oidc_accounts/ca.yml +++ b/config/locales/views/oidc_accounts/ca.yml @@ -1,33 +1,49 @@ --- ca: oidc_accounts: + create_link: + no_pending_oidc: No s'ha trobat cap autenticació OIDC pendent + create_user: + account_created: Benvingut/da! S'ha creat el teu compte. + account_creation_disabled: La creació de comptes SSO està desactivada. Contacta + amb un administrador. + no_pending_oidc: No s'ha trobat cap autenticació OIDC pendent link: - title_link: Enllaçar compte OIDC - title_create: Crear compte - verify_heading: Verificar la vostra identitat - verify_description_html: "Per enllaçar el vostre compte %{provider}%{email_suffix}, verifiqueu la vostra identitat introduint la contrasenya." - email_suffix_html: " (%{email})" + account_creation_disabled: La creació de nous comptes mitjançant inici de sessió + únic està desactivada. Contacta amb un administrador per crear el teu compte. + cancel: Cancel·la + create_description_html: No s'ha trobat cap compte amb el correu electrònic + %{email}. Fes clic a sota per crear un compte nou amb la + teva identitat de %{provider}. + create_heading: Crea un compte nou email_label: Correu electrònic - email_placeholder: Introduïu el vostre correu electrònic + email_placeholder: Introdueix el teu correu electrònic + email_suffix_html: " (%{email})" + info_email: 'Correu electrònic:' + info_name: 'Nom:' + no_pending_oidc: No s'ha trobat cap autenticació OIDC pendent password_label: Contrasenya - password_placeholder: Introduïu la vostra contrasenya - verify_hint: Això garanteix que només vós pugueu enllaçar comptes externs al vostre perfil. - submit_link: Enllaçar compte - create_heading: Crear compte nou - create_description_html: "No s'ha trobat cap compte amb el correu electrònic %{email}. Feu clic a baix per crear un compte nou amb la vostra identitat %{provider}." - info_email: "Correu electrònic:" - info_name: "Nom:" - submit_create: Crear compte - account_creation_disabled: La creació de comptes mitjançant l'inici de sessió únic està desactivada. Contacteu amb un administrador. - cancel: Cancel·lar + password_placeholder: Introdueix la teva contrasenya + submit_accept_invitation: Accepta la invitació + submit_create: Crea el compte + submit_link: Enllaça el compte + title_create: Crea un compte + title_link: Enllaça el compte OIDC + verify_description_html: Per enllaçar el teu compte %{provider}%{email_suffix}, + verifica la teva identitat introduint la contrasenya. + verify_heading: Verifica la teva identitat + verify_hint: Així garantim que només tu pots enllaçar comptes externs al teu + perfil. new_user: - title: Completar el compte - heading: Crear el compte - description: Confirmeu les vostres dades per completar la creació del compte amb la vostra identitat %{provider}. + cancel: Cancel·la + description: Confirma les teves dades per completar la creació del compte amb + la teva identitat de %{provider}. email_label: Correu electrònic (del proveïdor SSO) first_name_label: Nom - first_name_placeholder: Introduïu el vostre nom + first_name_placeholder: Introdueix el teu nom + heading: Crea el teu compte last_name_label: Cognom - last_name_placeholder: Introduïu el vostre cognom - submit: Crear compte - cancel: Cancel·lar \ No newline at end of file + last_name_placeholder: Introdueix el teu cognom + no_pending_oidc: No s'ha trobat cap autenticació OIDC pendent + submit: Crea el compte + title: Completa el teu compte diff --git a/config/locales/views/oidc_accounts/hu.yml b/config/locales/views/oidc_accounts/hu.yml index dd08ba7ed..90c9783f4 100644 --- a/config/locales/views/oidc_accounts/hu.yml +++ b/config/locales/views/oidc_accounts/hu.yml @@ -2,6 +2,7 @@ hu: oidc_accounts: link: + no_pending_oidc: Nem található függőben lévő OIDC-hitelesítés title_link: OIDC-fiók összekapcsolása title_create: Fiók létrehozása verify_heading: Igazold az azonosságodat @@ -21,7 +22,10 @@ hu: submit_accept_invitation: Meghívó elfogadása account_creation_disabled: Az egyszeri bejelentkezésen keresztüli új fiók létrehozása le van tiltva. Kérjük, lépj kapcsolatba egy rendszergazdával a fiókod létrehozásához. cancel: Mégse + create_link: + no_pending_oidc: Nem található függőben lévő OIDC-hitelesítés new_user: + no_pending_oidc: Nem található függőben lévő OIDC-hitelesítés title: Fiókod véglegesítése heading: Hozd létre a fiókodat description: Kérjük, erősítsd meg az adataidat a fiókod létrehozásának befejezéséhez a(z) %{provider} azonosítóddal. @@ -32,3 +36,7 @@ hu: last_name_placeholder: Add meg a vezetéknevedet submit: Fiók létrehozása cancel: Mégse + create_user: + no_pending_oidc: Nem található függőben lévő OIDC-hitelesítés + account_creation_disabled: Az SSO-fiók létrehozása le van tiltva. Kérjük, lépj kapcsolatba egy rendszergazdával. + account_created: "Üdvözlünk! A fiókod sikeresen létrejött." diff --git a/config/locales/views/onboardings/ca.yml b/config/locales/views/onboardings/ca.yml index 9036a1efe..919d84017 100644 --- a/config/locales/views/onboardings/ca.yml +++ b/config/locales/views/onboardings/ca.yml @@ -1,61 +1,71 @@ --- ca: onboardings: + goals: + ai_insights: Deixar que la IA m'ajudi a entendre les meves finances + budgeting: Gestionar plans financers i pressupostos + cashflow: Entendre el flux de caixa i les despeses + investments: Fer el seguiment d'inversions + optimization: Analitzar i optimitzar comptes + partner: Gestionar les finances amb la parella + reduce_stress: Reduir l'estrès o l'ansietat financera + submit: Següent + subtitle: Selecciona un o més objectius que tens amb %{product_name} com a eina + de finances personals. + title: Què t'ha portat aquí? + unified_accounts: Veure tots els meus comptes en un sol lloc header: - sign_out: Tancar sessió - setup: Configuració - preferences: Preferències goals: Objectius + preferences: Preferències + setup: Configuració + sign_out: Tanca la sessió start: Inici logout: - sign_out: Tancar sessió + sign_out: Tanca la sessió + preferences: + color_theme: Tema de color + currency: Divisa + date_format: Format de data + example: Compte d'exemple + locale: Idioma + preview: Previsualitza com es mostren les dades segons les preferències. + submit: Finalitza + subtitle: Configurem les teves preferències. + theme_dark: Fosc + theme_light: Clar + theme_system: Sistema + title: Configura les teves preferències show: - title: Configurem el teu compte - subtitle: Primer de tot, completem el teu perfil. + country: País first_name: Nom first_name_placeholder: Nom - last_name: Cognom - last_name_placeholder: Cognom + group_name: Nom del grup + group_name_placeholder: Nom del grup household_name: Nom de la llar household_name_placeholder: Nom de la llar - country: País - submit: Continuar - preferences: - title: Configura les teves preferències - subtitle: Configurem les teves preferències. - example: Compte d'exemple - preview: Previsualitza com es mostren les dades segons les preferències. - color_theme: Tema de colors - theme_system: Sistema - theme_light: Clar - theme_dark: Fosc - locale: Idioma - currency: Moneda - date_format: Format de data - submit: Completar - goals: - title: Què t'ha portat aquí? - subtitle: Selecciona un o més objectius que tens amb %{product_name} com a eina de finances personals. - unified_accounts: Veure tots els meus comptes en un sol lloc - cashflow: Entendre el flux de caixa i les despeses - budgeting: Gestionar plans financers i pressupostos - partner: Gestionar finances amb la parella - investments: Seguir les inversions - ai_insights: Deixar que la IA m'ajudi a entendre les meves finances - optimization: Analitzar i optimitzar comptes - reduce_stress: Reduir l'estrès financer o l'ansietat - submit: Següent + last_name: Cognom + last_name_placeholder: Cognom + moniker_family: Membres de la família (tu sol/a o amb la teva parella, fills, + etc.) + moniker_group: Grup de persones (empresa, club, associació, qualsevol altre + tipus) + moniker_prompt: Faràs servir %{product_name} amb... + submit: Continua + subtitle: Primer de tot, completem el teu perfil. + title: Configurem el teu compte trial: - title: Prova Sure durant 45 dies + continue_trial: Continua la prova data_deletion: Les dades s'eliminaran després - description_html: A partir d'avui pots provar el producte a fons.
Si t'agrada, allotja'l tu mateix o contribueix per continuar usant-lo aquí. - try_button: Provar Sure durant 45 dies - continue_trial: Continuar la prova - upgrade: Actualitzar - how_it_works: Com funciona + description_html: A partir d'avui pots fer una bona ullada al producte.
Si + t'agrada, autoallotja'l o contribueix per continuar fent-lo servir aquí. + how_it_works: Com funcionen les coses aquí + in_40_days: D'aquí 40 dies (%{date}) + in_40_days_description: T'avisarem perquè recordis exportar les teves dades. + in_45_days: D'aquí 45 dies (%{date}) + in_45_days_description: Eliminarem les teves dades — contribueix per continuar + fent servir Sure aquí! + title: Prova Sure durant 45 dies today: Avui today_description: Tindràs accés gratuït a Sure durant 45 dies al nostre AWS. - in_40_days: En 40 dies (%{date}) - in_40_days_description: Et notificarem per recordar-te d'exportar les teves dades. - in_45_days: En 45 dies (%{date}) - in_45_days_description: Eliminarem les teves dades — contribueix per continuar usant Sure aquí! \ No newline at end of file + try_button: Prova Sure durant 45 dies + upgrade: Actualitza diff --git a/config/locales/views/other_assets/ca.yml b/config/locales/views/other_assets/ca.yml index b157b7ef7..1894503db 100644 --- a/config/locales/views/other_assets/ca.yml +++ b/config/locales/views/other_assets/ca.yml @@ -2,10 +2,12 @@ ca: other_assets: edit: - balance_tracking_info: L'estat dels Altres Actius es segueix mitjançant valoracions manuals - utilitzant 'Nou saldo', no transaccions. El flux de caixa no afectarà el saldo del compte. + balance_tracking_info: Els altres actius es segueixen mitjançant valoracions + manuals utilitzant 'Nou saldo', no transaccions. El flux de caixa no afectarà + el saldo del compte. edit: Edita %{account} new: - balance_tracking_info: L'estat dels Altres Actius es segueix mitjançant valoracions manuals - utilitzant 'Nou saldo', no transaccions. El flux de caixa no afectarà el saldo del compte. + balance_tracking_info: Els altres actius es segueixen mitjançant valoracions + manuals utilitzant 'Nou saldo', no transaccions. El flux de caixa no afectarà + el saldo del compte. title: Introdueix els detalls de l'actiu diff --git a/config/locales/views/other_assets/hu.yml b/config/locales/views/other_assets/hu.yml index 5a60935d7..38cd263ed 100644 --- a/config/locales/views/other_assets/hu.yml +++ b/config/locales/views/other_assets/hu.yml @@ -3,7 +3,7 @@ hu: other_assets: edit: edit: '%{account} szerkesztése' - balance_tracking_info: 'Az egyéb eszközök értékét manuális értékelésekkel lehet követni az „Új egyenleg” funkcióval, nem tranzakciókkal. A pénzforgalom nem befolyásolja a számlaegyenleget.' + balance_tracking_info: 'Az egyéb vagyonelemek értékét manuális értékelésekkel lehet követni az „Új egyenleg” funkcióval, nem tranzakciókkal. A pénzforgalom nem befolyásolja a számlaegyenleget.' new: - title: Add meg az eszköz adatait - balance_tracking_info: 'Az egyéb eszközök értékét manuális értékelésekkel lehet követni az „Új egyenleg" funkcióval, nem tranzakciókkal. A pénzforgalom nem befolyásolja a számlaegyenleget.' + title: Add meg a vagyonelem adatait + balance_tracking_info: 'Az egyéb vagyonelemek értékét manuális értékelésekkel lehet követni az „Új egyenleg” funkcióval, nem tranzakciókkal. A pénzforgalom nem befolyásolja a számlaegyenleget.' diff --git a/config/locales/views/pages/ca.yml b/config/locales/views/pages/ca.yml index 4b0fdf4c7..13f95e886 100644 --- a/config/locales/views/pages/ca.yml +++ b/config/locales/views/pages/ca.yml @@ -6,8 +6,20 @@ ca: dashboard: balance_sheet: add_accounts: Afegeix els teus comptes de %{name} per veure'n el detall complet + add_asset_accounts: Afegeix els teus comptes d'actius per veure'n el detall + complet + add_liability_accounts: Afegeix els teus comptes de passius per veure'n el + detall complet + classifications: + asset: Actius + liability: Passius + name: Nom + no_asset: Encara no hi ha actius no_items: Encara no hi ha %{name} + no_liability: Encara no hi ha passius title: Balanç patrimonial + value: Valor + weight: Pes cashflow_sankey: add_transaction: Afegeix una transacció no_data_description: Afegeix transaccions per mostrar dades de flux de caixa @@ -16,15 +28,15 @@ ca: title: Flux de caixa drag_to_reorder: Arrossega per reordenar la secció investment_summary: - add_investment: Afegeix un compte d'inversió per seguir el teu portafoli - contributions: Contribucions + add_investment: Afegeix un compte d'inversió per seguir la teva cartera + contributions: Aportacions holding: Posició no_investments: No hi ha comptes d'inversió - period_activity: "Activitat del %{period}" + period_activity: 'Activitat — %{period}' return: Rendiment title: Inversions total_return: Rendiment total - trades: Negocis + trades: Operacions value: Valor weight: Pes withdrawals: Retirades @@ -44,10 +56,50 @@ ca: title: Encara no hi ha comptes outflows_donut: categories: Categories - title: Sortides - total_outflows: Total sortides + title: Sortides de caixa + total_outflows: Total de sortides de caixa value: Valor weight: Pes subtitle: Això és el que està passant amb les teves finances toggle_section: Commuta la visibilitat de la secció welcome: Benvingut/da de nou, %{name} + feedback: + bug_report: Informa d'un error + description: Fes-nos saber si tens cap comentari específic. No dubtis a incloure + enllaços a vídeos o captures de pantalla. + discuss: Comenta %{product} amb d'altres + feature_request: Sol·licita una funcionalitat + heading: Deixa un comentari + title: Comentaris + intro: + coming_soon: Experiència d'introducció properament + description: Estem creant una experiència d'inici més rica per conèixer els + teus objectius, fites i necessitats diàries. De moment, ves a la barra lateral + del xat per iniciar una conversa amb Sure i explica'ns on et trobes al teu + recorregut financer. + not_authorized: La introducció només està disponible per a usuaris convidats. + start_chatting: Comença a xatejar + welcome: Benvingut/da! + privacy: + heading: Política de privadesa + placeholder: El contingut de la política de privadesa es mostrarà aquí. + title: Política de privadesa + redis_configuration_error: + heading: Cal configurar Redis + page_title: Cal configurar Redis - Sure + refresh_hint: Un cop hagis configurat Redis, recarrega aquesta pàgina per continuar. + refresh_page: Recarrega la pàgina + setup_guide_hint: Segueix la nostra guia completa de configuració de Docker + per configurar Redis + subheading: La teva instal·lació de Sure amb self hosting necessita Redis configurat + correctament. + view_setup_guide: Veure la guia de configuració + why_required_body: Sure utilitza Redis per executar les tasques en segon pla + de Sidekiq, com ara la sincronització de dades de comptes, el processament + d'importacions i altres operacions de fons que mantenen les teves dades financeres + actualitzades. + why_required_title: Per què cal Redis? + terms: + heading: Condicions del servei + placeholder: El contingut de les condicions del servei es mostrarà aquí. + title: Condicions del servei diff --git a/config/locales/views/pages/en.yml b/config/locales/views/pages/en.yml index bd96938e5..df0a8a70c 100644 --- a/config/locales/views/pages/en.yml +++ b/config/locales/views/pages/en.yml @@ -51,11 +51,19 @@ en: title: "Balance Sheet" no_items: "No %{name} yet" add_accounts: "Add your %{name} accounts to see a full breakdown" + no_asset: "No assets yet" + no_liability: "No liabilities yet" + add_asset_accounts: "Add your asset accounts to see a full breakdown" + add_liability_accounts: "Add your liability accounts to see a full breakdown" name: "Name" weight: "Weight" value: "Value" + classifications: + asset: "Assets" + liability: "Liabilities" cashflow_sankey: title: "Cashflow" + zoom_out: "Back to full cashflow" no_data_title: "No cash flow data for this time period" no_data_description: "Add transactions to display cash flow data or expand the time period" add_transaction: "Add transaction" diff --git a/config/locales/views/pages/hu.yml b/config/locales/views/pages/hu.yml index 06e4831fa..b1393e2b7 100644 --- a/config/locales/views/pages/hu.yml +++ b/config/locales/views/pages/hu.yml @@ -1,6 +1,29 @@ --- hu: pages: + feedback: + title: Visszajelzés + heading: Visszajelzés küldése + description: Oszd meg velünk, ha konkrét visszajelzésed van. Nyugodtan csatolhatsz videóhivatkozásokat vagy képernyőképeket. + feature_request: Funkcióigény beküldése + bug_report: Hibajelentés + discuss: "%{product} megbeszélése másokkal" + intro: + not_authorized: "Az intro csak vendégfelhasználók számára érhető el." + welcome: "Üdvözöllek!" + coming_soon: Az intro hamarosan elérhető + description: "Gazdagabb bevezetési élményt fejlesztünk, hogy megismerjük a céljaidat, mérföldköveidet és mindennapi igényeidet. Addig is menj a csevegőoldalsávba, indíts egy beszélgetést a Sure-ral, és mesélj a pénzügyi útjaidról." + start_chatting: Csevegés indítása + redis_configuration_error: + page_title: Redis konfiguráció szükséges – Sure + heading: Redis konfiguráció szükséges + subheading: Az önállóan üzemeltetett Sure telepítésedhez megfelelően konfigurált Redis szükséges. + why_required_title: Miért szükséges a Redis? + why_required_body: A Sure Redis-t használ a Sidekiq háttérfeladatokhoz, például a számlaadatok szinkronizálásához, importálások feldolgozásához és más háttérműveletekhez, amelyek naprakészen tartják a pénzügyi adataidat. + view_setup_guide: Beállítási útmutató megtekintése + setup_guide_hint: Kövesd az átfogó Docker beállítási útmutatónkat a Redis konfigurálásához + refresh_hint: "Ha konfigurálta a Redis-t, frissítsd ezt az oldalt a folytatáshoz." + refresh_page: Oldal frissítése changelog: title: Újdonságok privacy: @@ -26,8 +49,18 @@ hu: no_account_title: Még nincs számla balance_sheet: title: "Mérleg" - no_items: "Még nincs %{name}" - add_accounts: "Add hozzá a(z) %{name} számláidat a teljes áttekintésért" + no_items: "Még nincsenek %{name}" + add_accounts: "Add hozzá %{name} számláidat a teljes áttekintésért" + no_asset: "Még nincs vagyonod" + no_liability: "Még nincsenek kötelezettségeid" + add_asset_accounts: "Adj hozzá vagyonszámlákat a teljes pénzügyi áttekintésért" + add_liability_accounts: "Adj hozzá kötelezettségszámlákat a teljes pénzügyi áttekintésért" + name: "Név" + weight: "Arány" + value: "Érték" + classifications: + asset: "Vagyon" + liability: "Kötelezettségek" cashflow_sankey: title: "Pénzforgalom" no_data_title: "Nincs pénzforgalmi adat erre az időszakra" diff --git a/config/locales/views/password_resets/ca.yml b/config/locales/views/password_resets/ca.yml index 310a33cfa..8c91bb633 100644 --- a/config/locales/views/password_resets/ca.yml +++ b/config/locales/views/password_resets/ca.yml @@ -1,14 +1,18 @@ +--- ca: password_resets: - disabled: "El restabliment de la contrasenya a través de Sure està desactivat. Si us plau, restableix la teva contrasenya a través del teu proveïdor d'identitat." + disabled: El restabliment de contrasenya a través de Sure està desactivat. Restableix + la teva contrasenya a través del teu proveïdor d'identitat. edit: - title: "Restableix la contrasenya" + title: Restableix la contrasenya new: - back: "Enrere" - requested: "Si us plau, revisa el teu correu electrònic; hi trobaràs un enllaç per restablir la contrasenya." - submit: "Restableix la contrasenya" - title: "Restableix la contrasenya" - sso_only_user: "El teu compte utilitza SSO per a l'autenticació. Si us plau, contacta amb l'administrador per gestionar les teves credencials." + back: Enrere + requested: Revisa el teu correu electrònic; hi trobaràs un enllaç per restablir + la contrasenya. + submit: Restableix la contrasenya + title: Restableix la contrasenya + sso_only_user: El teu compte utilitza SSO per a l'autenticació. Contacta amb el + teu administrador per gestionar les credencials. update: - invalid_token: "El codi de verificació (token) no és vàlid." - success: "La teva contrasenya s'ha restablert correctament." \ No newline at end of file + invalid_token: El token no és vàlid. + success: La teva contrasenya s'ha restablert. diff --git a/config/locales/views/passwords/ca.yml b/config/locales/views/passwords/ca.yml index 300a17fd5..0163cb1a9 100644 --- a/config/locales/views/passwords/ca.yml +++ b/config/locales/views/passwords/ca.yml @@ -4,7 +4,7 @@ ca: edit: password: Nova contrasenya password_challenge: Contrasenya actual - submit: Restableix contrasenya - title: Actualitza contrasenya + submit: Restableix la contrasenya + title: Actualitza la contrasenya update: success: La teva contrasenya s'ha restablert. diff --git a/config/locales/views/pdf_import_mailer/ca.yml b/config/locales/views/pdf_import_mailer/ca.yml new file mode 100644 index 000000000..a46919bd6 --- /dev/null +++ b/config/locales/views/pdf_import_mailer/ca.yml @@ -0,0 +1,21 @@ +--- +ca: + pdf_import_mailer: + next_steps: + document_stored_note: Aquest document s'ha desat per a la teva referència. Es + pot fer servir per donar context en futures converses amb la IA. + document_type_label: Tipus de document + footer_note: Aquest és un missatge automàtic. No responguis directament a aquest + correu electrònic. + greeting: Hola %{name}, + intro: Hem acabat d'analitzar el document PDF que has pujat a %{product}. + next_steps_intro: 'Tens diverses opcions:' + next_steps_label: Què cal fer ara? + option_delete: Elimina aquesta importació si ja no la necessites + option_extract_transactions: Extreu transaccions d'aquest extracte + option_keep_reference: Mantén aquest document com a referència per a futures + converses amb la IA + summary_label: Resum d'IA + transactions_note: Sembla que aquest document conté transaccions. Ara pots extreure-les + i revisar-les. + view_import_button: Mira els detalls de la importació diff --git a/config/locales/views/pending_duplicate_merges/ca.yml b/config/locales/views/pending_duplicate_merges/ca.yml new file mode 100644 index 000000000..c57fdfc09 --- /dev/null +++ b/config/locales/views/pending_duplicate_merges/ca.yml @@ -0,0 +1,23 @@ +--- +ca: + pending_duplicate_merges: + create: + invalid_transaction: La transacció seleccionada per fusionar no és vàlida + merge_failed: No s'han pogut fusionar les transaccions + merge_success: Transacció pendent fusionada amb la transacció comptabilitzada + no_posted_selected: Selecciona una transacció comptabilitzada amb la qual fusionar + new: + next: 10 següents → + no_candidates: No s'ha trobat cap transacció comptabilitzada en aquest compte. + pending_transaction: Transacció pendent + previous: "← 10 anteriors" + select_posted: Selecciona la transacció comptabilitzada amb la qual fusionar + showing_range: Mostrant %{start} - %{end} + submit_button: Fusiona transaccions + title: Fusiona amb una transacció comptabilitzada + warning_description: Fes-ho servir per fusionar manualment una transacció pendent + amb la seva versió comptabilitzada. Això eliminarà la transacció pendent i + només es conservarà la comptabilitzada. + warning_title: Fusió manual de duplicats + set_transaction: + pending_only: Aquesta funció només està disponible per a transaccions pendents diff --git a/config/locales/views/pending_duplicate_merges/hu.yml b/config/locales/views/pending_duplicate_merges/hu.yml index eee805273..191592600 100644 --- a/config/locales/views/pending_duplicate_merges/hu.yml +++ b/config/locales/views/pending_duplicate_merges/hu.yml @@ -1,6 +1,13 @@ --- hu: pending_duplicate_merges: + create: + no_posted_selected: Kérlek válassz egy könyvelt tranzakciót az összevonáshoz + invalid_transaction: Érvénytelen tranzakció van kijelölve az összevonáshoz + merge_success: A függőben lévő tranzakció összevonva a könyvelt tranzakcióval + merge_failed: Nem sikerült összevonni a tranzakciókat + set_transaction: + pending_only: Ez a funkció csak függőben lévő tranzakciókhoz érhető el new: title: Összevonás könyvelt tranzakcióval warning_title: Manuális duplikáció-összevonás diff --git a/config/locales/views/plaid_items/ca.yml b/config/locales/views/plaid_items/ca.yml index 7b3387c70..9e8b97259 100644 --- a/config/locales/views/plaid_items/ca.yml +++ b/config/locales/views/plaid_items/ca.yml @@ -5,27 +5,33 @@ ca: success: Compte enllaçat correctament. Espera mentre es sincronitzen els comptes. destroy: success: Comptes programats per a l'eliminació. + link_existing_account: + already_linked: Aquest compte Plaid ja està enllaçat + invalid_account: S'ha seleccionat un compte Plaid no vàlid + success: El compte s'ha enllaçat correctament a Plaid plaid_item: - add_new: Afegeix nova connexió - confirm_accept: Elimina institució + add_new: Afegeix una connexió nova + confirm_accept: Elimina l'entitat confirm_body: Això eliminarà permanentment tots els comptes d'aquest grup i totes les dades associades. - confirm_title: Vols eliminar la institució? + confirm_title: Vols eliminar l'entitat? connection_lost: Connexió perduda connection_lost_description: Aquesta connexió ja no és vàlida. Hauràs d'eliminar-la i tornar-la a afegir per continuar sincronitzant dades. delete: Elimina error: S'ha produït un error en sincronitzar les dades - no_accounts_description: No hem pogut carregar cap compte d'aquesta entitat + no_accounts_description: No s'ha pogut carregar cap compte d'aquesta entitat financera. no_accounts_title: No s'han trobat comptes - requires_update: Cal tornar a autenticar + requires_update: Reconnecta status: Darrera sincronització fa %{timestamp} status_never: Cal sincronitzar dades syncing: Sincronitzant... - update: Actualitza la connexió + update: Actualitza select_existing_account: cancel: Cancel·la description: Selecciona un compte Plaid per enllaçar-lo al teu compte existent link_account: Enllaça el compte + no_available_accounts: No hi ha comptes Plaid disponibles per enllaçar. Primer + connecta un compte Plaid nou. title: Enllaça %{account_name} amb Plaid diff --git a/config/locales/views/plaid_items/hu.yml b/config/locales/views/plaid_items/hu.yml index 6d4293eef..458bb24b9 100644 --- a/config/locales/views/plaid_items/hu.yml +++ b/config/locales/views/plaid_items/hu.yml @@ -22,7 +22,12 @@ hu: syncing: Szinkronizálás folyamatban... update: Frissítés select_existing_account: + no_available_accounts: Nincs elérhető Plaid-számla az összekapcsoláshoz. Először csatlakozz egy új Plaid-fiókhoz. title: "%{account_name} csatlakoztatása Plaid-hez" description: Válassz egy Plaid-számlát a meglévő számlád összekapcsolásához cancel: Mégse link_account: Számla összekapcsolása + link_existing_account: + invalid_account: Érvénytelen Plaid-számla van kijelölve + already_linked: Ez a Plaid-számla már össze van kapcsolva + success: A számla sikeresen össze lett kapcsolva a Plaid-del diff --git a/config/locales/views/preview/ca.yml b/config/locales/views/preview/ca.yml new file mode 100644 index 000000000..ae13dbd34 --- /dev/null +++ b/config/locales/views/preview/ca.yml @@ -0,0 +1,4 @@ +--- +ca: + preview: + not_enabled: Aquesta funció és experimental. Activa les funcions experimentals a Configuració → Preferències per provar-la. \ No newline at end of file diff --git a/config/locales/views/preview/en.yml b/config/locales/views/preview/en.yml new file mode 100644 index 000000000..9adb55036 --- /dev/null +++ b/config/locales/views/preview/en.yml @@ -0,0 +1,4 @@ +--- +en: + preview: + not_enabled: This feature is in preview. Enable preview features in Settings → Preferences to try it. diff --git a/config/locales/views/preview/es.yml b/config/locales/views/preview/es.yml new file mode 100644 index 000000000..bf85bfd41 --- /dev/null +++ b/config/locales/views/preview/es.yml @@ -0,0 +1,4 @@ +--- +es: + preview: + not_enabled: Esta función es experimental. Activa las funciones experimentales en Configuración → Preferencias para probarla. \ No newline at end of file diff --git a/config/locales/views/properties/ca.yml b/config/locales/views/properties/ca.yml index 496c9e355..b56b5d11b 100644 --- a/config/locales/views/properties/ca.yml +++ b/config/locales/views/properties/ca.yml @@ -1,6 +1,27 @@ --- ca: properties: + address: + address_line1_label: Adreça línia 1 + address_line1_placeholder: Carrer Major, 123 + city_label: Ciutat + city_placeholder: Barcelona + country_label: País + country_placeholder: ESP + postal_code_label: Codi postal + postal_code_placeholder: '08001' + save: Desa + state_region_label: Província/Comarca + state_region_placeholder: BCN + title: Introdueix l'immoble manualment + balances: + market_value_label: Valor de mercat estimat + market_value_tooltip: El valor de mercat estimat del teu immoble. Aquest número + sovint es pot trobar a llocs com Idealista o Fotocasa, i mai és un número + exacte. + next: Següent + save: Desa + title: Introdueix l'immoble manualment edit: edit: Edita %{account} form: @@ -22,7 +43,8 @@ ca: year_built: Any de construcció year_built_placeholder: '2000' new: - title: Introdueix els detalls de l'immoble + next: Següent + title: Introdueix l'immoble manualment overview: living_area: Superfície habitable market_value: Valor de mercat @@ -30,4 +52,40 @@ ca: trend: Tendència unknown: Desconegut year_built: Any de construcció - + overview_fields: + area_label: Superfície (opcional) + area_placeholder: '1200' + area_unit_label: Unitat de superfície + name_label: Nom + name_placeholder: Segona residència + property_type_label: Tipus d'immoble + square_feet: Peus quadrats + square_meters: Metres quadrats + subtype_prompt: Selecciona el tipus + year_built_label: Any de construcció (opcional) + year_built_placeholder: '1990' + subtypes: + agri_land: + long: Terra agrícola + short: Terra agrícola + apartment: + long: Pis + short: Pis + commercial: + long: Immoble comercial + short: Comercial + plot: + long: Solar / Terreny + short: Solar + rented: + long: Immoble llogat + short: Llogat + tabs: + overview: + edit_account_details: Edita els detalls del compte + living_area: Superfície habitable + market_value: Valor de mercat + purchase_price: Preu de compra + trend: Tendència + unknown: Desconegut + year_built: Any de construcció diff --git a/config/locales/views/properties/hu.yml b/config/locales/views/properties/hu.yml index 8b3218e78..4bc7021f9 100644 --- a/config/locales/views/properties/hu.yml +++ b/config/locales/views/properties/hu.yml @@ -23,6 +23,38 @@ hu: year_built_placeholder: '2000' new: title: Add meg az ingatlan adatait + next: "Tovább" + address: + title: "Add meg az ingatlan adatait" + address_line1_label: "Utca, házszám" + address_line1_placeholder: "Kossuth utca 1." + city_label: "Város" + city_placeholder: "Budapest" + state_region_label: "Megye/Kerület" + state_region_placeholder: "Budapest" + postal_code_label: "Irányítószám" + postal_code_placeholder: "1011" + country_label: "Ország" + country_placeholder: "Magyarország" + save: "Mentés" + balances: + title: "Add meg az ingatlan adatait" + market_value_label: "Becsült piaci érték" + market_value_tooltip: "Az ingatlan becsült piaci értéke. Ezt az értéket ingatlanértékelő oldalakon találhatod, és soha nem pontos szám." + save: "Mentés" + next: "Tovább" + overview_fields: + name_label: "Név" + name_placeholder: "Nyaraló" + subtype_prompt: "Típus kiválasztása" + property_type_label: "Ingatlantípus" + year_built_label: "Építési év (nem kötelező)" + year_built_placeholder: "1990" + area_label: "Alapterület (nem kötelező)" + area_placeholder: "1200" + square_feet: "Négyzetláb" + square_meters: "Négyzetméter" + area_unit_label: "Területi egység" overview: living_area: Alapterület market_value: Piaci érték @@ -30,3 +62,28 @@ hu: trend: Tendencia unknown: Ismeretlen year_built: Építési év + tabs: + overview: + living_area: Alapterület + market_value: Piaci érték + purchase_price: Vételár + trend: Tendencia + unknown: Ismeretlen + year_built: Építési év + edit_account_details: "Számlaadatok szerkesztése" + subtypes: + apartment: + short: Lakás + long: Lakás + plot: + short: Telek + long: Telek/Föld + commercial: + short: Kereskedelmi + long: Kereskedelmi ingatlan + rented: + short: Bérelt + long: Bérelt ingatlan + agri_land: + short: Mezőgazdasági + long: Mezőgazdasági föld diff --git a/config/locales/views/recurring_transactions/ca.yml b/config/locales/views/recurring_transactions/ca.yml index 0e444699b..2c74c907a 100644 --- a/config/locales/views/recurring_transactions/ca.yml +++ b/config/locales/views/recurring_transactions/ca.yml @@ -1,53 +1,64 @@ --- ca: recurring_transactions: - already_exists: A manual recurring transaction already exists for this pattern + already_exists: Ja existeix una transacció recurrent manual per a aquest patró amount_range: 'Rang: %{min} a %{max}' badges: manual: Manual cleaned_up: S'han netejat %{count} transaccions recurrents obsoletes - cleanup_stale: Neteja Obsoletes + cleanup_stale: Neteja obsoletes confirm_delete: Segur que vols eliminar aquesta transacció recurrent? creation_failed: No s'ha pogut crear la transacció recurrent. Comprova els detalls de la transacció i torna-ho a provar. day_of_month: Dia %{day} del mes - deleted: S'ha eliminat la transacció recurrent + deleted: Transacció recurrent eliminada empty: - description: Clica "Identifica Patrons" per detectar automàticament transaccions + description: Clica «Identifica patrons» per detectar automàticament transaccions recurrents del teu historial de transaccions. title: No s'han trobat transaccions recurrents - expected_on: S'esperava el %{date} + expected_in: + one: S'espera d'aquí a %{count} dia + other: S'espera d'aquí a %{count} dies + expected_today: S'espera avui identified: S'han identificat %{count} patrons de transaccions recurrents identify_patterns: Identifica patrons info: - automatic_description: "L'identificació automàtica també s'executa després de:" + automatic_description: 'La identificació automàtica també s''executa després + de:' manual_description: Pots identificar patrons manualment o netejar transaccions recurrents obsoletes utilitzant els botons de dalt. title: Detecció automàtica de patrons triggers: - - Importacions CSV completades (transaccions, operacions, comptes, etc.) - - Sincronitzacions de proveïdors completades (Plaid, SimpleFIN, etc.) - marked_active: S'ha marcat la transacció recurrent com a activa - marked_as_recurring: S'ha marcat la transacció com a recurrent - marked_inactive: S'ha marcat la transacció recurrent com a inactiva - projected: Projectat + - Importacions CSV completades (transaccions, operacions, comptes, etc.) + - Sincronitzacions de proveïdors completades (Plaid, SimpleFIN, etc.) + marked_active: Transacció recurrent marcada com a activa + marked_as_recurring: Transacció marcada com a recurrent + marked_inactive: Transacció recurrent marcada com a inactiva + projected: Projectada recurring: Recurrent settings: - enable_description: Detecta automàticament patrons de transaccions recurrents i - mostra les transaccions projectades properes. - enable_label: Activa Transaccions Recurrents - settings_updated: S'han actualitzat les configuracions de transaccions recurrents + enable_description: Detecta automàticament patrons de transaccions recurrents + i mostra les properes transaccions projectades. + enable_label: Activa les transaccions recurrents + settings_updated: S'ha actualitzat la configuració de transaccions recurrents status: active: Activa inactive: Inactiva table: actions: Accions amount: Import - expected_day: Dia Esperat - last_occurrence: Última Ocurrència + expected_day: Dia esperat + last_occurrence: Última ocurrència merchant: Nom - next_date: Propera Data + next_date: Pròxima data status: Estat - title: Transaccions Recurrents + title: Transaccions recurrents + transfer_already_exists: Ja existeix una transferència recurrent per a aquesta + parella de comptes + transfer_creation_failed: No s'ha pogut crear la transferència recurrent. Comprova + els detalls de la transferència i torna-ho a provar. + transfer_feature_disabled: Les transaccions recurrents estan desactivades per + a aquesta família + transfer_marked_as_recurring: Transferència marcada com a recurrent unexpected_error: S'ha produït un error inesperat en crear la transacció recurrent - upcoming: Transaccions Recurrents Properes + upcoming: Properes transaccions recurrents diff --git a/config/locales/views/recurring_transactions/hu.yml b/config/locales/views/recurring_transactions/hu.yml index b88edb27c..a20ecfade 100644 --- a/config/locales/views/recurring_transactions/hu.yml +++ b/config/locales/views/recurring_transactions/hu.yml @@ -50,3 +50,7 @@ hu: inactive: Inaktív badges: manual: Manuális + transfer_marked_as_recurring: Átutalás ismétlődőként jelölve + transfer_already_exists: Ehhez a számlápárhoz már létezik ismétlődő átutalás + transfer_creation_failed: Nem sikerült létrehozni az ismétlődő átutalást. Kérlek ellenőrizd az átutalás adatait, és próbáld újra. + transfer_feature_disabled: Az ismétlődő tranzakciók le vannak tiltva ennél a háztartásnál diff --git a/config/locales/views/registrations/ca.yml b/config/locales/views/registrations/ca.yml index 5e977ef2f..0069cfe20 100644 --- a/config/locales/views/registrations/ca.yml +++ b/config/locales/views/registrations/ca.yml @@ -15,17 +15,18 @@ ca: success: T'has registrat correctament. new: invitation_message: "%{inviter} t'ha convidat a unir-te com a %{role}" - join_family_title: Uneix-te a %{family} + join_family_title: Uneix-te a %{family} (%{moniker}) password_placeholder: Introdueix la teva contrasenya + password_requirements: + case: Majúscules i minúscules + length: Mínim 8 caràcters + number: Un número (0-9) + special: 'Un caràcter especial (!, @, #, $, %, etc)' role_admin: administrador/a + role_guest: convidat/da role_member: membre submit: Crea el compte title: Crea el teu compte welcome_body: Per començar, has de registrar un compte nou. Després podràs configurar opcions addicionals dins l'aplicació. welcome_title: Benvingut/da a Self Hosted %{product_name}! - password_requirements: - length: Mínim 8 caràcters - case: Majúscules i minúscules - number: Un número (0-9) - special: "Un caràcter especial (!, @, #, $, %, etc)" diff --git a/config/locales/views/reports/ca.yml b/config/locales/views/reports/ca.yml index 144b4fbb5..517dbfbd1 100644 --- a/config/locales/views/reports/ca.yml +++ b/config/locales/views/reports/ca.yml @@ -6,6 +6,7 @@ ca: no_budgets: No s'ha configurat cap categoria de pressupost per aquest mes over_by: Superat per remaining: Restant + shared: compartit spent: Gastat status: good: Sota control @@ -14,29 +15,29 @@ ca: suggested_daily: "%{amount} suggerits al dia per a %{days} dies restants" title: Rendiment del pressupost empty_state: - add_account: Afegir compte - add_transaction: Afegir transacció - description: Comença a fer seguiment de les teves finances afegint transaccions o connectant - els teus comptes per veure informes complets + add_account: Afegeix compte + add_transaction: Afegeix transacció + description: Comença a fer seguiment de les teves finances afegint transaccions + o connectant els teus comptes per veure informes complets title: No hi ha dades disponibles google_sheets_instructions: close: D'acord example: Exemple - go_to_api_keys: Anar a claus API + go_to_api_keys: Ves a claus API need_key: Per importar dades a Google Sheets, necessites una clau API. - open_sheets: Obrir Google Sheets + open_sheets: Obre Google Sheets ready: La teva URL CSV (amb clau API) està preparada. - security_warning: Aquesta URL inclou la teva clau API. Mantingues-la segura! - step1: Anar a Configuració → Claus API + security_warning: Aquesta URL inclou la teva clau API. Mantén-la segura! + step1: Ves a Configuració → Claus API step2: Crea una nova clau API amb permisos de "lectura" - step3: Còpia la clau API - step4: 'Afegeix-la a aquesta URL com: ?api_key=TEVA_CLAU' + step3: Copia la clau API + step4: 'Afegeix-la a aquesta URL com: ?api_key=LA_TEVA_CLAU' steps: |- Per importar a Google Sheets: 1. Crea un full de Google nou 2. A la cel·la A1, introdueix la fórmula que es mostra a continuació - 3. Prem Enter - then_use: Després usa l'URL completa amb =IMPORTDATA() a Google Sheets. + 3. Prem Retorn + then_use: Després fes servir l'URL completa amb =IMPORTDATA() a Google Sheets. title_no_key: "⚠️ Es requereix clau API" title_with_key: "✅ Copia l'URL per a Google Sheets" index: @@ -45,29 +46,70 @@ ca: to: Fins a drag_to_reorder: Arrossega per reordenar la secció export: Exporta CSV + next_decade: Dècada següent + next_period: Període següent + next_year: Any següent + period_label: + last_6_months: "%{start} – %{end}" + past_year: "%{year}" + quarterly: T%{quarter} %{year} + ytd: Any %{year} + period_picker: + quarter: T%{quarter} %{year} + ytd: Any %{year} periods: custom: Rang personalitzat last_6_months: Últims 6 mesos monthly: Mensual quarterly: Trimestral - ytd: Any fins avui - print_report: Imprimir informe - showing_period: Mostrant dades des de %{start} fins a %{end} - subtitle: Informació completa sobre la teva salut financera + ytd: Any en curs + previous_decade: Dècada anterior + previous_period: Període anterior + previous_year: Any anterior + print_report: Imprimeix l'informe + showing_period: Mostrant dades de %{start} a %{end} + subtitle: Visió completa de la teva salut financera title: Informes - toggle_section: Commutar visibilitat de la secció - invalid_date_range: La data final no pot ser anterior a la data inicial. Les dates s'han - canviat. + today: Avui + toggle_section: Commuta la visibilitat de la secció + invalid_date_range: La data final no pot ser anterior a la inicial. Les dates + s'han intercanviat. + investment_flows: + contributions: Aportacions + contributions_description: Diners afegits a inversions + description: Fes el seguiment dels diners que entren i surten dels teus comptes + d'inversió mitjançant aportacions i retirades. + net_flow: Flux net + net_flow_description: Canvi net total + title: Fluxos d'inversió + withdrawals: Retirades + withdrawals_description: Diners retirats de les inversions investment_performance: accounts: Comptes d'inversió - contributions: Contribucions del període - holding: Participació - portfolio_value: Valor del portfoli + and_more: "+%{count} més" + contributions: Aportacions del període + gains_by_tax_treatment: Guanys per tractament fiscal + holding: Posició + holdings: Posicions + holdings_count: + one: "%{count} posició" + other: "%{count} posicions" + no_data: "-" + portfolio_value: Valor de la cartera + realized_gains: Guanys realitzats return: Rendiment + sell_trades: Vendes + sells_count: + one: "%{count} venda" + other: "%{count} vendes" + taxable_realized_note: Aquests guanys poden estar subjectes a impostos title: Rendiment de la inversió - top_holdings: Principals participacions + top_holdings: Principals posicions + total_gains: Guanys totals total_return: Rendiment total + unrealized_gains: Guanys no realitzats value: Valor + view_details: Veure detalls weight: Pes withdrawals: Retirades del període net_worth: @@ -83,13 +125,13 @@ ca: document_title: Informe financer generated_on: Generat el %{date} investments: - contributions: Contribucions - holding: Participació - portfolio_value: Valor del portfoli + contributions: Aportacions + holding: Posició + portfolio_value: Valor de la cartera return: Rendiment this_period: aquest període title: Inversions - top_holdings: Principals participacions + top_holdings: Principals posicions total_return: Rendiment total value: Valor weight: Pes @@ -132,7 +174,7 @@ ca: budget_performance: Rendiment del pressupost income_minus_expenses: Ingressos menys despeses net_savings: Estalvi net - no_budget_data: No hi ha dades de pressupost per aquest període + no_budget_data: No hi ha dades de pressupost per a aquest període of_budget_used: del pressupost utilitzat total_expenses: Despeses totals total_income: Ingressos totals @@ -141,23 +183,23 @@ ca: export: csv: CSV excel: Excel - google_sheets: Obrir a Google Sheets - label: Exportar + google_sheets: Obre a Google Sheets + label: Exporta pdf: PDF filters: account: Compte all_accounts: Tots els comptes all_categories: Totes les categories all_tags: Totes les etiquetes - amount_max: Màxim import - amount_min: Mínim import - apply: Aplicar filtres + amount_max: Import màxim + amount_min: Import mínim + apply: Aplica filtres category: Categoria - clear: Esborrar filtres + clear: Neteja filtres date_range: Rang de dates tag: Etiqueta title: Filtres - no_transactions: No s'ha trobat activitat per al període i filtres seleccionats + no_transactions: No s'ha trobat cap activitat per al període i filtres seleccionats pagination: next: Següent previous: Anterior @@ -168,13 +210,13 @@ ca: amount_asc: Import (baix a alt) amount_desc: Import (alt a baix) date_desc: Data (més recent) - label: Ordenar per + label: Ordena per table: amount: Import category: Categoria entries: - one: entrada - other: entrades + one: "%{count} entrada" + other: "%{count} entrades" expense: Despeses income: Ingressos percentage: "% del total" @@ -189,21 +231,22 @@ ca: current: actual expenses: Despeses income: Ingressos - insight_higher_weekday: Gastes %{percent}% més per transacció en dies laborables + insight_higher_weekday: Gastes un %{percent}% més per transacció en dies laborables que en caps de setmana - insight_higher_weekend: Gastes %{percent}% més per transacció en caps de setmana - que en dies laborables - insight_similar: El teu gast per transacció és similar en dies laborables i caps de setmana + insight_higher_weekend: Gastes un %{percent}% més per transacció en caps de + setmana que en dies laborables + insight_similar: La teva despesa per transacció és similar en dies laborables + i caps de setmana insight_title: Anàlisi month: Mes monthly_breakdown: Detall mensual net: Net no_data: No hi ha dades de tendències disponibles - no_spending_data: No hi ha dades de despeses disponibles per aquest període + no_spending_data: No hi ha dades de despeses disponibles per a aquest període savings_rate: Taxa d'estalvi spending_patterns: Patrons de despesa title: Tendències i anàlisi total: Total transactions: Transaccions - weekday_spending: Despeses laborables - weekend_spending: Despeses de cap de setmana + weekday_spending: Despeses en dies laborables + weekend_spending: Despeses en caps de setmana diff --git a/config/locales/views/reports/hu.yml b/config/locales/views/reports/hu.yml index d0ec88489..c0dee944c 100644 --- a/config/locales/views/reports/hu.yml +++ b/config/locales/views/reports/hu.yml @@ -18,6 +18,21 @@ hu: from: Kezdő dátum to: Záró dátum showing_period: "Adatok megjelenítése: %{start} – %{end}" + previous_period: "Előző időszak" + next_period: "Következő időszak" + today: "Ma" + period_label: + quarterly: "N%{quarter} %{year}" + ytd: "ÉTD %{year}" + past_year: "%{year}" + last_6_months: "%{start} – %{end}" + period_picker: + quarter: "N%{quarter} %{year}" + ytd: "ÉTD %{year}" + previous_year: "Előző év" + next_year: "Következő év" + previous_decade: "Előző évtized" + next_decade: "Következő évtized" invalid_date_range: "A záró dátum nem lehet korábbi a kezdő dátumnál. A dátumok fel lettek cserélve." summary: total_income: Összes bevétel @@ -118,10 +133,10 @@ hu: title: Nettó vagyon current_net_worth: Jelenlegi nettó vagyon period_change: Időszaki változás - assets_vs_liabilities: Eszközök vs. kötelezettségek - total_assets: Eszközök + assets_vs_liabilities: Vagyon vs. kötelezettségek + total_assets: Vagyon total_liabilities: Kötelezettségek - no_assets: Nincsenek eszközök + no_assets: Nincs vagyon no_liabilities: Nincsenek kötelezettségek investment_performance: title: Befektetési teljesítmény @@ -155,8 +170,11 @@ hu: title: Befektetési pénzáramlás description: Kövesd nyomon a befektetési számláidra be- és onnan kiáramló pénzt contributions: Befizetések + contributions_description: Befektetésekbe befizetett összeg withdrawals: Kivétek + withdrawals_description: Befektetésekből kivett összeg net_flow: Nettó pénzáramlás + net_flow_description: Teljes nettó változás google_sheets_instructions: title_with_key: "✅ URL másolása Google Sheetshez" title_no_key: "⚠️ API-kulcs szükséges" @@ -190,7 +208,7 @@ hu: title: Nettó vagyon current_balance: Jelenlegi egyenleg this_period: ebben az időszakban - assets: Eszközök + assets: Vagyon liabilities: Kötelezettségek no_liabilities: Nincsenek kötelezettségek trends: diff --git a/config/locales/views/rules/ca.yml b/config/locales/views/rules/ca.yml index b1cacb21f..4a6085dd1 100644 --- a/config/locales/views/rules/ca.yml +++ b/config/locales/views/rules/ca.yml @@ -1,36 +1,106 @@ --- ca: + rule: + conditions: + condition_group: + add_condition: Afegeix condició + all: totes + and_prefix: i + any: qualsevol + match: coincideixen + of_the_following_conditions: de les condicions següents rules: actions: value_placeholder: Introdueix un valor apply_all: - ai_cost_message: Això utilitzarà IA per categoritzar fins a %{transactions} transaccions. - ai_cost_title: Estimació de Cost d'IA - button: Aplica Totes - confirm_button: Confirma i Aplica Totes + ai_cost_message: Això utilitzarà IA per categoritzar fins a %{transactions} + transaccions. + ai_cost_title: Estimació de cost d'IA + button: Aplica-les totes + confirm_button: Confirma i aplica-les totes confirm_message: Estàs a punt d'aplicar %{count} regles que afecten %{transactions} transaccions úniques. Confirma si vols continuar. - confirm_title: Aplica Totes les Regles + confirm_title: Aplica totes les regles cost_unavailable_model: Estimació de cost no disponible per al model "%{model}". - cost_unavailable_no_provider: Estimació de cost no disponible (no hi ha proveïdor LLM configurat). - cost_warning: Pots tenir costos, comprova amb el proveïdor del model per als + cost_unavailable_no_provider: Estimació de cost no disponible (no hi ha proveïdor + d'LLM configurat). + cost_warning: Pots tenir costos. Consulta amb el proveïdor del model per als preus més actualitzats. estimated_cost: 'Cost estimat: ~$%{cost}' - success: Totes les regles s'han posat a cua per a execució - view_usage: Veure l'historial d'ús + success: Totes les regles s'han posat a la cua per executar-se + view_usage: Mostra l'historial d'ús + clear_ai_cache: + button: Buida la memòria cau d'IA + confirm_body: Segur que vols buidar la memòria cau d'IA? Això permetrà que les + regles d'IA tornin a processar totes les transaccions. Pot generar costos + d'API addicionals. + confirm_button: Buida la memòria cau + confirm_title: Vols buidar la memòria cau d'IA? + success: La memòria cau d'IA s'està netejant. Pot trigar uns instants. + condition_filters: + transaction_type: + equal_to: Igual a + expense: Despesa + income: Ingrés + transfer: Transferència + confirm: + ai_cost_no_estimate_html: Això utilitzarà IA per categoritzar %{count} transaccions. + ai_cost_title: Estimació de cost d'IA + ai_cost_with_estimate_html: 'Això utilitzarà IA per categoritzar %{count} transaccions. + Cost estimat: ~$%{cost}' + apply_notice_html: Estàs a punt d'aplicar aquesta regla a %{count} %{resource} que compleixen els criteris especificats. + Confirma si vols continuar amb aquest canvi. + confirm_changes: Confirma els canvis + cost_unavailable_model: Estimació de cost no disponible per al model "%{model}". + cost_unavailable_no_provider: Estimació de cost no disponible (no hi ha proveïdor + d'LLM configurat). + cost_warning: Pots tenir costos. Consulta amb el proveïdor del model per als + preus més actualitzats. + title: Confirma els canvis + title_with_name: Confirma els canvis a "%{name}" + view_usage_history: Mostra l'historial d'ús + destroy: + success: Regla eliminada + destroy_all: + success: Totes les regles eliminades + form: + add_action: Afegeix acció + add_condition: Afegeix condició + add_condition_group: Afegeix grup de condicions + all_past_and_future: Totes les %{resource} passades i futures + rule_name_label: Nom de la regla (opcional) + rule_name_placeholder: Introdueix un nom per a aquesta regla + starting_from: A partir de + then: ALESHORES + index: + ai_cost_warning: Les accions de regla amb IA tenen cost. Filtra el màxim possible + per evitar costos innecessaris. + delete_all_rules: Elimina totes les regles + new_rule: Nova regla + no_rules_description: Configura regles per executar accions a les teves transaccions + i altres dades a cada sincronització. + no_rules_title: Encara no hi ha regles + page_title: Regles + rules_heading: Regles + sort_by: 'Ordena per:' + sort_name: Nom + sort_updated_at: Data d'actualització + toggle_sort_direction: Commuta el sentit d'ordenació no_action: Sense acció no_condition: Sense condició recent_runs: columns: date_time: Data/Hora execution_type: Tipus - rule_name: Nom de la Regla + rule_name: Nom de la regla status: Estat transactions_counts: + blocked: Bloquejades modified: Modificades processed: Processades - queued: En Cua - description: Visualitza l'historial d'execució de les teves regles incloent + queued: A la cua + description: Visualitza l'historial d'execució de les teves regles, incloent l'estat d'èxit/fallada i els recomptes de transaccions. execution_types: manual: Manual @@ -39,5 +109,21 @@ ca: failed: Fallada pending: Pendent success: Èxit - title: Execucions Recents - unnamed_rule: Regla Sense Nom + title: Execucions recents + unnamed_rule: Regla sense nom + rule: + action_label_to: "%{label} a %{value}" + all_past_and_future: Totes les %{resource} passades i futures + and_more_actions: + one: i 1 acció més + other: i %{count} accions més + and_more_conditions: + one: i 1 condició més + other: i %{count} condicions més + delete: Elimina + edit: Edita + on_or_after: "%{resource} el %{date} o després" + re_apply_rule: Torna a aplicar la regla + then: ALESHORES + update: + success: Regla actualitzada diff --git a/config/locales/views/rules/hu.yml b/config/locales/views/rules/hu.yml index 77d716338..23d879ab2 100644 --- a/config/locales/views/rules/hu.yml +++ b/config/locales/views/rules/hu.yml @@ -3,6 +3,53 @@ hu: rules: no_action: Nincs művelet no_condition: Nincs feltétel + rule: + edit: Szerkesztés + re_apply_rule: Szabály újraalkalmazása + delete: Törlés + then: AKKOR + and_more_conditions: + one: és 1 további feltétel + other: és %{count} további feltétel + and_more_actions: + one: és 1 további művelet + other: és %{count} további művelet + action_label_to: "%{label} erre: %{value}" + all_past_and_future: Összes korábbi és jövőbeli %{resource} + on_or_after: "%{resource} %{date} napon vagy azt követően" + form: + rule_name_label: Szabály neve (nem kötelező) + rule_name_placeholder: Add meg a szabály nevét + add_condition: Feltétel hozzáadása + add_condition_group: Feltételcsoport hozzáadása + add_action: Művelet hozzáadása + all_past_and_future: Összes korábbi és jövőbeli %{resource} + starting_from: Kezdve + then: AKKOR + index: + page_title: Szabályok + delete_all_rules: Összes szabály törlése + new_rule: Új szabály + ai_cost_warning: Az AI-t igénybe vevő szabályakciók pénzbe kerülnek. Szűrj minél szűkebbre a felesleges költségek elkerülése érdekében. + rules_heading: Szabályok + sort_by: "Rendezés:" + sort_name: Név szerint + sort_updated_at: Módosítás dátuma szerint + toggle_sort_direction: Rendezési irány váltása + no_rules_title: Még nincsenek szabályok + no_rules_description: Állíts be szabályokat, amelyek minden fiókszinkronizáláskor automatikusan elvégzik a megadott műveleteket a tranzakciókon és egyéb adatokon. + confirm: + title: Változtatások megerősítése + title_with_name: "Változtatások megerősítése: \"%{name}\"" + apply_notice_html: "Ezzel a szabályt %{count} %{resource} elemre alkalmazod, amelyek megfelelnek a feltételeknek. Kérjük, erősítsd meg, ha folytatni szeretnéd." + ai_cost_title: AI-költség becslése + ai_cost_with_estimate_html: "Ez AI segítségével kategorizál %{count} tranzakciót. Becsült költség: ~$%{cost}" + ai_cost_no_estimate_html: "Ez AI segítségével kategorizál %{count} tranzakciót." + cost_unavailable_model: "A(z) \"%{model}\" modellhez nem érhető el költségbecslés." + cost_unavailable_no_provider: A költségbecslés nem érhető el (nincs LLM-szolgáltató beállítva). + cost_warning: Költségek merülhetnek fel – a legfrissebb árakért ellenőrizd a modellszolgáltatónál. + view_usage_history: Felhasználási előzmények megtekintése + confirm_changes: Változtatások megerősítése actions: value_placeholder: Adj meg egy értéket apply_all: @@ -18,6 +65,12 @@ hu: cost_unavailable_no_provider: A költségbecslés nem érhető el (nincs LLM-szolgáltató beállítva). cost_warning: Költségek merülhetnek fel – a legfrissebb árakért ellenőrizd a modellszolgáltatónál. view_usage: Felhasználási előzmények megtekintése + update: + success: Szabály frissítve + destroy: + success: Szabály törölve + destroy_all: + success: Összes szabály törölve recent_runs: title: Legutóbbi futtatások description: Tekintsd meg a szabályok végrehajtási előzményeit, beleértve a sikeres/sikertelen állapotot és a tranzakciók számát. @@ -31,6 +84,7 @@ hu: queued: Sorban álló processed: Feldolgozott modified: Módosított + blocked: Blokkolt execution_types: manual: Manuális scheduled: Ütemezett @@ -50,3 +104,12 @@ hu: expense: Kiadás transfer: Átutalás equal_to: Egyenlő + rule: + conditions: + condition_group: + and_prefix: és + match: egyezik + all: összes + any: bármelyik + of_the_following_conditions: a következő feltételek közül + add_condition: Feltétel hozzáadása diff --git a/config/locales/views/securities/ca.yml b/config/locales/views/securities/ca.yml new file mode 100644 index 000000000..629d44140 --- /dev/null +++ b/config/locales/views/securities/ca.yml @@ -0,0 +1,14 @@ +--- +ca: + securities: + combobox: + display: "%{symbol} - %{name} (%{exchange})" + exchange_label: "%{symbol} (%{exchange})" + providers: + alpha_vantage: Alpha Vantage + binance_public: Binance + eodhd: EODHD + mfapi: MFAPI.in + tiingo: Tiingo + twelve_data: Twelve Data + yahoo_finance: Yahoo Finance diff --git a/config/locales/views/sessions/ca.yml b/config/locales/views/sessions/ca.yml index 8e87f4b4a..21a73cee8 100644 --- a/config/locales/views/sessions/ca.yml +++ b/config/locales/views/sessions/ca.yml @@ -3,34 +3,39 @@ ca: sessions: create: invalid_credentials: Correu electrònic o contrasenya incorrectes. - local_login_disabled: L'inici de sessió amb contrasenya local està inhabilitat. Utilitza l'inici de sessió únic. + local_login_disabled: L'inici de sessió amb contrasenya local està desactivat. + Utilitza l'inici de sessió únic. destroy: logout_successful: Has tancat la sessió correctament. failure: failed: No s'ha pogut autenticar. sso_failed: L'autenticació d'inici de sessió únic ha fallat. Torna-ho a provar. - sso_invalid_response: S'ha rebut una resposta invàlida del proveïdor SSO. Torna-ho + sso_invalid_response: S'ha rebut una resposta no vàlida del proveïdor SSO. Torna-ho a provar. - sso_provider_unavailable: El proveïdor SSO actualment no està disponible. Torna-ho + sso_provider_unavailable: El proveïdor SSO no està disponible actualment. Torna-ho a provar més tard o contacta amb un administrador. + mobile_sso_start: + redirecting_html: Redirigint a l'inici de sessió... Fes clic + aquí si no se't redirigeix. new: - demo_banner_message: Aquest és un entorn de demostració. Les credencials d'inici de sessió - s'han omplert automàticament per teva comoditat. No introduïis informació real o sensible. - demo_banner_title: Mode Demo Actiu + demo_banner_message: Aquest és un entorn de demostració. Les credencials d'inici + de sessió s'han omplert per comoditat. No introdueixis informació real o sensible. + demo_banner_title: Mode demostració actiu email: Correu electrònic email_placeholder: tu@exemple.com forgot_password: Has oblidat la contrasenya? google_auth_connect: Inicia sessió amb Google local_login_admin_only: L'inici de sessió local està restringit als administradors. - no_auth_methods_enabled: Actualment no hi ha cap mètode d'autenticació habilitat. Contacta - amb un administrador. - openid_connect: Inicia sessió amb OpenID Connect + no_auth_methods_enabled: Actualment no hi ha cap mètode d'autenticació habilitat. + Contacta amb un administrador. oidc: Inicia sessió amb OpenID Connect + openid_connect: Inicia sessió amb OpenID Connect password: Contrasenya password_placeholder: Introdueix la teva contrasenya submit: Inicia sessió - title: Inicia sessió al teu compte + title: Sure openid_connect: + account_linked: Compte enllaçat correctament a %{provider} failed: No s'ha pogut autenticar mitjançant OpenID Connect. post_logout: logout_successful: Has tancat la sessió correctament. diff --git a/config/locales/views/sessions/hu.yml b/config/locales/views/sessions/hu.yml index bc811fcce..c1578339f 100644 --- a/config/locales/views/sessions/hu.yml +++ b/config/locales/views/sessions/hu.yml @@ -16,6 +16,8 @@ hu: sso_provider_unavailable: "Az egyszeri bejelentkezés szolgáltatója jelenleg nem elérhető. Kérjük, próbáld újra később, vagy lépj kapcsolatba egy rendszergazdával." sso_invalid_response: "Érvénytelen választ kaptunk az egyszeri bejelentkezés szolgáltatójától. Kérjük, próbáld újra." sso_failed: "Az egyszeri bejelentkezés sikertelen volt. Kérjük, próbáld újra." + mobile_sso_start: + redirecting_html: "Átirányítás bejelentkezéshez... Kattints ide, ha nincs átirányítás." new: email: E-mail cím email_placeholder: te@pelda.hu diff --git a/config/locales/views/settings/api_keys/ca.yml b/config/locales/views/settings/api_keys/ca.yml index f61afb43b..1082e9419 100644 --- a/config/locales/views/settings/api_keys/ca.yml +++ b/config/locales/views/settings/api_keys/ca.yml @@ -2,114 +2,130 @@ ca: settings: api_keys: + create: + success: La teva clau API s'ha creat correctament created: continue: Continua a la configuració de claus API copy_key: Copia la clau API + copy_store_securely: Copia i desa aquesta clau de manera segura. La necessitaràs + per autenticar les peticions a l'API. + created_label: 'Creada:' critical_warning_1: Aquesta és l'única vegada que veuràs la teva clau API en text pla. critical_warning_2: Copia-la i desa-la de manera segura al teu gestor de contrasenyes o aplicació. - critical_warning_3: Si perds aquesta clau, hauràs de crear-ne una de nova. - critical_warning_title: "⚠️ Crític: Desa la teva clau API ara" + critical_warning_3: Si perds aquesta clau, n'hauràs de crear una de nova. + critical_warning_title: 'Crític: desa ara la teva clau API' + key_details_title: Detalls de la clau key_name: Nom + key_name_label: 'Nom:' + key_ready: La teva nova clau API "%{name}" s'ha creat i està a punt per utilitzar. + page_title: Clau API creada permissions: Permisos - success_description: La teva nova clau API està llesta per utilitzar. Assegura't - de copiar-la ara, ja que no la podràs tornar a veure. + permissions_label: 'Permisos:' + security_note_body: Aquesta és l'única vegada que es mostrarà la teva clau + API. Assegura't de copiar-la ara i desar-la de manera segura. Si perds aquesta + clau, n'hauràs de generar una de nova. + security_note_title: Nota de seguretat important + success_description: La teva nova clau API s'ha generat correctament. success_title: Clau API creada correctament title: Clau API creada usage_instructions: 'Utilitza la teva clau API incloent-la a la capçalera X-Api-Key:' - usage_instructions_title: Guia ràpida - your_api_key: La teva clau API - current_api_key: - active: Activa - ago: fa - created_at: Creat - description: La teva clau API activa està llesta per utilitzar. Mantén-la - segura i no la comparteixis mai públicament. - expires: Caduca - key_name: Nom - last_used: Últim ús - never_expires: No caduca mai - never_used: Mai utilitzada - permissions: Permisos - regenerate_key: Crea nova clau - revoke_confirmation: Segur que vols revocar aquesta clau API? Aquesta acció - no es pot desfer i desactivarà immediatament totes les aplicacions que utilitzin - aquesta clau. - revoke_key: Revoca clau - title: La teva clau API - usage_instructions: 'Inclou la teva clau API a la capçalera X-Api-Key quan - facis peticions a l''API de Maybe:' usage_instructions_title: Com utilitzar la teva clau API + your_api_key: La teva clau API + destroy: + cannot_revoke: Aquesta clau API no es pot revocar + not_found: Clau API no trobada + revoke_failed: No s'ha pogut revocar la clau API + revoked_successfully: La clau API s'ha revocat correctament new: cancel: Cancel·la create_key: Crea clau API - create_new_key: Crea nova clau API + create_new_api_key: Crea una nova clau API description: Configura la teva nova clau API amb un nom descriptiu i els permisos adequats. - name_help: Tria un nom descriptiu per identificar la finalitat d'aquesta clau. + name_help: Tria un nom descriptiu per ajudar-te a identificar la finalitat + d'aquesta clau. + name_help_text: Tria un nom descriptiu per ajudar-te a identificar aquesta + clau més endavant. name_label: Nom de la clau API - name_placeholder: p. ex., App Producció, Tauler d'Anàlisi - permissions_help: Selecciona els permisos que necessita la teva clau API. - Sempre pots crear una nova clau amb permisos diferents. + name_placeholder: p. ex., La meva app de pressupost, Seguidor de cartera + permissions_help: 'Selecciona els permisos que ha de tenir aquesta clau API:' permissions_label: Permisos + save_api_key: Desa la clau API scope_details: - read_accounts: Veure informació de compte, saldos i dades a nivell de compte - read_balances: Veure dades històriques de saldo i tendències de valor de + read_accounts: Veure informació del compte, saldos i dades a nivell de compte + read_balances: Veure dades històriques de saldos i tendències de valor del compte read_transactions: Veure dades de transaccions, categories i detalls de transaccions - write_transactions: Crear i actualitzar registres de transaccions (pròximament) - security_warning: La teva clau API només es mostrarà una vegada després de - la creació. Desa-la de manera segura i no la comparteixis mai públicament. - Si la perds, hauràs de crear-ne una de nova. - security_warning_title: Avís de seguretat important + write_transactions: Crear i actualitzar registres de transaccions (properament) + scope_read_only: Només lectura + scope_read_only_description: Veure els teus comptes, transaccions i saldos + scope_read_write: Lectura/Escriptura + scope_read_write_description: Veure les teves dades i crear noves transaccions + security_warning: La teva clau API només es mostrarà un cop després de la + creació. Desa-la de manera segura i no la comparteixis mai públicament. + Si la perds, n'hauràs de crear una de nova. + security_warning_body: La teva clau API només es mostrarà un cop després de + la creació. Assegura't de copiar-la i desar-la de manera segura. Qualsevol + persona amb accés a aquesta clau podrà accedir a les teves dades segons + els permisos que seleccionis. + security_warning_title: Avís de seguretat + subtitle: Genera una nova clau API per accedir a les teves dades de Sure de + manera programàtica. title: Crea clau API - no_api_key: - create_api_key: Crea clau API - description: Obtingues accés programàtic a les teves dades de Maybe amb una - clau API segura. - feature_1: Accedeix a les teves dades de compte programàticament - feature_2: Construeix integracions i aplicacions personalitzades - feature_3: Automatitza la recuperació i anàlisi de dades - security_note: La teva clau API tindrà permisos restringits segons els àmbits - seleccionats. Només pots tenir una clau API activa alhora. - security_note_title: Seguretat primer - title: Clau API - what_you_can_do: 'Què pots fer amb l''API:' show: current_api_key: - active: Actiu + active: Activa ago: fa - created_at: Creat - description: La teva clau API activa està llesta per utilitzar. Mantén-la + copy_api_key: Copia la clau API + copy_store_securely: Copia i desa aquesta clau de manera segura. La necessitaràs + per autenticar les peticions a l'API. + created_ago: Creada fa %{time} + created_at: Creada + description: La teva clau API activa està a punt per utilitzar. Mantén-la segura i no la comparteixis mai públicament. expires: Caduca key_name: Nom last_used: Últim ús + last_used_ago: Última utilització fa %{time} never_expires: No caduca mai never_used: Mai utilitzada permissions: Permisos - regenerate_key: Crea nova clau + regenerate_key: Crea una nova clau revoke_confirmation: Segur que vols revocar aquesta clau API? Aquesta acció - no es pot desfer i desactivarà immediatament totes les aplicacions que utilitzin - aquesta clau. - revoke_key: Revoca clau + no es pot desfer i desactivarà immediatament totes les aplicacions que + utilitzin aquesta clau. + revoke_key: Revoca la clau + scope_read_only: Només lectura + scope_read_write: Lectura/Escriptura title: La teva clau API usage_instructions: 'Inclou la teva clau API a la capçalera X-Api-Key quan - facis peticions a l''API de Maybe:' + facis peticions a l''API de %{product_name}:' usage_instructions_title: Com utilitzar la teva clau API + newly_created: + continue: Continua a la configuració de claus API + copy_api_key: Copia la clau API + copy_store_securely: Copia i desa aquesta clau de manera segura. La necessitaràs + per autenticar les peticions a l'API. + heading: Clau API creada correctament + how_to_use: Com utilitzar la teva clau API + key_ready: La teva nova clau API "%{name}" s'ha creat i està a punt per + utilitzar. + page_title: Clau API creada correctament + your_api_key: La teva clau API no_api_key: create_api_key: Crea clau API - description: Obtingues accés programàtic a les teves dades de Maybe amb una - clau API segura. - feature_1: Accedeix a les teves dades de compte programàticament + description: Obtén accés programàtic a les teves dades de Sure amb una clau + API segura. + feature_1: Accedeix a les dades del teu compte de manera programàtica feature_2: Construeix integracions i aplicacions personalitzades feature_3: Automatitza la recuperació i anàlisi de dades - heading: Accedeix a les teves dades de compte programàticament + heading: Accedeix a les dades del teu compte de manera programàtica security_note: La teva clau API tindrà permisos restringits segons els àmbits - seleccionats. Només pots tenir una clau API activa alhora. + que seleccionis. Només pots tenir una clau API activa alhora. security_note_title: Seguretat primer title: Clau API what_you_can_do: 'Què pots fer amb l''API:' diff --git a/config/locales/views/settings/api_keys/hu.yml b/config/locales/views/settings/api_keys/hu.yml index a0b601b92..ad0df2325 100644 --- a/config/locales/views/settings/api_keys/hu.yml +++ b/config/locales/views/settings/api_keys/hu.yml @@ -11,6 +11,13 @@ hu: read_balances: "Egyenlegek megtekintése" write_transactions: "Tranzakciók létrehozása" api_keys: + create: + success: "Az API-kulcsod sikeresen létrehozva" + destroy: + not_found: "Az API-kulcs nem található" + cannot_revoke: "Ez az API-kulcs nem vonható vissza" + revoked_successfully: "Az API-kulcs sikeresen visszavonva" + revoke_failed: "Nem sikerült visszavonni az API-kulcsot" show: title: "API-kulcs kezelése" no_api_key: @@ -24,18 +31,33 @@ hu: security_note_title: "Biztonság az első" security_note: "Az API-kulcsodnak korlátozott jogosultságai lesznek a kiválasztott hatókörök alapján. Egyszerre csak egy aktív API-kulcsod lehet." create_api_key: "API-kulcs létrehozása" + newly_created: + page_title: "API-kulcs sikeresen létrehozva" + heading: "API-kulcs sikeresen létrehozva!" + key_ready: "Az új \"%{name}\" API-kulcsod létrehozva és készen áll a használatra." + your_api_key: "Az API-kulcsod" + copy_store_securely: "Másold le és tárold biztonságosan. Szükséged lesz rá az API-kérések hitelesítéséhez." + copy_api_key: "API-kulcs másolása" + how_to_use: "Az API-kulcs használata" + continue: "Tovább az API-kulcs beállításaihoz" current_api_key: title: "Az API-kulcsod" description: "Az aktív API-kulcsod készen áll a használatra. Tartsd biztonságban, és soha ne oszd meg nyilvánosan." active: "Aktív" key_name: "Név" created_at: "Létrehozva" + created_ago: "Létrehozva %{time} ezelőtt" last_used: "Utoljára használva" + last_used_ago: "Utoljára használva %{time} ezelőtt" expires: "Lejár" ago: "ezelőtt" never_used: "Még nem használt" never_expires: "Nem jár le" permissions: "Jogosultságok" + scope_read_only: "Csak olvasható" + scope_read_write: "Olvasás/Írás" + copy_api_key: "API-kulcs másolása" + copy_store_securely: "Másold le és tárold biztonságosan. Szükséged lesz rá az API-kérések hitelesítéséhez." usage_instructions_title: "Az API-kulcs használata" usage_instructions: "Add meg az API-kulcsodat az X-Api-Key fejlécben, amikor kéréseket küldesz a(z) %{product_name} API-nak:" regenerate_key: "Új kulcs létrehozása" @@ -43,34 +65,52 @@ hu: revoke_confirmation: "Biztosan vissza szeretnéd vonni ezt az API-kulcsot? Ez a művelet nem vonható vissza, és azonnal letiltja az összes ezt a kulcsot használó alkalmazást." new: title: "API-kulcs létrehozása" - create_new_key: "Új API-kulcs létrehozása" + create_new_api_key: "Új API-kulcs létrehozása" + subtitle: "Generálj új API-kulcsot a Sure-adataid programozható eléréséhez." description: "Konfiguráld az új API-kulcsodat leíró névvel és megfelelő jogosultságokkal." name_label: "API-kulcs neve" name_placeholder: "pl.: Éles alkalmazás, Elemzési irányítópult" + name_help_text: "Válassz leíró nevet, amely segít azonosítani a kulcsot." name_help: "Válassz leíró nevet, amely segít azonosítani a kulcs célját." permissions_label: "Jogosultságok" - permissions_help: "Válaszd ki az API-kulcsod számára szükséges jogosultságokat. Bármikor létrehozhatsz új kulcsot eltérő jogosultságokkal." + permissions_help: "Válaszd ki az API-kulcsod számára szükséges jogosultságokat:" + scope_read_only: "Csak olvasható" + scope_read_only_description: "Fiókok, tranzakciók és egyenlegek megtekintése" + scope_read_write: "Olvasás/Írás" + scope_read_write_description: "Adatok megtekintése és új tranzakciók létrehozása" scope_details: read_accounts: "Fiókinformációk, egyenlegek és fiókszintű adatok megtekintése" read_transactions: "Tranzakciós adatok, kategóriák és tranzakciós részletek megtekintése" read_balances: "Korábbi egyenlegadatok és fiókérték-trendek megtekintése" write_transactions: "Tranzakciók létrehozása és frissítése (hamarosan)" - security_warning_title: "Fontos biztonsági figyelmeztetés" + security_warning_title: "Biztonsági figyelmeztetés" + security_warning_body: "Az API-kulcsod csak egyszer jelenik meg a létrehozás után. Győződj meg róla, hogy lemásolod és biztonságosan tárolod. Bárki, aki hozzáfér ehhez a kulcshoz, a kiválasztott jogosultságoknak megfelelően hozzáférhet az adataidhoz." security_warning: "Az API-kulcsod csak egyszer jelenik meg a létrehozás után. Tárold biztonságosan, és soha ne oszd meg nyilvánosan. Ha elveszíted, új kulcsot kell létrehoznod." create_key: "API-kulcs létrehozása" cancel: "Mégse" + save_api_key: "API-kulcs mentése" created: + page_title: "API-kulcs létrehozva" title: "API-kulcs létrehozva" success_title: "API-kulcs sikeresen létrehozva" - success_description: "Az új API-kulcsod készen áll a használatra. Feltétlenül másold le most, mert többé nem fogod látni." + success_description: "Az új API-kulcsod sikeresen generálva." + key_ready: "Az új \"%{name}\" API-kulcsod létrehozva és készen áll a használatra." your_api_key: "Az API-kulcsod" + copy_store_securely: "Másold le és tárold biztonságosan. Szükséged lesz rá az API-kérések hitelesítéséhez." + key_details_title: "Kulcs adatai" + key_name_label: "Név:" + permissions_label: "Jogosultságok:" + created_label: "Létrehozva:" + security_note_title: "Fontos biztonsági megjegyzés" + security_note_body: "Ez az egyetlen alkalom, amikor az API-kulcsod megjelenik. Mindenképpen másold le most és tárold biztonságosan. Ha elveszíted, újat kell generálnod." + usage_instructions_title: "Az API-kulcs használata" key_name: "Név" permissions: "Jogosultságok" critical_warning_title: "⚠️ Kritikus: Mentsd el az API-kulcsodat most" critical_warning_1: "Ez az egyetlen alkalom, amikor az API-kulcsod egyszerű szövegként látható." critical_warning_2: "Másold le és tárold biztonságosan a jelszókezelődben vagy az alkalmazásodban." critical_warning_3: "Ha elveszíted ezt a kulcsot, újat kell létrehoznod." - usage_instructions_title: "Gyors kezdés" + usage_instructions_title: "Az API-kulcs használata" usage_instructions: "Használd az API-kulcsodat az X-Api-Key fejlécbe illesztve:" copy_key: "API-kulcs másolása" continue: "Tovább az API-kulcs beállításaihoz" diff --git a/config/locales/views/settings/ca.yml b/config/locales/views/settings/ca.yml index 5d43209eb..9df987673 100644 --- a/config/locales/views/settings/ca.yml +++ b/config/locales/views/settings/ca.yml @@ -1,9 +1,5 @@ --- ca: - views: - settings: - payments: - renewal: "La teva contribució continua el %{date}." settings: ai_prompts: show: @@ -23,18 +19,125 @@ ca: subtitle: La IA categoritza automàticament les teves transaccions segons les categories definides title: Categoritzador de transaccions - payments: + appearances: show: - page_title: Pagament - subscription_subtitle: Actualitza la teva subscripció i dades de pagament - subscription_title: Gestiona la subscripció + dashboard_subtitle: Personalitza com es mostra el tauler de control + dashboard_title: Tauler de control + dashboard_two_column_description: Mostra els ginys del tauler en dues columnes + en pantalles grans. Si està desactivat, els ginys s'apilen en una sola columna. + dashboard_two_column_title: Disseny a dues columnes + page_title: Aparença + split_grouped_description: Mostra les transaccions dividides agrupades sota + la seva matriu a la llista de transaccions. Si està desactivat, els fills + apareixen com a files individuals. + split_grouped_title: Agrupa les transaccions dividides + theme_dark: Fosc + theme_light: Clar + theme_subtitle: Tria el tema preferit per a l'aplicació + theme_system: Sistema + theme_title: Tema + transactions_subtitle: Personalitza com es mostren les transaccions + transactions_title: Transaccions + debugs: + show: + context: + account: account=%{value} + account_provider: account_provider=%{value} + family: family=%{value} + provider: provider=%{value} + user: user=%{value} + empty: No s'han trobat esdeveniments de depuració. + filters: + account_id: ID del compte + account_provider_id: ID del proveïdor del compte + all: Tots + category: Categoria + end_date: Fins + family_id: ID de la família + level: Nivell + provider: Proveïdor + reset: Restableix + source: Origen + start_date: Des de + submit: Filtra + user_id: ID de l'usuari + missing_value: "-" + page_title: Depuració + subtitle: Esdeveniments operatius rellevants per a superadministradors. Els + més nous primer. + table: + category: Categoria + context: Context + level: Nivell + message: Missatge + metadata: Metadades + source: Origen + time: Hora + view_metadata: Veure + title: Registre d'esdeveniments de depuració hostings: ensure_admin: not_authorized: No autoritzat + llm_usages: + show: + avg_cost_per_request: Cost mitjà/sol·licitud + based_on_requests: Basat en %{with_cost} de %{total} sol·licituds amb dades + de cost + col_cost: Cost + col_date: Data + col_model: Model + col_operation: Operació + col_tokens: Tokens + completion: completació + cost_by_model: Cost per model + cost_by_operation: Cost per operació + cost_estimates_description: Els costos s'estimen segons els preus d'OpenAI + de 2025. Els costos reals poden variar. El preu és per cada milió de tokens + i varia segons el model. Els models personalitzats o amb self hosting mostraran + "N/D" i no s'inclouen als totals de cost. + cost_estimates_title: Sobre les estimacions de cost + end_date: Data de fi + failed: Errades + filter: Filtra + no_usage_data: No s'han trobat dades d'ús per al període seleccionat + page_title: Ús i costos d'LLM + prompt: prompt + recent_usage: Ús recent + start_date: Data d'inici + subtitle: Fes el seguiment del teu ús d'IA i els costos estimats + total_cost: Cost total + total_requests: Total de sol·licituds + total_tokens: Total de tokens + payments: + show: + choose_level: Tria un nivell + contributions_note: Les contribucions a %{product_name} apareixeran aquí. + currently_on_plan: 'Actualment al pla:' + manage: Gestiona + not_contributing_emphasis: no contribueixes + not_contributing_prefix: Actualment + page_title: Pagaments + payment_via_stripe: Pagament a través de Stripe + subscription_subtitle: Actualitza les teves dades de targeta de crèdit + subscription_title: Gestiona contribucions + trial_days_left: + one: Les dades s'eliminaran en %{count} dia + other: Les dades s'eliminaran en %{count} dies + trialing: Actualment fas servir la demostració oberta de %{product_name} preferences: show: + additional_currencies_label: Divises addicionals + base_currency_badge: Divisa base + base_currency_label: Divisa base + preview: + description: Activa funcions en desenvolupament etiquetades com a experimentals o canary. + title: Activa funcions experimentals country: País - currency: Moneda + currencies_more: "+%{count} més" + currencies_subtitle: Tria quines divises apareixen als camps de diners + currencies_title: Divises + currency: Divisa + currency_search_placeholder: Cerca divises date_format: Format de data default_account_order: Ordre de comptes per defecte default_period: Període per defecte @@ -42,12 +145,30 @@ ca: general_title: General language: Idioma language_auto: Idioma del navegador + manage_currencies: Gestiona divises + manage_currencies_subtitle: Desmarca les divises que mai utilitzes, o redueix + la llista a unes poques. + month_start_day: El mes del pressupost comença el + month_start_day_hint: Estableix quan comença el teu mes pressupostari (p. + ex., dia de cobrament) + month_start_day_warning: Els teus pressupostos i càlculs MTD utilitzaran aquest + dia d'inici personalitzat en lloc del dia 1 de cada mes. + translations_notice: Tingues en compte que encara estem treballant en les traduccions + a diversos idiomes. + no_additional_currencies: Cap seleccionada + no_matching_currencies: No s'han trobat divises page_title: Preferències - theme_dark: Fosc - theme_light: Clar - theme_subtitle: Tria el tema preferit per a l'aplicació - theme_system: Sistema - theme_title: Tema + save_currencies: Desa les divises + select_all_currencies: Selecciona-ho tot + select_base_only: Només la divisa base + selected_currencies_count: + one: "%{count} seleccionada" + other: "%{count} seleccionades" + sharing_default_label: Compartició predeterminada per a comptes nous + sharing_private: Mantén privat per defecte + sharing_shared: Comparteix amb tots els membres + sharing_subtitle: Controla com es comparteixen els comptes entre els membres + sharing_title: Compartició de comptes timezone: Fus horari profiles: destroy: @@ -82,10 +203,13 @@ ca: les teves dades i no es podrà desfer. email: Correu electrònic first_name: Nom + group_form_input_placeholder: Introdueix el nom del grup + group_form_label: Nom del grup + group_title: Membres del grup household_form_input_placeholder: Introdueix el nom de la llar household_form_label: Nom de la llar - household_subtitle: Convida membres de la família, parelles i altres persones. - Els convidats podran accedir al teu compte familiar i als comptes compartits. + household_subtitle: Els convidats poden iniciar sessió al teu compte de %{moniker} + i accedir als recursos compartits. household_title: Llar invitation_link: Enllaç d'invitació invite_member: Afegeix membre @@ -103,49 +227,346 @@ ca: reset_account_with_sample_data_warning: Elimina totes les teves dades existents i carrega dades d'exemple per explorar amb un entorn preomplert. save: Desa + providers: + bank_sync: + lede: Connecta comptes externs perquè transaccions, saldos i posicions flueixin + automàticament a Sure. + page_title: Sincronització bancària + binance_panel: + api_key_label: Clau API + api_key_placeholder: Enganxa la teva clau API de Binance + api_secret_label: Secret de l'API + api_secret_placeholder: Enganxa el teu secret de l'API de Binance + connect_button: Connecta Binance + disconnect_confirm: Segur que vols desconnectar Binance? + ip_hint_body: 'Afegeix la IP de sortida del servidor de l''aplicació a la + llista blanca de la clau API de Binance:' + ip_hint_contact_admin: Contacta amb el teu administrador per obtenir la IP + de sortida del servidor de l'aplicació. + ip_hint_title: Cal incloure la IP a la llista blanca + no_withdraw_body: No activis permisos de retirada en crear la teva clau API + de Binance. Sure només necessita accés de lectura. + no_withdraw_title: Només clau de lectura + setup_instructions: 'Per connectar Binance, crea una clau API de només lectura:' + step1_html: Ves a Binance API + Management + step2: Crea una nova clau API només amb el permís Enable Reading + step3: Enganxa la teva clau API i secret a sota + sync: Sincronitza + syncing: Sincronitzant... + clear_filter: Neteja filtres + coinbase_panel: + api_key_label: Clau API + api_key_placeholder: Introdueix la teva clau API de Coinbase + api_secret_label: Secret de l'API + api_secret_placeholder: Introdueix el teu secret de l'API de Coinbase + connect_button: Connecta Coinbase + disconnect_confirm: Segur que vols desconnectar aquesta connexió de Coinbase? + Els teus comptes sincronitzats passaran a ser comptes manuals. + setup_instructions: 'Per connectar Coinbase:' + step1_html: Ves a Coinbase + API Settings + step2: Crea una nova clau API amb permisos de només lectura (veure comptes, + veure transaccions) + step3: Copia la teva clau API i secret de l'API i enganxa'ls a sota + sync: Sincronitza + syncing: Sincronitzant... + connect: Connecta + drawer_trust_statement: Accés només de lectura. Sure mai no pot moure diners + i les teves credencials s'emmagatzemen xifrades. + empty_filter: Cap proveïdor coincideix amb el teu filtre. + enable_banking_panel: + add_connection: Afegeix connexió + application_id_label: ID d'aplicació + application_id_placeholder_new: Introdueix l'ID d'aplicació + application_id_placeholder_update: Introdueix el nou ID per actualitzar + callback_url_instruction: Per a l'URL de retorn de trucada, fes servir %{callback_url}. + client_certificate_label: Certificat de client (amb clau privada) + config_locked_message: Desconnecta tots els bancs vinculats abans de canviar + aquestes credencials. + config_locked_title: Configuració bloquejada + configured: Configurat + connect_bank: Connecta banc + connected_bank: Banc connectat + connection: Connexió + connection_error: Error de connexió + country_label: País + ready_to_link: Llest per enllaçar comptes + reconnect: Reconnecta + remove: Elimina + remove_confirm: Segur que vols eliminar aquesta connexió? + save_and_connect: Desa i connecta + select_country: Selecciona país... + session_expired_reconnect: Sessió expirada — reconnecta + session_expires: 'La sessió expira: %{date}' + step_1_html: Ves a %{link} i obtén les teves credencials de desenvolupador. + step_2: Tria el teu país i enganxa l'ID d'aplicació + certificat de client + a sota. + step_3: Desa, després utilitza Afegeix connexió per enllaçar el teu banc. + sync: Sincronitza + syncing: Sincronitzant + unknown: Desconegut + update_connection: Actualitza connexió + encryption_error: + message: La sincronització bancària requereix Active Record encryption configurat. + Estableix primary_key, deterministic_key i key_derivation_salt a les teves + credencials de Rails o variables d'entorn. + title: Falten les claus de xifratge + groups: + available: Disponibles + empty_available: Tots els proveïdors disponibles estan connectats. + your_connections: Les teves connexions + health_strip: + accounts_syncing: comptes sincronitzant-se + connected: connectats + last_synced: Última sincronització fa %{time} + needs_attention: necessita atenció + ibkr_panel: + accounts_tab: Comptes + configuration: + all_other_options: 'Tota la resta d''opcions de configuració: "No"' + date_format: 'Format de data: yyyy-MM-dd' + date_time_separator: 'Separador de data/hora: ; (punt i coma)' + format: 'Format: XML' + models: 'Models: Opcional' + period: 'Període: Últims 365 dies naturals' + profit_and_loss: 'Pèrdues i guanys: Per defecte' + time_format: 'Format d''hora: HH:mm:ss' + disconnect_confirm: Vols desconnectar Interactive Brokers? + flex_query_details: + configuration_heading: Estableix aquestes opcions de consulta + eyebrow: Flex Query + sections_heading: Activa aquestes seccions i camps + summary: Expandeix per veure les seccions, camps i configuració exactes + que ha d'incloure la teva Flex Query d'activitat d'IBKR. + title: Seccions, camps i configuració + not_configured: No configurat. + query_id_label: ID de consulta + query_id_placeholder_existing: Deixa en blanc per mantenir l'ID actual + query_id_placeholder_new: Introdueix el teu ID de Flex Query d'IBKR + report_window_note: Els informes Flex d'IBKR estan limitats a la finestra + de consulta configurada a IBKR. Sure importarà les posicions actuals completes + més fins a 365 dies d'activitat d'aquest informe. + save_configuration: Desa la configuració + sections: + account_information: 'Account Information: Account ID, Currency' + cash_report: 'Cash Report:' + cash_report_fields: 'Fields: Currency, Ending Cash' + cash_report_options: 'Options: None' + cash_transactions: 'Cash Transactions:' + cash_transactions_fields: 'Fields: Amount, Conid, Currency, FX Rate To Base, + Report Date, Transaction ID, Type' + cash_transactions_options: 'Options: Dividends, Deposits & Withdrawals, + Detail' + change_in_position_value_summary: 'Change In Position Value Summary: Currency, + End Of Period Value' + net_asset_value: 'Net Asset Value (NAV) in Base:' + net_asset_value_fields: 'Fields: Currency, Report Date, Total' + net_asset_value_options: 'Options: None' + open_positions: 'Open Positions:' + open_positions_fields: 'Fields: Asset Class, Conid, Cost Basis Price, Currency, + FX Rate To Base, Mark Price, Quantity, Report Date, Security ID, Security + ID Type, Side, Symbol' + open_positions_options: 'Options: Summary' + trades: 'Trades:' + trades_fields: 'Fields: Asset Class, Buy/Sell, Conid, Currency, FX Rate + To Base, IB Commission, IB Commission Currency, Quantity, Symbol, Trade + Date, Trade ID, TradePrice, Transaction ID' + trades_options: 'Options: Execution' + status_configured_prefix: "%{summary}. Visita la" + status_configured_suffix: pestanya per gestionar els comptes descoberts. + steps: + step_1: Al teu IBKR Client Portal, navega a "Performance & Reports" > "Flex + Queries". + step_2: Fes clic a la icona "+" a la secció "Activity Flex Query" per crear + una nova consulta. + step_3: Anomena la teva consulta (p. ex., "Sure Sync"), després revisa els + detalls de la Flex Query a sota i activa les seccions, camps i opcions + de configuració llistades. + step_4: Desa la consulta, anota el teu "Query ID", després usa la icona + d'engranatge a la secció "Flex Web Service Configuration" per generar + un Token d'accés. + step_5: Enganxa el teu Query ID i Token a sota, desa la configuració, i + ves a Comptes per enllaçar els comptes d'IBKR descoberts. + sync: Sincronitza + token_label: Token + token_placeholder_existing: Deixa en blanc per mantenir el Token actual + token_placeholder_new: Introdueix el teu Token d'IBKR Flex Web Service + update_configuration: Actualitza la configuració + kraken_panel: + add_connection: Afegeix connexió Kraken + api_key_label: Clau API + api_key_placeholder: Enganxa la teva clau API de Kraken + api_secret_label: Clau privada + api_secret_placeholder: Enganxa la teva clau privada de Kraken + connection_name_label: Nom de la connexió + connection_name_placeholder: Kraken principal + default_connection_name: Kraken + disconnect: Desconnecta + disconnect_confirm: Segur que vols desconnectar %{name}? + keep_api_key_placeholder: Deixa en blanc per mantenir la clau API existent + keep_api_secret_placeholder: Deixa en blanc per mantenir la clau privada existent + read_only_body: No atorguis permisos de trading, cancel·lació, retirada, exportació, + llibre major, Earn, staking o transferència. Sure només importa saldos, + posicions i operacions spot. + read_only_title: Sincronització només de lectura amb l'exchange + setup_accounts: Configura compte + step1_html: Ves a Kraken API settings + step2: Crea una clau API només amb Query Funds i Query Closed Orders & Trades. + step3: Enganxa la clau API i la clau privada a sota. + sync: Sincronitza + syncing: Sincronitzant... + update_connection: Actualitza connexió + lunchflow_panel: + api_key_label: Clau API + api_key_placeholder_new: Enganxa la clau API aquí + api_key_placeholder_update: Introdueix la nova clau API per actualitzar + base_url_label: URL base (opcional) + base_url_placeholder: https://lunchflow.app/api/v1 (per defecte) + save_and_connect: Desa i connecta + step_1_html: Ves a %{link} i crea una clau API. + step_2: Enganxa la teva clau a sota i connecta. + step_3: Després ves a Comptes per enllaçar els teus comptes sincronitzats. + update_connection: Actualitza connexió + maturity: + alpha: Alfa + beta: Beta + meta: + last_synced: Sincronitzat fa %{time} + no_recent_sync: Sincronització vençuda + reconsent_needed: + one: Cal renovar el consentiment en 1 dia + other: Cal renovar el consentiment en %{count} dies + reconsent_required: Cal renovar el consentiment + registration_needed: Cal registrar-se + sync_error: Error de sincronització + not_authorized: No autoritzat + not_found: Proveïdor no trobat. + plaid_eu_panel: + step_1_html: Obre el %{link} i copia el teu Client ID i Secret Key d'UE. + plaid_panel: + step_1_html: Obre el %{link} i copia el teu Client ID i Secret Key. + step_2: Tria un entorn. Fes servir sandbox per a proves i production per a + comptes reals. + step_3: Enganxa les teves credencials a sota i connecta. + recently_synced: Sincronitzat recentment. Torna-ho a provar d'aquí a un moment. + search_filters: + aria_label: Cerca proveïdors + chips: + all: Tots + bank: Bancs + crypto: Cripto + investment: Inversions + placeholder: Cerca proveïdors + setup_steps: + eyebrow: Configuració + need_help: Necessites ajuda? + simplefin_panel: + save_and_connect: Desa i connecta + setup_token_label: Token de configuració + setup_token_placeholder: Enganxa el token de configuració de SimpleFIN + step_1_html: Ves a %{link} per obtenir un token d'un sol ús. + step_2: Enganxa el token a sota i connecta. + step_3: Després ves a Comptes per enllaçar els teus comptes sincronitzats. + status: + err: Error + off: No configurat + ok: Connectat + warn: Cal acció + sync_all: Sincronitza-ho tot + sync_all_in_progress: Sincronitzant tots els proveïdors connectats… + sync_all_recently: Sincronització ja en curs. Torna-ho a provar d'aquí a un + moment. + sync_provider: Sincronitza ara + sync_provider_in_progress: Sincronització iniciada. + sync_provider_no_items: No hi ha connexions disponibles per sincronitzar. + taglines: + binance: Sincronitza els teus saldos spot de Binance utilitzant una clau API + de només lectura. + brex: Sincronitza l'activitat d'efectiu i targeta corporativa de Brex amb + accés de només lectura. + coinbase: Importa les teves posicions cripto de Coinbase i fes el seguiment + del rendiment. + coinstats: Fes el seguiment de tota la teva cartera cripto a través de carteres + i exchanges. + enable_banking: Sincronitza comptes bancaris europeus mitjançant l'open banking + PSD2. + ibkr: Sincronitza comptes d'inversió d'Interactive Brokers mitjançant importacions + Flex Query. + indexa_capital: Fes el seguiment de la teva cartera d'inversió automatitzada + d'Indexa Capital. + kraken: Sincronitza saldos i operacions spot de Kraken utilitzant una clau + API de només lectura. + lunchflow: Connecta més de 20.000 bancs de més de 40 països (Regne Unit, UE, + EUA i més!). + mercury: Sincronitza automàticament els teus comptes bancaris empresarials + de Mercury. + plaid: Connecta milers d'institucions financeres dels EUA mitjançant Plaid. + plaid_eu: Connecta institucions financeres europees mitjançant Plaid (PSD2 + / Open Banking). + simplefin: Connecta comptes bancaris dels EUA mitjançant el protocol obert + SimpleFIN. + snaptrade: Connecta comptes d'inversió mitjançant la xarxa d'agregació SnapTrade. + sophtron: Connecta bancs i serveis dels EUA i Canadà. + update: + no_changes: No s'ha fet cap canvi + updated_successfully: Configuració del proveïdor actualitzada correctament securities: show: - page_title: Valor + page_title: Seguretat sso_confirm_body: Segur que vols desconnectar el teu compte de %{provider}? - Pots tornar-lo a connectar més tard iniciant sessió amb aquest proveïdor una altra vegada. + Pots tornar-lo a connectar més tard iniciant sessió amb aquest proveïdor + una altra vegada. sso_confirm_button: Desconnecta sso_confirm_title: Desconnectar compte? - sso_connect_hint: Tanca sessió i inicia amb un proveïdor SSO per connectar un compte. + sso_connect_hint: Tanca sessió i inicia amb un proveïdor SSO per connectar + un compte. sso_disconnect: Desconnecta sso_last_used: Darrer ús sso_never: Mai sso_no_email: Sense correu electrònic sso_no_identities: No hi ha comptes SSO connectats - sso_subtitle: Gestiona les teves connexions de compte amb inici de sessió únic + sso_subtitle: Gestiona les teves connexions de compte amb inici de sessió + únic sso_title: Comptes connectats - sso_warning_message: Aquesta és la teva única mètode d'inici de sessió. Hauries de configurar una contrasenya - a la teva configuració de seguretat abans de desconnectar-te, altrament podries quedar blocat - fora del teu compte. + sso_warning_message: Aquesta és l'única forma d'inici de sessió. Hauries de + configurar una contrasenya a la teva configuració de seguretat abans de + desconnectar, altrament podries quedar bloquejat/da fora del teu compte. settings_nav: accounts_label: Comptes advanced_section_title: Avançat ai_prompts_label: Prompts d'IA api_key_label: Clau API api_keys_label: Clau API + appearance_label: Aparença bank_sync_label: Sincronització bancària - payment_label: Pagament categories_label: Categories + debug_label: Depuració + exports_label: Exportacions feedback_label: Feedback general_section_title: General - imports_label: Importacions - exports_label: Exportacions guides_label: Guies + imports_label: Importacions + llm_usage_label: Ús d'LLM logout: Tanca la sessió merchants_label: Comerços other_section_title: Més + payment_label: Pagament preferences_label: Preferències profile_label: Informació del perfil + providers_label: Proveïdors recurring_transactions_label: Recurrent rules_label: Regles security_label: Seguretat - self_hosting_label: Autoallotjament + self_hosting_label: Self hosting + sso_providers_label: Proveïdors SSO + statement_vault_label: Arxiu d'extractes tags_label: Etiquetes transactions_section_title: Transaccions + users_label: Usuaris whats_new_label: Novetats settings_nav_link_large: next: Següent @@ -153,5 +574,10 @@ ca: user_avatar_field: accepted_formats: JPG o PNG. Màxim 5MB. change: Canvia la foto - choose: Pujar foto + choose: Puja una foto choose_label: "(opcional)" + views: + settings: + payments: + cancellation: La teva contribució finalitza el %{date}. + renewal: La teva contribució continua el %{date}. diff --git a/config/locales/views/settings/en.yml b/config/locales/views/settings/en.yml index 590a4dd6a..e7abc768f 100644 --- a/config/locales/views/settings/en.yml +++ b/config/locales/views/settings/en.yml @@ -6,6 +6,42 @@ en: renewal: "Your contribution continues on %{date}." cancellation: "Your contribution ends on %{date}." settings: + debugs: + show: + page_title: "Debug" + title: "Debug event log" + subtitle: "Meaningful operational events for super admins. Newest first." + empty: "No debug events found." + missing_value: "-" + filters: + all: "All" + category: "Category" + level: "Level" + source: "Source" + provider: "Provider" + start_date: "From" + end_date: "To" + family_id: "Family ID" + account_id: "Account ID" + user_id: "User ID" + account_provider_id: "Account provider ID" + submit: "Filter" + reset: "Reset" + table: + time: "Time" + level: "Level" + category: "Category" + source: "Source" + message: "Message" + context: "Context" + metadata: "Metadata" + view_metadata: "View" + context: + provider: "provider=%{value}" + family: "family=%{value}" + account: "account=%{value}" + user: "user=%{value}" + account_provider: "account_provider=%{value}" llm_usages: show: page_title: "LLM Usage & Costs" @@ -95,6 +131,7 @@ en: month_start_day: Budget month starts on month_start_day_hint: Set when your budget month starts (e.g., payday) month_start_day_warning: Your budgets and MTD calculations will use this custom start day instead of the 1st of each month. + translations_notice: Please note, we are still working on translations for various languages. currencies_title: "%{moniker} Currencies" currencies_subtitle: Choose which currencies appear in money fields for your %{moniker} base_currency_label: Base currency @@ -117,6 +154,9 @@ en: sharing_default_label: Default sharing for new accounts sharing_shared: Share with all members sharing_private: Keep private by default + preview: + title: Enable preview features + description: Opt in to in-progress features tagged preview or canary. profiles: destroy: cannot_remove_self: You cannot remove yourself from the account. @@ -219,6 +259,7 @@ en: api_keys_label: API Key appearance_label: Appearance bank_sync_label: Bank sync + debug_label: Debug settings_nav_link_large: next: Next previous: Back @@ -301,6 +342,8 @@ en: encryption_error: title: Encryption keys missing message: "Bank sync needs Active Record encryption configured. Set primary_key, deterministic_key and key_derivation_salt in your Rails credentials or environment variables." + provider_form: + save_and_connect: "Save and connect" coinbase_panel: setup_instructions: "To connect Coinbase:" step1_html: Go to Coinbase API Settings diff --git a/config/locales/views/settings/es.yml b/config/locales/views/settings/es.yml index e8cf7fb0c..1ff5af650 100644 --- a/config/locales/views/settings/es.yml +++ b/config/locales/views/settings/es.yml @@ -47,6 +47,9 @@ es: month_start_day: El mes de presupuesto comienza el month_start_day_hint: Establece cuándo empieza tu mes financiero (ej. el día de cobro) month_start_day_warning: Tus presupuestos y cálculos del mes en curso utilizarán este día personalizado en lugar del día 1 de cada mes. + preview: + title: Habilitar funciones experimentales + description: Activa las funciones en desarrollo etiquetadas como experimentales o canary. profiles: destroy: cannot_remove_self: No puedes eliminarte a ti mismo de la cuenta. diff --git a/config/locales/views/settings/hostings/ca.yml b/config/locales/views/settings/hostings/ca.yml index e435ab6ea..02b1a6282 100644 --- a/config/locales/views/settings/hostings/ca.yml +++ b/config/locales/views/settings/hostings/ca.yml @@ -2,61 +2,185 @@ ca: settings: hostings: + alpha_vantage_settings: + description: Introdueix la clau API d'Alpha Vantage. Admet ETF europeus a + London Stock Exchange, XETRA i altres mercats. + env_configured_message: Configurat correctament mitjançant la variable d'entorn + ALPHA_VANTAGE_API_KEY. + label: Clau API + no_health_check_note: La comprovació de l'estat de la connexió no està disponible + per a aquest proveïdor a causa del límit estricte de sol·licituds. + placeholder: Introdueix aquí la teva clau API d'Alpha Vantage + rate_limit_warning: El nivell gratuït d'Alpha Vantage està limitat a 25 crides + d'API al dia. Útil com a proveïdor complementari per a ETF europeus no disponibles + en altres proveïdors. + show_details: "(mostra detalls)" + step_1_html: Visita alphavantage.co + i obté la teva clau API gratuïta. + step_2: Copia la clau API i enganxa-la a sota. + title: Alpha Vantage + assistant_settings: + agent_id_help: Encamina cap a un agent específic quan el proveïdor n'allotja + diversos. Deixa-ho en blanc per al predeterminat. + agent_id_label: ID de l'agent (opcional) + agent_id_placeholder: main (predeterminat) + confirm_disconnect: + body: Això eliminarà l'URL desat, el token i l'ID de l'agent, i canviarà + a l'assistent integrat. Pots reconnectar més tard introduint credencials + noves. + title: Desconnectar l'assistent extern? + description: Tria com respon l'assistent del xat. Integrat utilitza el teu + proveïdor d'LLM configurat directament. Extern delega en un agent d'IA remot + que pot retrucar a les eines financeres de Sure via MCP. + disconnect_button: Desconnecta + disconnect_description: Elimina la connexió a l'assistent extern i torna a + l'assistent integrat. + disconnect_title: Connexió externa + env_configured_external: Configurat correctament mitjançant variables d'entorn. + env_notice: El tipus d'assistent està fixat a '%{type}' mitjançant la variable + d'entorn ASSISTANT_TYPE. + external_configured: Configurat + external_not_configured: No configurat. Introdueix l'URL i el token a sota, + o estableix les variables d'entorn EXTERNAL_ASSISTANT_URL i EXTERNAL_ASSISTANT_TOKEN. + external_status: Endpoint de l'assistent extern + title: Assistent d'IA + token_help: El token d'autenticació proporcionat pel teu agent extern. S'envia + com a Bearer token a cada sol·licitud. + token_label: Token d'API + token_placeholder: Introdueix el token del teu proveïdor d'agent + type_builtin: Integrat (LLM directe) + type_external: Extern (agent remot) + type_label: Tipus d'assistent + url_help: L'URL complet de l'endpoint d'API del teu agent. El teu proveïdor + d'agent te'l donarà. + url_label: URL de l'endpoint + url_placeholder: https://your-agent-host/v1/chat brand_fetch_settings: description: Introdueix el Client ID proporcionat per Brand Fetch + env_configured_message: Has configurat correctament el teu Client ID de Brand + Fetch mitjançant la variable d'entorn BRAND_FETCH_CLIENT_ID. + high_res_description: Quan està activat, els logotips es recuperaran amb resolució + 120×120 en lloc de 40×40. Això proporciona imatges més nítides en pantalles + d'alta densitat. + high_res_label: Activa logotips d'alta resolució label: Client ID placeholder: Introdueix aquí el teu Client ID - title: Brand Fetch + setup_step_1_html: Visita brandfetch.com i crea un + compte de desenvolupador gratuït de Brand Fetch. + setup_step_2_html: Ves a la pàgina Logo API. + setup_step_3: Toca la icona de l'ull a la secció "Your Client ID" per revelar + el teu Client ID i enganxa'l a sota. + show_details: "(mostra detalls)" + title: Configuració de Brand Fetch clear_cache: - cache_cleared: La memòria cau de dades s'ha netejat. Això pot trigar uns instants + cache_cleared: La memòria cau de dades s'ha netejat. Pot trigar uns instants a completar-se. + disconnect_external_assistant: + external_assistant_disconnected: Assistent extern desconnectat + ensure_super_admin_for_onboarding: + not_authorized: No estàs autoritzat/da a fer aquesta acció + eodhd_settings: + description: Introdueix el token d'API proporcionat per EODHD. Admet ETF europeus + a LSE, XETRA i altres mercats internacionals. + env_configured_message: Configurat correctament mitjançant la variable d'entorn + EODHD_API_KEY. + label: Token d'API + placeholder: Introdueix aquí el teu token d'API d'EODHD + rate_limit_warning: El nivell gratuït d'EODHD està limitat a 20 crides d'API + al dia. Útil com a proveïdor complementari per a ETF europeus no disponibles + en altres proveïdors. + show_details: "(mostra detalls)" + step_1_html: Visita eodhd.com i crea un compte gratuït. + step_2_html: Ves al teu tauler per trobar el teu + token d'API. + step_3: Copia el teu token d'API i enganxa'l a sota. + title: EODHD invite_code_settings: - description: Cada nou usuari que s'uneixi a la teva instància de %{product} - només ho podrà fer mitjançant un codi d'invitació + default_family_description: Posa els nous usuaris en aquesta família/grup + només si no tenen invitació. + default_family_none: Cap (crear nova família) + default_family_title: Família predeterminada per a nous usuaris + description: Controla com es registra la gent a la teva instància de %{product}. email_confirmation_description: Quan està activat, els usuaris hauran de confirmar el seu correu electrònic quan el canviïn. email_confirmation_title: Requereix confirmació de correu electrònic - generate_tokens: Genera nou codi + generate_tokens: Genera un nou codi generated_tokens: Codis generats states: closed: Tancat invite_only: Només per invitació open: Obert - title: Requereix codi d'invitació per registrar-se - not_authorized: No estàs autoritzat/da per realitzar aquesta acció + title: Inici de sessió + not_authorized: No estàs autoritzat/da a fer aquesta acció openai_settings: access_token_label: Token d'accés access_token_placeholder: Introdueix aquí el teu token d'accés + budget_description: S'aplica a totes les crides d'LLM — historial de xat, + autocategorització, detecció de comerç i processament de PDF. Els valors + predeterminats són conservadors per a models locals amb context reduït. + Augmenta'ls per a models al núvol amb finestres de context més grans. + budget_heading: Pressupost de tokens + context_window_help: 'Tokens totals que el model acceptarà. Per defecte: 2048 + — puja a 8192+ per a OpenAI al núvol o models locals amb context gran.' + context_window_label: Finestra de context (opcional) description: Introdueix el token d'accés i, opcionalment, configura un proveïdor - OpenAI compatible personalitzat + compatible amb OpenAI personalitzat env_configured_message: Configurat correctament mitjançant variables d'entorn. json_mode_auto: Auto (recomanat) json_mode_help: El mode estricte funciona millor amb models de pensament (qwen-thinking, - deepseek-reasoner). El mode None funciona millor amb models estàndard (llama, mistral, - gpt-oss). - json_mode_json_object: JSON Object + deepseek-reasoner). El mode None funciona millor amb models estàndard (llama, + mistral, gpt-oss). + json_mode_json_object: Objecte JSON json_mode_label: Mode JSON - json_mode_none: None (millor per models estàndard) - json_mode_strict: Estrict (millor per models de pensament) + json_mode_none: Cap (millor per a models estàndard) + json_mode_strict: Estricte (millor per a models de pensament) + max_items_per_call_help: 'Límit superior per als lots d''autocategorització + / detecció de comerç. Per defecte: 25. Els lots més grans es divideixen + automàticament per encabir-se a la finestra de context.' + max_items_per_call_label: Màxim d'elements per lot (opcional) + max_response_tokens_help: 'Tokens reservats per a la resposta del model. Per + defecte: 512. Redueix per alliberar espai per a un historial més llarg.' + max_response_tokens_label: Màxim de tokens de resposta (opcional) model_label: Model (opcional) model_placeholder: gpt-4.1 (per defecte) title: OpenAI uri_base_label: URL base de l'API (opcional) uri_base_placeholder: https://api.openai.com/v1 (per defecte) provider_selection: - description: Tria quin servei utilitzar per obtenir tipus de canvi i preus de - valors. Yahoo Finance és gratuït i no requereix clau API. Twelve Data - requereix una clau API gratuïta però pot oferir més cobertura de dades. - env_configured_message: La selecció de proveïdor està inhabilitada perquè les variables - d'entorn (EXCHANGE_RATE_PROVIDER o SECURITIES_PROVIDER) estan configurades. Per habilitar - la selecció aquí, elimina aquestes variables d'entorn de la teva configuració. - exchange_rate_provider_label: Proveïdor de Tipus de Canvi + binance_public_hint: gratuït, sense clau API — només cripto (BTC, ETH, etc.) + description: Tria un únic proveïdor per obtenir tipus de canvi de divisa. + env_configured_message: La selecció de proveïdor està desactivada perquè hi + ha variables d'entorn configurades. Per activar la selecció aquí, elimina + aquestes variables d'entorn de la teva configuració. + exchange_rate_description: Tria un únic proveïdor per obtenir tipus de canvi + de divisa. + exchange_rate_provider_label: Proveïdor de tipus de canvi + exchange_rate_title: Proveïdor de tipus de canvi + mfapi_hint: gratuït, sense clau API — només fons mutus indis providers: + alpha_vantage: Alpha Vantage + binance_public: Binance + eodhd: EODHD + mfapi: MFAPI.in + tiingo: Tiingo twelve_data: Twelve Data yahoo_finance: Yahoo Finance - securities_provider_label: Proveïdor de Valors (Preus d'Accions) - title: Selecció de Proveïdor + requires_api_key: requereix clau API + requires_api_key_alpha_vantage: requereix clau API, límit de 25 crides/dia + requires_api_key_eodhd: requereix clau API, límit de 20 crides/dia + securities_description: Activa un o més proveïdors per obtenir preus d'accions, + ETF i fons d'inversió. En cercar, es consulten tots els proveïdors activats + i es combinen els resultats. + securities_title: Proveïdors de valors + twelve_data_hint: requereix clau API, 800 crèdits/dia + yahoo_finance_hint: gratuït, no cal clau API show: + ai_assistant: Assistent d'IA clear_cache: Neteja la memòria cau de dades clear_cache_warning: Netejar la memòria cau de dades eliminarà tots els tipus de canvi, preus de valors, saldos de comptes i altres dades. Això no eliminarà @@ -65,50 +189,82 @@ ca: body: Segur que vols netejar la memòria cau de dades? Això eliminarà tots els tipus de canvi, preus de valors, saldos de comptes i altres dades. Aquesta acció no es pot desfer. - title: Neteja la memòria cau de dades? + title: Netejar la memòria cau de dades? danger_zone: Zona perillosa - financial_data_providers: Proveïdors de Dades Financeres - general: Serveis externs + financial_data_providers: Proveïdors de dades financeres + general: Configuració general invites: Codis d'invitació - sync_settings: Configuració de Sincronització - title: Autoallotjament + sync_settings: Configuració de sincronització + title: Self hosting + sync_auto_sync_scheduler!: + scheduler_sync_failed: La configuració s'ha desat, però no s'ha pogut actualitzar + la planificació de sincronització. Torna-ho a provar o revisa els registres + del servidor. sync_settings: auto_sync_description: Quan està activat, tots els comptes es sincronitzaran - automàticament diàriament a l'hora especificada. + automàticament cada dia a l'hora especificada. auto_sync_label: Activa la sincronització automàtica - auto_sync_time_description: Especifica l'hora del dia quan hauria de produir-se + auto_sync_time_description: Especifica l'hora del dia en què s'ha de produir la sincronització automàtica. auto_sync_time_label: Hora de sincronització (HH:MM) - env_configured_message: Aquesta configuració està inhabilitada perquè una variable - d'entorn del proveïdor (SIMPLEFIN_INCLUDE_PENDING o PLAID_INCLUDE_PENDING) està configurada. Elimina - per habilitar aquesta configuració. - include_pending_description: Quan està activat, les transaccions pendents (no liquidades) - s'importaran i es reconciliaran automàticament quan es publiquin. Inhabilita si - el teu banc proporciona dades pendents no fiables. + env_configured_message: Aquesta configuració està desactivada perquè una variable + d'entorn del proveïdor (SIMPLEFIN_INCLUDE_PENDING o PLAID_INCLUDE_PENDING) + està establerta. Elimina-la per activar aquesta opció. + include_pending_description: Quan està activat, les transaccions pendents + (no liquidades) s'importaran i es reconciliaran automàticament quan es publiquin. + Desactiva-ho si el teu banc proporciona dades pendents poc fiables. include_pending_label: Inclou transaccions pendents + tiingo_settings: + description: Introdueix el token d'API proporcionat per Tiingo. El nivell + gratuït admet 50 símbols únics per hora amb més de 30 anys d'historial. + env_configured_message: Configurat correctament mitjançant la variable d'entorn + TIINGO_API_KEY. + label: Token d'API + placeholder: Introdueix aquí el teu token d'API de Tiingo + show_details: "(mostra detalls)" + step_1_html: Visita tiingo.com i crea un compte gratuït. + step_2_html: Ves a la pàgina Token d'API. + step_3: Copia el teu token d'API i enganxa'l a sota. + title: Tiingo twelve_data_settings: - api_calls_used: "%{used} / %{limit} crides diàries a l'API utilitzades (%{percentage})" + api_calls_used: "%{used} / %{limit} crides diàries d'API utilitzades (%{percentage})" description: Introdueix la clau API proporcionada per Twelve Data env_configured_message: Configurat correctament mitjançant la variable d'entorn TWELVE_DATA_API_KEY. label: Clau API placeholder: Introdueix aquí la teva clau API plan: Pla %{plan} + plan_upgrade_warning_description: Els següents símbols de la teva cartera + no poden sincronitzar preus amb el teu pla actual de Twelve Data. + plan_upgrade_warning_title: Alguns símbols requereixen un pla de pagament + requires_plan: requereix el pla %{plan} + show_details: "(mostra detalls)" + step_1_html: Visita twelvedata.com i crea un + compte de desenvolupador gratuït de Twelve Data. + step_2_html: Ves a la pàgina claus d'API. + step_3: Revela la teva Secret Key i enganxa-la a sota. title: Twelve Data + view_pricing: Veure preus de Twelve Data update: failure: Valor de configuració invàlid - invalid_onboarding_state: Estat d'incorporació invàlid - invalid_sync_time: Format d'hora de sincronització invàlid. Utilitza el format HH:MM (p. ex., - 02:30). - scheduler_sync_failed: S'ha desat la configuració, però no s'ha pogut actualitzar el programa de sincronització. - Torna-ho a provar o revisa els registres del servidor. + invalid_llm_budget: "%{field} ha de ser un nombre enter ≥ %{minimum}." + invalid_onboarding_state: Estat d'inici de sessió invàlid + invalid_sync_time: Format d'hora de sincronització invàlid. Utilitza el format + HH:MM (p. ex., 02:30). + scheduler_sync_failed: La configuració s'ha desat, però no s'ha pogut actualitzar + la planificació de sincronització. Torna-ho a provar o revisa els registres + del servidor. success: Configuració actualitzada yahoo_finance_settings: connection_failed: No s'ha pogut connectar amb Yahoo Finance - description: Yahoo Finance ofereix accés gratuït a preus d'accions, tipus de canvi - i dades financeres sense requerir clau API. + description: Yahoo Finance ofereix accés gratuït a preus d'accions, tipus + de canvi i dades financeres sense necessitat de clau API. status_active: Yahoo Finance està actiu i funcionant status_inactive: La connexió a Yahoo Finance ha fallat title: Yahoo Finance - troubleshooting: Comprova la connexió a Internet i la configuració del tallafocs. És possible que - Yahoo Finance estigui temporalment no disponible. + troubleshooting: Comprova la connexió a Internet i la configuració del tallafoc. + És possible que Yahoo Finance estigui temporalment no disponible. diff --git a/config/locales/views/settings/hostings/hu.yml b/config/locales/views/settings/hostings/hu.yml index 4d9d4148a..3d0131bfb 100644 --- a/config/locales/views/settings/hostings/hu.yml +++ b/config/locales/views/settings/hostings/hu.yml @@ -80,6 +80,11 @@ hu: body: Ez eltávolítja a mentett URL-t, tokent és ügynökazonosítót, és visszavált a beépített asszisztensre. Később újra csatlakozhatsz új hitelesítő adatok megadásával. brand_fetch_settings: description: Add meg a Brand Fetch által biztosított kliens-azonosítót + env_configured_message: Sikeresen konfiguráltad a Brand Fetch kliens-azonosítódat a BRAND_FETCH_CLIENT_ID környezeti változón keresztül. + show_details: "(részletek megjelenítése)" + setup_step_1_html: 'Látogass el a brandfetch.com oldalra, és hozz létre egy ingyenes Brand Fetch fejlesztői fiókot.' + setup_step_2_html: 'Menj a Logo API oldalra.' + setup_step_3: 'Kattints a szem ikonra a „Your Client ID" rész alatt, hogy megjelenítsd a kliens-azonosítódat, majd illeszd be alább.' label: Kliens-azonosító placeholder: Add meg ide a kliens-azonosítódat title: Brand Fetch beállítások @@ -176,6 +181,10 @@ hu: clear_cache: cache_cleared: Az adatcache törölve. Ez néhány percet vehet igénybe. not_authorized: Nincs jogosultságod ehhez a művelethez + ensure_super_admin_for_onboarding: + not_authorized: Nincs jogosultságod ehhez a művelethez + sync_auto_sync_scheduler!: + scheduler_sync_failed: A beállítások mentve, de a szinkronizálási ütemezés frissítése nem sikerült. Kérjük, próbáld újra, vagy ellenőrizd a szerver naplóit. sync_settings: auto_sync_label: Automatikus szinkronizálás engedélyezése auto_sync_description: Ha engedélyezve van, az összes fiók naponta automatikusan szinkronizálódik a megadott időpontban. diff --git a/config/locales/views/settings/hu.yml b/config/locales/views/settings/hu.yml index 4d4d3dc91..b43b6cc97 100644 --- a/config/locales/views/settings/hu.yml +++ b/config/locales/views/settings/hu.yml @@ -6,6 +6,32 @@ hu: renewal: "A hozzájárulásod %{date}-én megújul." cancellation: "A hozzájárulásod %{date}-én lejár." settings: + llm_usages: + show: + page_title: "LLM-használat és -költségek" + subtitle: "Kövesd nyomon az AI-használatot és a becsült költségeket" + start_date: "Kezdő dátum" + end_date: "Záró dátum" + filter: "Szűrő" + total_requests: "Összes kérés" + total_tokens: "Összes token" + prompt: "prompt" + completion: "befejezés" + total_cost: "Összes költség" + avg_cost_per_request: "Átl. költség/kérés" + based_on_requests: "%{total} kérésből %{with_cost} rendelkezik költségadattal" + cost_by_operation: "Költség műveletek szerint" + cost_by_model: "Költség modellek szerint" + recent_usage: "Legutóbbi használat" + col_date: "Dátum" + col_operation: "Művelet" + col_model: "Modell" + col_tokens: "Tokenek" + col_cost: "Költség" + failed: "Sikertelen" + no_usage_data: "Nem található használati adat a kiválasztott időszakra" + cost_estimates_title: "A költségbecslésekről" + cost_estimates_description: "A költségek az OpenAI 2025-ös árazása alapján vannak becsülve. A tényleges költségek eltérhetnek. Az árazás millió tokenenként van megadva, és modellenként változik. Az egyéni vagy önállóan üzemeltetett modellek \"N/A\"-t mutatnak, és nem szerepelnek a költségösszesítőkben." ai_prompts: show: page_title: MI promptok @@ -26,6 +52,17 @@ hu: page_title: Fizetések subscription_subtitle: Frissítsd bankkártyaadataidat subscription_title: Hozzájárulások kezelése + currently_on_plan: "Jelenleg a" + trialing: "Jelenleg a %{product_name} nyílt demóját használod" + trial_days_left: + one: "Az adatok %{count} nap múlva törlődnek" + other: "Az adatok %{count} nap múlva törlődnek" + not_contributing_prefix: "Jelenleg" + not_contributing_emphasis: "nem járulsz hozzá" + contributions_note: "A(z) %{product_name} felé tett hozzájárulásaid itt jelennek meg." + manage: "Kezelés" + choose_level: "Szint kiválasztása" + payment_via_stripe: "Fizetés Stripe-on keresztül" appearances: show: page_title: Megjelenés @@ -159,8 +196,10 @@ hu: general_section_title: Általános imports_label: Importálások exports_label: Exportálások + llm_usage_label: LLM-használat logout: Kijelentkezés merchants_label: Kereskedők + providers_label: Szolgáltatók guides_label: Útmutatók other_section_title: Egyéb preferences_label: Preferenciák @@ -169,8 +208,11 @@ hu: rules_label: Szabályok security_label: Biztonság self_hosting_label: Saját üzemeltetés + sso_providers_label: SSO-szolgáltatók + statement_vault_label: Kimutatástár tags_label: Címkék transactions_section_title: Tranzakciók + users_label: Felhasználók whats_new_label: Újdonságok api_keys_label: API-kulcs appearance_label: Megjelenés @@ -184,6 +226,76 @@ hu: choose_label: (nem kötelező) change: Fotó módosítása providers: + update: + updated_successfully: Szolgáltatói beállítások sikeresen frissítve + no_changes: Nem történt változtatás + not_authorized: Nincs jogosultság + bank_sync: + page_title: Banki szinkronizálás + lede: Csatlakoztasd a külső számlákat, hogy a tranzakciók, egyenlegek és portfólióadatok automatikusan áramlanak a Sure-ba. + status: + ok: Csatlakoztatva + warn: Beavatkozás szükséges + err: Hiba + off: Nincs konfigurálva + maturity: + beta: Béta + alpha: Alfa + drawer_trust_statement: "Csak olvasási hozzáférés. A Sure soha nem tud pénzt mozgatni, és a hitelesítő adatok titkosítva vannak tárolva." + setup_steps: + eyebrow: Beállítás + need_help: "Segítségre van szükséged?" + connect: Csatlakozás + groups: + your_connections: A te kapcsolataid + available: Elérhető + empty_available: Minden elérhető szolgáltató csatlakoztatva van. + health_strip: + connected: csatlakoztatva + needs_attention: figyelmet igényel + accounts_syncing: számla szinkronizálódik + last_synced: Utoljára szinkronizálva %{time} ezelőtt + meta: + sync_error: Szinkronizálási hiba + no_recent_sync: Szinkronizálás lejárt + registration_needed: Regisztráció szükséges + reconsent_required: Újrahozzájárulás szükséges + reconsent_needed: + one: Újrahozzájárulás szükséges 1 napon belül + other: Újrahozzájárulás szükséges %{count} napon belül + last_synced: Szinkronizálva %{time} ezelőtt + sync_all: Összes szinkronizálása + sync_all_in_progress: Az összes csatlakoztatott szolgáltató szinkronizálása folyamatban... + sync_all_recently: Szinkronizálás már folyamatban van. Próbáld újra egy pillanat múlva. + sync_provider: Szinkronizálás most + sync_provider_in_progress: Szinkronizálás elindítva. + recently_synced: Nemrég szinkronizálva. Próbáld újra egy pillanat múlva. + taglines: + simplefin: US bankszámlák csatlakoztatása az open SimpleFIN protokollon keresztül. + lunchflow: 40+ ország 20 000+ bankjának csatlakoztatása (Egyesült Királyság, EU, USA stb.!) + enable_banking: Európai bankszámlák szinkronizálása PSD2 open banking révén. + coinstats: Teljes kriptoportfólió nyomon követése tárcákon és tőzsdéken keresztül. + mercury: Mercury üzleti bankszámlák automatikus szinkronizálása. + brex: Brex készpénz és vállalati kártya tevékenység szinkronizálása csak olvasási hozzáféréssel. + coinbase: Coinbase kriptoeszközök importálása és teljesítmény nyomon követése. + binance: Binance spot egyenlegek szinkronizálása csak olvasási API-kulccsal. + kraken: Kraken egyenlegek és spot ügyletek szinkronizálása csak olvasási API-kulccsal. + snaptrade: Brókeri számlák csatlakoztatása a SnapTrade aggregációs hálózaton keresztül. + ibkr: Interactive Brokers befektetési számlák szinkronizálása Flex Query importálással. + indexa_capital: Indexa Capital automatizált befektetési portfólió nyomon követése. + sophtron: US és kanadai bankok és közüzemi szolgáltatók csatlakoztatása. + plaid: Ezernyi US pénzintézet csatlakoztatása Plaid-en keresztül. + plaid_eu: Európai pénzintézetek csatlakoztatása Plaid-en keresztül (PSD2 / Open Banking). + search_filters: + aria_label: Szolgáltatók keresése + placeholder: Szolgáltatók keresése + chips: + all: Összes + bank: Bankok + crypto: Kripto + investment: Befektetések + empty_filter: Nincs a szűrőnek megfelelő szolgáltató. + clear_filter: Szűrők törlése show: coinbase_title: Coinbase encryption_error: @@ -208,6 +320,8 @@ hu: step2: "Hozz létre egy új API-kulcsot, csak olvasási engedéllyel" step3: "Illeszd be az API-kulcsodat és az API-titkodat az alábbiakba" no_withdraw_warning: "Figyelmeztetés: NE engedélyezd a kifizetési jogosultságot" + no_withdraw_title: "Csak olvasható kulcs" + no_withdraw_body: "Ne engedélyezd a kifizetési jogosultságot a Binance API-kulcs létrehozásakor. A Sure csak olvasási hozzáférést igényel." ip_hint_title: "IP-cím-engedélyezési lista szükséges" ip_hint_body: "Add hozzá az alkalmazásszerver kimenő IP-címét a Binance API-kulcs engedélyezési listájához:" ip_hint_contact_admin: "Az alkalmazásszerver kimenő IP-címéért fordulj a rendszergazdádhoz." @@ -219,6 +333,136 @@ hu: syncing: Szinkronizálás... sync: Szinkronizálás disconnect_confirm: "Biztosan le szeretnéd választani a Binance-t?" + kraken_panel: + step1_html: 'Nyisd meg a Kraken API-beállításait' + step2: "Hozz létre egy API-kulcsot csak Lekérdezési alapok és Lekérdezési zárt megbízások & ügyletek jogosultsággal." + step3: "Illeszd be az API-kulcsot és a privát kulcsot az alábbiakba." + read_only_title: "Csak olvasási tőzsdei szinkronizálás" + read_only_body: "Ne adj kereskedési, visszavonási, kifizetési, exportálási, főkönyvi, Earn, staking vagy átutalási jogosultságot. A Sure csak egyenlegeket, pozíciókat és spot ügyletek adatait importálja." + default_connection_name: Kraken + add_connection: Kraken-kapcsolat hozzáadása + update_connection: Kapcsolat frissítése + connection_name_label: Kapcsolat neve + connection_name_placeholder: Fő Kraken + api_key_label: API-kulcs + api_key_placeholder: Illeszd be a Kraken API-kulcsodat + keep_api_key_placeholder: Hagyd üresen a meglévő API-kulcs megtartásához + api_secret_label: Privát kulcs + api_secret_placeholder: Illeszd be a Kraken privát kulcsodat + keep_api_secret_placeholder: Hagyd üresen a meglévő privát kulcs megtartásához + setup_accounts: Számla beállítása + syncing: Szinkronizálás... + sync: Szinkronizálás + disconnect: Lecsatlakozás + disconnect_confirm: "Biztosan le szeretnéd választani a(z) %{name}-t?" enable_banking_panel: callback_url_instruction: "A visszahívási URL-hez használd a következőt: %{callback_url}." connection_error: Kapcsolódási hiba + step_1_html: "Menj a(z) %{link} oldalra, és szerezd meg a fejlesztői hitelesítő adataidat." + step_2: "Válaszd ki az országodat, és illeszd be az alkalmazásazonosítót és az ügyfél-tanúsítványt alább." + step_3: "Mentsd el, majd a Kapcsolat hozzáadása gombbal csatlakoztasd a bankod." + config_locked_title: "Konfiguráció zárolva" + config_locked_message: "Válassz le minden csatlakoztatott bankot a hitelesítő adatok módosítása előtt." + application_id_label: "Alkalmazásazonosító" + application_id_placeholder_new: "Add meg az alkalmazásazonosítót" + application_id_placeholder_update: "Add meg az új azonosítót a frissítéshez" + client_certificate_label: "Ügyfél-tanúsítvány (privát kulccsal)" + save_and_connect: "Mentés és csatlakozás" + update_connection: "Kapcsolat frissítése" + connected_bank: "Csatlakoztatott bank" + session_expires: "Munkamenet lejárata: %{date}" + unknown: "Ismeretlen" + connection: "Kapcsolat" + session_expired_reconnect: "Munkamenet lejárt – csatlakozz újra" + configured: "Konfigurálva" + ready_to_link: "Kész számlák összekapcsolására" + sync: "Szinkronizálás" + reconnect: "Újracsatlakozás" + connect_bank: "Bank csatlakoztatása" + remove: "Eltávolítás" + remove_confirm: "Biztosan el szeretnéd távolítani ezt a kapcsolatot?" + add_connection: "Kapcsolat hozzáadása" + syncing: "Szinkronizálás" + select_country: "Ország kiválasztása..." + country_label: "Ország" + lunchflow_panel: + step_1_html: "Menj a(z) %{link} oldalra és hozz létre egy API-kulcsot." + step_2: "Illeszd be a kulcsodat alább és csatlakozz." + step_3: "Ezután menj a Számlák menübe a szinkronizált számlák összekapcsolásához." + api_key_label: "API-kulcs" + api_key_placeholder_new: "Illeszd be ide az API-kulcsot" + api_key_placeholder_update: "Add meg az új API-kulcsot a frissítéshez" + base_url_label: "Alap URL (nem kötelező)" + base_url_placeholder: "https://lunchflow.app/api/v1 (alapértelmezett)" + save_and_connect: "Mentés és csatlakozás" + update_connection: "Kapcsolat frissítése" + simplefin_panel: + step_1_html: "Menj a(z) %{link} oldalra egy egyszeri beállítási tokenért." + step_2: "Illeszd be a tokent alább és csatlakozz." + step_3: "Ezután menj a Számlák menübe a szinkronizált számlák összekapcsolásához." + setup_token_label: "Beállítási token" + setup_token_placeholder: "SimpleFIN beállítási token beillesztése" + save_and_connect: "Mentés és csatlakozás" + plaid_panel: + step_1_html: "Nyisd meg a(z) %{link} oldalt, és másold ki az ügyfél-azonosítódat és titkos kulcsodat." + step_2: "Válassz környezetet. Teszteléshez sandbox, éles számlákhoz production." + step_3: "Illeszd be a hitelesítő adataidat alább és csatlakozz." + plaid_eu_panel: + step_1_html: "Nyisd meg a(z) %{link} oldalt, és másold ki az EU ügyfél-azonosítódat és titkos kulcsodat." + not_found: Szolgáltató nem található. + sync_provider_no_items: Nincs elérhető kapcsolat a szinkronizáláshoz. + ibkr_panel: + steps: + step_1: 'Az IBKR ügyfélportálon menj a „Teljesítmény és Jelentések" > „Flex lekérdezések" menübe.' + step_2: 'Kattints a „+" ikonra az „Activity Flex Query" részben egy új lekérdezés létrehozásához.' + step_3: 'Nevezd el a lekérdezést (pl. „Sure Sync"), majd tekintsd át az alábbi Flex Query részleteket, és engedélyezd a felsorolt szakaszokat, mezőket és konfigurációs lehetőségeket.' + step_4: 'Mentsd el a lekérdezést, jegyezd fel a „Query ID"-t, majd a „Flex Web Service Configuration" részben a fogaskerék ikonnal hozz létre egy hozzáférési tokent.' + step_5: "Illeszd be a Query ID-t és a tokent alább, mentsd el a konfigurációt, majd menj a Számlák menübe a felderített IBKR-számlák összekapcsolásához." + flex_query_details: + eyebrow: Flex Query + title: Szakaszok, mezők és konfiguráció + summary: Bővítsd ki a pontos szakaszok, mezők és beállítások megtekintéséhez, amelyeket az IBKR Activity Flex Query-nek tartalmaznia kell. + sections_heading: Engedélyezd ezeket a szakaszokat és mezőket + configuration_heading: Állítsd be ezeket a lekérdezési opciókat + sections: + account_information: "Számla adatai: Számlaazonosító, Pénznem" + cash_report: "Készpénzjelentés:" + cash_report_options: "Opciók: Nincs" + cash_report_fields: "Mezők: Pénznem, Záró készpénz" + cash_transactions: "Készpénztranzakciók:" + cash_transactions_options: "Opciók: Osztalékok, Befizetések és kifizetések, Részletek" + cash_transactions_fields: "Mezők: Összeg, Conid, Pénznem, FX-árfolyam alaphoz, Jelentési dátum, Tranzakció-azonosító, Típus" + change_in_position_value_summary: "Pozícióérték változásának összefoglalója: Pénznem, Időszak végi érték" + net_asset_value: "Nettó eszközérték (NAV) alapban:" + net_asset_value_options: "Opciók: Nincs" + net_asset_value_fields: "Mezők: Pénznem, Jelentési dátum, Összesen" + open_positions: "Nyitott pozíciók:" + open_positions_options: "Opciók: Összefoglalás" + open_positions_fields: "Mezők: Eszközosztály, Conid, Bekerülési ár, Pénznem, FX-árfolyam alaphoz, Piaci ár, Mennyiség, Jelentési dátum, Értékpapír-azonosító, Értékpapír-azonosító típus, Oldal, Szimbólum" + trades: "Ügyletek:" + trades_options: "Opciók: Végrehajtás" + trades_fields: "Mezők: Eszközosztály, Vétel/Eladás, Conid, Pénznem, FX-árfolyam alaphoz, IB jutalék, IB jutalék pénzneme, Mennyiség, Szimbólum, Ügylet dátuma, Ügylet-azonosító, Ügylet ára, Tranzakció-azonosító" + configuration: + models: "Modellek: Opcionális" + format: "Formátum: XML" + period: "Időszak: Utolsó 365 naptári nap" + date_format: "Dátumformátum: éééé-HH-nn" + time_format: "Időformátum: ÓÓ:pp:mm" + date_time_separator: "Dátum/idő elválasztó: ; (pontosvessző)" + profit_and_loss: "Nyereség és veszteség: Alapértelmezett" + all_other_options: 'Minden egyéb konfigurációs opció: „Nem"' + report_window_note: "Az IBKR Flex-jelentések az IBKR-ben konfigurált lekérdezési ablakra korlátozódnak. A Sure a teljes aktuális pozíciókat, valamint a jelentésből legfeljebb 365 nap tevékenységet importál." + sync: Szinkronizálás + disconnect_confirm: Leválasztja az Interactive Brokers-t? + query_id_label: Lekérdezés azonosítója + query_id_placeholder_new: Add meg az IBKR Flex lekérdezés azonosítóját + query_id_placeholder_existing: Hagyd üresen a meglévő azonosító megtartásához + token_label: Token + token_placeholder_new: Add meg az IBKR Flex Web Service tokenedet + token_placeholder_existing: Hagyd üresen a meglévő token megtartásához + save_configuration: Konfiguráció mentése + update_configuration: Konfiguráció frissítése + status_configured_prefix: "%{summary}. Látogasd meg a" + accounts_tab: Számlák + status_configured_suffix: fület a felderített számlák kezeléséhez. + not_configured: Nincs konfigurálva. diff --git a/config/locales/views/settings/securities/ca.yml b/config/locales/views/settings/securities/ca.yml index c75c90bac..2fd509e4b 100644 --- a/config/locales/views/settings/securities/ca.yml +++ b/config/locales/views/settings/securities/ca.yml @@ -3,10 +3,40 @@ ca: settings: securities: show: - disable_mfa: Desactiva 2FA + disable_mfa: Desactiva la 2FA disable_mfa_confirm: Segur que vols desactivar l'autenticació en dos passos? Això farà que el teu compte sigui menys segur. - enable_mfa: Activa 2FA + enable_mfa: Activa la 2FA mfa_description: Afegeix una capa extra de seguretat al teu compte requerint un codi de la teva app d'autenticació en iniciar sessió + mfa_disabled_description: Activa la 2FA per afegir una capa extra de seguretat + al teu compte. + mfa_disabled_status_html: L'autenticació en dos passos està desactivada + mfa_enabled_description: El teu compte està protegit amb una capa addicional + de seguretat. + mfa_enabled_status_html: L'autenticació en dos passos està activada mfa_title: Autenticació en dos passos + webauthn_add: Afegeix passkey o clau de seguretat + webauthn_added: Afegida el %{date} + webauthn_description: Utilitza una passkey, Touch ID, Windows Hello o una + clau de seguretat de maquinari com a segon factor en iniciar sessió. + webauthn_empty: Encara no hi ha cap passkey o clau de seguretat registrada. + webauthn_last_used: Última utilització fa %{time_ago} + webauthn_name_label: Nom de la clau + webauthn_name_placeholder: Touch ID MacBook, YubiKey, etc. + webauthn_remove: Elimina + webauthn_remove_confirm: Segur que vols eliminar aquesta passkey o clau de + seguretat? + webauthn_remove_confirm_body: Hauràs de tornar a registrar aquesta passkey + o clau de seguretat abans de poder utilitzar-la per a la verificació d'inici + de sessió. + webauthn_title: Passkeys i claus de seguretat + webauthn_unsupported: Aquest navegador no admet passkeys ni claus de seguretat. + webauthn_credentials: + default_name: Clau de seguretat + failure: No s'ha pogut desar aquesta passkey o clau de seguretat. Torna-ho a provar. + mfa_required: Activa l'autenticació en dos passos abans d'afegir una passkey o + clau de seguretat. + success: Passkey o clau de seguretat eliminada. diff --git a/config/locales/views/settings/securities/en.yml b/config/locales/views/settings/securities/en.yml index 453df4ccd..1b8ae5641 100644 --- a/config/locales/views/settings/securities/en.yml +++ b/config/locales/views/settings/securities/en.yml @@ -7,6 +7,10 @@ en: disable_mfa_confirm: Are you sure you want to disable two-factor authentication? This will make your account less secure. enable_mfa: Enable 2FA + mfa_enabled_status_html: "Two-factor authentication is enabled" + mfa_enabled_description: Your account is protected with an additional layer of security. + mfa_disabled_status_html: "Two-factor authentication is disabled" + mfa_disabled_description: Enable 2FA to add an extra layer of security to your account. mfa_description: Add an extra layer of security to your account by requiring a code from your authenticator app when signing in mfa_title: Two-Factor Authentication diff --git a/config/locales/views/settings/securities/hu.yml b/config/locales/views/settings/securities/hu.yml index 3d28037dc..f3dddd801 100644 --- a/config/locales/views/settings/securities/hu.yml +++ b/config/locales/views/settings/securities/hu.yml @@ -7,6 +7,10 @@ hu: disable_mfa_confirm: Biztosan le szeretnéd tiltani a kétlépéses hitelesítést? Ez kevésbé biztonságossá teszi a fiókodat. enable_mfa: 2FA engedélyezése + mfa_enabled_status_html: "A kétlépéses hitelesítés engedélyezve" + mfa_enabled_description: A fiókod egy extra biztonsági réteggel védett. + mfa_disabled_status_html: "A kétlépéses hitelesítés letiltva" + mfa_disabled_description: Engedélyezd a 2FA-t, hogy extra védelmet adj a fiókodnak. mfa_description: Adj egy extra biztonsági réteget a fiókodhoz azzal, hogy bejelentkezéskor kódot kérsz az hitelesítő alkalmazásodtól mfa_title: Kétlépéses hitelesítés diff --git a/config/locales/views/settings/sso_identities/ca.yml b/config/locales/views/settings/sso_identities/ca.yml index 08fe9fd6e..0c84ad741 100644 --- a/config/locales/views/settings/sso_identities/ca.yml +++ b/config/locales/views/settings/sso_identities/ca.yml @@ -3,5 +3,5 @@ ca: settings: sso_identities: destroy: - cannot_unlink_last: No es pot desvincular l'últim + cannot_unlink_last: No es pot desvincular l'última identitat success: Èxit diff --git a/config/locales/views/shared/ca.yml b/config/locales/views/shared/ca.yml index 7dcbd7a99..b1f9457d7 100644 --- a/config/locales/views/shared/ca.yml +++ b/config/locales/views/shared/ca.yml @@ -1,19 +1,34 @@ --- ca: + concerns: + self_hostable: + redis_configured: Redis ja està configurat correctament! Ara pots configurar + la teva aplicació Sure. shared: + cancel: Cancel·la confirm_modal: accept: Confirma body_html: "

No podràs desfer aquesta acció

" cancel: Cancel·la title: Segur que vols continuar? - money_field: - label: Import + custom_confirm: + default_body: Aquesta acció no es pot desfer. + default_btn_text: Confirma + default_title: Segur que vols continuar? exchange_rate_tabs: calculate_rate_tab: Calcular la taxa FX convert_tab: Convertir amb la taxa FX destination_amount: Quantitat de destinació exchange_rate: Taxa de canvi - exchange_rate_help: Trieu com introduir la quantitat. + exchange_rate_help: Tria com introduir la quantitat. + family_moniker: + group_plural: Grups + group_singular: Grup + plural: Famílies + singular: Família + money_field: + label: Import + require_admin: Només els administradors poden fer aquesta acció syncing_notice: syncing: S'estan sincronitzant les dades dels comptes... transaction_tabs: diff --git a/config/locales/views/shared/en.yml b/config/locales/views/shared/en.yml index 75d0dff32..6acc96633 100644 --- a/config/locales/views/shared/en.yml +++ b/config/locales/views/shared/en.yml @@ -25,8 +25,10 @@ en: default_body: "This is not reversible." default_btn_text: "Confirm" family_moniker: - singular: Family + group_plural: Groups + group_singular: Group plural: Families + singular: Family trend_change: no_change: "no change" cancel: Cancel diff --git a/config/locales/views/shared/hu.yml b/config/locales/views/shared/hu.yml index d8896b0a4..8f0809e72 100644 --- a/config/locales/views/shared/hu.yml +++ b/config/locales/views/shared/hu.yml @@ -1,5 +1,8 @@ --- hu: + concerns: + self_hostable: + redis_configured: "A Redis most megfelelően van konfigurálva! Mostantól beállíthatod a Sure alkalmazásodat." shared: confirm_modal: accept: Megerősítés @@ -17,5 +20,17 @@ hu: syncing_notice: syncing: Számlák adatainak szinkronizálása... require_admin: "Ezt a műveletet csak adminisztrátorok hajthatják végre" + custom_confirm: + default_title: "Biztosan?" + default_body: "Ez a művelet nem vonható vissza." + default_btn_text: "Megerősítés" + family_moniker: + singular: Háztartás + plural: Háztartások trend_change: no_change: "nincs változás" + cancel: Mégse + transaction_tabs: + expense: Kiadás + income: Bevétel + transfer: Átutalás diff --git a/config/locales/views/simplefin_items/ca.yml b/config/locales/views/simplefin_items/ca.yml index addb9cb72..7e882f3e5 100644 --- a/config/locales/views/simplefin_items/ca.yml +++ b/config/locales/views/simplefin_items/ca.yml @@ -2,39 +2,59 @@ ca: simplefin_items: complete_account_setup: - all_skipped: S'han ignorat tots els comptes. No s'ha creat cap compte. + all_skipped: S'han omès tots els comptes. No s'ha creat cap compte. no_accounts: No hi ha comptes per configurar. stale_accounts_errors: - one: "L'acció del compte obsolet ha fallat: %{count}. Consulta els registres per a més detalls." - other: "Les accions dels comptes obsolets han fallat: %{count}. Consulta els registres per a més detalls." - stale_accounts_processed: 'Comptes obsolets: %{deleted} eliminats, %{moved} moguts.' - success: Els comptes SimpleFIN s'han configurat correctament! Les teves transaccions - i posicions s'estan important en segon pla. + one: "%{count} acció de compte obsolet ha fallat. Consulta els registres per + a més detalls." + other: "%{count} accions de comptes obsolets han fallat. Consulta els registres + per a més detalls." + stale_accounts_processed: 'Comptes obsolets: %{deleted} eliminats, %{moved} + moguts.' + success: + one: S'ha creat correctament %{count} compte SimpleFIN! Les teves transaccions + i posicions s'estan important en segon pla. + other: S'han creat correctament %{count} comptes SimpleFIN! Les teves transaccions + i posicions s'estan important en segon pla. create: errors: blank_token: Introdueix un token de configuració SimpleFIN. create_failed: 'No s''ha pogut connectar: %{message}' - invalid_token: Token de configuració invàlid. Comprova que has copiat el token - complet des de SimpleFIN Bridge. + invalid_token: Token de configuració no vàlid. Comprova que has copiat el + token complet des de SimpleFIN Bridge. token_compromised: El token de configuració pot estar compromès, caducat o ja utilitzat. Crea'n un de nou. - unexpected: S'ha produït un error inesperat. Torna-ho a provar o contacta - amb el suport. + unexpected: S'ha produït un error inesperat. Torna-ho a provar. success: Connexió SimpleFIN afegida correctament! Els teus comptes apareixeran en breu mentre es sincronitzen en segon pla. destroy: success: La connexió SimpleFIN s'eliminarà + dismiss_replacement_suggestion: + dismissed: Suggeriment de substitució descartat edit: + cancel: Cancel·la + connection_needs_update: 'La teva connexió SimpleFIN necessita actualització:' + header_subtitle: Obtén un nou token de configuració per reconnectar el teu compte + SimpleFIN setup_token: help_text: El token ha de ser una cadena llarga que comenci amb lletres i números label: 'Token de configuració SimpleFIN:' placeholder: Enganxa aquí el teu token de configuració SimpleFIN... + step_1_html: Visita SimpleFIN Bridge per crear un nou token de configuració + step_2: Copia el token i enganxa'l a continuació + step_3: Fes clic a "Actualitza" per restaurar l'accés + title: Actualitza la connexió SimpleFIN + update: Actualitza link_existing_account: errors: - invalid_simplefin_account: S'ha seleccionat un compte SimpleFIN invàlid - only_manual: Només es poden enllaçar comptes manuals - success: S'ha enllaçat el compte correctament amb SimpleFIN + different_provider: Aquest compte està enllaçat a un altre proveïdor. Desenllaça'l + primer d'aquell proveïdor i després enllaça'l a SimpleFIN. + invalid_simplefin_account: S'ha seleccionat un compte SimpleFIN no vàlid + only_manual: Només els comptes manuals es poden enllaçar + success: El compte s'ha enllaçat correctament a SimpleFIN new: cancel: Cancel·la connect: Connecta @@ -45,55 +65,117 @@ ca: message: one: "%{count} transacció pendent duplicada conciliada" other: "%{count} transaccions pendents duplicades conciliades" + replacement_prompt: + confirm_body: "“%{account_name}” s'enllaçarà a “%{new_name}”. El teu historial + de transaccions es manté; les transaccions futures vindran de la nova targeta." + confirm_title: Vols tornar a enllaçar a la nova targeta? + description: "“%{account_name}” està enllaçat a “%{old_name}”, que no ha tingut + activitat recent i té saldo zero. Una nova targeta, “%{new_name}”, està activa + a la mateixa entitat. Torna a enllaçar-la per mantenir l'historial intacte." + dismiss_aria: Descarta el suggeriment de substitució + relink: Torna a enllaçar a la nova targeta + title: La teva targeta de %{institution} pot haver estat substituïda select_existing_account: - all_accounts_already_linked: Sembla que ja s'han enllaçat tots els comptes de SimpleFIN. + all_accounts_already_linked: Sembla que tots els comptes SimpleFIN ja estan + enllaçats. cancel: Cancel·la - check_provider_health: Comprova l'estat del proveïdor + check_provider_health: Comprova que la teva connexió SimpleFIN està activa a + Configuració → Proveïdors. currently_linked_to: 'Actualment enllaçat a: %{account_name}' description: Selecciona un compte SimpleFIN per enllaçar-lo al teu compte existent link_account: Enllaça el compte - no_accounts_found: No s'han trobat comptes SimpleFIN per a aquesta família. + no_accounts_found: No s'han trobat comptes SimpleFIN per a %{moniker}. title: Enllaça %{account_name} amb SimpleFIN - unlink_to_move: Per moure un enllaç, primer des-enllaça'l del menú d'accions del compte. - wait_for_sync: Si acabes de connectar o sincronitzar, torna-ho a provar després que la sincronització completi. + unlink_to_move: Per moure un enllaç, primer desenllaça'l del menú d'accions + del compte. + wait_for_sync: Si acabes de connectar o sincronitzar, torna-ho a provar després + que la sincronització acabi. setup_accounts: + account_card: + balance: Saldo + account_type_checking_savings: Corrent o estalvis + account_type_checking_savings_desc: Comptes bancaris habituals + account_type_credit_card: Targeta de crèdit + account_type_credit_card_desc: Comptes de targeta de crèdit + account_type_investment: Inversió + account_type_investment_desc: Corredoria, comptes 401(k), IRA + account_type_label: 'Tipus de compte:' + account_type_loan: Préstec o hipoteca + account_type_loan_desc: Comptes de deute + account_type_other_asset: Altre actiu + account_type_other_asset_desc: Tota la resta + activity: + days_ago: + one: fa 1 dia + other: fa %{count} dies + dormant: Sense activitat en %{days} dies + empty: Encara no s'han importat transaccions + likely_closed: Sense activitat recent i saldo zero — pot ser una targeta tancada + o substituïda + recent: + one: 1 transacció • darrera %{when} + other: "%{count} transaccions • darrera %{when}" + today: avui + yesterday: ahir + cancel: Cancel·la + choose_account_type: 'Tria el tipus de compte correcte per a cada compte SimpleFIN:' + create_accounts: Crea comptes + creating_accounts: Creant comptes... + header_subtitle: Tria els tipus de compte correctes per als teus comptes importats stale_accounts: action_delete: Elimina el compte i totes les transaccions action_move: 'Mou les transaccions a:' action_prompt: Què vols fer? action_skip: Omet ara - description: Aquests comptes existeixen a la teva base de dades però ja no s'ofereixen - per SimpleFIN. Això pot passar quan les configuracions del compte canvien a nivell superior. + description: Aquests comptes existeixen a la teva base de dades, però ja no + els ofereix SimpleFIN. Això pot passar quan la configuració del compte canvia + al proveïdor. title: Comptes ja no disponibles a SimpleFIN transaction_count: one: "%{count} transacció" other: "%{count} transaccions" + title: Configura els teus comptes SimpleFIN + transaction_history_description_html: SimpleFIN normalment proporciona 60-90 + dies d'historial de transaccions, segons el teu banc. Després de + la configuració inicial, les noves transaccions es sincronitzaran automàticament. + La disponibilitat de les dades històriques varia segons l'entitat i el tipus + de compte. + transaction_history_title: 'Historial de transaccions:' simplefin_item: - add_new: Afegeix nova connexió + accounts_skipped_label: 'Omesos: %{count}' + accounts_skipped_tooltip: S'han omès alguns comptes per errors durant la sincronització + add_new: Afegeix una connexió nova confirm_accept: Elimina la connexió confirm_body: Això eliminarà permanentment tots els comptes d'aquest grup i totes les dades associades. confirm_title: Vols eliminar la connexió SimpleFIN? delete: Elimina deletion_in_progress: "(eliminació en curs...)" - duplicate_accounts_skipped: S'han omès alguns comptes perquè eren duplicats — utilitza 'Enllaça - comptes existents' per fusionar-los. + duplicate_accounts_skipped: S'han omès alguns comptes perquè eren duplicats + — utilitza 'Enllaça comptes existents' per fusionar-los. error: S'ha produït un error en sincronitzar les dades + more_accounts_available: + one: "%{count} compte més disponible per configurar" + other: "%{count} comptes més disponibles per configurar" no_accounts_description: Aquesta connexió encara no té cap compte sincronitzat. no_accounts_title: No s'han trobat comptes - reconciled_details_note: "(consulta el resum de la sincronització per a més detalls)" - requires_update: Cal tornar a autenticar - setup_action: Configura nous comptes + rate_limited_ago: Límit de velocitat aplicat (fa %{time}) + rate_limited_recently: Límit de velocitat aplicat recentment + reconciled_details_note: "(consulta el resum de la sincronització per a més + detalls)" + requires_update: Reconnecta + setup_accounts_menu: Configura comptes + setup_action: Configura els nous comptes setup_description: Tria els tipus de compte per als teus nous comptes SimpleFIN importats. - setup_needed: Nous comptes llestos per configurar + setup_needed: Nous comptes a punt per configurar stale_pending_accounts: 'a: %{accounts}' stale_pending_note: "(exclòs dels pressupostos)" status: Darrera sincronització fa %{timestamp} status_never: Mai sincronitzat status_with_summary: Darrera sincronització fa %{timestamp} • %{summary} syncing: Sincronitzant... - update: Actualitza la connexió + update: Actualitza stale_pending_status: message: one: "%{count} transacció pendent anterior a %{days} dies" @@ -101,12 +183,11 @@ ca: update: errors: blank_token: Introdueix un token de configuració SimpleFIN. - invalid_token: Token de configuració invàlid. Comprova que has copiat el token - complet des de SimpleFIN Bridge. + invalid_token: Token de configuració no vàlid. Comprova que has copiat el + token complet des de SimpleFIN Bridge. token_compromised: El token de configuració pot estar compromès, caducat o ja utilitzat. Crea'n un de nou. - unexpected: S'ha produït un error inesperat. Torna-ho a provar o contacta - amb el suport. + unexpected: S'ha produït un error inesperat. Torna-ho a provar. update_failed: 'No s''ha pogut actualitzar la connexió: %{message}' success: Connexió SimpleFIN actualitzada correctament! Els teus comptes s'estan tornant a connectar. diff --git a/config/locales/views/simplefin_items/hu.yml b/config/locales/views/simplefin_items/hu.yml index ff1fad2d3..c2d844bc9 100644 --- a/config/locales/views/simplefin_items/hu.yml +++ b/config/locales/views/simplefin_items/hu.yml @@ -30,7 +30,34 @@ hu: label: "SimpleFIN beállítási token:" placeholder: "Illeszd be ide a SimpleFIN beállítási tokenedet..." help_text: "A token egy betűkkel és számokkal kezdődő hosszú karakterlánc" + title: SimpleFIN kapcsolat frissítése + header_subtitle: Szerezz be egy új beállítási tokent a SimpleFIN-fiókod újracsatlakoztatásához + connection_needs_update: "A SimpleFIN kapcsolatodat frissíteni kell:" + step_1_html: "Látogass el a SimpleFIN Bridge oldalra egy új beállítási token létrehozásához" + step_2: Másold ki a tokent és illeszd be alább + step_3: "Kattints a \"Frissítés\" gombra a hozzáférés visszaállításához" + update: Frissítés + cancel: Mégse setup_accounts: + title: SimpleFIN számlák beállítása + header_subtitle: Válaszd ki az importált számlák helyes típusait + choose_account_type: "Válaszd ki a megfelelő számlatípust minden SimpleFIN számlához:" + account_type_checking_savings: Folyó- vagy megtakarítási + account_type_checking_savings_desc: Normál bankszámlák + account_type_credit_card: Hitelkártya + account_type_credit_card_desc: Hitelkártya számlák + account_type_investment: Befektetési + account_type_investment_desc: "Brókeri, 401(k), IRA számlák" + account_type_loan: Hitel vagy jelzálog + account_type_loan_desc: Adósságszámlák + account_type_other_asset: Egyéb vagyon + account_type_other_asset_desc: Minden más + transaction_history_title: "Tranzakciós előzmények:" + transaction_history_description_html: "A SimpleFIN általában 60-90 nap tranzakciós előzményt biztosít, a banktól függően. A kezdeti beállítás után az új tranzakciók automatikusan szinkronizálódnak. Az előzmények elérhetősége intézményenként és számlatípusonként változó." + account_type_label: "Számla típusa:" + create_accounts: Számlák létrehozása + creating_accounts: Számlák létrehozása... + cancel: Mégse account_card: balance: "Egyenleg" activity: diff --git a/config/locales/views/snaptrade_items/ca.yml b/config/locales/views/snaptrade_items/ca.yml new file mode 100644 index 000000000..d270af3cf --- /dev/null +++ b/config/locales/views/snaptrade_items/ca.yml @@ -0,0 +1,209 @@ +--- +ca: + providers: + snaptrade: + accounts_count: + one: "%{count} compte" + other: "%{count} comptes" + client_id_label: Client ID + client_id_placeholder: Introdueix el teu Client ID de SnapTrade + client_id_update_placeholder: Introdueix un nou Client ID per actualitzar + connect_button: Connecta un broker + connected_brokerages: 'Connectats:' + connection_description: Connecta't al teu broker a través de SnapTrade (25+ + brokers admesos) + connections_error: 'No s''han pogut carregar les connexions: %{message}' + consumer_key_label: Consumer Key + consumer_key_placeholder: Introdueix la teva Consumer Key de SnapTrade + consumer_key_update_placeholder: Introdueix un nou Consumer Key per actualitzar + delete_connection: Elimina + delete_connection_body: Això eliminarà permanentment la connexió de %{brokerage} + de SnapTrade. Tots els comptes d'aquest broker quedaran sense enllaçar. Hauràs + de reconnectar per sincronitzar aquests comptes de nou. + delete_connection_confirm: Elimina la connexió + delete_connection_title: Vols eliminar la connexió amb el broker? + delete_orphaned_user: Elimina + delete_orphaned_user_body: Això eliminarà permanentment aquest usuari orfe de + SnapTrade i totes les seves connexions de broker, alliberant places de connexió. + delete_orphaned_user_confirm: Elimina el registre + delete_orphaned_user_title: Vols eliminar el registre orfe? + description: SnapTrade connecta amb més de 25 brokers importants (Fidelity, + Vanguard, Schwab, Robinhood, etc.) i proporciona l'historial complet d'operacions + amb etiquetes d'activitat i cost base. + free_tier_warning: El nivell gratuït de SnapTrade cobreix 5 connexions de broker. + Per a més, amplia el teu pla a SnapTrade. + loading_connections: Carregant connexions... + manage_connections: Gestiona connexions + name: SnapTrade + needs_linking: necessita enllaç + needs_setup: + one: "%{count} necessita configuració" + other: "%{count} necessiten configuració" + no_connections: No s'han trobat connexions de broker. + orphaned_connection: Connexió orfe (no sincronitzada localment) + orphaned_user: Registre orfe + orphaned_users_description: Aquests són registres d'usuari de SnapTrade anteriors + que ocupen places de connexió. Elimina'ls per alliberar places. + orphaned_users_title: + one: "%{count} registre orfe" + other: "%{count} registres orfes" + save_button: Desa la configuració + setup_accounts_button: Configura comptes + setup_title: 'Instruccions de configuració:' + status_connected: + one: "%{count} compte de SnapTrade" + other: "%{count} comptes de SnapTrade" + status_needs_registration: Credencials desades. Finalitza la configuració per + connectar un broker. + status_ready: Llest per connectar brokers + step_1_html: Crea un compte a dashboard.snaptrade.com + step_2: Copia el teu Client ID i Consumer Key des del panell + step_3: Introdueix les teves credencials a continuació i fes clic a Desa + step_4: Ves a la pàgina de comptes i utilitza 'Connecta un altre broker' per + enllaçar els teus comptes d'inversió + update_button: Actualitza la configuració + snaptrade_item: + brokerage_summary: + count: + one: "%{count} broker" + other: "%{count} brokers" + none: No hi ha brokers connectats + institution_summary: + count: + one: "%{count} entitat" + other: "%{count} entitats" + none: No hi ha entitats connectades + sync_status: + no_accounts: No s'han trobat comptes + synced: + one: "%{count} compte sincronitzat" + other: "%{count} comptes sincronitzats" + synced_with_setup: "%{linked} sincronitzats, %{unlinked} necessiten configuració" + syncer: + activities_fetching_async: Les activitats s'estan obtenint en segon pla. Pot + trigar fins a un minut per a connexions de broker noves. + calculating: Calculant saldos... + checking_config: Comprovant la configuració dels comptes... + discovering: Descobrint comptes... + importing: Important comptes des de SnapTrade... + needs_setup: "%{count} comptes necessiten configuració..." + processing: Processant posicions i activitats... + snaptrade_items: + callback: + no_item: No s'ha trobat la configuració de SnapTrade. + success: Broker connectat! Selecciona quins comptes vols enllaçar. + complete_account_setup: + link_failed: 'No s''han pogut enllaçar els comptes: %{errors}' + no_accounts: No s'ha seleccionat cap compte per enllaçar. + partial_success: + one: S'ha enllaçat %{count} compte. %{failed_count} no s'han pogut enllaçar. + other: S'han enllaçat %{count} comptes. %{failed_count} no s'han pogut enllaçar. + success: + one: S'ha enllaçat correctament %{count} compte. + other: S'han enllaçat correctament %{count} comptes. + connect: + connection_failed: 'No s''ha pogut connectar a SnapTrade: %{message}' + decryption_failed: No s'han pogut llegir les credencials de SnapTrade. Elimina + aquesta connexió i torna-la a crear. + connections: + unknown_brokerage: Broker desconegut + create: + success: SnapTrade s'ha configurat correctament. + default_name: Connexió SnapTrade + delete_connection: + api_deletion_failed: No s'ha pogut eliminar la connexió de SnapTrade — falten + les credencials. La connexió encara pot existir al teu compte SnapTrade. + failed: 'No s''ha pogut eliminar la connexió: %{message}' + missing_authorization_id: Falta l'ID d'autorització + success: La connexió s'ha eliminat correctament. S'ha alliberat una plaça. + delete_orphaned_user: + failed: No s'ha pogut eliminar el registre orfe. + success: El registre orfe s'ha eliminat correctament. + destroy: + success: S'ha programat la connexió SnapTrade per a la seva eliminació. + link_accounts: + use_setup_flow: Utilitza en el seu lloc el flux de configuració de comptes + link_existing_account: + failed: 'No s''ha pogut enllaçar el compte: %{message}' + not_found: No s'ha trobat el compte. + success: S'ha enllaçat correctament al compte SnapTrade. + preload_accounts: + not_configured: SnapTrade no està configurat. + select_accounts: + not_configured: SnapTrade no està configurat. + select_existing_account: + balance_label: 'Saldo:' + cancel_button: Cancel·la + connect_hint: Pot ser que hagis de connectar primer un broker. + header: Enllaça un compte existent + link_button: Enllaça + linking_to: 'Enllaçant al compte:' + no_accounts: No hi ha comptes SnapTrade sense enllaçar disponibles. + not_found: No s'ha trobat el compte o la configuració de SnapTrade. + settings_link: Ves a la configuració del proveïdor + subtitle: Selecciona un compte SnapTrade per enllaçar + title: Enllaça amb un compte SnapTrade + setup_accounts: + account_number: 'Compte:' + available_accounts: Comptes disponibles + back_to_settings: Torna a la configuració + balance_label: 'Saldo:' + cancel_button: Cancel·la + create_button: Crea els comptes seleccionats + creating: Creant comptes... + done_button: Fet + free_tier_note: El nivell gratuït de SnapTrade permet 5 connexions de broker. + Revisa el teu panell de SnapTrade per veure l'ús actual. + header: Configura els teus comptes SnapTrade + info_activities: Historial d'operacions amb etiquetes d'activitat (Compra, Venda, + Dividend, etc.) + info_cost_basis: Cost base per posició (quan estigui disponible) + info_history: Fins a 3 anys d'historial de transaccions + info_holdings: Posicions amb preus i quantitats actuals + info_title: Dades d'inversió SnapTrade + link_button: Enllaça + linked_accounts: Ja enllaçats + linked_to: 'Enllaçat a:' + loading: Obtenint comptes des de SnapTrade... + loading_hint: Fes clic a Actualitza per comprovar si hi ha comptes. + no_accounts_message: No s'ha trobat cap compte de broker. Això pot passar si + has cancel·lat la connexió o si el teu broker no està admès. + no_accounts_title: No s'han trobat comptes + or_link_existing: 'O enllaça a un compte existent en lloc de crear-ne un de + nou:' + refresh: Actualitza + select_account: Selecciona un compte... + subtitle: Selecciona quins comptes de broker vols enllaçar + sync_start_date_help: Deixa-ho en blanc per a tot l'historial disponible + sync_start_date_label: 'Importa transaccions des de:' + syncing: Obtenint els teus comptes... + title: Configura comptes SnapTrade + try_again: Connecta un broker + snaptrade_item: + accounts_need_setup: + one: "%{count} compte necessita configuració" + other: "%{count} comptes necessiten configuració" + add_another_brokerage: Connecta un altre broker + connect_brokerage: Connecta un broker + delete: Elimina + deletion_in_progress: Eliminació en curs... + error: Error de sincronització + manage_connections: Gestiona connexions + more_accounts_available: + one: "%{count} compte més disponible per configurar" + other: "%{count} comptes més disponibles per configurar" + no_accounts_description: Connecta un broker per importar els teus comptes d'inversió. + no_accounts_title: No s'han descobert comptes + reconnect: Reconnecta + requires_update: La connexió necessita actualització + setup_accounts_menu: Configura comptes + setup_action: Configura comptes + setup_description: Alguns comptes de SnapTrade necessiten ser enllaçats a comptes + de Sure. + setup_needed: Els comptes necessiten configuració + status: Darrera sincronització fa %{timestamp} - %{summary} + status_never: Mai sincronitzat + syncing: Sincronitzant... + update: + success: La configuració de SnapTrade s'ha actualitzat correctament. diff --git a/config/locales/views/snaptrade_items/hu.yml b/config/locales/views/snaptrade_items/hu.yml index 424ba7ca3..dab3d05ce 100644 --- a/config/locales/views/snaptrade_items/hu.yml +++ b/config/locales/views/snaptrade_items/hu.yml @@ -2,6 +2,8 @@ hu: snaptrade_items: default_name: "SnapTrade kapcsolat" + link_accounts: + use_setup_flow: Használd helyette a számlabeállítási folyamatot create: success: "SnapTrade sikeresen beállítva." update: @@ -74,6 +76,8 @@ hu: available_accounts: "Elérhető számlák" balance_label: "Egyenleg:" account_number: "Számla:" + sync_start_date_label: "Tranzakciók importálása ettől:" + sync_start_date_help: "Hagyd üresen az összes elérhető előzményhez" create_button: "Kiválasztott számlák létrehozása" cancel_button: "Mégse" creating: "Számlák létrehozása..." @@ -133,6 +137,7 @@ hu: needs_setup: one: "%{count} beállítást igényel" other: "%{count} beállítást igényel" + status_needs_registration: "Hitelesítő adatok elmentve. Fejezd be a beállítást egy brókercég csatlakoztatásához." status_ready: "Készen áll brókercégek csatlakoztatásához" setup_accounts_button: "Számlák beállítása" connect_button: "Brókercég csatlakoztatása" diff --git a/config/locales/views/sophtron_items/ca.yml b/config/locales/views/sophtron_items/ca.yml new file mode 100644 index 000000000..3b5321b74 --- /dev/null +++ b/config/locales/views/sophtron_items/ca.yml @@ -0,0 +1,365 @@ +--- +ca: + sophtron_items: + api_error: + bad_credentials: 'Credencials bancàries: comprova que el nom d''usuari i la + contrasenya són correctes' + check_provider_settings: Revisa la configuració del proveïdor + common_issues_title: 'Problemes habituals:' + expired_credentials: 'Credencials caducades: genera un nou ID d''usuari i clau + d''accés des de Sophtron' + incorrect_user_id: 'ID d''usuari incorrecte: verifica el teu ID d''usuari a + la configuració del proveïdor' + institution_timeout: 'Temps esgotat de l''entitat: la pàgina d''inici de sessió + del banc no ha acabat a temps' + institution_unable_to_connect: No s'ha pogut connectar amb l'entitat + invalid_access_key: 'Clau d''accés no vàlida: revisa la teva clau d''accés a + la configuració del proveïdor' + network_issue: 'Problema de xarxa: comprova la teva connexió a internet' + service_down: 'Servei caigut: l''API de Sophtron pot estar temporalment no disponible' + title: Error de connexió amb Sophtron + try_again: Torna a intentar la connexió + unable_to_connect: No s'ha pogut connectar a Sophtron + unsupported_mfa: 'Compatibilitat MFA: Sophtron pot no donar suport al flux de + verificació actual d''aquesta entitat' + verification_code: 'Codi de verificació: assegura''t que has introduït l''últim + codi abans que caduqui' + complete_account_setup: + all_skipped: S'han omès tots els comptes. No s'ha creat cap compte. + api_error: Error de connexió amb l'API + creation_failed: No s'han pogut crear els comptes + no_accounts: No hi ha comptes per configurar. + success: S'han creat correctament %{count} compte(s). + unexpected_error: S'ha produït un error inesperat + connect: + cancel: Cancel·la + captcha: Captcha + connect: Connecta + institution_search_label: Entitat + institution_search_placeholder: Cerca pel nom del banc + no_institutions: No s'han trobat entitats coincidents. + password: Contrasenya + search: Cerca + search_too_short: Introdueix almenys dos caràcters per cercar. + title: Connecta una entitat Sophtron + username: Nom d'usuari + connect_institution: + api_error: 'La connexió Sophtron ha fallat: %{message}' + missing_parameters: Selecciona una entitat i introdueix les teves credencials + d'inici de sessió bancari. + connection_status: + api_error: 'Error de connexió amb l''API: %{message}' + attempt: Intent %{attempt} de %{max} + check_again: Torna a comprovar + failed: Sophtron no ha pogut completar la connexió amb aquesta entitat. + failed_timeout: Sophtron ha esgotat el temps mentre l'entitat completava l'inici + de sessió. + timeout: Sophtron no ha completat la connexió dins del temps previst. Pots tornar + a comprovar-ho o intentar reconnectar més tard. + title: Connectant Sophtron + waiting: Sophtron encara s'està connectant a la teva entitat. + create: + success: La connexió Sophtron s'ha creat correctament + defaults: + name: Connexió Sophtron + destroy: + success: La connexió Sophtron s'ha eliminat + edit: + access_key: + help_text: La clau d'accés ha de ser una cadena llarga que comenci amb lletres + i números + label: 'Clau d''accés de Sophtron:' + placeholder: Enganxa aquí la teva clau d'accés de Sophtron... + user_id: + help_text: L'ID d'usuari ha de ser una cadena llarga que comenci amb lletres + i números + label: 'ID d''usuari de Sophtron:' + placeholder: Enganxa aquí el teu ID d'usuari de Sophtron... + index: + title: Connexions Sophtron + link_accounts: + all_already_linked: + one: El compte seleccionat (%{names}) ja està enllaçat + other: 'Tots els %{count} comptes seleccionats ja estan enllaçats: %{names}' + api_error: Error de connexió amb l'API + invalid_account_names: + one: No es pot enllaçar un compte sense nom + other: No es poden enllaçar %{count} comptes sense nom + link_failed: No s'han pogut enllaçar els comptes + no_access_key: La clau d'accés de Sophtron no està configurada. Configura-la + a la configuració. + no_accounts_found: No s'han trobat comptes. Comprova la configuració de la teva + clau API. + no_accounts_selected: Selecciona almenys un compte + no_credentials_configured: Primer, configura el teu ID d'usuari i clau d'accés + de Sophtron a la configuració del proveïdor. + no_institution_connected: Primer connecta una entitat bancària amb Sophtron. + no_user_id: L'ID d'usuari de Sophtron no està configurat. Configura'l a la configuració. + partial_invalid: S'han enllaçat correctament %{created_count} compte(s), %{already_linked_count} + ja estaven enllaçats, %{invalid_count} compte(s) tenien noms no vàlids + partial_success: 'S''han enllaçat correctament %{created_count} compte(s). %{already_linked_count} + compte(s) ja estaven enllaçats: %{already_linked_names}' + success: + one: S'ha enllaçat correctament %{count} compte + other: S'han enllaçat correctament %{count} comptes + link_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + api_error: Error de connexió amb l'API + invalid_account_name: No es pot enllaçar un compte sense nom + missing_parameters: Falten paràmetres obligatoris + no_institution_connected: Primer connecta una entitat bancària amb Sophtron. + sophtron_account_already_linked: Aquest compte Sophtron ja està enllaçat a un + altre compte + sophtron_account_not_found: No s'ha trobat el compte Sophtron + success: S'ha enllaçat correctament %{account_name} amb Sophtron + unexpected_error: S'ha produït un error inesperat + loading: + loading_message: Carregant comptes de Sophtron... + loading_title: Carregant + manual_sync_complete: + close: Tanca + description: Els saldos dels comptes acabaran d'actualitzar-se en segon pla. + message: S'han descarregat les transaccions després de la verificació de Sophtron. + title: Sincronització Sophtron iniciada + mfa: + captcha: Text del captcha + captcha_alt: Captcha de Sophtron + phone_confirmed: He confirmat per telèfon + submit: Envia + title: Verificació Sophtron + token: Codi de verificació + new: + access_key: Clau d'accés + access_key_placeholder: enganxa la teva clau d'accés de Sophtron + cancel: Cancel·la + connect: Connecta + title: Connecta Sophtron + user_id: ID d'usuari + user_id_placeholder: enganxa el teu ID d'usuari de Sophtron + preload_accounts: + api_error: Error de connexió amb l'API + no_access_key: La clau d'accés de Sophtron no està configurada. Configura-la + a la configuració. + no_accounts_found: No s'han trobat comptes. Comprova la configuració de la teva + clau API. + no_credentials_configured: Primer, configura el teu ID d'usuari i clau d'accés + de Sophtron a la configuració del proveïdor. + no_user_id: L'ID d'usuari de Sophtron no està configurat. Configura'l a la configuració. + preload_accounts: precarrega els comptes + unexpected_error: S'ha produït un error inesperat + redirect_after_account_link: + all_already_linked: + one: El compte seleccionat ja està enllaçat + other: Tots els %{count} comptes seleccionats ja estan enllaçats + invalid_account_names: + one: No es pot enllaçar %{count} compte sense nom + other: No es poden enllaçar %{count} comptes sense nom + link_failed: No s'han pogut enllaçar els comptes + partial_invalid: S'han enllaçat %{created_count} compte(s). %{already_linked_count} + ja estaven enllaçats, %{invalid_count} tenien noms no vàlids. + partial_success: S'han enllaçat %{created_count} compte(s). %{already_linked_count} + compte(s) ja estaven enllaçats. + success: + one: S'ha enllaçat correctament %{count} compte. + other: S'han enllaçat correctament %{count} comptes. + render_connection_timeout: + timeout: S'ha esgotat el temps de connexió. Torna-ho a provar. + select_accounts: + accounts_selected: comptes seleccionats + api_error: Error de connexió amb l'API + cancel: Cancel·la + configure_name_in_sophtron: No es pot importar — configura el nom del compte + a Sophtron + description: Selecciona els comptes que vols enllaçar al teu compte de %{product_name}. + link_accounts: Enllaça els comptes seleccionats + no_access_key: La clau d'accés de Sophtron no està configurada. Configura-la + a la configuració. + no_accounts_found: No s'han trobat comptes. Comprova la configuració de la teva + clau API. + no_credentials_configured: Primer, configura el teu ID d'usuari i clau d'accés + de Sophtron a la configuració del proveïdor. + no_institution_connected: Primer connecta una entitat bancària amb Sophtron. + no_name_placeholder: "(Sense nom)" + no_user_id: L'ID d'usuari de Sophtron no està configurat. Configura'l a la configuració. + title: Selecciona comptes Sophtron + unexpected_error: S'ha produït un error inesperat + select_existing_account: + account_already_linked: Aquest compte ja està enllaçat a un proveïdor + all_accounts_already_linked: Tots els comptes Sophtron ja estan enllaçats + api_error: Error de connexió amb l'API + cancel: Cancel·la + configure_name_in_sophtron: No es pot importar — configura el nom del compte + a Sophtron + description: Selecciona un compte Sophtron per enllaçar-lo amb aquest compte. + Les transaccions es sincronitzaran i deduplicaran automàticament. + link_account: Enllaça compte + no_access_key: La clau d'accés de Sophtron no està configurada. Configura-la + a la configuració. + no_account_specified: No s'ha especificat cap compte + no_accounts_found: No s'han trobat comptes Sophtron. Comprova la configuració + de la teva clau API. + no_institution_connected: Primer connecta una entitat bancària amb Sophtron. + no_name_placeholder: "(Sense nom)" + no_user_id: L'ID d'usuari de Sophtron no està configurat. Configura'l a la configuració. + title: Enllaça %{account_name} amb Sophtron + unexpected_error: S'ha produït un error inesperat + select_option: Selecciona %{type} + setup_accounts: + account_type_label: 'Tipus de compte:' + account_types: + credit_card: Targeta de crèdit + depository: Compte corrent o d'estalvis + investment: Compte d'inversió + loan: Préstec o hipoteca + other_asset: Altre actiu + skip: Omet aquest compte + all_accounts_linked: Tots els teus comptes Sophtron ja s'han configurat. + api_error: Error de connexió amb l'API + balance: Saldo + cancel: Cancel·la + choose_account_type: 'Tria el tipus de compte correcte per a cada compte Sophtron:' + create_accounts: Crea comptes + creating_accounts: Creant comptes... + fetch_failed: No s'han pogut obtenir els comptes + historical_data_range: 'Rang de dades històriques:' + no_access_key: La clau d'accés de Sophtron no està configurada. Revisa la configuració + de la connexió. + no_accounts_to_setup: No hi ha comptes per configurar + no_institution_connected: L'entitat Sophtron encara no està connectada. + no_user_id: L'ID d'usuari de Sophtron no està configurat. Revisa la configuració + de la connexió. + subtitle: Tria els tipus de compte correctes per als teus comptes importats + subtype_labels: + credit_card: '' + depository: 'Subtipus de compte:' + investment: 'Tipus d''inversió:' + loan: 'Tipus de préstec:' + other_asset: '' + subtype_messages: + credit_card: Les targetes de crèdit es configuraran automàticament com a comptes + de targeta de crèdit. + other_asset: No calen opcions addicionals per a altres actius. + sync_start_date_help: Selecciona fins on vols sincronitzar l'historial de transaccions. + Hi ha un màxim de 3 anys d'historial disponible. + sync_start_date_label: 'Comença a sincronitzar transaccions des de:' + title: Configura els teus comptes Sophtron + unexpected_error: S'ha produït un error inesperat + sophtron_entry: + processor: + unknown_transaction: Transacció desconeguda + sophtron_item: + accounts_need_setup: Els comptes necessiten configuració + automatic_sync: Utilitza la sincronització automàtica + automatic_sync_for: Utilitza la sincronització automàtica per a %{institution} + delete: Elimina la connexió + deletion_in_progress: eliminació en curs... + error: Error + manual_sync: Sincronització manual + manual_sync_action: Requereix sincronització manual + manual_sync_action_for: Requereix sincronització manual per a %{institution} + no_accounts_description: Aquesta connexió encara no té comptes enllaçats. + no_accounts_title: No hi ha comptes + setup_action: Configura els nous comptes + setup_description: "%{linked} de %{total} comptes enllaçats. Tria els tipus + de compte per als teus nous comptes Sophtron importats." + setup_needed: Nous comptes a punt per configurar + status: Sincronitzat fa %{timestamp} + status_never: Mai sincronitzat + status_with_summary: Darrera sincronització fa %{timestamp} • %{summary} + sync_now: Sincronitza ara + syncing: Sincronitzant... + total: Total + unlinked: Sense enllaç + sophtron_panel: + field_descriptions: + access_key_html: "Clau d'accés: la teva credencial de clau + d'accés de Sophtron" + base_url_html: "URL base: l'URL de l'endpoint de l'API de + Sophtron, normalment https://api.sophtron.com/api" + user_id_html: "ID d'usuari: la teva credencial d'ID d'usuari + de Sophtron" + field_descriptions_title: 'Descripció dels camps:' + fields: + access_key: + label: Clau d'accés + placeholder_edit: "••••••••" + placeholder_new: Enganxa la teva clau d'accés de Sophtron + base_url: + label: URL base + placeholder: https://api.sophtron.com/api + user_id: + label: ID d'usuari + placeholder_edit: "••••••••" + placeholder_new: Enganxa el teu ID d'usuari de Sophtron + save: Desa la configuració + setup_instructions: + step_1_html: Visita Sophtron per obtenir les teves credencials API + step_2: Copia el teu ID d'usuari i clau d'accés des de la configuració del + teu compte Sophtron + step_3: Enganxa les credencials a continuació i fes clic a Desa; Sure crearà + o reutilitzarà el teu ID de client de Sophtron automàticament + setup_instructions_title: 'Instruccions de configuració:' + update: Actualitza la configuració + sophtron_setup_required: + description: Abans d'enllaçar comptes Sophtron, has de configurar el teu ID + d'usuari i clau d'accés de Sophtron. + go_to_provider_settings: Ves a la configuració del proveïdor + heading: ID d'usuari i clau d'accés sense configurar + message: Per completar la configuració de la teva connexió Sophtron, ves a la + pàgina de configuració del proveïdor i segueix les instruccions per autoritzar + i configurar la teva connexió Sophtron. + setup_steps_title: 'Passos de configuració:' + step_1_html: Ves a Configuració → Proveïdors de sincronització bancària + step_2_html: Localitza la secció Sophtron + step_3_html: Introdueix el teu ID d'usuari i clau d'accés de Sophtron + step_4: Torna aquí per enllaçar els teus comptes + title: Cal configurar Sophtron + start_manual_sync: + already_running: Ja s'està executant una sincronització. + api_error: 'Error de l''API: %{message}' + no_linked_accounts: No hi ha comptes enllaçats disponibles per sincronitzar. + start_manual_sync_for_account: + failed: No s'ha pogut sincronitzar el compte + submit_mfa: + api_error: 'La verificació ha fallat: %{message}' + invalid_security_answers: Les respostes de seguretat falten o són massa llargues. + unknown_challenge: Pas de verificació Sophtron desconegut. + subtype: subtipus + sync: + already_running: La sincronització manual de Sophtron ja s'està executant. + api_error: 'La sincronització manual de Sophtron ha fallat: %{message}' + failed: La sincronització manual de Sophtron ha fallat + no_linked_accounts: Aquesta entitat Sophtron no té cap compte enllaçat per sincronitzar. + processing_failed: La sincronització manual de Sophtron no ha pogut processar + les transaccions actualitzades. + success: Sincronització iniciada + syncer: + accounts_need_setup: "%{count} compte(s) necessiten configuració" + calculating_balances: Calculant saldos per als comptes enllaçats... + checking_account_configuration: Comprovant la configuració dels comptes... + importing_accounts: Important comptes des de Sophtron... + manual_sync_required: Cal sincronització manual de Sophtron per a aquesta entitat; + els seus comptes s'ometen durant la sincronització automàtica. + processing_transactions: Processant transaccions per als comptes enllaçats... + toggle_manual_sync: + success_disabled: L'entitat Sophtron se sincronitzarà automàticament. + success_enabled: L'entitat Sophtron ara requereix sincronització manual. + type: tipus + update: + errors: + access_key_compromised: La clau d'accés pot estar compromesa, caducada o ja + utilitzada. Crea'n una de nova. + blank_access_key: Introdueix una clau d'accés de Sophtron. + blank_user_id: Introdueix un ID d'usuari de Sophtron. + invalid_access_key: Clau d'accés no vàlida. Comprova que has copiat la clau + d'accés completa des de Sophtron. + invalid_user_id: ID d'usuari no vàlid. Comprova que has copiat l'ID d'usuari + complet des de Sophtron. + unexpected: S'ha produït un error inesperat. Torna-ho a provar o contacta + amb el suport. + update_failed: 'No s''ha pogut actualitzar la connexió: %{message}' + user_id_compromised: L'ID d'usuari pot estar compromès, caducat o ja utilitzat. + Crea'n un de nou. + success: La connexió Sophtron s'ha actualitzat correctament! Els teus comptes + s'estan tornant a connectar. diff --git a/config/locales/views/sophtron_items/hu.yml b/config/locales/views/sophtron_items/hu.yml index a4cb2d375..c64f06715 100644 --- a/config/locales/views/sophtron_items/hu.yml +++ b/config/locales/views/sophtron_items/hu.yml @@ -59,6 +59,42 @@ hu: no_accounts_found: Nem találhatók számlák. Kérlek ellenőrizd az API-kulcs konfigurációdat. no_access_key: A Sophtron hozzáférési kulcs nincs beállítva. Kérlek állítsd be a Beállításokban. no_user_id: A Sophtron felhasználói azonosító nincs beállítva. Kérlek állítsd be a Beállításokban. + no_institution_connected: Kérlek először csatlakoztass egy banki intézményt a Sophtron-nal. + connect: + cancel: Mégse + captcha: Captcha + connect: Csatlakozás + institution_search_label: Intézmény + institution_search_placeholder: Keresés banknév szerint + no_institutions: Nem találhatók egyező intézmények. + password: Jelszó + search: Keresés + search_too_short: Legalább két karaktert adj meg a kereséshez. + title: Sophtron intézmény csatlakoztatása + username: Felhasználónév + connect_institution: + api_error: "Sophtron kapcsolódás sikertelen: %{message}" + missing_parameters: Válassz intézményt és add meg a banki bejelentkezési adataidat. + connection_status: + api_error: "API kapcsolódási hiba: %{message}" + attempt: "%{attempt}. kísérlet a(z) %{max}-ból" + check_again: Ellenőrzés újra + failed: A Sophtron nem tudta befejezni ezt az intézményi kapcsolatot. + failed_timeout: A Sophtron túllépte az időkorlátot, miközben az intézmény befejezi a bejelentkezést. + timeout: A Sophtron nem fejezte be a kapcsolódást a várt időn belül. Ellenőrizheted újra, vagy próbálkozz meg a kapcsolódással később. + title: Sophtron csatlakoztatása + waiting: A Sophtron még kapcsolódik az intézményedhez. + mfa: + captcha: Captcha szöveg + captcha_alt: Sophtron captcha + phone_confirmed: Telefonon megerősítettem + submit: Elküldés + title: Sophtron ellenőrzés + token: Ellenőrző kód + submit_mfa: + api_error: "Ellenőrzés sikertelen: %{message}" + invalid_security_answers: A biztonsági válaszok hiányoznak vagy túl hosszúak. + unknown_challenge: Ismeretlen Sophtron ellenőrzési lépés. sophtron_item: accounts_need_setup: Számlák beállítást igényelnek automatic_sync: Automatikus szinkronizálás használata @@ -102,6 +138,7 @@ hu: no_user_id: A Sophtron felhasználói azonosító nincs beállítva. Kérlek állítsd be a Beállításokban. no_credentials_configured: "Kérlek előbb állítsd be a Sophtron API felhasználói azonosítódat és hozzáférési kulcsodat a Szolgáltatói beállításokban." no_name_placeholder: "(Nincs név)" + no_institution_connected: Kérlek először csatlakoztass egy banki intézményt a Sophtron-nal. title: Sophtron számlák kiválasztása select_existing_account: account_already_linked: Ez a számla már össze van kapcsolva egy szolgáltatóval @@ -116,7 +153,9 @@ hu: no_access_key: A Sophtron hozzáférési kulcs nincs beállítva. Kérlek állítsd be a Beállításokban. no_user_id: A Sophtron felhasználói azonosító nincs beállítva. Kérlek állítsd be a Beállításokban. no_name_placeholder: "(Nincs név)" + no_institution_connected: Kérlek először csatlakoztass egy banki intézményt a Sophtron-nal. title: "%{account_name} összekapcsolása a Sophtron-nal" + unexpected_error: "Váratlan hiba történt" link_existing_account: account_already_linked: Ez a számla már össze van kapcsolva egy szolgáltatóval api_error: "API kapcsolódási hiba" @@ -125,6 +164,7 @@ hu: sophtron_account_already_linked: Ez a Sophtron számla már össze van kapcsolva egy másik számlával sophtron_account_not_found: Sophtron számla nem található missing_parameters: Hiányzó kötelező paraméterek + no_institution_connected: Kérlek először csatlakoztass egy banki intézményt a Sophtron-nal. success: "%{account_name} sikeresen összekapcsolva a Sophtron-nal" setup_accounts: account_type_label: "Számla típusa:" @@ -135,13 +175,14 @@ hu: no_accounts_to_setup: "Nincs beállítandó számla" no_access_key: "A Sophtron hozzáférési kulcs nincs beállítva. Kérlek ellenőrizd a kapcsolati beállításaidat." no_user_id: "A Sophtron felhasználói azonosító nincs beállítva. Kérlek ellenőrizd a kapcsolati beállításaidat." + no_institution_connected: "A Sophtron intézmény még nincs csatlakoztatva." account_types: skip: Számla kihagyása depository: Folyó- vagy megtakarítási számla credit_card: Hitelkártya investment: Befektetési számla loan: Hitel vagy jelzálog - other_asset: Egyéb eszköz + other_asset: Egyéb vagyon subtype_labels: depository: "Számla altípusa:" credit_card: "" @@ -150,7 +191,7 @@ hu: other_asset: "" subtype_messages: credit_card: "A hitelkártyák automatikusan hitelkártya számlákként lesznek beállítva." - other_asset: "Az egyéb eszközökhöz nincs szükség további beállításokra." + other_asset: "Az egyéb vagyonelemekhez nincs szükség további beállításokra." balance: Egyenleg cancel: Mégse choose_account_type: "Válaszd ki a megfelelő számlatípust minden Sophtron számlához:" @@ -198,13 +239,19 @@ hu: api_error: title: "Sophtron kapcsolódási hiba" unable_to_connect: "Nem sikerült csatlakozni a Sophtron-hoz" + institution_unable_to_connect: "Nem sikerült csatlakozni az intézményhez" common_issues_title: "Gyakori problémák:" incorrect_user_id: "Helytelen felhasználói azonosító: Ellenőrizd a felhasználói azonosítódat a Szolgáltatói beállításokban" invalid_access_key: "Érvénytelen hozzáférési kulcs: Ellenőrizd a hozzáférési kulcsodat a Szolgáltatói beállításokban" expired_credentials: "Lejárt hitelesítő adatok: Hozz létre új felhasználói azonosítót és hozzáférési kulcsot a Sophtron-ban" network_issue: "Hálózati probléma: Ellenőrizd az internetkapcsolatodat" service_down: "Szolgáltatás leállása: A Sophtron API ideiglenesen nem érhető el" + bad_credentials: "Banki bejelentkezési adatok: Ellenőrizd, hogy a felhasználónév és jelszó helyes-e" + verification_code: "Ellenőrző kód: Győződj meg róla, hogy a legújabb kódot adtad meg, mielőtt lejárt" + institution_timeout: "Intézményi időtúllépés: A bank bejelentkezési oldala nem fejezte be a folyamatot időben" + unsupported_mfa: "MFA-támogatás: A Sophtron esetleg nem támogatja az intézmény jelenlegi ellenőrzési folyamatát" check_provider_settings: "Szolgáltatói beállítások ellenőrzése" + try_again: "Próbálkozz újra a csatlakozással" select_option: "%{type} kiválasztása" subtype: "altípus" type: "típus" @@ -243,3 +290,24 @@ hu: sophtron_entry: processor: unknown_transaction: "Ismeretlen tranzakció" + render_connection_timeout: + timeout: "A kapcsolat túllépte az időkorlátot. Kérlek próbáld újra." + redirect_after_account_link: + invalid_account_names: + one: "%{count} számlát nem lehet összekapcsolni üres névvel" + other: "%{count} számlát nem lehet összekapcsolni üres névvel" + partial_invalid: "%{created_count} számla összekapcsolva. %{already_linked_count} már össze volt kapcsolva, %{invalid_count} érvénytelen névvel rendelkezik." + partial_success: "%{created_count} számla összekapcsolva. %{already_linked_count} számla már össze volt kapcsolva." + success: + one: "%{count} számla sikeresen összekapcsolva." + other: "%{count} számla sikeresen összekapcsolva." + all_already_linked: + one: "A kiválasztott számla már össze van kapcsolva" + other: "Mind a(z) %{count} kiválasztott számla már össze van kapcsolva" + link_failed: "Nem sikerült összekapcsolni a számlákat" + start_manual_sync: + already_running: "Már folyamatban van egy szinkronizálás." + no_linked_accounts: "Nincs elérhető összekapcsolt számla a szinkronizáláshoz." + api_error: "API hiba: %{message}" + start_manual_sync_for_account: + failed: "Nem sikerült szinkronizálni a számlát" diff --git a/config/locales/views/splits/ca.yml b/config/locales/views/splits/ca.yml new file mode 100644 index 000000000..437a7280d --- /dev/null +++ b/config/locales/views/splits/ca.yml @@ -0,0 +1,51 @@ +--- +ca: + splits: + child: + description: Aquesta entrada forma part d'una transacció dividida. + edit_split: Edita la divisió + title: Part d'una divisió + unsplit: Desfés la divisió + create: + not_splittable: Aquesta transacció no es pot dividir. + success: Transacció dividida correctament + destroy: + success: Divisió desfeta correctament + edit: + description: Modifica les entrades de la divisió d'aquesta transacció. + not_split: Aquesta transacció no està dividida. + submit: Actualitza la divisió + title: Edita la divisió + new: + add_row: Afegeix divisió + amount_label: Import + amounts_must_match: La suma dels imports de la divisió ha de ser igual a l'import + original de la transacció. + cancel: Cancel·la + category_label: Categoria + description: Divideix aquesta transacció en diverses entrades amb categories + i imports diferents. + name_label: Nom + name_placeholder: Nom de la divisió + original_amount: Import + original_date: 'Data:' + original_name: 'Nom:' + remaining: Restant + remove_row: Elimina + split_number: 'Divisió #%{number}' + submit: Divideix la transacció + title: Divideix la transacció + uncategorized: "(sense categoria)" + show: + button: Divideix + button_description: Divideix aquesta transacció en diverses entrades amb categories + i imports diferents. + button_title: Divideix la transacció + description: Aquesta transacció s'ha dividit en les entrades següents. + title: Entrades de la divisió + unsplit_button: Desfés la divisió + unsplit_confirm: Això eliminarà totes les entrades de la divisió i restaurarà + la transacció original. + unsplit_title: Desfés la divisió + update: + success: Divisió actualitzada correctament diff --git a/config/locales/views/subscriptions/ca.yml b/config/locales/views/subscriptions/ca.yml index eb162c4ca..521b8124b 100644 --- a/config/locales/views/subscriptions/ca.yml +++ b/config/locales/views/subscriptions/ca.yml @@ -1,14 +1,26 @@ --- ca: subscriptions: + create: + trial_already_used: Ja has començat o completat una prova. Actualitza per continuar. + welcome: Benvingut/da a Sure! self_hosted_alert: "%{product_name} no està disponible en mode autoallotjat." + success: + contribution_failed: Alguna cosa ha anat malament en processar la teva contribució. + Torna-ho a provar. + welcome_with_contribution: Benvingut/da a Sure! Agraïm la teva contribució. upgrade: - contribute_and_support_sure: "Contribuir i donar suport a Sure" - cta: "Continua donant suport al desenvolupament d'aquest codi!" + account_settings: Configuració del compte + already_contributing: Ja hi estàs contribuint. Gràcies! + contribute_and_support_sure: Contribueix i dona suport a Sure + cta: Continua donant suport al desenvolupament d'aquest codi! header: - support: "Suport" - sure: "Sure" - today: "avui" - redirect_to_stripe: "En el proper pas, se us redirigirà a Stripe, que gestiona les targetes de crèdit per nosaltres." - trialing: "Les teves dades s'eliminaran en %{days} dies" - trial_over: "El teu període de prova ha acabat" \ No newline at end of file + support: Dona suport a + sure: Sure + today: avui + page_title: Actualitza + redirect_to_stripe: Al pas següent, se't redirigirà a Stripe, que gestiona les + targetes de crèdit per a nosaltres. + sign_out: Tanca la sessió + trial_over: El teu període de prova ha acabat + trialing: Les teves dades s'eliminaran d'aquí %{days} dies diff --git a/config/locales/views/subscriptions/hu.yml b/config/locales/views/subscriptions/hu.yml index 996f3a56b..b2b70f03f 100644 --- a/config/locales/views/subscriptions/hu.yml +++ b/config/locales/views/subscriptions/hu.yml @@ -3,6 +3,10 @@ hu: subscriptions: self_hosted_alert: "%{product_name} önállóan üzemeltetett módban nem érhető el." upgrade: + already_contributing: Már hozzájárulsz. Köszönjük! + page_title: "Frissítés" + account_settings: "Fiókbeállítások" + sign_out: "Kijelentkezés" contribute_and_support_sure: "Járulj hozzá és támogasd a Sure-t" cta: "Folytasd ennek a kódbázisnak a fejlesztésének támogatását!" header: @@ -12,3 +16,9 @@ hu: redirect_to_stripe: "A következő lépésben átirányítunk a Stripe-ra, amely kezeli a bankkártyás fizetéseket." trialing: "Az adataid %{days} nap múlva törlésre kerülnek" trial_over: "A próbaidőszakod lejárt" + create: + welcome: "Üdvözlünk a Sure-ban!" + trial_already_used: "Már elindítottál vagy befejezted egy próbaidőszakot. A folytatáshoz kérlek frissítsd az előfizetésedet." + success: + welcome_with_contribution: "Üdvözlünk a Sure-ban! Köszönjük a hozzájárulásodat." + contribution_failed: "Hiba történt a hozzájárulás feldolgozása során. Kérlek próbáld újra." diff --git a/config/locales/views/tag/deletions/ca.yml b/config/locales/views/tag/deletions/ca.yml index 21559e806..e9e59777d 100644 --- a/config/locales/views/tag/deletions/ca.yml +++ b/config/locales/views/tag/deletions/ca.yml @@ -6,6 +6,7 @@ ca: deleted: Etiqueta eliminada new: delete_and_leave_uncategorized: Elimina "%{tag_name}" + delete_and_reassign: Elimina i reassigna delete_and_recategorize: Elimina "%{tag_name}" i assigna una nova etiqueta delete_tag: Vols eliminar l'etiqueta? explanation: "%{tag_name} s'eliminarà de les transaccions i altres entitats diff --git a/config/locales/views/tag/deletions/hu.yml b/config/locales/views/tag/deletions/hu.yml index c923f762f..f0a10847e 100644 --- a/config/locales/views/tag/deletions/hu.yml +++ b/config/locales/views/tag/deletions/hu.yml @@ -7,6 +7,7 @@ hu: new: delete_and_leave_uncategorized: '"%{tag_name}" törlése' delete_and_recategorize: '"%{tag_name}" törlése és új címke hozzárendelése' + delete_and_reassign: Törlés és újraosztás delete_tag: Törlöd a címkét? explanation: "%{tag_name} el lesz távolítva a tranzakciókból és egyéb, címkézett elemekből. Ahelyett, hogy címke nélkül maradnának, alább új címkét is hozzárendelhetsz." replacement_tag_prompt: Válassz címkét diff --git a/config/locales/views/tags/ca.yml b/config/locales/views/tags/ca.yml index c34489679..95a611a80 100644 --- a/config/locales/views/tags/ca.yml +++ b/config/locales/views/tags/ca.yml @@ -6,11 +6,14 @@ ca: error: 'Error en crear l''etiqueta: %{error}' destroy: deleted: Etiqueta eliminada + destroy_all: + all_deleted: Totes les etiquetes eliminades edit: edit: Edita l'etiqueta form: placeholder: Nom de l'etiqueta index: + delete_all: Elimina-les totes empty: Encara no hi ha etiquetes new: Nova etiqueta tags: Etiquetes diff --git a/config/locales/views/tags/hu.yml b/config/locales/views/tags/hu.yml index 0edff9b46..ee487af83 100644 --- a/config/locales/views/tags/hu.yml +++ b/config/locales/views/tags/hu.yml @@ -6,6 +6,8 @@ hu: error: 'Hiba a címke létrehozásakor: %{error}' destroy: deleted: Címke törölve + destroy_all: + all_deleted: Minden címke törölve edit: edit: Címke szerkesztése form: @@ -14,6 +16,7 @@ hu: empty: Még nincsenek címkék new: Új címke tags: Címkék + delete_all: Összes törlése new: new: Új címke tag: diff --git a/config/locales/views/trades/ca.yml b/config/locales/views/trades/ca.yml index ef908c4df..be167ae6d 100644 --- a/config/locales/views/trades/ca.yml +++ b/config/locales/views/trades/ca.yml @@ -5,15 +5,26 @@ ca: account: Compte de transferència (opcional) account_prompt: Cerca compte amount: Import + dividend_requires_security: El valor és obligatori per als dividends + fee: Comissió de la transacció holding: Símbol del valor + holding_optional: Símbol del valor (opcional) price: Preu per acció qty: Quantitat - submit: Afegeix transacció + submit: Afegeix la transacció ticker_placeholder: AAPL type: Tipus + type_buy: Compra + type_deposit: Dipòsit + type_dividend: Dividend + type_interest: Interès + type_sell: Venda + type_withdrawal: Retirada header: buy: Compra current_market_price_label: Preu de mercat actual + dividend: Dividend + interest: Interès overview: Resum purchase_price_label: Preu de compra purchase_qty_label: Quantitat comprada @@ -24,17 +35,25 @@ ca: title: Nova transacció show: additional: Addicional + amount_label: Import + buy: Compra category_label: Categoria cost_per_share_label: Cost per acció date_label: Data delete: Elimina delete_subtitle: Aquesta acció no es pot desfer - delete_title: Elimina operació + delete_title: Elimina l'operació details: Detalls - exclude_subtitle: Aquesta operació no s'inclourà en informes ni càlculs + exclude_subtitle: Aquesta operació no s'inclourà als informes ni als càlculs exclude_title: Exclou de l'analítica + fee_label: Comissió de la transacció no_category: Sense categoria note_label: Nota note_placeholder: Afegeix aquí qualsevol nota addicional... + provider_disabled_warning: Actualitzacions de preu en pausa — el proveïdor %{provider} + està desactivat. Torna a activar-lo a la configuració o reassigna la posició + a un altre proveïdor. quantity_label: Quantitat + sell: Venda settings: Configuració + type_label: Tipus diff --git a/config/locales/views/transactions/ca.yml b/config/locales/views/transactions/ca.yml index dc3b94981..e147de78d 100644 --- a/config/locales/views/transactions/ca.yml +++ b/config/locales/views/transactions/ca.yml @@ -1,6 +1,148 @@ --- ca: transactions: + activity_labels: + buy: Compra + contribution: Aportació + dividend: Dividend + exchange: Bescanvi + fee: Comissió + interest: Interès + other: Altres + reinvestment: Reinversió + sell: Venda + sweep_in: Sweep entrant + sweep_out: Sweep sortint + transfer: Transferència + withdrawal: Retirada + attachments: + attachment_deleted: Adjunt eliminat correctament + browse_to_add: Cerca per afegir fitxers + cannot_exceed: No es poden superar %{count} adjunts per transacció + delete_failed: No s'ha pogut eliminar l'adjunt. Torna-ho a provar o contacta + amb suport. + failed_delete: 'No s''ha pogut eliminar l''adjunt: %{error}' + failed_upload: 'No s''ha pogut pujar l''adjunt: %{error}' + files: + one: Fitxer (1) + other: Fitxers (%{count}) + max_reached: S'ha arribat al límit de fitxers (%{count}/%{max}). Elimina un + fitxer existent per pujar-ne un altre. + no_attachments: Encara no hi ha adjunts + no_files_selected: No s'ha seleccionat cap fitxer per pujar + select_up_to: Selecciona fins a %{count} fitxers (imatges o PDF, màx %{size}MB + cadascun) • %{used} d'%{count} utilitzats + upload: Puja + upload_failed: No s'ha pogut pujar l'adjunt. Torna-ho a provar o contacta amb + suport. + uploaded_many: "%{count} adjunts pujats correctament" + uploaded_one: Adjunt pujat correctament + bulk_updates: + new: + cancel: Cancel·la + category_label: Categoria + category_prompt: Selecciona una categoria + date_label: Data + header_title: Edita transaccions + merchant_label: Comerç + merchant_prompt: Selecciona un comerç + name_label: Nom + name_placeholder: Introdueix un nom que s'aplicarà a les transaccions seleccionades + none: "(cap)" + notes_label: Notes + notes_placeholder: Introdueix una nota que s'aplicarà a les transaccions seleccionades + overview: Resum + save: Desa + tags_label: Etiquetes + transactions_section: Transaccions + categorizes: + create: + categorized: + one: 1 transacció categoritzada + other: "%{count} transaccions categoritzades" + rule_creation_failed: Transaccions categoritzades, però no s'ha pogut crear + la regla (potser ja existeix). + entry_row: + assign_category_select: Assigna categoria per a %{name} + include_checkbox: Inclou %{name} + show: + all_done: Totes les transaccions estan categoritzades + assign_category: Assigna una categoria + assign_category_prompt: "→ assigna" + col_amount: Import + col_category: Categoria + col_date: Data + col_transaction: Transacció + create_rule_label: Crea regla de categorització + exit: Surt + filter_placeholder: Cerca categories... + no_categories: No hi ha categories coincidents + remaining: + one: Queda 1 transacció sense categoritzar + other: Queden %{count} transaccions sense categoritzar + rule_description_prefix: Les futures transaccions de tipus %{type} amb nom + que contingui + rule_description_suffix: també haurien de rebre aquesta categoria. + skip: Omet + transaction_count: + one: 1 transacció + other: "%{count} transaccions" + transactions_hint: Desmarca per excloure una transacció, o assigna-li una + categoria diferent directament a la seva fila. + type_expense: Despesa + type_income: Ingrés + convert_to_trade: + account_label: 'Compte:' + amount_label: 'Import:' + cancel: Cancel·la + conversion_note: 'Convertit de la transacció: %{original_name} (%{original_date})' + date_label: 'Data:' + description: Converteix aquesta transacció en una operació amb detalls de valor + errors: + already_converted: Aquesta transacció ja s'ha convertit o exclòs + conversion_failed: 'No s''ha pogut convertir la transacció: %{error}' + enter_qty_or_price: Introdueix la quantitat o el preu per acció. L'altre es + calcularà a partir de l'import de la transacció. + enter_ticker: Introdueix un símbol de cotització + invalid_qty_or_price: Quantitat o preu invàlids. Introdueix valors positius + vàlids. + not_investment_account: Només es poden convertir en operacions les transaccions + de comptes d'inversió + security_not_found: El valor seleccionat ja no existeix. Selecciona'n un altre. + select_security: Selecciona o introdueix un valor + unexpected_error: 'Error inesperat durant la conversió: %{error}' + exchange_hint: Deixa-ho en blanc per detectar-ho automàticament + exchange_label: Mercat (opcional) + exchange_placeholder: XNAS + price_hint: Preu per acció (%{currency}) + price_label: Preu per acció + price_mismatch_message: El teu preu (%{entered_price}/acció) difereix significativament + del preu de mercat actual de %{ticker} (%{market_price}). Si sembla incorrecte, + potser has seleccionat el valor equivocat — prova "Introdueix una cotització + personalitzada" per especificar el correcte. + price_mismatch_title: El preu pot no coincidir + price_placeholder: p. ex. 52,15 + qty_or_price_hint: Introdueix com a mínim la quantitat O el preu. L'altre es + calcularà a partir de l'import de la transacció (%{amount}). + quantity_hint: Nombre d'accions operades + quantity_label: Quantitat (accions) + quantity_placeholder: p. ex. 20 + security_custom: "+ Introdueix un ticker personalitzat" + security_label: Valor + security_not_listed_hint: No veus el teu valor? Selecciona "Introdueix un ticker + personalitzat" al final de la llista. + security_prompt: Selecciona un valor... + submit: Converteix en operació + success: Transacció convertida en operació + ticker_hint: Introdueix el símbol del valor (p. ex. AAPL, MSFT) + ticker_placeholder: AAPL + ticker_search_hint: Cerca per símbol o nom d'empresa, o escriu un símbol personalitzat + ticker_search_placeholder: Cerca un símbol... + title: Converteix en operació de valors + trade_type_hint: Compra o ven accions d'un valor + trade_type_label: Tipus d'operació + create: + created: Transacció creada dismiss_duplicate: failure: No s'ha pogut rebutjar la suggerència de duplicat success: Mantingudes com a transaccions separades @@ -9,6 +151,7 @@ ca: account_prompt: Selecciona un compte amount: Import category: Categoria + category_label: Categoria category_prompt: Selecciona una categoria date: Data description: Descripció @@ -16,6 +159,7 @@ ca: details: Detalls expense: Despesa income: Ingrés + merchant_label: Comerç none: "(cap)" note_label: Notes note_placeholder: Introdueix una nota @@ -25,25 +169,57 @@ ca: header: edit_categories: Edita categories edit_imports: Edita importacions - edit_merchants: Edita comerciants + edit_merchants: Edita comerços edit_tags: Edita etiquetes import: Importa index: + categorize_button: + one: Categoritza (1) + other: Categoritza (%{count}) + edit_categories: Edita categories + edit_imports: Edita importacions + edit_merchants: Edita comerços + edit_rules: Edita regles + edit_tags: Edita etiquetes import: Importa + new_rule: Nova regla + new_transaction: Nova transacció + title: Transaccions transaction: transacció transactions: transaccions + keep_both: 'No, mantén-les totes dues' + list: + drag_drop_subtitle: Puja transaccions directament + drag_drop_title: Deixa anar el CSV per importar + transaction: transacció + transactions: transaccions + mark_recurring: Marca com a recurrent + mark_recurring_subtitle: Segueix-ho com a transacció recurrent. La variància d'import + es calcula automàticament a partir dels últims 6 mesos de transaccions similars. + mark_recurring_title: Transacció recurrent merge_duplicate: failure: No s'han pogut fusionar les transaccions success: Les transaccions s'han fusionat correctament new: new_transaction: Nova transacció + pending_duplicate_merge: + confirm_title: Fusiona amb la transacció publicada (%{posted_amount}) + possible_duplicate: Duplicat? + possible_duplicate_short: Dup? + reject_title: Mantén com a transaccions separades + review_recommended: Revisa + review_recommended_short: Rev + potential_duplicate_description: Aquesta transacció pendent pot ser la mateixa + que la transacció publicada a sota. Si és així, fusiona-les per evitar comptabilitzar + dues vegades. + potential_duplicate_title: S'ha detectat un duplicat possible search: filters: account: Compte amount: Import category: Categoria date: Data - merchant: Comerciant + merchant: Comerç status: Estat tag: Etiqueta type: Tipus @@ -62,6 +238,9 @@ ca: on_or_before: el %{date} o abans pending: Pendent transfer: Transferència + date_filter: + end_date: Data de fi + start_date: Data d'inici status_filter: confirmed: Confirmada pending: Pendent @@ -70,6 +249,8 @@ ca: income: Ingrés transfer: Transferència form: + filter: Filtra + search_placeholder: Cerca transaccions... toggle_selection_checkboxes: Commuta totes les caselles menu: account_filter: Compte @@ -79,7 +260,7 @@ ca: category_filter: Categoria clear_filters: Neteja filtres date_filter: Data - merchant_filter: Comerciant + merchant_filter: Comerç status_filter: Estat tag_filter: Etiqueta type_filter: Tipus @@ -87,45 +268,102 @@ ca: equal_to: igual a greater_than: major que less_than: menor que + selection_bar: + duplicate: Duplica + edit: Edita + selected: seleccionades show: account_label: Compte + activity_type: Tipus d'activitat + activity_type_description: Tipus d'activitat d'inversió (compra, venda, dividend, + etc.). Detectat automàticament o establert manualment. + additional_details: Detalls addicionals amount: Import + attachments: Adjunts category_label: Categoria + convert: Converteix + convert_to_trade_button: Converteix en operació + convert_to_trade_description: Converteix aquesta transacció en una operació + de compra o venda amb detalls de valor per al seguiment de la cartera. + convert_to_trade_title: Converteix en operació de valors date_label: Data delete: Elimina delete_subtitle: Això eliminarà permanentment la transacció, afectarà els teus saldos històrics i no es podrà desfer. - delete_title: Eliminar transacció + delete_title: Elimina la transacció + description: Descripció details: Detalls - keep_both: No, mantenir ambdós - mark_recurring: Marcar com a recurrent - mark_recurring_subtitle: Segueix-ho com a transacció recurrent. La variància d'import - es calcula automàticament a partir dels últims 6 mesos de transaccions similars. + exclude: Exclou + exclude_description: Les transaccions excloses es retiraran dels càlculs i informes + de pressupost. + keep_both: 'No, mantén-les totes dues' + loan_payment: Pagament de préstec + mark_recurring: Marca com a recurrent + mark_recurring_subtitle: Segueix-ho com a transacció recurrent. La variància + d'import es calcula automàticament a partir dels últims 6 mesos de transaccions + similars. mark_recurring_title: Transacció recurrent - merchant_label: Comerciant + memo: Memo + merchant_label: Comerç merge_duplicate: Sí, fusiona-les name_label: Nom nature: Tipus none: "(cap)" note_label: Notes note_placeholder: Introdueix una nota + one_time_description: Les transaccions puntuals s'exclouran de determinats càlculs + i informes de pressupost per ajudar-te a veure el que realment és important. + one_time_title: "%{type} puntual" + open_matcher: Obre l'aparellador overview: Resum - potential_duplicate_description: Aquesta transacció pendent pot ser la mateixa que - la transacció publicada a sota. Si és així, fusiona-les per evitar comptabilitzar dues vegades. - potential_duplicate_title: S'ha detectat duplicat possible + payee: Beneficiari + pending_duplicate_merger_button: Obre el fusionador + pending_duplicate_merger_description: Fusiona manualment aquesta transacció + pendent amb la seva versió publicada. + pending_duplicate_merger_title: Duplicat d'una transacció publicada? + potential_duplicate_description: Aquesta transacció pendent pot ser la mateixa + que la transacció publicada a sota. Si és així, fusiona-les per evitar comptabilitzar + dues vegades. + potential_duplicate_title: S'ha detectat un duplicat possible + provider_extras: Extres del proveïdor settings: Configuració + tab_transactions: Transaccions + tab_upcoming: Properes tags_label: Etiquetes - uncategorized: "(sense categoritzar)" - loan_payment: Pagament de préstec transfer: Transferència + transfer_matcher_description: Connecta aquesta transacció amb la seva contrapart + en un altre compte. + transfer_or_debt_payment: Transferència o pagament de deute? + uncategorized: "(sense categoritzar)" + split_parent_row: + split_label: Divisió + transfer_match: + auto_matched: Aparellada + auto_matched_short: A/A + confirm_match: Confirma la coincidència + payment_confirmed: Pagament confirmat + reject_match: Rebutja la coincidència + transfer_confirmed: Transferència confirmada + summary: + expenses: Despeses + income: Ingressos + inflow: Entrada + outflow: Sortida + total_transactions: Total de transaccions toggle_recurring_section: Mostra/Amaga les transaccions recurrents properes transaction: + activity_type_tooltip: Tipus d'activitat d'inversió + linked_with_provider: Vinculat amb %{provider} pending: Pendent pending_tooltip: Transacció pendent — pot canviar quan es publiqui - linked_with_provider: Vinculat amb %{provider} possible_duplicate: Duplicat? potential_duplicate_tooltip: Això pot ser un duplicat d'una altra transacció review_recommended: Revisa review_recommended_tooltip: Diferència d'import important — es recomana revisar per comprovar si és un duplicat + split: Divisió + split_child_tooltip: Part d'una transacció dividida + split_tooltip: Aquesta transacció s'ha dividit en múltiples entrades unknown_name: Transacció desconeguda + update: + updated: Transacció actualitzada diff --git a/config/locales/views/transactions/en.yml b/config/locales/views/transactions/en.yml index 5cde05d72..d051ef130 100644 --- a/config/locales/views/transactions/en.yml +++ b/config/locales/views/transactions/en.yml @@ -3,12 +3,27 @@ en: transactions: bulk_updates: new: + cancel: Cancel + category_label: Category + category_prompt: Select a category + date_label: Date + header_title: Edit transactions + merchant_label: Merchant + merchant_prompt: Select a merchant name_label: Name name_placeholder: Enter a name that will be applied to selected transactions + none: "(none)" + notes_label: Notes + notes_placeholder: Enter a note that will be applied to selected transactions + overview: Overview + save: Save + tags_label: Tags + transactions_section: Transactions unknown_name: Unknown transaction selection_bar: duplicate: Duplicate edit: Edit + selected: selected form: details: Details account: Account @@ -111,6 +126,13 @@ en: keep_both: No, keep both split_parent_row: split_label: "Split" + transfer_match: + auto_matched: Auto-matched + auto_matched_short: A/M + confirm_match: Confirm match + payment_confirmed: Payment is confirmed + reject_match: Reject match + transfer_confirmed: Transfer is confirmed transaction: pending: Pending pending_tooltip: Pending transaction — may change when posted diff --git a/config/locales/views/transactions/hu.yml b/config/locales/views/transactions/hu.yml index ed516d633..bd12ab3c2 100644 --- a/config/locales/views/transactions/hu.yml +++ b/config/locales/views/transactions/hu.yml @@ -3,17 +3,34 @@ hu: transactions: bulk_updates: new: + cancel: Mégse + category_label: Kategória + category_prompt: Válassz kategóriát + date_label: Dátum + header_title: Tranzakciók szerkesztése + merchant_label: Kereskedő + merchant_prompt: Válassz kereskedőt name_label: Név name_placeholder: Add meg a kiválasztott tranzakciókra alkalmazandó nevet + none: "(egyik sem)" + notes_label: Megjegyzések + notes_placeholder: Add meg a kiválasztott tranzakciókra alkalmazandó megjegyzést + overview: Áttekintés + save: Mentés + tags_label: Címkék + transactions_section: Tranzakciók unknown_name: Ismeretlen tranzakció selection_bar: duplicate: Duplikálás edit: Szerkesztés + selected: kijelölve form: + details: Részletek account: Számla account_prompt: Válassz számlát amount: Összeg category: Kategória + category_label: Kategória category_prompt: Válassz kategóriát date: Dátum description: Leírás @@ -27,9 +44,22 @@ hu: submit: Tranzakció hozzáadása tags_label: Címkék transfer: Átutalás + create: + created: Tranzakció létrehozva + update: + updated: Tranzakció frissítve new: new_transaction: Új tranzakció show: + keep_both: Nem, mindkettőt tartsd meg + loan_payment: Hiteltörlesztés + mark_recurring: Ismétlődőként jelölés + mark_recurring_subtitle: Kövesd ezt ismétlődő tranzakcióként. Az összegeltérés automatikusan kiszámításra kerül az elmúlt 6 hónap hasonló tranzakcióiból. + mark_recurring_title: Ismétlődő tranzakció + merge_duplicate: Igen, egyesítsd őket + potential_duplicate_description: Ez a függőben lévő tranzakció megegyezhet az alábbi közzétett tranzakcióval. Ha igen, egyesítsd őket a kettős könyvelés elkerülése érdekében. + potential_duplicate_title: Lehetséges duplikátum észlelve + transfer: Átutalás account_label: Számla amount: Összeg category_label: Kategória @@ -64,6 +94,14 @@ hu: tab_transactions: Tranzakciók tab_upcoming: Közelgő uncategorized: "(kategorizálatlan)" + additional_details: "További részletek" + payee: "Kedvezményezett" + description: "Leírás" + memo: "Megjegyzés" + provider_extras: "Szolgáltatói kiegészítők" + transfer_or_debt_payment: "Átutalás vagy adósságtörlesztés?" + open_matcher: "Összevonó megnyitása" + convert: "Konvertálás" activity_labels: buy: Vétel sell: Eladás @@ -125,9 +163,17 @@ hu: edit_tags: Címkék szerkesztése import: Import index: + title: "Tranzakciók" transaction: tranzakció transactions: tranzakció import: Import + new_rule: "Új szabály" + edit_rules: "Szabályok szerkesztése" + edit_categories: "Kategóriák szerkesztése" + edit_tags: "Címkék szerkesztése" + edit_merchants: "Kereskedők szerkesztése" + edit_imports: "Importok szerkesztése" + new_transaction: "Új tranzakció" categorize_button: one: "Kategorizálás (1)" other: "Kategorizálás (%{count})" @@ -224,6 +270,9 @@ hu: unexpected_error: "Váratlan hiba a konverzió során: %{error}" searches: filters: + date_filter: + start_date: "Kezdő dátum" + end_date: "Záró dátum" amount_filter: equal_to: Egyenlő greater_than: Nagyobb, mint @@ -262,6 +311,8 @@ hu: less_than: kisebb, mint form: toggle_selection_checkboxes: Összes jelölőnégyzet be/ki + search_placeholder: "Tranzakciók keresése..." + filter: "Szűrő" attachments: cannot_exceed: "Tranzakciónként legfeljebb %{count} melléklet engedélyezett" uploaded_one: "Melléklet sikeresen feltöltve" diff --git a/config/locales/views/transfer_matches/ca.yml b/config/locales/views/transfer_matches/ca.yml new file mode 100644 index 000000000..b4890ec6e --- /dev/null +++ b/config/locales/views/transfer_matches/ca.yml @@ -0,0 +1,27 @@ +--- +ca: + transfer_matches: + create: + success: Transferència creada + matching_fields: + create_new_transaction: Crea una nova transacció + match_existing_recommended: Aparella amb una transacció existent (recomanat) + matching_method: Mètode d'aparellament + matching_transaction: Transacció coincident + no_matching_transactions: No s'ha trobat cap transacció que coincideixi amb + la dels teus altres comptes. Selecciona un compte i et crearem una nova transacció + d'entrada. + select_method: Selecciona un mètode per aparellar les teves transaccions. + target_account: Compte de destinació + new: + create_transfer_match: Crea l'aparellament de transferència + from_account: Compte d'origen + from_account_named: 'Compte d''origen: %{name}' + header: + subtitle: Aparella la transacció corresponent a un altre compte o crea'n una + de nova si no existeix. + title: Aparella la transferència o el pagament + inflow_transaction: Transacció d'entrada + outflow_transaction: Transacció de sortida + to_account: Compte de destinació + to_account_named: 'Compte de destinació: %{name}' diff --git a/config/locales/views/transfer_matches/hu.yml b/config/locales/views/transfer_matches/hu.yml index 0a6d73cc4..f4ac47f51 100644 --- a/config/locales/views/transfer_matches/hu.yml +++ b/config/locales/views/transfer_matches/hu.yml @@ -1,7 +1,24 @@ --- hu: transfer_matches: + create: + success: Átutalás létrehozva new: header: title: Átutalás vagy fizetés párosítása subtitle: Párosítsd a megfelelő tranzakciót egy másik számlán, vagy hozz létre újat, ha még nem létezik. + from_account: Forrásszámla + from_account_named: "Forrásszámla: %{name}" + to_account: Célszámla + to_account_named: "Célszámla: %{name}" + outflow_transaction: Kiáramlási tranzakció + inflow_transaction: Beáramlási tranzakció + create_transfer_match: Átutalás-egyezés létrehozása + matching_fields: + select_method: Válassz módszert a tranzakciók párosításához. + match_existing_recommended: Meglévő tranzakció párosítása (ajánlott) + create_new_transaction: Új tranzakció létrehozása + matching_method: Párosítási módszer + matching_transaction: Párosított tranzakció + target_account: Célszámla + no_matching_transactions: Nem találtunk párosítható tranzakciókat a többi számlán. Kérlek válassz számlát, és létrehozunk egy új beáramlási tranzakciót. diff --git a/config/locales/views/transfers/ca.yml b/config/locales/views/transfers/ca.yml index d94033ceb..dcce62762 100644 --- a/config/locales/views/transfers/ca.yml +++ b/config/locales/views/transfers/ca.yml @@ -7,25 +7,43 @@ ca: success: Transferència eliminada form: amount: Import + calculate_rate_tab: Calcula la taxa de canvi + convert_tab: Converteix amb la taxa de canvi date: Data + destination_amount: Import rebut + destination_amount_display: 'Import rebut: %{amount}' + exchange_rate: Taxa de canvi + exchange_rate_display: 'Taxa de canvi: %{rate}' + exchange_rate_help: Tria com introduir l'import de la transferència. expense: Despesa from: Des de income: Ingrés select_account: Selecciona un compte + source_amount: Import enviat submit: Crea transferència - to: Fins a + to: A transfer: Transferència new: title: Nova transferència show: + amount: Import + category: Categoria + date: Data delete: Elimina transferència - delete_subtitle: Això eliminarà la transferència. No s'eliminaran les transaccions + delete_subtitle: Això elimina la transferència. No s'eliminaran les transaccions associades. delete_title: Vols eliminar la transferència? details: Detalls + from: Des de + mark_recurring: Marca com a recurrent + mark_recurring_subtitle: Fes el seguiment d'aquesta transferència com a patró + recurrent al feed de properes i a la pàgina de recurrents. + mark_recurring_title: Marca la transferència com a recurrent note_label: Notes note_placeholder: Afegeix una nota a aquesta transferència overview: Resum settings: Configuració + to: A + uncategorized: Sense categoria update: success: Transferència actualitzada diff --git a/config/locales/views/transfers/hu.yml b/config/locales/views/transfers/hu.yml index de8535642..18df870c0 100644 --- a/config/locales/views/transfers/hu.yml +++ b/config/locales/views/transfers/hu.yml @@ -30,9 +30,18 @@ hu: delete_subtitle: Ez eltávolítja az átutalást. Az alapul szolgáló tranzakciókat nem törli. delete_title: Eltávolítja az átutalást? details: Részletek + mark_recurring: Ismétlődőként jelölés + mark_recurring_subtitle: Kövesd ezt az átutalást ismétlődő mintaként a közelgő eseménylistában és az ismétlődők oldalon. + mark_recurring_title: Átutalás ismétlődőként jelölése note_label: Megjegyzések note_placeholder: Adj meg egy megjegyzést ehhez az átutaláshoz overview: Áttekintés settings: Beállítások + from: Honnan + to: Hova + date: Dátum + amount: Összeg + category: Kategória + uncategorized: Kategorizálatlan update: success: Átutalás frissítve diff --git a/config/locales/views/users/ca.yml b/config/locales/views/users/ca.yml index fa1cef12c..972c53999 100644 --- a/config/locales/views/users/ca.yml +++ b/config/locales/views/users/ca.yml @@ -1,21 +1,31 @@ --- ca: - no_pending_change: No hi ha canvis pendents users: destroy: success: El teu compte s'ha eliminat. resend_confirmation_email: - no_pending_change: No hi ha canvi de correu electrònic actualment pendent! - success: S'ha posat a cua un nou correu electrònic de confirmació per ser enviat. + no_pending_change: Actualment no hi ha cap canvi de correu electrònic pendent! + success: S'ha posat a la cua un nou correu electrònic de confirmació per enviar-se. reset: success: El teu compte s'ha restablert. Les dades s'eliminaran en segon pla - en uns instants. - unauthorized: No estàs autoritzat/da per realitzar aquesta acció. + d'aquí a una estona. + unauthorized: No estàs autoritzat/da per fer aquesta acció reset_with_sample_data: success: El teu compte s'ha restablert i s'estan preparant dades de mostra. - Veureu dades de demostració en breu. + Veuràs les dades de demostració d'aquí a poc. update: email_change_failed: No s'ha pogut canviar l'adreça de correu electrònic. - email_change_initiated: Revisa el teu nou correu electrònic per instruccions + email_change_initiated: Revisa el teu nou correu electrònic per veure les instruccions de confirmació. success: El teu perfil s'ha actualitzat. + roles: + admin: Administrador/a + member: Membre + super_admin: Superadministrador/a + user_menu: + changelog: Registre de canvis + contact: Contacte + feedback: Comentaris + log_out: Tanca la sessió + settings: Configuració + version: Versió diff --git a/config/locales/views/users/en.yml b/config/locales/views/users/en.yml index a10da27c5..9537d57ba 100644 --- a/config/locales/views/users/en.yml +++ b/config/locales/views/users/en.yml @@ -16,7 +16,12 @@ en: unauthorized: You are not authorized to perform this action reset_with_sample_data: success: Your account has been reset and sample data is being prepared. You’ll see demo data shortly. + roles: + admin: Admin + member: Member + super_admin: Super admin user_menu: + aria_label: Open account menu version: Version settings: Settings changelog: Changelog diff --git a/config/locales/views/users/hu.yml b/config/locales/views/users/hu.yml index 8d0a73f82..6cc4bdb4b 100644 --- a/config/locales/views/users/hu.yml +++ b/config/locales/views/users/hu.yml @@ -15,3 +15,10 @@ hu: unauthorized: Nincs jogosultságod ezt a műveletet végrehajtani. reset_with_sample_data: success: A fiókod visszaállítva, és a mintaadatok előkészítése folyamatban van. Hamarosan megjelennek a demóadatok. + user_menu: + version: Verzió + settings: Beállítások + changelog: Változásnapló + feedback: Visszajelzés + contact: Kapcsolat + log_out: Kijelentkezés diff --git a/config/locales/views/valuations/ca.yml b/config/locales/views/valuations/ca.yml index c16d76481..a7e6b567d 100644 --- a/config/locales/views/valuations/ca.yml +++ b/config/locales/views/valuations/ca.yml @@ -1,6 +1,31 @@ --- ca: valuations: + confirmation_contents: + account_balance: saldo del compte + asset_value: valor de l'actiu + balance: saldo + brokerage_cash: Efectiu del compte de valors + change: canvi + credit_card_balance: saldo de la targeta de crèdit + crypto_balance: saldo de cripto + holdings_value: Valor de les posicions + liability_balance: saldo del passiu + loan_balance: saldo del préstec + 'on': el + property_value: valor de l'immoble + recalculate_notice: Totes les transaccions i saldos futurs es recalcularan segons + aquest %{change_or_update}. + this_will: Això %{action_verb} el valor del compte el + to: a + to_colon: 'a:' + total_account_value: Valor total del compte + update: actualització + vehicle_value: valor del vehicle + create: + account_updated: Compte actualitzat + errors: + amount_required: L'import és obligatori form: amount: Import submit: Afegeix actualització de saldo @@ -10,7 +35,7 @@ ca: change: canvi date: data new_entry: Nova entrada - no_valuations: Encara no hi ha valoracions per aquest compte + no_valuations: Encara no hi ha valoracions per a aquest compte valuations: Valor value: valor new: @@ -19,14 +44,20 @@ ca: title: Nou saldo show: amount: Import + amount_label: Valor del compte en la data date_label: Data delete: Elimina delete_subtitle: Aquesta acció no es pot desfer delete_title: Elimina entrada details: Detalls name_label: Nom - name_placeholder: Introdueix un nom per aquesta entrada + name_placeholder: Introdueix un nom per a aquesta entrada note_label: Notes note_placeholder: Afegeix qualsevol detall addicional sobre aquesta entrada + opening_balance: Saldo inicial overview: Resum settings: Configuració + update_value: Actualitza el valor + update: + account_updated: Compte actualitzat + entry_updated: Entrada actualitzada diff --git a/config/locales/views/valuations/hu.yml b/config/locales/views/valuations/hu.yml index 53ad3986b..f00a1cfa8 100644 --- a/config/locales/views/valuations/hu.yml +++ b/config/locales/views/valuations/hu.yml @@ -1,6 +1,33 @@ --- hu: valuations: + confirmation_contents: + this_will: "Ez %{action_verb} a számlaértéket" + to_colon: "erre:" + total_account_value: Számla teljes értéke + holdings_value: Portfólió értéke + brokerage_cash: Brókeri készpénz + account_balance: számlaegyenleg + credit_card_balance: hitelkártya-egyenleg + loan_balance: hitelegyenleg + property_value: ingatlan értéke + vehicle_value: jármű értéke + crypto_balance: kriptoegyenleg + asset_value: vagyonérték + liability_balance: kötelezettségegyenleg + balance: egyenleg + "on": "ezen:" + to: "erre:" + recalculate_notice: "Minden jövőbeli tranzakció és egyenleg újraszámításra kerül ezen %{change_or_update} alapján." + change: változás + update: frissítés + create: + account_updated: Számla frissítve + update: + account_updated: Számla frissítve + entry_updated: Bejegyzés frissítve + errors: + amount_required: Az összeg megadása kötelező form: amount: Összeg submit: Egyenlegfrissítés hozzáadása @@ -17,6 +44,7 @@ hu: title: Új egyenleg show: amount: Összeg + amount_label: Számlaérték a megadott napon date_label: Dátum delete: Törlés delete_subtitle: Ez a művelet nem vonható vissza @@ -28,3 +56,5 @@ hu: note_placeholder: Adj meg további részleteket erről a bejegyzésről overview: Áttekintés settings: Beállítások + opening_balance: "Nyitóegyenleg" + update_value: Érték frissítése diff --git a/config/locales/views/vehicles/ca.yml b/config/locales/views/vehicles/ca.yml index cda63ed3f..1f5d7d43e 100644 --- a/config/locales/views/vehicles/ca.yml +++ b/config/locales/views/vehicles/ca.yml @@ -23,4 +23,13 @@ ca: trend: Tendència unknown: Desconegut year: Any - + tabs: + overview: + current_price: Preu actual + edit_account_details: Edita els detalls del compte + make_model: Marca i model + mileage: Quilometratge + purchase_price: Preu de compra + trend: Tendència + unknown: Desconegut + year: Any diff --git a/config/locales/views/vehicles/hu.yml b/config/locales/views/vehicles/hu.yml index dfad86013..6ad9810c2 100644 --- a/config/locales/views/vehicles/hu.yml +++ b/config/locales/views/vehicles/hu.yml @@ -23,3 +23,13 @@ hu: trend: Tendencia unknown: Ismeretlen year: Évjárat + tabs: + overview: + current_price: Jelenlegi ár + make_model: Márka és modell + mileage: Kilométeróra-állás + purchase_price: Vételár + trend: Tendencia + unknown: Ismeretlen + year: Évjárat + edit_account_details: "Számlaadatok szerkesztése" diff --git a/config/routes.rb b/config/routes.rb index 656a6c285..7d5ec7e2c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -236,8 +236,9 @@ Rails.application.routes.draw do namespace :settings do resource :profile, only: [ :show, :destroy ] - resource :preferences, only: :show + resource :preferences, only: %i[show update] resource :appearance, only: %i[show update] + resource :debug, only: :show resource :hosting, only: %i[show update] do delete :clear_cache, on: :collection delete :disconnect_external_assistant, on: :collection @@ -656,8 +657,8 @@ Rails.application.routes.draw do get "up" => "rails/health#show", as: :rails_health_check # Render dynamic PWA files from app/views/pwa/* - get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker - get "manifest" => "rails/pwa#manifest", as: :pwa_manifest + get "service-worker" => "pwa#service_worker", as: :pwa_service_worker, defaults: { format: :js } + get "manifest" => "pwa#manifest", as: :pwa_manifest, defaults: { format: :json } get "imports/:import_id/upload/sample_csv", to: "import/uploads#sample_csv", as: :import_upload_sample_csv diff --git a/config/schedule.yml b/config/schedule.yml index 3e1b0291a..6e1c8bb3a 100644 --- a/config/schedule.yml +++ b/config/schedule.yml @@ -31,6 +31,12 @@ clean_data: queue: "scheduled" description: "Cleans up old data (e.g., expired merchant associations, expired archived exports)" +clean_debug_log_entries: + cron: "30 3 * * *" # daily at 3:30 AM + class: "DebugLogCleanupJob" + queue: "scheduled" + description: "Deletes debug log entries older than 90 days" + clean_inactive_families: cron: "0 4 * * *" # daily at 4:00 AM class: "InactiveFamilyCleanerJob" diff --git a/db/migrate/20260517122500_create_debug_log_entries.rb b/db/migrate/20260517122500_create_debug_log_entries.rb new file mode 100644 index 000000000..34755fb5a --- /dev/null +++ b/db/migrate/20260517122500_create_debug_log_entries.rb @@ -0,0 +1,35 @@ +class CreateDebugLogEntries < ActiveRecord::Migration[7.2] + def up + create_table :debug_log_entries, id: :uuid do |t| + t.string :category, null: false + t.string :level, null: false + t.text :message, null: false + t.string :source, null: false + t.jsonb :metadata, null: false, default: {} + t.references :family, type: :uuid, foreign_key: { on_delete: :nullify }, null: true + t.references :account, type: :uuid, foreign_key: { on_delete: :nullify }, null: true + t.references :user, type: :uuid, foreign_key: { on_delete: :nullify }, null: true + t.references :account_provider, type: :uuid, foreign_key: { on_delete: :nullify }, null: true + t.string :provider_key + + t.timestamps + end + + add_check_constraint :debug_log_entries, + "level IN ('debug', 'info', 'warn', 'error')", + name: "chk_debug_log_entries_level" + + add_index :debug_log_entries, :created_at + add_index :debug_log_entries, :category + add_index :debug_log_entries, :level + add_index :debug_log_entries, :source + add_index :debug_log_entries, :provider_key + add_index :debug_log_entries, [ :category, :created_at ] + add_index :debug_log_entries, [ :provider_key, :created_at ] + end + + def down + remove_check_constraint :debug_log_entries, name: "chk_debug_log_entries_level", if_exists: true + drop_table :debug_log_entries + end +end diff --git a/db/migrate/20260519092118_rename_beta_features_enabled_preference.rb b/db/migrate/20260519092118_rename_beta_features_enabled_preference.rb new file mode 100644 index 000000000..6e9f36ea3 --- /dev/null +++ b/db/migrate/20260519092118_rename_beta_features_enabled_preference.rb @@ -0,0 +1,30 @@ +class RenameBetaFeaturesEnabledPreference < ActiveRecord::Migration[7.2] + # Renames the JSONB preference key `beta_features_enabled` to + # `preview_features_enabled` for every user that has the old key set. + # The gate was introduced in PR #1829 and never moved past the Goals + # rollout, so opt-in counts are small — but copying the value across keeps + # any early adopters opted in after the rename. + def up + execute(<<~SQL) + UPDATE users + SET preferences = (preferences - 'beta_features_enabled') + || jsonb_build_object( + 'preview_features_enabled', + COALESCE(preferences->'preview_features_enabled', preferences->'beta_features_enabled') + ) + WHERE preferences ? 'beta_features_enabled' + SQL + end + + def down + execute(<<~SQL) + UPDATE users + SET preferences = (preferences - 'preview_features_enabled') + || jsonb_build_object( + 'beta_features_enabled', + COALESCE(preferences->'beta_features_enabled', preferences->'preview_features_enabled') + ) + WHERE preferences ? 'preview_features_enabled' + SQL + end +end diff --git a/db/migrate/20260519100000_add_sure_import_verification_to_imports.rb b/db/migrate/20260519100000_add_sure_import_verification_to_imports.rb new file mode 100644 index 000000000..d73a24fd5 --- /dev/null +++ b/db/migrate/20260519100000_add_sure_import_verification_to_imports.rb @@ -0,0 +1,6 @@ +class AddSureImportVerificationToImports < ActiveRecord::Migration[7.2] + def change + add_column :imports, :expected_record_counts, :jsonb, null: false, default: {} + add_column :imports, :readback_verification, :jsonb, null: false, default: {} + end +end diff --git a/db/schema.rb b/db/schema.rb index 48a5ae2cc..3606b67e7 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: 2026_05_14_120002) do +ActiveRecord::Schema[7.2].define(version: 2026_05_19_100000) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -476,6 +476,33 @@ ActiveRecord::Schema[7.2].define(version: 2026_05_14_120002) do t.index ["enrichable_type", "enrichable_id"], name: "index_data_enrichments_on_enrichable" end + create_table "debug_log_entries", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "category", null: false + t.string "level", null: false + t.text "message", null: false + t.string "source", null: false + t.jsonb "metadata", default: {}, null: false + t.uuid "family_id" + t.uuid "account_id" + t.uuid "user_id" + t.uuid "account_provider_id" + t.string "provider_key" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["account_id"], name: "index_debug_log_entries_on_account_id" + t.index ["account_provider_id"], name: "index_debug_log_entries_on_account_provider_id" + t.index ["category", "created_at"], name: "index_debug_log_entries_on_category_and_created_at" + t.index ["category"], name: "index_debug_log_entries_on_category" + t.index ["created_at"], name: "index_debug_log_entries_on_created_at" + t.index ["family_id"], name: "index_debug_log_entries_on_family_id" + t.index ["level"], name: "index_debug_log_entries_on_level" + t.index ["provider_key", "created_at"], name: "index_debug_log_entries_on_provider_key_and_created_at" + t.index ["provider_key"], name: "index_debug_log_entries_on_provider_key" + t.index ["source"], name: "index_debug_log_entries_on_source" + t.index ["user_id"], name: "index_debug_log_entries_on_user_id" + t.check_constraint "level::text = ANY (ARRAY['debug'::character varying, 'info'::character varying, 'warn'::character varying, 'error'::character varying]::text[])", name: "chk_debug_log_entries_level" + end + create_table "depositories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -944,6 +971,8 @@ ActiveRecord::Schema[7.2].define(version: 2026_05_14_120002) do t.text "ai_summary" t.string "document_type" t.jsonb "extracted_data" + t.jsonb "expected_record_counts", default: {}, null: false + t.jsonb "readback_verification", default: {}, null: false t.index ["family_id"], name: "index_imports_on_family_id" end @@ -1925,6 +1954,10 @@ ActiveRecord::Schema[7.2].define(version: 2026_05_14_120002) do add_foreign_key "coinbase_items", "families" add_foreign_key "coinstats_accounts", "coinstats_items" add_foreign_key "coinstats_items", "families" + add_foreign_key "debug_log_entries", "account_providers", on_delete: :nullify + add_foreign_key "debug_log_entries", "accounts", on_delete: :nullify + add_foreign_key "debug_log_entries", "families", on_delete: :nullify + add_foreign_key "debug_log_entries", "users", on_delete: :nullify add_foreign_key "enable_banking_accounts", "enable_banking_items" add_foreign_key "enable_banking_items", "families" add_foreign_key "entries", "accounts", on_delete: :cascade diff --git a/design/tokens/sure.tokens.json b/design/tokens/sure.tokens.json index 5d899749b..6e63b3b6b 100644 --- a/design/tokens/sure.tokens.json +++ b/design/tokens/sure.tokens.json @@ -18,12 +18,24 @@ "white": { "$value": "#ffffff", "$type": "color" }, "black": { "$value": "#0B0B0B", "$type": "color" }, - "success": { "$value": "{color.green.600}", "$type": "color", "$extensions": { "sure.dark": "{color.green.500}" } }, + "success": { "$value": "{color.green.700}", "$type": "color", "$extensions": { "sure.dark": "{color.green.400}" } }, "warning": { "$value": "{color.yellow.600}", "$type": "color", "$extensions": { "sure.dark": "{color.yellow.400}" } }, "destructive": { "$value": "{color.red.600}", "$type": "color", "$extensions": { "sure.dark": "{color.red.400}" } }, "info": { "$value": "{color.blue.600}", "$type": "color", "$extensions": { "sure.dark": "{color.blue.500}" } }, "shadow": { "$value": "{color.black|6%}", "$type": "color", "$extensions": { "sure.dark": "{color.white|8%}" } }, + "link": { "$value": "{color.blue.600}", "$type": "color", "$extensions": { "sure.dark": "{color.blue.500}" } }, + "tertiary": { "$value": "{color.alpha-black.100}", "$type": "color", "$extensions": { "sure.dark": "{color.alpha-white.200}" } }, + "surface": { "$value": "{color.gray.50}", "$type": "color", "$extensions": { "sure.dark": "{color.black}" } }, + "surface-hover": { "$value": "{color.gray.100}", "$type": "color", "$extensions": { "sure.dark": "{color.gray.800}" } }, + "surface-inset": { "$value": "{color.gray.100}", "$type": "color", "$extensions": { "sure.dark": "{color.gray.800}" } }, + "surface-inset-hover": { "$value": "{color.gray.200}", "$type": "color", "$extensions": { "sure.dark": "{color.gray.800}" } }, + "container": { "$value": "{color.white}", "$type": "color", "$extensions": { "sure.dark": "{color.gray.900}" } }, + "container-hover": { "$value": "{color.gray.50}", "$type": "color", "$extensions": { "sure.dark": "{color.gray.800}" } }, + "container-inset": { "$value": "{color.gray.50}", "$type": "color", "$extensions": { "sure.dark": "{color.gray.800}" } }, + "container-inset-hover": { "$value": "{color.gray.100}", "$type": "color", "$extensions": { "sure.dark": "{color.gray.700}" } }, + "nav-indicator": { "$value": "{color.black}", "$type": "color", "$extensions": { "sure.dark": "{color.white}" } }, + "gray": { "25": { "$value": "#FAFAFA", "$type": "color" }, "50": { "$value": "#F7F7F7", "$type": "color" }, @@ -253,14 +265,6 @@ }, "utility": { - "bg-surface": { "$type": "utility", "$value": "{color.gray.50}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.black}" } }, - "bg-surface-hover": { "$type": "utility", "$value": "{color.gray.100}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.800}" } }, - "bg-surface-inset": { "$type": "utility", "$value": "{color.gray.100}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.800}" } }, - "bg-surface-inset-hover": { "$type": "utility", "$value": "{color.gray.200}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.800}" } }, - "bg-container": { "$type": "utility", "$value": "{color.white}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.900}" } }, - "bg-container-hover": { "$type": "utility", "$value": "{color.gray.50}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.800}" } }, - "bg-container-inset": { "$type": "utility", "$value": "{color.gray.50}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.800}" } }, - "bg-container-inset-hover":{ "$type": "utility","$value": "{color.gray.100}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.700}" } }, "bg-inverse": { "$type": "utility", "$value": "{color.gray.800}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.white}" } }, "bg-inverse-hover": { "$type": "utility", "$value": "{color.gray.700}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.100}" } }, "bg-overlay": { @@ -280,7 +284,6 @@ "text-inverse": { "$type": "utility", "$value": "{color.white}", "$extensions": { "sure.utility": { "prefix": "text" }, "sure.dark": "{color.gray.900}" } }, "text-secondary": { "$type": "utility", "$value": "{color.gray.500}", "$extensions": { "sure.utility": { "prefix": "text" }, "sure.dark": "{color.gray.300}" } }, "text-subdued": { "$type": "utility", "$value": "{color.gray.400}", "$extensions": { "sure.utility": { "prefix": "text" }, "sure.dark": "{color.gray.500}" } }, - "text-link": { "$type": "utility", "$value": "{color.blue.600}", "$extensions": { "sure.utility": { "prefix": "text" }, "sure.dark": "{color.blue.500}" } }, "shadow-border-xs": { "$type": "utility", @@ -325,7 +328,6 @@ "border-primary": { "$type": "utility", "$value": "{color.alpha-black.300}", "$extensions": { "sure.utility": { "prefix": "border" }, "sure.dark": "{color.alpha-white.400}" } }, "border-secondary": { "$type": "utility", "$value": "{color.alpha-black.200}", "$extensions": { "sure.utility": { "prefix": "border" }, "sure.dark": "{color.alpha-white.300}" } }, - "border-tertiary": { "$type": "utility", "$value": "{color.alpha-black.100}", "$extensions": { "sure.utility": { "prefix": "border" }, "sure.dark": "{color.alpha-white.200}" } }, "border-divider": { "$type": "utility", "$value": "border-tertiary" }, "border-subdued": { "$type": "utility", "$value": "{color.alpha-black.50}", "$extensions": { "sure.utility": { "prefix": "border" }, "sure.dark": "{color.alpha-white.100}" } }, "border-solid": { "$type": "utility", "$value": "{color.black}", "$extensions": { "sure.utility": { "prefix": "border" }, "sure.dark": "{color.white}" } }, @@ -346,7 +348,6 @@ "tab-item-active": { "$type": "utility", "$value": "{color.white}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.700}" } }, "tab-item-hover": { "$type": "utility", "$value": "{color.gray.200}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.gray.800}" } }, - "tab-bg-group": { "$type": "utility", "$value": "{color.gray.50}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.alpha-black.700}" } }, - "bg-nav-indicator": { "$type": "utility", "$value": "{color.black}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.white}" } } + "tab-bg-group": { "$type": "utility", "$value": "{color.gray.50}", "$extensions": { "sure.utility": { "prefix": "bg" }, "sure.dark": "{color.alpha-black.700}" } } } } diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index ebc4c4425..456e7ffbf 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -1733,6 +1733,72 @@ components: unassigned_mappings_count: type: integer minimum: 0 + ImportVerificationReadback: + type: object + description: SureImport only. Expected NDJSON counts compared to family-scoped + database readback after publish. + properties: + status: + type: string + enum: + - not_verified + - matched + - mismatch + - failed + - reverted + checked_at: + type: string + format: date-time + nullable: true + expected_record_counts: + type: object + additionalProperties: + type: integer + before_counts: + type: object + additionalProperties: + type: integer + after_counts: + type: object + additionalProperties: + type: integer + actual_delta_counts: + type: object + additionalProperties: + type: integer + checked_counts: + type: object + additionalProperties: + type: integer + mismatches: + type: object + additionalProperties: + type: object + required: + - expected + - actual + properties: + expected: + type: integer + actual: + type: integer + error: + type: string + nullable: true + ImportVerification: + type: object + description: SureImport only. Captured at upload and completed after import + publish. + required: + - expected_record_counts + - readback + properties: + expected_record_counts: + type: object + additionalProperties: + type: integer + readback: + "$ref": "#/components/schemas/ImportVerificationReadback" ImportPreflightContent: type: object required: @@ -1802,6 +1868,7 @@ components: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport @@ -1889,6 +1956,7 @@ components: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport @@ -1941,6 +2009,7 @@ components: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport @@ -1972,6 +2041,8 @@ components: "$ref": "#/components/schemas/ImportConfiguration" stats: "$ref": "#/components/schemas/ImportStats" + verification: + "$ref": "#/components/schemas/ImportVerification" ImportCollection: type: object required: @@ -4482,6 +4553,7 @@ paths: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport @@ -4540,6 +4612,7 @@ paths: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport @@ -4646,6 +4719,7 @@ paths: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport @@ -4747,7 +4821,7 @@ paths: get: summary: Retrieve an import description: Retrieve detailed information about a specific import, including - configuration and row statistics. + configuration, row statistics, and SureImport readback verification when available. tags: - Imports security: @@ -4883,6 +4957,7 @@ paths: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport @@ -4993,6 +5068,7 @@ paths: - TradeImport - AccountImport - MintImport + - ActualImport - CategoryImport - RuleImport - SureImport diff --git a/docs/llm-guides/gating-a-preview-feature.md b/docs/llm-guides/gating-a-preview-feature.md new file mode 100644 index 000000000..008513ed3 --- /dev/null +++ b/docs/llm-guides/gating-a-preview-feature.md @@ -0,0 +1,128 @@ +# Gating a preview feature + +Sure ships preview features behind a single per-user toggle. Users opt in via Settings → Preferences. Opted-in users see your feature; everyone else doesn't. This guide is for hooking a new feature into the gate. + +The intent is to ship in-progress work without blocking smaller PRs on a "feels finished" bar. You gate the entry points (routes, nav, anything that links into your feature) and iterate behind them. Once stable, you remove the gate in a small follow-up PR. + +## How the gate works + +The state lives on `users.preferences["preview_features_enabled"]`, a key inside the existing JSONB column. It defaults to `false`. Reading it goes through `User#preview_features_enabled?`. + +`ApplicationController` includes the `PreviewGateable` concern, which exposes two methods to every controller: + +- `preview_features_enabled?`. Returns a boolean. `false` for logged-out callers. +- `require_preview_features!`. A `before_action` helper. Redirects users without preview access to `/` with a flash that points them at Settings → Preferences. + +The concern also registers `preview_features_enabled?` as a helper method, so views can call it directly. + +Key files: + +- `app/controllers/concerns/preview_gateable.rb`. The concern. +- `app/models/user.rb`. The `preview_features_enabled?` predicate. +- `app/views/settings/preferences/show.html.erb`. The toggle UI users see. +- `app/components/DS/pill.rb`. The `Preview` / `Canary` marker pill. +- `config/locales/views/preview/en.yml`. The redirect flash copy. + +## Gating a controller + +Add `require_preview_features!` as a `before_action`. That's it. + +```ruby +class GoalsController < ApplicationController + before_action :require_preview_features! +end +``` + +Routes stay defined; the gate runs per-request. Users without preview access hitting `/goals` get redirected with a flash. Preview users pass through. + +If only some actions are gated, scope the `before_action`: + +```ruby +class TransactionsController < ApplicationController + before_action :require_preview_features!, only: %i[forecast scenarios] +end +``` + +## Gating a view + +Wrap the relevant fragment in the helper: + +```erb +<% if preview_features_enabled? %> +
  • + <%= link_to t(".nav.goals"), goals_path %> +
  • +<% end %> +``` + +Same pattern works for dashboard widgets, scoreboard cards, anything that surfaces preview data alongside non-preview data. The helper resolves on every request and reflects the current user's preference. + +## Marking the feature in the UI + +When a preview surface renders for an opted-in user, mark it. The pill component lives in the design system: + +```erb +<%# Next to a page header. The md size pairs with h1 / h2. %> +<%= render DS::Pill.new(label: "Preview", size: :md) %> + +<%# Next to a sidebar nav label or section title. sm is the default. %> +<%= render DS::Pill.new(label: "Preview") %> + +<%# Same shape, fuchsia tone, for canary / experimental surfaces. %> +<%= render DS::Pill.new(label: "Canary", tone: :fuchsia) %> + +<%# Sidebar icon rail has no room for a label. The dot-only mode keeps the tone semantics without the text. %> +<%= render DS::Pill.new(tone: :violet, dot_only: true, title: "Preview") %> +``` + +Default tone is violet. Tones available: `violet`, `indigo`, `fuchsia`, `amber`, `gray`. Styles: `soft` (default), `filled`, `outline`. Sizes: `sm` (default), `md`. The Lookbook preview at `/design-system` (look for `PillComponentPreview#default`) flips every option, so you can see what your call site renders without a round trip to Rails. + +## Tests + +Gated controllers should test both states. The pattern: + +```ruby +class GoalsControllerTest < ActionDispatch::IntegrationTest + setup do + sign_in @user = users(:family_admin) + end + + test "redirects users without preview access" do + @user.update!(preferences: (@user.preferences || {}).merge("preview_features_enabled" => false)) + + get goals_url + + assert_redirected_to root_path + assert_match(/preview/i, flash[:alert]) + end + + test "renders for users with preview access" do + @user.update!(preferences: (@user.preferences || {}).merge("preview_features_enabled" => true)) + + get goals_url + + assert_response :success + end +end +``` + +If you write a system test, flip the preference in setup the same way before the visit. + +## Removing the gate when the feature ships GA + +When a feature moves from preview to general availability, removing the gate is a small mechanical PR: + +1. Drop the `before_action :require_preview_features!` line from the controller. +2. Unwrap the `if preview_features_enabled?` blocks in views. +3. Drop the `DS::Pill` markers from headers, nav, and section titles. +4. Delete the controller / view tests that exercise the redirect. + +Grep for `require_preview_features!` and `preview_features_enabled?` near your feature to confirm nothing's left behind. + +## Notes + +The flag is per-user, not per-family. Two users in the same family can see different versions of the product if one opts in and the other doesn't. That's intentional. Data is family-scoped, but visibility is a personal preference. If you write a feature that creates family-shared data (goals, budgets, etc.), the data persists when a user toggles preview off. The UI just disappears from their view while still showing up for opted-in family members. + +The gate does nothing for background jobs. If your feature has a Sidekiq cron job, it runs regardless of who has preview enabled. That's usually correct (data should keep flowing), but if the job sends notifications or emails, gate those at the send site too. + +The redirect target is `/`. If you want gated controllers to land somewhere else (a docs page, an opt-in nudge), override `require_preview_features!` in the controller, or write a thin custom `before_action` that calls `preview_features_enabled?` directly. diff --git a/spec/requests/api/v1/imports_spec.rb b/spec/requests/api/v1/imports_spec.rb index a12cb7a8c..7d6691612 100644 --- a/spec/requests/api/v1/imports_spec.rb +++ b/spec/requests/api/v1/imports_spec.rb @@ -97,7 +97,7 @@ RSpec.describe 'API V1 Imports', type: :request do schema: { type: :string, enum: %w[pending complete importing reverting revert_failed failed] } parameter name: :type, in: :query, required: false, description: 'Filter by import type', - schema: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport CategoryImport RuleImport SureImport] } + schema: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport ActualImport CategoryImport RuleImport SureImport] } response '200', 'imports listed' do schema '$ref' => '#/components/schemas/ImportCollection' @@ -138,7 +138,7 @@ RSpec.describe 'API V1 Imports', type: :request do }, type: { type: :string, - enum: %w[TransactionImport TradeImport AccountImport MintImport CategoryImport RuleImport SureImport], + enum: %w[TransactionImport TradeImport AccountImport MintImport ActualImport CategoryImport RuleImport SureImport], description: 'Import type (defaults to TransactionImport)' }, account_id: { @@ -286,7 +286,7 @@ RSpec.describe 'API V1 Imports', type: :request do parameter name: :id, in: :path, type: :string, required: true, description: 'Import ID' get 'Retrieve an import' do - description 'Retrieve detailed information about a specific import, including configuration and row statistics.' + description 'Retrieve detailed information about a specific import, including configuration, row statistics, and SureImport readback verification when available.' tags 'Imports' security [ { apiKeyAuth: [] } ] produces 'application/json' @@ -388,7 +388,7 @@ RSpec.describe 'API V1 Imports', type: :request do }, type: { type: :string, - enum: %w[TransactionImport TradeImport AccountImport MintImport CategoryImport RuleImport SureImport], + enum: %w[TransactionImport TradeImport AccountImport MintImport ActualImport CategoryImport RuleImport SureImport], description: 'Import type to validate (defaults to TransactionImport)' }, account_id: { diff --git a/spec/swagger_helper.rb b/spec/swagger_helper.rb index d27ad818f..0372ce03a 100644 --- a/spec/swagger_helper.rb +++ b/spec/swagger_helper.rb @@ -947,6 +947,58 @@ RSpec.configure do |config| unassigned_mappings_count: { type: :integer, minimum: 0 } } }, + ImportVerificationReadback: { + type: :object, + description: 'SureImport only. Expected NDJSON counts compared to family-scoped database readback after publish.', + properties: { + status: { type: :string, enum: %w[not_verified matched mismatch failed reverted] }, + checked_at: { type: :string, format: :'date-time', nullable: true }, + expected_record_counts: { + type: :object, + additionalProperties: { type: :integer } + }, + before_counts: { + type: :object, + additionalProperties: { type: :integer } + }, + after_counts: { + type: :object, + additionalProperties: { type: :integer } + }, + actual_delta_counts: { + type: :object, + additionalProperties: { type: :integer } + }, + checked_counts: { + type: :object, + additionalProperties: { type: :integer } + }, + mismatches: { + type: :object, + additionalProperties: { + type: :object, + required: %w[expected actual], + properties: { + expected: { type: :integer }, + actual: { type: :integer } + } + } + }, + error: { type: :string, nullable: true } + } + }, + ImportVerification: { + type: :object, + description: 'SureImport only. Captured at upload and completed after import publish.', + required: %w[expected_record_counts readback], + properties: { + expected_record_counts: { + type: :object, + additionalProperties: { type: :integer } + }, + readback: { '$ref' => '#/components/schemas/ImportVerificationReadback' } + } + }, ImportPreflightContent: { type: :object, required: %w[filename content_type byte_size], @@ -999,7 +1051,7 @@ RSpec.configure do |config| type: :object, required: %w[type valid content stats errors warnings], properties: { - type: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport CategoryImport RuleImport SureImport] }, + type: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport ActualImport CategoryImport RuleImport SureImport] }, valid: { type: :boolean }, content: { '$ref' => '#/components/schemas/ImportPreflightContent' }, stats: { '$ref' => '#/components/schemas/ImportPreflightStats' }, @@ -1063,7 +1115,7 @@ RSpec.configure do |config| required: %w[id type status created_at updated_at status_detail], properties: { id: { type: :string, format: :uuid }, - type: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport CategoryImport RuleImport SureImport] }, + type: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport ActualImport CategoryImport RuleImport SureImport] }, status: { type: :string, enum: %w[pending complete importing reverting revert_failed failed] }, created_at: { type: :string, format: :'date-time' }, updated_at: { type: :string, format: :'date-time' }, @@ -1078,7 +1130,7 @@ RSpec.configure do |config| required: %w[id type status created_at updated_at status_detail configuration stats], properties: { id: { type: :string, format: :uuid }, - type: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport CategoryImport RuleImport SureImport] }, + type: { type: :string, enum: %w[TransactionImport TradeImport AccountImport MintImport ActualImport CategoryImport RuleImport SureImport] }, status: { type: :string, enum: %w[pending complete importing reverting revert_failed failed] }, created_at: { type: :string, format: :'date-time' }, updated_at: { type: :string, format: :'date-time' }, @@ -1086,7 +1138,8 @@ RSpec.configure do |config| error: { type: :string, nullable: true }, status_detail: { '$ref' => '#/components/schemas/ImportStatusDetail' }, configuration: { '$ref' => '#/components/schemas/ImportConfiguration' }, - stats: { '$ref' => '#/components/schemas/ImportStats' } + stats: { '$ref' => '#/components/schemas/ImportStats' }, + verification: { '$ref' => '#/components/schemas/ImportVerification' } } }, ImportCollection: { diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index 770b6256e..57f01828c 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -36,7 +36,40 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase driven_by :selenium_remote_chrome, screen_size: [ 1400, 1400 ] else - driven_by :selenium, using: ENV["CI"].present? ? :headless_chrome : ENV.fetch("E2E_BROWSER", :chrome).to_sym, screen_size: [ 1400, 1400 ] + requested_browser = ENV["E2E_BROWSER"].presence&.to_sym + local_browser = case requested_browser + when :headless_chrome then :chrome + when :headless_firefox then :firefox + else requested_browser || :chrome + end + + headless = ENV["CI"].present? || requested_browser.in?([ :headless_chrome, :headless_firefox ]) || ENV["DISPLAY"].blank? + + Capybara.register_driver :selenium_local_chrome do |app| + options = case local_browser + when :firefox + Selenium::WebDriver::Firefox::Options.new.tap do |firefox_options| + firefox_options.add_argument("--width=1400") + firefox_options.add_argument("--height=1400") + firefox_options.add_argument("-headless") if headless + end + else + Selenium::WebDriver::Chrome::Options.new.tap do |chrome_options| + chrome_options.add_argument("--window-size=1400,1400") + chrome_options.add_argument("--headless=new") if headless + chrome_options.add_argument("--no-sandbox") + chrome_options.add_argument("--disable-dev-shm-usage") + end + end + + Capybara::Selenium::Driver.new( + app, + browser: local_browser, + options: options + ) + end + + driven_by :selenium_local_chrome, screen_size: [ 1400, 1400 ] end def teardown diff --git a/test/components/previews/menu_component_preview.rb b/test/components/previews/menu_component_preview.rb index 78049537b..cf5e1b8e9 100644 --- a/test/components/previews/menu_component_preview.rb +++ b/test/components/previews/menu_component_preview.rb @@ -12,33 +12,14 @@ class MenuComponentPreview < ViewComponent::Preview end end - def avatar - render DS::Menu.new(variant: "avatar") do |menu| - menu_contents(menu) - end - end - private def menu_contents(menu) - menu.with_header do - content_tag(:div, class: "p-3") do - content_tag(:h3, "Menu header", class: "font-medium text-primary") - end - end - menu.with_item(variant: "link", text: "Link", href: "#", icon: "plus") menu.with_item(variant: "button", text: "Action", href: "#", method: :post, icon: "circle") menu.with_item(variant: "button", text: "Action destructive", href: "#", method: :delete, icon: "circle") menu.with_item(variant: "divider") - menu.with_custom_content do - content_tag(:div, class: "p-4") do - safe_join([ - content_tag(:h3, "Custom content header", class: "font-medium text-primary"), - content_tag(:p, "Some custom content", class: "text-sm text-secondary") - ]) - end - end + menu.with_item(variant: "link", text: "Another link", href: "#", icon: "external-link") end end diff --git a/test/components/previews/pill_component_preview.rb b/test/components/previews/pill_component_preview.rb new file mode 100644 index 000000000..88a7aa93f --- /dev/null +++ b/test/components/previews/pill_component_preview.rb @@ -0,0 +1,26 @@ +class PillComponentPreview < ViewComponent::Preview + # @param tone select ["violet", "indigo", "fuchsia", "amber", "gray"] + # @param style select ["soft", "filled", "outline"] + # @param size select ["sm", "md"] + # @param label text + # @param show_dot toggle + # @param dot_only toggle + def default(tone: "violet", style: "soft", size: "sm", label: "Preview", show_dot: true, dot_only: false) + render DS::Pill.new( + label: label, + tone: tone.to_sym, + style: style.to_sym, + size: size.to_sym, + show_dot: show_dot, + dot_only: dot_only + ) + end + + def canary + render DS::Pill.new(label: "Canary", tone: :fuchsia) + end + + def dot_only_collapsed_sidebar + render DS::Pill.new(dot_only: true, tone: :violet) + end +end diff --git a/test/components/previews/tooltip_component_preview.rb b/test/components/previews/tooltip_component_preview.rb index 68bd6c320..a6345ef0b 100644 --- a/test/components/previews/tooltip_component_preview.rb +++ b/test/components/previews/tooltip_component_preview.rb @@ -6,7 +6,8 @@ class TooltipComponentPreview < ViewComponent::Preview # @param icon text # @param size select [xs, sm, md, lg, xl, 2xl] # @param color select [default, white, success, warning, destructive, current] - def default(text: "This is helpful information", placement: "top", offset: 10, cross_axis: 0, icon: "info", size: "sm", color: "default") + # @param as select [button, span] + def default(text: "This is helpful information", placement: "top", offset: 10, cross_axis: 0, icon: "info", size: "sm", color: "default", as: "button") render DS::Tooltip.new( text: text, placement: placement, @@ -14,7 +15,8 @@ class TooltipComponentPreview < ViewComponent::Preview cross_axis: cross_axis, icon: icon, size: size, - color: color + color: color, + as: as.to_sym ) end diff --git a/test/controllers/api/v1/imports_controller_test.rb b/test/controllers/api/v1/imports_controller_test.rb index d414e7e1b..41d6c2e43 100644 --- a/test/controllers/api/v1/imports_controller_test.rb +++ b/test/controllers/api/v1/imports_controller_test.rb @@ -120,6 +120,47 @@ class Api::V1::ImportsControllerTest < ActionDispatch::IntegrationTest json_response["data"]["stats"]["unassigned_mappings_count"] end + test "should show Sure import verification" do + sure_import = @family.imports.create!(type: "SureImport") + sure_import.ndjson_file.attach( + io: StringIO.new(build_ndjson([ + { type: "Account", data: { + id: "account-1", + name: "API Verified Checking", + balance: "100.00", + currency: "USD", + accountable_type: "Depository" + } }, + { type: "Valuation", data: { + id: "valuation-1", + account_id: "account-1", + date: "2024-01-14", + amount: "100.00", + currency: "USD", + kind: "opening_anchor" + } } + ])), + filename: "sure.ndjson", + content_type: "application/x-ndjson" + ) + sure_import.sync_ndjson_rows_count! + sure_import.publish + + get api_v1_import_url(sure_import), headers: api_headers(@api_key) + + assert_response :success + json_response = JSON.parse(response.body) + verification = json_response.dig("data", "verification") + + assert_equal 1, verification.dig("expected_record_counts", "accounts") + assert_equal 1, verification.dig("expected_record_counts", "valuations") + assert_equal "matched", verification.dig("readback", "status") + assert_equal 1, verification.dig("readback", "actual_delta_counts", "accounts") + assert_equal 1, verification.dig("readback", "actual_delta_counts", "valuations") + assert_equal 0, verification.dig("readback", "checked_counts", "balances") + assert_empty verification.dig("readback", "mismatches") + end + test "should list sanitized import row diagnostics" do get rows_api_v1_import_url(@diagnostic_import), headers: api_headers(@read_only_api_key) @@ -988,6 +1029,56 @@ class Api::V1::ImportsControllerTest < ActionDispatch::IntegrationTest assert_includes data["required_headers"], "Amount" end + test "should apply Actual defaults before preflight header validation" do + actual_content = [ + "Account,Date,Payee,Notes,Category_Group,Category,Amount,Split_Amount,Cleared", + "Checking Account,2024-01-01,Coffee Shop,Morning coffee,Food,Coffee,-4.25,0,Cleared" + ].join("\n") + + assert_no_difference("Import.count") do + post preflight_api_v1_imports_url, + params: { + type: "ActualImport", + raw_file_content: actual_content + }, + headers: api_headers(@read_only_api_key) + end + + assert_response :success + data = JSON.parse(response.body)["data"] + + assert_equal "ActualImport", data["type"] + assert_equal true, data["valid"] + assert_empty data["missing_required_headers"] + assert_includes data["required_headers"], "Date" + assert_includes data["required_headers"], "Amount" + end + + test "should not overwrite explicit Actual preflight column mappings with defaults" do + actual_content = [ + "Booked On,Value,Payee", + "2024-01-01,-4.25,Coffee Shop" + ].join("\n") + + assert_no_difference("Import.count") do + post preflight_api_v1_imports_url, + params: { + type: "ActualImport", + raw_file_content: actual_content, + date_col_label: "Booked On", + amount_col_label: "Value" + }, + headers: api_headers(@read_only_api_key) + end + + assert_response :success + data = JSON.parse(response.body)["data"] + + assert_equal true, data["valid"] + assert_equal [ "Booked On", "Value" ], data["required_headers"] + assert_empty data["missing_required_headers"] + end + test "should not overwrite explicit Mint preflight column mappings with defaults" do mint_content = [ "Posted On,Value,Description", @@ -1133,6 +1224,10 @@ class Api::V1::ImportsControllerTest < ActionDispatch::IntegrationTest private + def build_ndjson(records) + records.map(&:to_json).join("\n") + end + def api_headers(api_key) { "X-Api-Key" => api_key.plain_key } end diff --git a/test/controllers/imports_controller_test.rb b/test/controllers/imports_controller_test.rb index dbea78d2d..eea32693a 100644 --- a/test/controllers/imports_controller_test.rb +++ b/test/controllers/imports_controller_test.rb @@ -3,6 +3,7 @@ require "test_helper" class ImportsControllerTest < ActionDispatch::IntegrationTest setup do sign_in @user = users(:family_admin) + ensure_tailwind_build end test "gets index" do @@ -33,6 +34,7 @@ class ImportsControllerTest < ActionDispatch::IntegrationTest assert_select "button", text: "Import transactions", count: 0 assert_select "button", text: "Import investments", count: 0 assert_select "button", text: "Import from Mint", count: 1 + assert_select "button", text: "Import from Actual Budget", count: 1 assert_select "button", text: "Import from Quicken (QIF)", count: 1 assert_select "span", text: "Import accounts first to unlock this option.", count: 2 assert_select "div[aria-disabled=true]", count: 3 diff --git a/test/controllers/pages_controller_test.rb b/test/controllers/pages_controller_test.rb index 73c39f5a1..023a983f9 100644 --- a/test/controllers/pages_controller_test.rb +++ b/test/controllers/pages_controller_test.rb @@ -43,6 +43,25 @@ class PagesControllerTest < ActionDispatch::IntegrationTest assert_select "[data-controller='sankey-chart']" end + test "dashboard renders sankey chart zoom controls and stable node ids" do + parent_category = @family.categories.create!(name: "Shopping", color: "#FF5733") + subcategory = @family.categories.create!(name: "Groceries", parent: parent_category, color: "#33FF57") + + create_transaction(account: @family.accounts.first, name: "General shopping", amount: 100, category: parent_category) + create_transaction(account: @family.accounts.first, name: "Grocery store", amount: 50, category: subcategory) + + get root_path + + assert_response :ok + assert_select "[data-sankey-chart-target='zoomOutButton'][hidden]", count: 2 + + chart = css_select("[data-controller='sankey-chart']").first + sankey_data = JSON.parse(chart["data-sankey-chart-data-value"]) + + assert_includes sankey_data.fetch("nodes").map { |node| node.fetch("id") }, "cash_flow_node" + assert sankey_data.fetch("nodes").any? { |node| node.fetch("id").start_with?("expense_") } + end + test "changelog" do VCR.use_cassette("git_repository_provider/fetch_latest_release_notes") do get changelog_path diff --git a/test/controllers/pwa_controller_test.rb b/test/controllers/pwa_controller_test.rb new file mode 100644 index 000000000..b7b18ce5a --- /dev/null +++ b/test/controllers/pwa_controller_test.rb @@ -0,0 +1,11 @@ +require "test_helper" + +class PwaControllerTest < ActionDispatch::IntegrationTest + test "manifest responds successfully for html accept headers" do + get "/manifest", headers: { "Accept" => "text/html" } + + assert_response :success + assert_equal "application/manifest+json", response.media_type + assert_includes response.body, '"start_url": "/"' + end +end diff --git a/test/controllers/settings/debugs_controller_test.rb b/test/controllers/settings/debugs_controller_test.rb new file mode 100644 index 000000000..7179738b8 --- /dev/null +++ b/test/controllers/settings/debugs_controller_test.rb @@ -0,0 +1,68 @@ +require "test_helper" + +class Settings::DebugsControllerTest < ActionDispatch::IntegrationTest + setup do + ensure_tailwind_build + + @entry = DebugLogEntry.create!( + category: "security_price_fetch", + level: "warn", + message: "Could not fetch prices", + source: "Security::Price::Importer", + provider_key: "twelve_data", + family: families(:dylan_family), + account: accounts(:depository), + user: users(:family_admin), + metadata: { ticker: "AAPL" } + ) + end + + test "super admins can view debug log" do + sign_in users(:sure_support_staff) + + get settings_debug_url + + assert_response :success + assert_match "Debug event log", response.body + assert_match @entry.message, response.body + end + + test "non super admins are redirected" do + sign_in users(:family_admin) + + get settings_debug_url + + assert_redirected_to root_url + end + + test "filters by provider key" do + sign_in users(:sure_support_staff) + + DebugLogEntry.create!( + category: "security_price_fetch", + level: "warn", + message: "Should be filtered out", + source: "Security::Price::Importer", + provider_key: "finnhub", + family: families(:dylan_family), + account: accounts(:depository), + user: users(:family_admin), + metadata: { ticker: "MSFT" } + ) + + get settings_debug_url, params: { provider_key: "twelve_data" } + + assert_response :success + assert_match @entry.message, response.body + refute_match "Should be filtered out", response.body + end + + test "ignores invalid uuid filters" do + sign_in users(:sure_support_staff) + + get settings_debug_url, params: { family_id: "not-a-uuid" } + + assert_response :success + assert_match @entry.message, response.body + end +end diff --git a/test/controllers/settings/preferences_controller_test.rb b/test/controllers/settings/preferences_controller_test.rb index d2f5142fc..5d49f9ee0 100644 --- a/test/controllers/settings/preferences_controller_test.rb +++ b/test/controllers/settings/preferences_controller_test.rb @@ -21,4 +21,33 @@ class Settings::PreferencesControllerTest < ActionDispatch::IntegrationTest assert_includes response.body, "your group" assert_select "select[name='user[family_attributes][currency]']", count: 0 end + + test "renders preview features toggle for non-admin users too" do + sign_in users(:family_member) + get settings_preferences_url + + assert_response :success + assert_includes response.body, "Enable preview features" + end + + test "update toggles preview_features_enabled on" do + user = users(:family_admin) + assert_not user.preview_features_enabled? + + patch settings_preferences_url, params: { user: { preview_features_enabled: "1" } } + + assert_redirected_to settings_preferences_url + assert user.reload.preview_features_enabled? + end + + test "update toggles preview_features_enabled off" do + user = users(:family_admin) + user.update!(preferences: (user.preferences || {}).merge("preview_features_enabled" => true)) + assert user.preview_features_enabled? + + patch settings_preferences_url, params: { user: { preview_features_enabled: "0" } } + + assert_redirected_to settings_preferences_url + assert_not user.reload.preview_features_enabled? + end end diff --git a/test/fixtures/files/imports/actual.csv b/test/fixtures/files/imports/actual.csv new file mode 100644 index 000000000..03c504d5d --- /dev/null +++ b/test/fixtures/files/imports/actual.csv @@ -0,0 +1,5 @@ +Account,Date,Payee,Notes,Category_Group,Category,Amount,Split_Amount,Cleared +Checking Account,2024-01-01,Landlord,January rent,Housing,Rent,-1500.00,0,Reconciled +Credit Card,2024-01-02,Coffee Shop,Morning coffee,Food,Coffee,-4.25,0,Cleared +Checking Account,2024-01-05,Employer,Monthly salary,Income,Paycheck,2500.00,0,Reconciled +Checking Account,2024-01-06,Internal Transfer,Move to savings,,Transfer,-250.00,0,Not cleared diff --git a/test/helpers/imports_helper_test.rb b/test/helpers/imports_helper_test.rb new file mode 100644 index 000000000..5640f891b --- /dev/null +++ b/test/helpers/imports_helper_test.rb @@ -0,0 +1,77 @@ +require "test_helper" +require "ostruct" + +class ImportsHelperTest < ActionView::TestCase + test "dry run resource labels come from locale keys" do + %i[ + transactions balances accounts categories tags rules merchants + recurring_transactions transfers rejected_transfers trades holdings + valuations budgets budget_categories + ].each do |key| + assert_equal I18n.t("imports.dry_run_resources.#{key}"), dry_run_resource(key).label + end + + balances = dry_run_resource(:balances) + assert_equal "line-chart", balances.icon + assert_equal "text-secondary", balances.text_class + assert_equal "bg-container-inset", balances.bg_class + + resources = %i[ + transactions balances accounts categories tags rules merchants + recurring_transactions transfers rejected_transfers trades holdings + valuations budgets budget_categories + ].map { |key| dry_run_resource(key) } + resources.each do |resource| + refute_match(/\b(?:text|bg)-[a-z]+-\d{2,3}/, [ resource.text_class, resource.bg_class ].join(" ")) + end + end + + test "import verification view handles missing readback payload" do + import = OpenStruct.new(verification_payload: {}) + + verification = import_verification_view(import) + + assert_equal "not_verified", verification.status + assert_equal 0, verification.checked_total + assert_equal 0, verification.mismatches_count + assert_empty verification.mismatches_preview + refute verification.mismatches? + end + + test "import verification view handles nil readback payload" do + import = OpenStruct.new(verification_payload: { readback: nil }) + + verification = import_verification_view(import) + + assert_equal "not_verified", verification.status + assert_equal 0, verification.checked_total + assert_equal 0, verification.mismatches_count + assert_empty verification.mismatches_preview + refute verification.mismatches? + end + + test "import verification view shapes readback counts and mismatch preview" do + import = OpenStruct.new( + verification_payload: { + readback: { + status: "mismatch", + checked_counts: { accounts: 1, transactions: "2" }, + mismatches: { + accounts: { expected: 1, actual: 0 }, + transactions: { expected: 2, actual: 1 }, + categories: { expected: 3, actual: 2 }, + tags: { expected: 4, actual: 3 } + } + } + } + ) + + verification = import_verification_view(import) + + assert_equal "mismatch", verification.status + assert_equal 3, verification.checked_total + assert_equal 4, verification.mismatches_count + assert_equal %w[accounts transactions categories], verification.mismatches_preview.map(&:first) + assert verification.mismatches? + end +end diff --git a/test/javascript/utils/sankey_zoom_test.mjs b/test/javascript/utils/sankey_zoom_test.mjs new file mode 100644 index 000000000..ab0425b71 --- /dev/null +++ b/test/javascript/utils/sankey_zoom_test.mjs @@ -0,0 +1,128 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { + sankeyNodeHasChildren, + zoomSankeyData, +} from "../../../app/javascript/utils/sankey_zoom.mjs"; + +test("zooms an expense category to the clicked root and descendants", () => { + const data = { + nodes: [ + { id: "cash_flow_node", name: "Cash Flow" }, + { id: "expense_shopping", name: "Shopping" }, + { id: "expense_sub_groceries", name: "Groceries" }, + { id: "expense_sub_clothes", name: "Clothes" }, + { id: "expense_dining", name: "Dining" }, + ], + links: [ + { source: 0, target: 1, value: 150 }, + { source: 1, target: 2, value: 100 }, + { source: 1, target: 3, value: 50 }, + { source: 0, target: 4, value: 75 }, + ], + currency_symbol: "$", + }; + + assert.equal(sankeyNodeHasChildren(data, "expense_shopping"), true); + assert.equal(sankeyNodeHasChildren(data, "expense_sub_groceries"), false); + + const zoomed = zoomSankeyData(data, "expense_shopping"); + + assert.deepEqual(zoomed.nodes.map((node) => node.id), [ + "expense_shopping", + "expense_sub_groceries", + "expense_sub_clothes", + ]); + assert.deepEqual( + zoomed.links.map((link) => [link.source, link.target, link.value]), + [ + [0, 1, 100], + [0, 2, 50], + ], + ); + assert.equal(zoomed.currency_symbol, "$"); +}); + +test("zooms an income category by following incoming child links", () => { + const data = { + nodes: [ + { id: "income_salary", name: "Salary" }, + { id: "cash_flow_node", name: "Cash Flow" }, + { id: "income_sub_bonus", name: "Bonus" }, + { id: "income_sub_equity", name: "Equity" }, + { id: "income_interest", name: "Interest" }, + ], + links: [ + { source: 0, target: 1, value: 250 }, + { source: 2, target: 0, value: 100 }, + { source: 3, target: 0, value: 150 }, + { source: 4, target: 1, value: 25 }, + ], + currency_symbol: "$", + }; + + assert.equal(sankeyNodeHasChildren(data, "income_salary"), true); + assert.equal(sankeyNodeHasChildren(data, "income_sub_bonus"), false); + + const zoomed = zoomSankeyData(data, "income_salary"); + + assert.deepEqual(zoomed.nodes.map((node) => node.id), [ + "income_salary", + "income_sub_bonus", + "income_sub_equity", + ]); + assert.deepEqual( + zoomed.links.map((link) => [link.source, link.target, link.value]), + [ + [1, 0, 100], + [2, 0, 150], + ], + ); +}); + +test("zooms the cashflow node to its expense (outbound) descendants", () => { + const data = { + nodes: [ + { id: "income_salary", name: "Salary" }, + { id: "cash_flow_node", name: "Cash Flow" }, + { id: "expense_shopping", name: "Shopping" }, + { id: "expense_sub_groceries", name: "Groceries" }, + ], + links: [ + { source: 0, target: 1, value: 200 }, + { source: 1, target: 2, value: 150 }, + { source: 2, target: 3, value: 100 }, + ], + }; + + assert.equal(sankeyNodeHasChildren(data, "cash_flow_node"), true); + + const zoomed = zoomSankeyData(data, "cash_flow_node"); + + assert.deepEqual(zoomed.nodes.map((node) => node.id), [ + "cash_flow_node", + "expense_shopping", + "expense_sub_groceries", + ]); + assert.deepEqual( + zoomed.links.map((link) => [link.source, link.target, link.value]), + [ + [0, 1, 150], + [1, 2, 100], + ], + ); +}); + +test("does not zoom malformed data without a cashflow node", () => { + const data = { + nodes: [ + { id: "expense_shopping", name: "Shopping" }, + { id: "expense_sub_groceries", name: "Groceries" }, + ], + links: [{ source: 0, target: 1, value: 100 }], + }; + + assert.equal(sankeyNodeHasChildren(data, "expense_shopping"), false); + assert.equal(zoomSankeyData(data, "expense_shopping"), data); +}); diff --git a/test/jobs/debug_log_cleanup_job_test.rb b/test/jobs/debug_log_cleanup_job_test.rb new file mode 100644 index 000000000..df66ce5be --- /dev/null +++ b/test/jobs/debug_log_cleanup_job_test.rb @@ -0,0 +1,77 @@ +require "test_helper" + +class DebugLogCleanupJobTest < ActiveJob::TestCase + setup do + @original_retention_days = Rails.application.config.x.debug_log.retention_days + Rails.application.config.x.debug_log.retention_days = 90 + end + + teardown do + Rails.application.config.x.debug_log.retention_days = @original_retention_days + end + + test "deletes entries older than 90 days" do + travel_to Time.zone.parse("2026-05-17 12:00:00") do + old_entry = DebugLogEntry.create!( + category: "old_event", + level: "info", + message: "old", + source: "Test", + created_at: 91.days.ago, + updated_at: 91.days.ago + ) + boundary_entry = DebugLogEntry.create!( + category: "boundary_event", + level: "info", + message: "boundary", + source: "Test", + created_at: 90.days.ago, + updated_at: 90.days.ago + ) + recent_entry = DebugLogEntry.create!( + category: "recent_event", + level: "info", + message: "recent", + source: "Test" + ) + + assert_difference "DebugLogEntry.count", -1 do + DebugLogCleanupJob.perform_now + end + + assert_not DebugLogEntry.exists?(old_entry.id) + assert DebugLogEntry.exists?(boundary_entry.id) + assert DebugLogEntry.exists?(recent_entry.id) + end + end + + test "uses configured retention days" do + Rails.application.config.x.debug_log.retention_days = 30 + + travel_to Time.zone.parse("2026-05-17 12:00:00") do + old_entry = DebugLogEntry.create!( + category: "old_event", + level: "info", + message: "old", + source: "Test", + created_at: 31.days.ago, + updated_at: 31.days.ago + ) + boundary_entry = DebugLogEntry.create!( + category: "boundary_event", + level: "info", + message: "boundary", + source: "Test", + created_at: 30.days.ago, + updated_at: 30.days.ago + ) + + assert_difference "DebugLogEntry.count", -1 do + DebugLogCleanupJob.perform_now + end + + assert_not DebugLogEntry.exists?(old_entry.id) + assert DebugLogEntry.exists?(boundary_entry.id) + end + end +end diff --git a/test/lib/catalan_pluralization_test.rb b/test/lib/catalan_pluralization_test.rb new file mode 100644 index 000000000..d9cda5c18 --- /dev/null +++ b/test/lib/catalan_pluralization_test.rb @@ -0,0 +1,23 @@ +require "test_helper" +require "securerandom" + +class CatalanPluralizationTest < ActiveSupport::TestCase + test "uses rails i18n plural rules for catalan" do + translation_key = "test_pluralization_#{SecureRandom.hex(6)}" + + I18n.backend.store_translations(:ca, translation_key => { + sample: { + one: "one", + other: "other" + } + }) + + path = "#{translation_key}.sample" + + assert_equal "other", I18n.t(path, locale: :ca, count: 0) + assert_equal "one", I18n.t(path, locale: :ca, count: 1) + assert_equal "other", I18n.t(path, locale: :ca, count: 2) + assert_equal "other", I18n.t(path, locale: :ca, count: 5) + assert_equal "other", I18n.t(path, locale: :ca, count: 100) + end +end diff --git a/test/models/account_test.rb b/test/models/account_test.rb index a903f5d86..6b1507159 100644 --- a/test/models/account_test.rb +++ b/test/models/account_test.rb @@ -99,6 +99,13 @@ class AccountTest < ActiveSupport::TestCase assert_equal opening_date, opening_anchor.entry.date end + test "accountable display names expose singular and group contexts" do + assert_equal "Investment", Investment.singular_display_name + assert_equal "Investments", Investment.display_name + assert_equal "Cash", Depository.singular_display_name + assert_equal "Cash", Depository.display_name + end + test "gets short/long subtype label" do investment = Investment.new(subtype: "hsa") account = @family.accounts.create!( diff --git a/test/models/actual_import_test.rb b/test/models/actual_import_test.rb new file mode 100644 index 000000000..7cc0b3470 --- /dev/null +++ b/test/models/actual_import_test.rb @@ -0,0 +1,53 @@ +require "test_helper" + +class ActualImportTest < ActiveSupport::TestCase + setup do + @family = families(:dylan_family) + end + + test "default column mappings are applied after create" do + import = @family.imports.create!(type: "ActualImport") + + ActualImport.default_column_mappings.each do |attribute, value| + assert_equal value, import.public_send(attribute) + end + end + + test "generated rows preserve stable source row numbers" do + import = @family.imports.create!( + type: "ActualImport", + raw_file_str: file_fixture("imports/actual.csv").read, + col_sep: "," + ) + + import.generate_rows_from_csv + + assert_equal (1..4).to_a, import.rows.order(:source_row_number).pluck(:source_row_number) + end + + test "generated rows combine category group and category" do + import = @family.imports.create!( + type: "ActualImport", + raw_file_str: file_fixture("imports/actual.csv").read, + col_sep: "," + ) + + import.generate_rows_from_csv + + assert_equal "Food: Coffee", import.rows.order(:source_row_number).second.category + assert_equal "Income: Paycheck", import.rows.order(:source_row_number).third.category + assert_equal "Transfer", import.rows.order(:source_row_number).fourth.category + end + + test "generated rows fall back to category group when category is blank" do + import = @family.imports.create!( + type: "ActualImport", + raw_file_str: file_fixture("imports/actual.csv").read.sub("Housing,Rent", "Housing,"), + col_sep: "," + ) + + import.generate_rows_from_csv + + assert_equal "Housing", import.rows.order(:source_row_number).first.category + end +end diff --git a/test/models/balance_sheet_test.rb b/test/models/balance_sheet_test.rb index 9021baf27..558657279 100644 --- a/test/models/balance_sheet_test.rb +++ b/test/models/balance_sheet_test.rb @@ -56,9 +56,9 @@ class BalanceSheetTest < ActiveSupport::TestCase asset_groups = BalanceSheet.new(@family).assets.account_groups assert_equal 3, asset_groups.size - assert_equal 1000 + 2000, asset_groups.find { |ag| ag.name == I18n.t("accounts.types.depository") }.total - assert_equal 3000, asset_groups.find { |ag| ag.name == I18n.t("accounts.types.investment") }.total - assert_equal 5000, asset_groups.find { |ag| ag.name == I18n.t("accounts.types.other_asset") }.total + assert_equal 1000 + 2000, asset_groups.find { |ag| ag.name == Depository.display_name }.total + assert_equal 3000, asset_groups.find { |ag| ag.name == Investment.display_name }.total + assert_equal 5000, asset_groups.find { |ag| ag.name == OtherAsset.display_name }.total end test "calculates liability group totals" do @@ -71,8 +71,8 @@ class BalanceSheetTest < ActiveSupport::TestCase liability_groups = BalanceSheet.new(@family).liabilities.account_groups assert_equal 2, liability_groups.size - assert_equal 1000 + 2000, liability_groups.find { |ag| ag.name == I18n.t("accounts.types.credit_card") }.total - assert_equal 3000 + 5000, liability_groups.find { |ag| ag.name == I18n.t("accounts.types.other_liability") }.total + assert_equal 1000 + 2000, liability_groups.find { |ag| ag.name == CreditCard.display_name }.total + assert_equal 3000 + 5000, liability_groups.find { |ag| ag.name == OtherLiability.display_name }.total end private diff --git a/test/models/debug_log_entry_test.rb b/test/models/debug_log_entry_test.rb new file mode 100644 index 000000000..47cdb6291 --- /dev/null +++ b/test/models/debug_log_entry_test.rb @@ -0,0 +1,20 @@ +require "test_helper" + +class DebugLogEntryTest < ActiveSupport::TestCase + test "capture infers provider key and family from account" do + entry = DebugLogEntry.capture( + category: "provider_sync", + level: "warn", + message: "Provider event", + source: "Provider::Test", + account: accounts(:depository), + provider: :twelve_data, + metadata: { test: true } + ) + + assert entry.persisted? + assert_equal "twelve_data", entry.provider_key + assert_equal accounts(:depository), entry.account + assert_equal accounts(:depository).family, entry.family + end +end diff --git a/test/models/ibkr_account/data_helpers_test.rb b/test/models/ibkr_account/data_helpers_test.rb new file mode 100644 index 000000000..bc8089ac1 --- /dev/null +++ b/test/models/ibkr_account/data_helpers_test.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require "test_helper" + +class IbkrAccount::DataHelpersTest < ActiveSupport::TestCase + class TestHelper + include IbkrAccount::DataHelpers + + public :parse_decimal + end + + setup do + @helper = TestHelper.new + end + + test "parse_decimal returns nil for nil input" do + assert_nil @helper.parse_decimal(nil) + end + + test "parse_decimal returns nil for blank string" do + assert_nil @helper.parse_decimal("") + assert_nil @helper.parse_decimal(" ") + end + + test "parse_decimal returns nil for dash placeholder" do + assert_nil @helper.parse_decimal("-") + end + + test "parse_decimal converts parentheses notation to negative" do + assert_equal BigDecimal("-1234.56"), @helper.parse_decimal("(1234.56)") + end + + test "parse_decimal converts parentheses notation with comma-separated number" do + assert_equal BigDecimal("-1234.56"), @helper.parse_decimal("(1,234.56)") + end + + test "parse_decimal strips commas from positive numbers" do + assert_equal BigDecimal("1234.56"), @helper.parse_decimal("1,234.56") + end + + test "parse_decimal parses plain decimal string" do + assert_equal BigDecimal("3351.00"), @helper.parse_decimal("3351.00") + end + + test "parse_decimal returns nil for empty parentheses" do + assert_nil @helper.parse_decimal("()") + end + + test "parse_decimal returns nil for unclosed parenthesis" do + assert_nil @helper.parse_decimal("(123") + end + + test "parse_decimal returns nil for non-numeric string" do + assert_nil @helper.parse_decimal("N/A") + assert_nil @helper.parse_decimal("not_a_number") + end +end diff --git a/test/models/ibkr_account/historical_balances_sync_test.rb b/test/models/ibkr_account/historical_balances_sync_test.rb index 22d082284..66b5ee89b 100644 --- a/test/models/ibkr_account/historical_balances_sync_test.rb +++ b/test/models/ibkr_account/historical_balances_sync_test.rb @@ -21,33 +21,23 @@ class IbkrAccount::HistoricalBalancesSyncTest < ActiveSupport::TestCase current_balance: 3351, cash_balance: 1000.5, raw_equity_summary_payload: [ - { - currency: "CHF", - report_date: "2026-05-07", - cash: "900.50", - stock: "2300.50", - total: "3201.00" - }, - { - currency: "CHF", - report_date: "2026-05-08", - cash: "1000.50", - stock: "2350.50", - total: "3351.00" - } + { report_date: "2026-05-07", total: "3201.00" }, + { report_date: "2026-05-08", total: "3351.00" } ] ) @ibkr_account.ensure_account_provider!(@account) end - test "upserts historical balances without creating activity entries" do + # Seed an existing balance row as if the materializer already ran. + def seed_balance(date:, balance:, cash_balance:) + non_cash = balance - cash_balance @account.balances.create!( - date: Date.new(2026, 5, 7), - balance: 0, - cash_balance: 0, + date: date, + balance: balance, + cash_balance: cash_balance, currency: "CHF", - start_cash_balance: 0, - start_non_cash_balance: 0, + start_cash_balance: cash_balance, + start_non_cash_balance: non_cash, cash_inflows: 0, cash_outflows: 0, non_cash_inflows: 0, @@ -57,60 +47,183 @@ class IbkrAccount::HistoricalBalancesSyncTest < ActiveSupport::TestCase non_cash_adjustments: 0, flows_factor: 1 ) + end + + test "overrides total from IBKR equity summary while preserving materializer cash split" do + seed_balance(date: Date.new(2026, 5, 7), balance: 3000.00, cash_balance: 900.50) + seed_balance(date: Date.new(2026, 5, 8), balance: 3100.00, cash_balance: 1000.50) assert_no_difference "@account.entries.count" do IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! end - first_balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") - second_balance = @account.balances.find_by!(date: Date.new(2026, 5, 8), currency: "CHF") + first = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") + second = @account.balances.find_by!(date: Date.new(2026, 5, 8), currency: "CHF") - assert_equal BigDecimal("3201.0"), first_balance.end_balance - assert_equal BigDecimal("900.5"), first_balance.end_cash_balance - assert_equal BigDecimal("2300.5"), first_balance.end_non_cash_balance + # Total overridden with IBKR's reported figure + assert_equal BigDecimal("3201.00"), first.end_balance + assert_equal BigDecimal("3351.00"), second.end_balance - assert_equal BigDecimal("3351.0"), second_balance.end_balance - assert_equal BigDecimal("1000.5"), second_balance.end_cash_balance - assert_equal BigDecimal("2350.5"), second_balance.end_non_cash_balance - assert_equal BigDecimal("900.5"), second_balance.start_cash_balance - assert_equal BigDecimal("2300.5"), second_balance.start_non_cash_balance + # Cash preserved from the materializer, not read from equity summary + assert_equal BigDecimal("900.50"), first.end_cash_balance + assert_equal BigDecimal("1000.50"), second.end_cash_balance + + # Non-cash = IBKR total - materializer cash + assert_equal BigDecimal("2300.50"), first.end_non_cash_balance + assert_equal BigDecimal("2350.50"), second.end_non_cash_balance end - test "accepts equity summary rows when stored account currency casing differs" do - @ibkr_account.update!(currency: "chf") + test "uses zero cash when no prior materializer balance exists for a date" do + # No existing balance rows — first-ever sync + IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! + + balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") + assert_equal BigDecimal("3201.00"), balance.end_balance + assert_equal BigDecimal("0"), balance.end_cash_balance + assert_equal BigDecimal("3201.00"), balance.end_non_cash_balance + end + + test "accepts rows without a currency field (Flex configs that omit the attribute)" do + @ibkr_account.update!( + raw_equity_summary_payload: [ + { report_date: "2026-05-07", total: "3201.00" } # no currency key + ] + ) + seed_balance(date: Date.new(2026, 5, 7), balance: 3000.00, cash_balance: 900.50) IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! - first_balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") - second_balance = @account.balances.find_by!(date: Date.new(2026, 5, 8), currency: "CHF") - - assert_equal BigDecimal("3201.0"), first_balance.end_balance - assert_equal BigDecimal("3351.0"), second_balance.end_balance + balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") + assert_equal BigDecimal("3201.00"), balance.end_balance + assert_equal BigDecimal("900.50"), balance.end_cash_balance end - test "skips malformed equity summary rows and still imports valid rows" do + test "accepts rows when account currency casing differs from payload" do + @ibkr_account.update!(currency: "chf") + seed_balance(date: Date.new(2026, 5, 7), balance: 3000.00, cash_balance: 900.50) + + @ibkr_account.update!( + raw_equity_summary_payload: [ + { currency: "CHF", report_date: "2026-05-07", total: "3201.00" } + ] + ) + + IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! + + balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") + assert_equal BigDecimal("3201.00"), balance.end_balance + end + + test "skips BASE_SUMMARY rows" do + @ibkr_account.update!( + raw_equity_summary_payload: [ + { currency: "BASE_SUMMARY", report_date: "2026-05-07", total: "9999.00" }, + { currency: "CHF", report_date: "2026-05-07", total: "3201.00" } + ] + ) + + IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! + + balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") + assert_equal BigDecimal("3201.00"), balance.end_balance + end + + test "skips rows with a mismatched explicit currency" do + @ibkr_account.update!( + raw_equity_summary_payload: [ + { currency: "USD", report_date: "2026-05-07", total: "9999.00" }, + { currency: "CHF", report_date: "2026-05-07", total: "3201.00" } + ] + ) + + IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! + + balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") + assert_equal BigDecimal("3201.00"), balance.end_balance + end + + test "skips malformed rows and still imports valid ones" do @ibkr_account.update!( raw_equity_summary_payload: [ nil, "bad-row", [], - { - currency: "CHF", - report_date: "2026-05-09", - cash: "1100.50", - total: "3400.00" - } + { report_date: "2026-05-11", total: "3400.00" } ] ) + seed_balance(date: Date.new(2026, 5, 11), balance: 3300.00, cash_balance: 1100.50) assert_nothing_raised do IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! end - balance = @account.balances.find_by!(date: Date.new(2026, 5, 9), currency: "CHF") + balance = @account.balances.find_by!(date: Date.new(2026, 5, 11), currency: "CHF") + assert_equal BigDecimal("3400.00"), balance.end_balance + assert_equal BigDecimal("1100.50"), balance.end_cash_balance + end - assert_equal BigDecimal("3400.0"), balance.end_balance - assert_equal BigDecimal("1100.5"), balance.end_cash_balance - assert_equal BigDecimal("2299.5"), balance.end_non_cash_balance + test "fills weekend and holiday gaps by carrying forward the last IBKR total with materializer cash" do + # Simulate the real-world situation: IBKR has no weekend rows, and historical + # holdings only cover the current snapshot so the materializer writes total=cash + # for gap dates. HistoricalBalancesSync must write the correct total for those days. + @ibkr_account.update!( + raw_equity_summary_payload: [ + { report_date: "2026-05-08", total: "3351.00" }, # Friday + # Saturday May 9 and Sunday May 10 absent — IBKR never sends them + { report_date: "2026-05-11", total: "3400.00" } # Monday + ] + ) + + # Materializer computed correct cash for all dates; wrong total for the weekend + seed_balance(date: Date.new(2026, 5, 8), balance: 3351.00, cash_balance: 900.50) + seed_balance(date: Date.new(2026, 5, 9), balance: 900.50, cash_balance: 900.50) # wrong total + seed_balance(date: Date.new(2026, 5, 10), balance: 900.50, cash_balance: 900.50) # wrong total + seed_balance(date: Date.new(2026, 5, 11), balance: 3400.00, cash_balance: 910.00) + + IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! + + saturday = @account.balances.find_by!(date: Date.new(2026, 5, 9), currency: "CHF") + sunday = @account.balances.find_by!(date: Date.new(2026, 5, 10), currency: "CHF") + + # Total corrected to Friday's IBKR total; cash preserved from materializer + assert_equal BigDecimal("3351.00"), saturday.end_balance + assert_equal BigDecimal("900.50"), saturday.end_cash_balance + assert_equal BigDecimal("2450.50"), saturday.end_non_cash_balance + + assert_equal BigDecimal("3351.00"), sunday.end_balance + assert_equal BigDecimal("900.50"), sunday.end_cash_balance + assert_equal BigDecimal("2450.50"), sunday.end_non_cash_balance + end + + test "skips rows with missing or unparseable total" do + @ibkr_account.update!( + raw_equity_summary_payload: [ + { report_date: "2026-05-06", total: "N/A" }, # unparseable string — before first valid date + { report_date: "2026-05-07", total: nil }, # nil total + { report_date: "2026-05-08", total: "3351.00" } # valid + ] + ) + + IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! + + # Gap-fill starts at the first valid trading day (May 8), so pre-range + # dates with bad totals must not produce any balance row. + assert_nil @account.balances.find_by(date: Date.new(2026, 5, 6), currency: "CHF") + assert_nil @account.balances.find_by(date: Date.new(2026, 5, 7), currency: "CHF") + assert_not_nil @account.balances.find_by(date: Date.new(2026, 5, 8), currency: "CHF") + end + + test "writes balance row with zero total for fully liquidated dates" do + @ibkr_account.update!( + raw_equity_summary_payload: [ + { report_date: "2026-05-07", total: "0" }, + { report_date: "2026-05-08", total: "3351.00" } + ] + ) + + IbkrAccount::HistoricalBalancesSync.new(@ibkr_account).sync! + + balance = @account.balances.find_by!(date: Date.new(2026, 5, 7), currency: "CHF") + assert_equal BigDecimal("0"), balance.end_balance end end diff --git a/test/models/ibkr_account_processor_test.rb b/test/models/ibkr_account_processor_test.rb index 94555bb61..7e2254f61 100644 --- a/test/models/ibkr_account_processor_test.rb +++ b/test/models/ibkr_account_processor_test.rb @@ -189,7 +189,7 @@ class IbkrAccountProcessorTest < ActiveSupport::TestCase assert_not_nil holding assert_equal BigDecimal("30"), holding.qty - assert_equal BigDecimal("123.1667"), holding.cost_basis + assert_in_delta BigDecimal("123.1667"), holding.cost_basis, BigDecimal("0.0001") end test "processor repairs default opening anchor after importing activity entries" do diff --git a/test/models/security/price/importer_test.rb b/test/models/security/price/importer_test.rb index a182a6c4a..547c4eb88 100644 --- a/test/models/security/price/importer_test.rb +++ b/test/models/security/price/importer_test.rb @@ -81,6 +81,32 @@ class Security::Price::ImporterTest < ActiveSupport::TestCase ).import_provider_prices end + test "logs provider fetch failures to debug log" do + Security::Price.delete_all + + error = Provider::Error.new("Rate limit exceeded") + + @provider.stubs(:fetch_security_prices).returns(provider_error_response(error)) + + assert_difference "DebugLogEntry.count", 1 do + Security::Price::Importer.new( + security: @security, + security_provider: @provider, + start_date: 2.days.ago.to_date, + end_date: Date.current + ).import_provider_prices + end + + entry = DebugLogEntry.order(:created_at).last + assert_equal "security_price_fetch", entry.category + assert_equal "warn", entry.level + assert_equal "Could not fetch prices for ticker", entry.message + assert_equal "security/price/importer", entry.source.underscore + assert_equal @security.id, entry.metadata["security_id"] + assert_equal @security.ticker, entry.metadata["ticker"] + assert_equal "Rate limit exceeded", entry.metadata["provider_error"] + end + test "writes post-listing prices when holding predates provider history" do # Regression: a 2018-06-15 trade for a pair the provider only has from # 2020-01-03 onwards (e.g. BTCEUR on Binance) used to hit the diff --git a/test/models/security/provided_test.rb b/test/models/security/provided_test.rb index 521a249ba..0b06d8d79 100644 --- a/test/models/security/provided_test.rb +++ b/test/models/security/provided_test.rb @@ -153,6 +153,30 @@ class Security::ProvidedTest < ActiveSupport::TestCase assert_equal fallback_provider, @security.price_data_provider end + test "import_provider_details logs provider metadata failures to debug log" do + provider = mock("provider") + provider.stubs(:class).returns(Provider::TwelveData) + provider.stubs(:fetch_security_info).returns( + provider_error_response(Provider::Error.new("metadata unavailable")) + ) + + @security.stubs(:price_data_provider).returns(provider) + + assert_difference "DebugLogEntry.count", 1 do + @security.import_provider_details + end + + entry = DebugLogEntry.order(:created_at).last + assert_equal "security_metadata_fetch", entry.category + assert_equal "warn", entry.level + assert_equal "Failed to get security info", entry.message + assert_equal "security", entry.source.underscore + assert_equal @security.id, entry.metadata["security_id"] + assert_equal @security.ticker, entry.metadata["ticker"] + assert_equal "metadata unavailable", entry.metadata["provider_error"] + assert_equal "twelve_data", entry.provider_key + end + # --- provider_status --- test "provider_status returns provider_unavailable when assigned provider disabled" do diff --git a/test/models/sure_import_test.rb b/test/models/sure_import_test.rb index 9345dea60..ff99bb6fd 100644 --- a/test/models/sure_import_test.rb +++ b/test/models/sure_import_test.rb @@ -164,6 +164,52 @@ class SureImportTest < ActiveSupport::TestCase assert_equal 3, @import.rows_count end + test "sync_ndjson_rows_count! persists expected record counts" do + attach_ndjson(build_ndjson([ + { type: "Account", data: { id: "account-1" } }, + { type: "Balance", data: { id: "balance-1" } }, + { type: "Transaction", data: { id: "transaction-1" } }, + { type: "UnknownType", data: { id: "unknown-1" } } + ])) + + @import.reload + + assert_equal 4, @import.rows_count + assert_equal 1, @import.expected_record_counts["accounts"] + assert_equal 1, @import.expected_record_counts["balances"] + assert_equal 1, @import.expected_record_counts["transactions"] + assert_not @import.expected_record_counts.key?("unknown_type") + assert_equal({}, @import.readback_verification) + end + + test "import resyncs expected counts from current attachment" do + attach_ndjson(build_ndjson([ + { type: "Account", data: { id: "stale-account" } } + ])) + @import.ndjson_file.attach( + io: StringIO.new(build_ndjson([ + { type: "Category", data: { + id: "current-category", + name: "Current Category", + color: "#407706", + classification: "expense", + lucide_icon: "shapes" + } } + ])), + filename: "current.ndjson", + content_type: "application/x-ndjson" + ) + + @import.import! + @import.reload + + assert_equal 1, @import.rows_count + assert_equal 0, @import.expected_record_counts["accounts"] + assert_equal 1, @import.expected_record_counts["categories"] + assert_equal 1, @import.readback_verification.dig("expected_record_counts", "categories") + assert_equal "matched", @import.readback_verification["status"] + end + test "publishes import successfully" do attach_ndjson(build_ndjson([ { type: "Account", data: { @@ -190,6 +236,163 @@ class SureImportTest < ActiveSupport::TestCase assert_equal "Depository", account.accountable_type end + test "publish records matched readback verification from family-scoped deltas" do + other_family = Family.create!(name: "Other Family", currency: "USD", locale: "en", date_format: "%m-%d-%Y") + other_family.accounts.create!( + name: "Other Checking", + balance: 100, + currency: "USD", + accountable: Depository.new + ) + + attach_ndjson(importable_history_ndjson) + + @import.publish + @import.reload + + verification = @import.readback_verification + + assert_equal "complete", @import.status + assert_equal "matched", verification["status"] + assert_equal 1, verification.dig("expected_record_counts", "accounts") + assert_equal 1, verification.dig("expected_record_counts", "categories") + assert_equal 1, verification.dig("expected_record_counts", "tags") + assert_equal 1, verification.dig("expected_record_counts", "merchants") + assert_equal 1, verification.dig("expected_record_counts", "transactions") + assert_equal 1, verification.dig("expected_record_counts", "valuations") + assert_equal 1, verification.dig("actual_delta_counts", "accounts") + assert_equal 1, verification.dig("actual_delta_counts", "categories") + assert_equal 1, verification.dig("actual_delta_counts", "tags") + assert_equal 1, verification.dig("actual_delta_counts", "merchants") + assert_equal 1, verification.dig("actual_delta_counts", "transactions") + assert_equal 1, verification.dig("actual_delta_counts", "valuations") + assert_equal 0, verification.dig("checked_counts", "balances") + assert_empty verification["mismatches"] + assert_equal 1, other_family.accounts.count + end + + test "publish verifies expected zero record types against unexpected readback deltas" do + attach_ndjson(build_ndjson([ + { type: "Account", data: { + id: "account-1", + name: "Implicit Opening Anchor", + balance: "100.00", + currency: "USD", + accountable_type: "Depository", + accountable: { subtype: "checking" } + } } + ])) + + @import.publish + @import.reload + + verification = @import.readback_verification + + assert_equal "complete", @import.status + assert_equal "mismatch", verification["status"] + assert_equal 0, verification.dig("expected_record_counts", "valuations") + assert_equal 0, verification.dig("checked_counts", "valuations") + assert_equal 1, verification.dig("actual_delta_counts", "valuations") + assert_equal({ "expected" => 0, "actual" => 1 }, verification.dig("mismatches", "valuations")) + end + + test "publish records mismatch when expected rows are skipped by readback" do + attach_ndjson(build_ndjson([ + { type: "Transaction", data: { + id: "transaction-1", + account_id: "missing-account", + date: "2024-01-15", + amount: "12.34", + name: "Skipped transaction", + currency: "USD" + } } + ])) + + @import.publish + @import.reload + + assert_equal "complete", @import.status + assert_equal "mismatch", @import.readback_verification["status"] + assert_equal({ "expected" => 1, "actual" => 0 }, @import.readback_verification.dig("mismatches", "transactions")) + end + + test "failed publish records failed verification without partial mutation" do + attach_ndjson(build_ndjson([ + { type: "Account", data: { + id: "account-1", + name: "Rollback Account", + balance: "100.00", + currency: "USD", + accountable_type: "Depository" + } }, + { type: "Transaction", data: { + id: "transaction-1", + account_id: "account-1", + date: "not-a-date", + amount: "12.34", + name: "Bad date", + currency: "USD" + } } + ])) + + initial_account_count = @family.accounts.count + initial_transaction_count = @family.entries.where(entryable_type: "Transaction").count + + @import.publish + @import.reload + + assert_equal "failed", @import.status + assert_equal initial_account_count, @family.accounts.count + assert_equal initial_transaction_count, @family.entries.where(entryable_type: "Transaction").count + assert_equal "failed", @import.readback_verification["status"] + assert_equal 0, @import.readback_verification.dig("actual_delta_counts", "accounts") + assert_equal 0, @import.readback_verification.dig("actual_delta_counts", "transactions") + end + + test "failed publish keeps original error when failed verification cannot be recorded" do + before_counts = @import.send(:readback_count_snapshot) + original_error = StandardError.new("original import failure") + logged_messages = [] + + Rails.logger.stubs(:warn).with do |message| + logged_messages << message unless logged_messages.include?(message) + true + end + @import.stubs(:update_columns).raises(StandardError, "verification write failed") + + @import.send(:record_failed_readback_verification!, before_counts:, error: original_error) + + assert_match(/Failed to record Sure import readback verification/, logged_messages.first) + assert_match(/verification write failed/, logged_messages.first) + end + + test "revert marks Sure readback verification as reverted" do + attach_ndjson(importable_history_ndjson) + + @import.publish + assert_equal "matched", @import.reload.verification_status + + @import.revert + + assert_equal "pending", @import.status + assert_equal "reverted", @import.verification_status + end + + test "revert failure leaves existing Sure readback verification untouched" do + attach_ndjson(importable_history_ndjson) + + @import.publish + verification = @import.reload.readback_verification + + @import.stub(:entries, -> { raise StandardError, "revert failed before pending" }) do + @import.revert + end + + assert_equal "revert_failed", @import.status + assert_equal verification, @import.readback_verification + assert_equal "matched", @import.verification_status + end + test "import tracks created accounts for revert" do attach_ndjson(build_ndjson([ { type: "Account", data: { @@ -239,4 +442,53 @@ class SureImportTest < ActiveSupport::TestCase def build_ndjson(records) records.map(&:to_json).join("\n") end + + def importable_history_ndjson + build_ndjson([ + { type: "Account", data: { + id: "account-1", + name: "Verified Checking", + balance: "1000.00", + currency: "USD", + accountable_type: "Depository", + accountable: { subtype: "checking" } + } }, + { type: "Valuation", data: { + id: "valuation-1", + account_id: "account-1", + date: "2024-01-14", + amount: "1000.00", + currency: "USD", + kind: "opening_anchor" + } }, + { type: "Category", data: { + id: "category-1", + name: "Verified Category", + color: "#407706", + classification: "expense", + lucide_icon: "shapes" + } }, + { type: "Tag", data: { + id: "tag-1", + name: "Verified Tag", + color: "#407706" + } }, + { type: "Merchant", data: { + id: "merchant-1", + name: "Verified Merchant", + color: "#407706" + } }, + { type: "Transaction", data: { + id: "transaction-1", + account_id: "account-1", + category_id: "category-1", + merchant_id: "merchant-1", + tag_ids: [ "tag-1" ], + date: "2024-01-15", + amount: "12.34", + name: "Verified transaction", + currency: "USD" + } } + ]) + end end diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 9912e5a9e..5139fff09 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -660,6 +660,23 @@ class UserTest < ActiveSupport::TestCase assert_equal "custom_role", User.role_for_new_family_creator(fallback_role: "custom_role") end + # Preview features preference tests + test "preview_features_enabled? defaults to false" do + @user.update!(preferences: {}) + assert_not @user.preview_features_enabled? + end + + test "preview_features_enabled? true only when explicitly true" do + @user.update!(preferences: { "preview_features_enabled" => true }) + assert @user.preview_features_enabled? + + @user.update!(preferences: { "preview_features_enabled" => false }) + assert_not @user.preview_features_enabled? + + @user.update!(preferences: { "preview_features_enabled" => "yes" }) + assert_not @user.preview_features_enabled?, "truthy non-boolean should not enable" + end + # ActiveStorage attachment cleanup tests test "purging a user removes attached profile image" do user = users(:family_admin) diff --git a/test/system/accounts_test.rb b/test/system/accounts_test.rb index 555959190..b7595f238 100644 --- a/test/system/accounts_test.rb +++ b/test/system/accounts_test.rb @@ -105,7 +105,7 @@ class AccountsTest < ApplicationSystemTestCase end def assert_account_created(accountable_type, &block) - click_link Accountable.from_type(accountable_type).display_name.singularize + click_link Accountable.from_type(accountable_type).singular_display_name click_link "Enter account balance" if accountable_type.in?(%w[Depository Investment Crypto Loan CreditCard]) account_name = "[system test] #{accountable_type} Account" @@ -164,6 +164,6 @@ class AccountsTest < ApplicationSystemTestCase end def humanized_accountable(accountable_type) - Accountable.from_type(accountable_type).display_name.singularize + Accountable.from_type(accountable_type).singular_display_name end end diff --git a/test/system/imports_test.rb b/test/system/imports_test.rb index 15b146e24..e5667817e 100644 --- a/test/system/imports_test.rb +++ b/test/system/imports_test.rb @@ -22,9 +22,7 @@ class ImportsTest < ApplicationSystemTestCase fill_in "import[raw_file_str]", with: file_fixture("imports/transactions.csv").read - within "form" do - click_on "Upload CSV" - end + find_field("import[raw_file_str]").find(:xpath, "./ancestor::form").click_button("Upload CSV") select "Date", from: "import[date_col_label]" select "YYYY-MM-DD", from: "import[date_format]" @@ -73,9 +71,7 @@ class ImportsTest < ApplicationSystemTestCase fill_in "import[raw_file_str]", with: file_fixture("imports/trades.csv").read - within "form" do - click_on "Upload CSV" - end + find_field("import[raw_file_str]").find(:xpath, "./ancestor::form").click_button("Upload CSV") select "date", from: "import[date_col_label]" select "YYYY-MM-DD", from: "import[date_format]" @@ -116,9 +112,7 @@ class ImportsTest < ApplicationSystemTestCase fill_in "import[raw_file_str]", with: file_fixture("imports/accounts.csv").read - within "form" do - click_on "Upload CSV" - end + find_field("import[raw_file_str]").find(:xpath, "./ancestor::form").click_button("Upload CSV") select "type", from: "import[entity_type_col_label]" select "name", from: "import[name_col_label]" @@ -166,9 +160,7 @@ class ImportsTest < ApplicationSystemTestCase fill_in "import[raw_file_str]", with: file_fixture("imports/mint.csv").read - within "form" do - click_on "Upload CSV" - end + find_field("import[raw_file_str]").find(:xpath, "./ancestor::form").click_button("Upload CSV") click_on "Apply configuration" @@ -195,4 +187,42 @@ class ImportsTest < ApplicationSystemTestCase click_on "Back to dashboard" end + + test "actual import" do + visit new_import_path + + # Pending CSV-style imports default the dialog to the Raw Data tab; Actual lives under Financial Tools. + click_on "Financial Tools" + click_on "Import from Actual Budget" + + within_testid("import-tabs") do + click_on "Copy & Paste" + end + + fill_in "import[raw_file_str]", with: file_fixture("imports/actual.csv").read + + find_field("import[raw_file_str]").find(:xpath, "./ancestor::form").click_button("Upload CSV") + + click_on "Apply configuration" + + click_on "Next step" + + assert_selector "h1", text: "Assign your categories" + click_on "Next" + + assert_selector "h1", text: "Assign your accounts" + click_on "Next" + + click_on "Publish import" + + assert_text "Import in progress" + + perform_enqueued_jobs + + click_on "Check status" + + assert_text "Import successful" + + click_on "Back to dashboard" + end end diff --git a/test/system/settings_test.rb b/test/system/settings_test.rb index 1107c2aed..96ec24dcc 100644 --- a/test/system/settings_test.rb +++ b/test/system/settings_test.rb @@ -104,7 +104,7 @@ class SettingsTest < ApplicationSystemTestCase def open_settings_from_sidebar user_menu = find("div[data-testid=user-menu]", match: :first, visible: :visible) within user_menu do - find("[data-DS--menu-target='button']", match: :first).click + find("[data-DS--popover-target='button']", match: :first).click click_link "Settings", match: :first end end diff --git a/workers/preview/src/index.ts b/workers/preview/src/index.ts index 872cf1a99..5e60a8757 100644 --- a/workers/preview/src/index.ts +++ b/workers/preview/src/index.ts @@ -62,7 +62,7 @@ const WAITING_MESSAGES: Record = { export class RailsContainer extends Container { defaultPort = 3000; - pingEndpoint = "container/up"; + pingEndpoint = "localhost/up"; entrypoint = ["/rails/bin/preview-entrypoint", "bundle", "exec", "puma", "-C", "config/puma.rb"]; envVars = { RAILS_ENV: "production", diff --git a/workers/preview/wrangler.toml b/workers/preview/wrangler.toml index e180a62b7..17e95b899 100644 --- a/workers/preview/wrangler.toml +++ b/workers/preview/wrangler.toml @@ -17,6 +17,7 @@ enabled = true [[containers]] class_name = "RailsContainer" image = "../../Dockerfile.preview" +instance_type = "basic" max_instances = 1 # Durable Object binding for the container