Files
sure/app/components/savings/progress_ring_component.html.erb
Guillem Arias 093831a6e5 fix(savings_goals): neutral ring percent, chart start vertical-line, contribution select wrapper, deterministic account colors
Ring percentage no longer takes the warning yellow tint when behind —
the colored ring stroke + status pill + catch-up alert already signal
the state, doubling it on the percent number was noise. Reached stays
green (celebratory), everything else uses text-primary (white/dark).

Chart vertical line at the left edge was the (start_date, $0) point
the controller prepended to the saved series. When start_date equals
the first contribution date (now common after the earlier earliest-
contribution fix), this drew a vertical jump from $0 to first
contribution at x=start. Skip the prepend when there's no temporal
gap so the line starts at the first real point.

Add Contribution modal — wrap the source-account select in the styled
form-field via f.select instead of label_tag + bare select_tag. Match
the rest of Sure's form controls. Also pass hide_currency on the
amount field so single-currency families don't see a redundant USD
dropdown.

Account avatar colors — replace Ruby String#hash (randomized per
process by Ruby for DoS protection) with a deterministic MD5-based
pick from Savings::GoalAvatarComponent::PALETTE. Same account name
now resolves to the same color across processes and across
components. Apply via a new Savings::GoalAvatarComponent.color_for
helper used by both the form stepper account list and the goal-card
AccountStackComponent (which was hardcoding blue-500 for every avatar
in the stack, hence Chase + Ally looking identical on the wedding
card).
2026-05-11 16:58:17 +02:00

16 lines
965 B
Plaintext

<div data-controller="donut-chart"
data-donut-chart-segments-value="<%= goal.to_donut_segments_json.to_json %>"
data-donut-chart-segment-height-value="6"
class="relative mx-auto"
style="width: <%= size %>px; height: <%= size %>px;">
<div data-donut-chart-target="chartContainer" class="absolute inset-0 pointer-events-none"></div>
<div data-donut-chart-target="contentContainer" class="flex items-center justify-center h-full">
<div data-donut-chart-target="defaultContent" class="flex flex-col items-center text-center">
<span class="text-secondary text-xs mb-1"><%= t("savings_goals.show.ring.saved") %></span>
<span class="text-3xl font-medium tabular-nums privacy-sensitive <%= percent_text_class %>"><%= percent %>%</span>
<span class="text-xs text-subdued tabular-nums mt-1"><%= amount_label %></span>
<span class="text-xs text-subdued tabular-nums">of <%= target_label %></span>
</div>
</div>
</div>