From a05df8546fef360e7fab52e39e95028af09df8a0 Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Sun, 20 Sep 2026 21:08:52 +1200 Subject: [PATCH] Colour progress bars by how the planting is getting on Blue while growing, green while harvesting, amber when late, red when very late, grey when finished. The track is now neutral grey so every colour reads against it. Planting#progress_state decides, and the garden cards, planting progress and timeline bars use it. Co-Authored-By: Claude Sonnet 5 --- app/assets/stylesheets/_variables.scss | 6 ++--- app/assets/stylesheets/overrides.scss | 22 +++++++++++++++++++ app/javascript/components/PlantingRow.jsx | 6 ++--- app/models/concerns/predict_planting.rb | 15 +++++++++++++ app/serializers/garden_card_serializer.rb | 1 + app/views/plantings/_progress.html.haml | 2 +- app/views/plantings/_timeline.html.haml | 2 +- spec/models/planting_spec.rb | 16 ++++++++++++++ .../garden_card_serializer_spec.rb | 4 ++++ 9 files changed, 66 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/_variables.scss b/app/assets/stylesheets/_variables.scss index b32101769..4308b1214 100644 --- a/app/assets/stylesheets/_variables.scss +++ b/app/assets/stylesheets/_variables.scss @@ -111,8 +111,8 @@ $btn-font-weight: 500; $btn-box-shadow: $material-shadow-raised; $btn-active-box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 3px rgba(0, 0, 0, 0.12), 0 4px 15px 0 rgba(0, 0, 0, 0.2); -// Progress bars: a thin strip, dark green filled over a lighter green track, as before. -// (These were Bootstrap 3 variables the old skin ignored; Bootstrap 5 reads them.) +// Progress bars: a thin strip over a neutral track. The bar's colour shows how the planting is +// getting on (see .progress-bar--* in overrides.scss). $progress-height: 0.875rem; -$progress-bg: lighten($green, 15%); +$progress-bg: #e0e0e0; $progress-bar-bg: $green; diff --git a/app/assets/stylesheets/overrides.scss b/app/assets/stylesheets/overrides.scss index 38eb1a84f..c601318b4 100755 --- a/app/assets/stylesheets/overrides.scss +++ b/app/assets/stylesheets/overrides.scss @@ -456,6 +456,7 @@ ul.thumbnail-buttons { text-align: justify; } +// Buttons are uppercase, as in the old skin, except link buttons. // Bootstrap only draws the button shadow when $enable-shadows is on, so draw it here. .btn { box-shadow: var(--bs-btn-box-shadow); @@ -486,6 +487,27 @@ ul.thumbnail-buttons { --bs-btn-active-bg: rgba(0, 0, 0, 0.12); } +// Progress bar colours by state (Planting#progress_state). +.progress-bar--growing { + background-color: var(--bs-info); +} + +.progress-bar--harvesting { + background-color: var(--bs-success); +} + +.progress-bar--late { + background-color: var(--bs-warning); +} + +.progress-bar--super_late { + background-color: var(--bs-danger); +} + +.progress-bar--finished { + background-color: var(--bs-secondary); +} + // The card variables drop the card's border, which also drew the line under a // header, so put that line back. .card-header { diff --git a/app/javascript/components/PlantingRow.jsx b/app/javascript/components/PlantingRow.jsx index aec40f58a..744041c92 100644 --- a/app/javascript/components/PlantingRow.jsx +++ b/app/javascript/components/PlantingRow.jsx @@ -29,7 +29,7 @@ export default function PlantingRow({planting, defaultIconUrl, highlighted}) { {planting.progress_note ? ( {planting.progress_note} ) : ( - + )}
@@ -45,14 +45,14 @@ export default function PlantingRow({planting, defaultIconUrl, highlighted}) { ); } -function Progress({percentage, finishLabel}) { +function Progress({percentage, state, finishLabel}) { if (percentage === null || percentage === undefined) return null; return (
"100", "aria-valuemin" => "0", "aria-valuenow" => planting.percentage_grown, role: "progressbar", style: "width: #{planting.percentage_grown}%"} + .progress-bar{class: "progress-bar--#{planting.progress_state}", "aria-valuemax" => "100", "aria-valuemin" => "0", "aria-valuenow" => planting.percentage_grown, role: "progressbar", style: "width: #{planting.percentage_grown}%"} .float-start #{sprintf '%.0f', planting.percentage_grown}% diff --git a/app/views/plantings/_timeline.html.haml b/app/views/plantings/_timeline.html.haml index 49f9c6549..062b13470 100644 --- a/app/views/plantings/_timeline.html.haml +++ b/app/views/plantings/_timeline.html.haml @@ -14,7 +14,7 @@ %p.small #{finished_icon} Finish expected #{I18n.l planting.finish_predicted_at} - if planting.planted_at.present? && planting.expected_lifespan.present? .progress - .progress-bar{"aria-valuemax" => "100", "aria-valuemin" => "0", "aria-valuenow" => planting.percentage_grown, role: "progressbar", style: "width: #{planting.percentage_grown}%"} + .progress-bar{class: "progress-bar--#{planting.progress_state}", "aria-valuemax" => "100", "aria-valuemin" => "0", "aria-valuenow" => planting.percentage_grown, role: "progressbar", style: "width: #{planting.percentage_grown}%"} %ul.list-unstyled.d-flex.justify-content-between - in_weeks(planting.expected_lifespan).times do |week_number| %li{class: planting.planted_at + week_number.weeks > Time.zone.today ? 'text-muted progress-fade' : '', 'data-bs-toggle': "tooltip", 'data-bs-placement': "top", title: I18n.l(planting.planted_at + week_number.weeks)} diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index 8839017f1..671e3affd 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -113,6 +113,22 @@ describe Planting do end end + describe '#progress_state' do + let(:planting) { described_class.new } + + def states(finished: false, super_late: false, late: false, harvest_time: false) + allow(planting).to receive_messages(finished?: finished, super_late?: super_late, late?: late, + harvest_time?: harvest_time) + planting.progress_state + end + + it { expect(states).to eq :growing } + it { expect(states(harvest_time: true)).to eq :harvesting } + it { expect(states(late: true, harvest_time: true)).to eq :late } + it { expect(states(late: true, super_late: true)).to eq :super_late } + it { expect(states(finished: true, late: true)).to eq :finished } + end + describe 'planting first harvest preductions' do context 'no data' do let(:planting) { create(:planting) } diff --git a/spec/serializers/garden_card_serializer_spec.rb b/spec/serializers/garden_card_serializer_spec.rb index 75ae02a42..5e056cac1 100644 --- a/spec/serializers/garden_card_serializer_spec.rb +++ b/spec/serializers/garden_card_serializer_spec.rb @@ -92,6 +92,10 @@ describe GardenCardSerializer do expect(planting).to include(url: "/plantings/#{annual.slug}", crop: { name: 'lettuce', icon_url: nil }) end + it 'says how the planting is getting on, for the progress bar colour' do + expect(serialize(garden)[:annuals].first[:progress_state]).to eq :growing + end + it 'says why there is no progress bar' do annual.update!(planted_at: nil)