- Renamed all instances of 'Activity' to 'Job' in views, controllers, and models.
- Updated routes to reflect the change from activities to jobs.
- Modified database schema to rename the activities table to jobs and adjusted related columns.
- Updated locale files to change activity-related translations to jobs.
- Adjusted tests to ensure they reference jobs instead of activities.
- Removed the category field from jobs as they are now a plain list.
- Updated seed data and sample data generation to create jobs instead of activities.
- Deleted Elasticsearch gems from Gemfile and Gemfile.lock.
- Updated README and TECH documentation to reflect the removal of Elasticsearch.
- Removed Elasticsearch-related code from models, controllers, services, and factories.
- Adjusted tests to eliminate dependencies on Elasticsearch.
- Cleaned up Docker configuration and environment variables related to Elasticsearch.
- Added a TODO file for future gem reviews and potential removals.
- Removed NurseryScoped concern and associated controllers for plant_out and leftovers.
- Introduced TransplantModal component for handling the transplanting of seedlings.
- Updated PlantingsController to support transplanting with a new date handling method.
- Modified GardensHelper to provide active gardens for transplanting.
- Updated NurseryChip component to include transplant functionality.
- Removed legacy plant_out views and associated routes.
- Adjusted tests to reflect the new transplanting workflow and removed obsolete tests related to plant_out.
* Restore the Ruby 4.0.6 upgrade
PR #4831 committed a stale Gemfile.lock over the newer one, taking
.ruby-version back to 3.2.3 and rolling back active_median, dalli,
parallel, rbs and selenium-webdriver. Dockerfile and
.devcontainer/Dockerfile still build on Ruby 4, so the Gemfile's version
check fails against the image.
Restores both files to what they were before that merge.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Tidy plantings#show, and make cards and menus consistent
This page read as a page about the crop rather than about one member's
planting, and its sections each did things their own way. Changes follow
the conventions written up in the UI consistency guide.
Identity
- Title, meta description and OpenGraph all read "<crop> planting by
<owner>"; the hero carries a muted "planting by X in Y" subtitle and
the scientific name moves to the crop card.
- Breadcrumb's last item is plain text, not a link to the current page.
Actions
- One actions menu per page: a quiet three-dot button in the top right of
the hero, rendered by the new PlantingActions island, opening the
EditPlanting, RecordHarvest, SaveSeeds, MarkFinished and AddPhoto
dialogs that already existed for the garden list.
- Menu items are lower case, so a menu reads as a list of things you can
do rather than a row of headings.
- Transplanting moves out of the sidebar into a dialog off that menu: it
is done once in a planting's life and should not hold real estate.
- The second seed-saving dropdown and the loose photo buttons are gone;
each section keeps one quiet "add" on its heading bar as the non-JS
path.
- The plant-part icons from the server-rendered harvest form now reach
the dialog, via icon_url on HarvestFormSerializer.
Fact cards
- Every card fills the same four slots, and the core cards always render
so one planting's page has the same shape as the next.
- Progress reads as a percentage with "day 43 of 90" beneath; quantity
and "grown from" merge into one card rather than both saying
"seedling"; rating is stars and renders even when unrated.
- Dates go through I18n.l and standard_time_distance instead of
assembling abbr_month_names by hand.
- Adds Planting#planned?, replacing three copies of age_in_days < 0.
- Perennial no longer claims the plant "grows back each year".
Cards by type
- Harvest cards get square corners, a warm accent and the harvest icon,
and say "<crop> harvest", so they are not mistaken for plantings.
- Seed cards are drawn as seed packets: portrait, papery, torn top edge,
printed band, small print along the foot and the year saved stamped on
them.
Layout
- The page wrapper is .planting-show, not .planting: that is the planting
*card's* class, and its absolutely positioned badges and quick actions
were leaking onto this page.
- Sections are bordered blocks with their heading bar as the lid, so a
heading and its content read as one thing.
- One spacing scale, and the hero aligns to the same left edge as
everything below it.
Copy
- Section headings and empty states go through en.yml, in one voice.
- "Add a photo to visually track growth of this planting, to Flickr,
iNaturalist or Pl@ntNet" was nonsense: photos come from Flickr only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Use the harvest and seed cards site-wide, and rate a planting in place
The new harvest cards and seed packets only appeared on plantings#show.
Everywhere else either used the old thumbnails or hand-rolled its own
markup, which is what made harvests and plantings look alike in the first
place.
- members#show and members/_harvests render harvests/card. The latter also
wrapped each card in another .card, which nested a card in a card.
- The homepage harvest list was hand-rolled markup beside a seeds section
that already used seeds/card; both now use the shared partials.
- Homepage seed packets go in an .index-cards grid. Outside one they have
no width, and the packet's 3:4 ratio made each half the page wide.
- harvests/_harvest and seeds/_seed chose between card and thumbnail on a
`full:` local that nothing passes. Both render the card.
The crop pages' harvest and seed panels are lists of links in a sidebar,
not card grids, so they are left alone.
Section "add" buttons now open the same dialogs as the actions menu, via a
data-planting-dialog attribute the island listens for. Their href stays as
the fallback without JavaScript.
The rating card is now clickable: for someone who may edit the planting it
renders StarRating, which saves the new rating and puts it back if the
save fails. The card's own heading is the label, so the fieldset legend is
hidden rather than saying "Rating" twice.
"More photos" is a plain link again, and only shows when there are more
photos than the page is displaying — the photos are now paginated to 12,
where before the whole set was loaded and the link always showed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Put the like button beside the planting's name
It sat on its own below the hero, with a section's worth of space above
and below it, reading as an orphan rather than as something belonging to
the planting.
It now sits on the title line, right after the name, at its own size
rather than the title's.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Draw a border around the planting's own data
The title, facts, photos, harvests, seeds and planned activities now sit
inside one subtle border, so they read as one body of data rather than
running into the sidebar beside them.
Also drops the raised shadow from the like button. The global .btn shadow
made the heart look like a call to action it isn't.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Tidy the planting page sidebar, and the add-photo dialog
The sidebar was three blocks with three different treatments: a bare
owner card, the shared crop card, and a bordered neighbours section. They
now all use the same sections as the main column, with a heading bar each.
- The owner block leads with the avatar and who grows this where, rather
than a heading repeating "Planted by".
- The crop card renders without its footer here. "Add to my garden" and
"Save seeds" made no sense beside a planting you are already growing,
and the page offers both already. crops/_crop takes actions: false;
everywhere else keeps them.
- Partials shared with other pages bring their own .card, which inside a
section is a box in a box, so those are flattened.
Add-photo dialog:
- It now says what it is adding to: "Add photo to chives planting",
rather than "Add a photo to chives". Garden cards say which garden.
- While Flickr is being read the body holds roughly the height the picker
will take and centres the spinner, instead of a short dialog with a
spinner in the corner that jumps open when the photos arrive.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Say what kind of record a page is about in its title
"Chives" is a crop. A page about one member's chives should say "Chives
planting" in its heading, not leave the reader to work it out from the
furniture around it. The same for harvests and saved seeds.
- plantings#show: "Chives planting", subtitle "by <owner> in <garden>".
- harvests#show: "Basil harvest", subtitle "by <owner> · <date>". The
owner was in a %small inside the h1 before.
- seeds#show: already said "seeds"; it now names who saved them.
Gardens are left as they are: a garden's name is the member's own, so the
noun belongs in the subtitle rather than appended to a name that may
already contain it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* One corner radius for all data cards, and harvest months by season
Cards used three different shapes: plantings rounded at 5%, harvests and
seed packets square. A percentage radius also draws an ellipse that
changes with the card's size, so a tall packet and a square planting card
curved differently. There is now one $card-radius, used by every data
card and by the section boxes.
Harvest months are grouped into the grower's own seasons, three months
each, named and kept together, starting at their spring — so a Wellington
gardener sees spring begin in September. Where we have no latitude we
show the plain January-to-December row rather than guessing at a
hemisphere.
The grower's location now appears in the page subtitle. It decides the
seasons and the harvest times, so it belongs with the rest of the
planting's identity rather than only as a "nearby" link in the sidebar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Tidy the harvest months block
It was loose text at the end of the timeline partial: a bare "Harvest
months:" label, twelve badges, and a trailing "in <place>" that now
repeats the location in the page subtitle.
- Moved into its own partial with a proper label, rather than trailing
off the timeline.
- Dropped the repeated location.
- A legend says what a highlighted month means. Nothing said so before.
- The empty state is its own muted line instead of a sentence running on
from the label, and no longer says "we need more data" at the reader.
- Each badge carries its full month name for screen readers, and
highlighted ones say they are harvest months. The quiet months were
aria-hidden, so a screen reader heard the harvest months with no
calendar around them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Give the sidebar crop block its own partial
Reusing crops/_crop inside a section meant a card inside a box: a white
strip between the green heading and the photo, the card's own shadow
sitting proud of the section, a photo that overshot the right edge, and
two corner radii disagreeing. Flattening it with negative margins was
fighting the card rather than fixing it.
plantings/_crop is written for this spot instead: the photo runs edge to
edge under the heading bar, the crop's name is title-cased with its
scientific name beneath, and the growing times are a short list rather
than three stats laid out side by side.
crops/_crop goes back to how it was, including its footer buttons, since
nothing needs to suppress them now.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Update the specs for the tidied planting page
Mostly copy and flow changes from the tidy-up, but two real bugs came out
of running them.
Bugs fixed:
- planting_actions_props didn't pass planted_at or today, which
MarkFinishedModal needs to decide whether "today" may be offered and
where the date box starts. Without them the dialog threw while
rendering, and with no error boundary React tore down the whole island,
so the actions menu vanished entirely.
- The dialogs reloaded the page from inside the save callback, tearing
the page down while the dialog was still finishing its own update. They
now close first and reload on the next tick.
Menu items are lower-cased in CSS, as the garden cards already do it,
rather than by calling downcase on the shared button translations. That
was mangling labels other pages show in sentence case.
Specs:
- Menu, dialog and section-heading flows updated: the actions menu opens
dialogs rather than navigating, so recording a harvest, marking a
planting finished, editing and transplanting all drive the dialog.
- Copy: "grows this in", "day 14 of 50", "Planned" for a future planting,
"4 of 5", the new harvest-months wording, and the add-photo dialog
naming what it adds to.
- The parent-seed example asserted a link to the planting, which came
from the breadcrumb; the last crumb is the page you are on, so it is
plain text now and the example checks the seed link instead.
- Removed spec/features/shared_examples/append_date.rb. It drove the old
datepicker finish flow and had one caller.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Stop avatars shifting the page during feature specs
spec/features/places/searching_a_place_spec.rb intermittently failed on
"goes to members' index page": the click on "View all members >>" landed
on nothing and the browser stayed put.
Member avatars come from gravatar.com over the network and were rendered
with img-fluid and no dimensions, so they reserved no space until they
arrived. The link sits directly under that grid. Capybara found the link,
an avatar landed, the link moved, and the click missed.
rails_helper meant to prevent this, but its guard tested for Poltergeist's
url_blacklist. Poltergeist is long gone and Selenium's browser has no such
method, so the condition was always false and the block never ran.
- Give the two avatar image tags explicit width and height, so the box is
reserved before the image loads. This fixes real layout shift for
members too, not only the specs.
- Replace the dead guard with config.x.blank_avatars, which browser specs
set, making avatar_uri return a blank inline GIF. Helper specs still
assert the real Gravatar URLs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Fix avatar URI logic to prevent layout shift in all environments
* Add waiting assertions to prevent premature content checks after saving harvest
* Refactor PlantingActions to improve dialog handling and state management
Enhance PlantingRating to prevent multiple saves and improve error messaging
* Fix date input handling in planting edit dialog
* Add neighbour planting sidebar with improved styling and layout
* Tidy crops#show, and share the record page layout
The planting page's layout was planting-specific CSS. It is now a shared
.record-page / .record-panel in _record_page.scss, and crops#show uses it:
the crop's own data inside one border, the sidebar outside, sections as
bordered blocks with a heading bar as the lid.
Along the way a duplicate section rule and two copies of the kebab button
styling collapsed into one each.
Crop page:
- Scientific and alternate names sit under the crop's name, where they
belong, instead of having a sidebar card of their own. Wranglers add and
edit them from the actions menu, in a dialog; the loose "Add" buttons in
the page body are gone.
- The actions menu is the same three-dot kebab as plantings, in the top
right of the hero. The "you are a CROP WRANGLER" banner is gone: seeing
the menu already tells you that. Menu items have no icons now, except
delete, which keeps its icon and its red.
- Growing facts were split three ways — prose in the hero, prediction
cards in the main column, an OpenFarm list in the sidebar — and the
hero prose was the same fields as the OpenFarm ones. One "Growing X"
section of fact cards now holds all of it.
- The sidebar listed planting, harvest and seed counts directly above
three sections with those same names. The counts are headline numbers
in the hero instead, which also fills the space the hero was wasting.
- Main column reads top to bottom: how to grow it, how members grow it,
varieties, companions, photos, video, where it grows, posts, history.
Headings say something rather than naming a partial.
- Crop actions are just "Add to my garden". Recording a harvest, saving
seeds, posting and marking a planting failed all belong to a planting
you already have.
- The charts section rendered as an empty white strip whenever a crop had
any plantings or harvests but no chart to draw.
- The hero photo moved to the sidebar, where it has room.
Also: the whimsical icons perch on the heading bar below them rather than
sitting inside the box, the garden picker dialog gives every row the same
shape so the names line up, and crops/_grown_for.html.haml is deleted —
nothing rendered it once its content moved into the growing cards.
Specs are not updated yet: crop_detail_page_spec clicks "Record harvest"
on this page, which no longer exists.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Refactor crop-related views and styles for improved layout and functionality
- Update styles in _crops.scss for better alignment and spacing.
- Enhance _record_page.scss with a new section footer for actions.
- Modify _alternate_names.html.haml to improve dropdown functionality for editing and deleting names.
- Change _history.html.haml header to "Edit history" for clarity.
- Adjust _info.haml to display sowing method and sun requirements prominently.
- Revise _openfarm_data.html.haml to remove unnecessary comments and clarify content.
- Update _photos.html.haml to include a section footer for the "More photos" link.
- Refine _posts.html.haml to streamline the display of posts and actions.
- Improve _scientific_names.html.haml to enhance dropdown functionality for scientific names.
- Update tests in alternate_name_spec.rb and scientific_name_spec.rb to reflect UI changes.
- Remove unused _grown_for.html.haml_spec.rb file.
* Replace language text field with a dropdown select for improved user experience
* Enhance editable forms and fact cards for improved user interaction and layout
* Refactor styles and improve layout for planting details, including muted text color updates and enhanced card displays
* Refactor crop detail page for improved SEO and user experience, including updated links and content for planting and growing information.
* Adjust section add button width for better layout on heading bar
* Update link text for consistency and clarity in crop detail page
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
PATCH /plantings/:slug.json now returns the garden's refreshed card, as
create does, or the validation errors as 422. Annual plantings in the
card say whether the viewer can edit them.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A planting can now choose one of its crop's alternate names (eg. "lauki"
for calabash, "aubergine" for eggplant) and shows it instead of the
crop's primary name.
- plantings.alternate_name_id, validated to belong to the planting's crop
- Planting#display_name, used on cards, the planting page, garden lists,
the member page, the homepage and the RSS/ICS feeds
- planting form offers the crop's alternate names, preselecting the one
that was searched for
- crop autosuggest shows the matched alternate name, eg.
"aubergine (eggplant)", via matched_alternate_name in the search JSON
Part of #554
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Add rake tasks to pull crops and a member's data from production
crops:pull_from_production copies approved crops, and
members:pull_from_production copies one member's gardens, plantings and
planting photos, from growstuff.org into a local database. Both refuse to
run in a production environment.
They are built to be gentle on a server that has been struggling: one
request at a time with a pause between requests, exponential backoff
(honouring Retry-After) on timeouts, 429s and 5xx, and a hard stop rather
than endless retries. The client also stops if a server keeps sending the
same page, and will not follow a next link to another host.
Gardens and plantings come from the site's own JSON, which carries every
column; the JSON:API only exposes a garden's name, and its related
resource endpoints return the wrong records. Only the crops that a
member's plantings use are fetched. Flickr photos are stored as records
pointing at Flickr's image URLs, as on production, so nothing is
downloaded from Flickr.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Add ACTIVE_ONLY option to the member import
ACTIVE_ONLY=true leaves out the site's all=1 flag, so production lists only
the member's active gardens and current (not finished, not failed)
plantings. The server does the filtering, so it also means fewer requests,
and no crops or photos are fetched for plantings that are skipped.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Bundle JavaScript with esbuild via jsbundling-rails
Adds React and an esbuild build (yarn build, yarn build:watch) that writes
app/assets/builds/react_islands.js, which Sprockets serves. jsbundling-rails
runs the build as part of assets:precompile, which CI and the Dockerfile
already run after yarn install.
react_islands.jsx is the entry point: it mounts a React component into every
element with data-react-component. No components are registered yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Add react_component view helper
Renders an empty element carrying the component name and its props as JSON,
for react_islands.jsx to mount a React component into. Props go through
Rails' attribute escaping.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Show a React GardenSummary island on the gardens index
The first React island, to prove the pipeline end to end: server-rendered
props (owner and garden count) drive a small component with client-side
state. Loaded only on this page, deferred, via the scripts content block.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Add GardenCardSerializer for the React garden cards
Turns a page of gardens into plain hashes: the garden, its owner, its
actions menu, and its active plantings split into perennials and annuals,
with progress, badges and quick actions. It mirrors what gardens/_card,
gardens/_actions and the planting partials render today, so the server
still decides labels, links and permissions.
Active plantings for the whole page are loaded in one query (with harvests
and the crop's parents), instead of several queries per garden.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Render the garden cards on the index with React
The gardens index now hands GardenCardSerializer's output to a GardenCards
island instead of rendering gardens/_card per garden. The actions menu moves
to the top right of the card header. Everything else on the card is the same:
image, perennials, and each annual planting with badges, progress bar and its
own quick actions menu. The server still chooses labels, links and
permissions.
The dropdowns keep the existing Bootstrap and jquery_ujs markup
(data-bs-toggle, data-method, data-confirm), so mark inactive, delete and the
confirmations work unchanged. Menu button ids are now unique per card, so the
edit-from-index spec finds the menu by its Actions text instead of the old
repeated id.
gardens/_card stays for the activity page. This replaces the GardenSummary
island, which only proved the pipeline.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Don't raise when validating a planting that has no garden
owner_must_match_garden_owner called garden.owner unconditionally, so a
planting with a missing garden raised NoMethodError (a 500) instead of
failing the garden presence validation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Create plantings as JSON for the React garden cards
POST /plantings.json returns the garden's updated card (201), or the
validation errors (422), so the cards can show a new planting without a page
reload. It is for our own pages only: session cookie plus CSRF token, and no
CORS headers, unlike the public /api/v1.
Creating now also checks the garden is yours. Before, can :create Planting
had no garden condition and create never authorized the garden, so a crafted
request could plant into someone else's garden. This applies to the HTML form
as well. A missing garden is still left to the presence validation.
CanCan::AccessDenied now answers JSON requests with a 403 and an error,
instead of redirecting them.
The request spec logs in through a real cookie session to exercise CSRF
protection: PlantingsController uses the null_session strategy, so a request
without the token is treated as signed out (401), and the sign_in test helper
would bypass that.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Don't ask which garden when planting from a garden
Arriving at the planting form with a garden_id of one of your own gardens
(from 'Plant something here') now shows 'Planting in <garden>' with a hidden
garden field and a link to choose a different one, instead of the garden
radio buttons. Any other arrival, including a garden_id that isn't yours,
still asks as before.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Open 'Plant something here' as a dialog over the garden cards
Clicking 'Plant something here' on a card opens a dialog to plant into that
garden, without leaving the list or asking which garden. Saving posts to
POST /plantings.json, swaps in the garden's updated card so the new planting
shows straight away (briefly highlighted, with a confirmation), and closes the
dialog. Errors show inside it and it stays open. A ctrl/cmd/shift-click still
opens the normal form.
The dialog is a React-controlled Bootstrap modal: focus moves in and is
trapped, Escape and the backdrop close it, and focus returns afterwards. The
crop picker searches /crops/search.json like the existing autosuggest, and the
planted-from and sun choices come from Planting's constants via props.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Use the Bootstrap 4 class names the app's CSS defines in the card components
The stylesheet is MDB 4 (Bootstrap 4), with Bootstrap 5's JavaScript on top,
so Bootstrap 5-only classes had no styling: the dialog's close button was
btn-close (a small grey box), and visually-hidden, form-select and text-start
did nothing. Use close with a times sign, sr-only, form-control and text-left,
as the app's existing modals do.
dropdown-menu-end stays, because Bootstrap 5's dropdown JavaScript reads it to
place the menu; dropdown-menu-right is added for the CSS.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Make the plant-something form read as a sentence
'I planted [N] [crop](s) on [date] from [seed] in [sun].' Each blank is an
underlined inline field: quantity, the crop search, the planted date, and
planted-from and sun/shade selects. The (s) drops away when the quantity is 1.
The blanks are labelled for screen readers (Quantity, Crop, Planted date,
Planted from, Sun or shade). Notes and 'Mark as finished' stay below.
The browser spec now fills in quantity, planted from and sun as well, and
checks they are saved.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Hint at typing a crop name, and offer to request one that isn't found
The crop blank says 'type a crop name'. When a search finds nothing it says
so and links to the new-crop form (in a new tab, so the dialog stays open),
as the old planting form did.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Say 'number' in the quantity blank
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Choose a crop with the cursor keys
The crop picker is now an accessible combobox. As you type, matches appear in
a listbox: Up and Down move through them, Enter chooses the highlighted one
(or the top match if none is highlighted), and Escape closes the list before a
second Escape closes the dialog. Focus moves to 'Change' once a crop is chosen.
Matches can still be clicked.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Trim the plant-something form to just the sentence
Remove 'Mark as finished' and the 'Tell us more about it' notes from the
dialog, along with the never-shown rating field it carried in its state.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Make the highlighted crop match obvious
The theme's list-group 'active' shade was barely darker than the other
matches. The one Enter would choose now has a solid blue background, white
bold text and a darker left edge.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Tidy the plant-something sentence layout
Group the sentence into phrases (I planted..., on..., from..., in...) that stay
together when it wraps, so a word is never stranded away from its blank. Hide
the quantity spinner that clipped 'number', widen the date, and give the two
selects a minimum width, with a grey 'optional' when they are still empty.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Don't let a second Enter undo a chosen crop
After choosing a crop the input is replaced by the crop's name and a Change
button. Focus went to that button, so pressing Enter again pressed it and
cleared the choice. Focus now moves on to the date blank, so a second Enter
submits the form as it would from any field.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Plant with one search and a confirmation, instead of the sentence form
The dialog asks one big question, 'What did you plant?', with the same
crop search as before (arrow keys, Enter, and a way to request a crop that
isn't found). Choosing a crop shows it back ('You're planting lettuce in
Orchard, today.') with Change and Plant it buttons, and focus lands on Plant
it so Enter confirms. The planting gets today's date and no other details;
those can be added later, which keeps adding one quick.
Drops the sentence blanks, their styles, and the planted-from/sun option lists
the page passed down.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Fix unreadable text on a just-planted crop
The highlight for a newly added planting set an inline pale green background
on the crop chip. Chips are brown with white text, so the name became white on
light green. The highlight is now a CSS class that leaves the chip's colours
alone: a soft green row with a left bar for annual plantings, and a green ring
around the chip for perennials. The browser spec checks the chip carries no
inline style.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Tidy the plant dialog and show what is happening at each stage
Standard patterns so the dialog always says where you are and what it is doing:
- a two-step indicator (Choose a crop, Confirm) with a tick on the finished step
- a spinner in the search box while searching, plus a 'Searching...' status, a
count of matches, and an info icon on the 'no crops match' note
- the choice shown back as a Crop / Garden / When summary with a Change button
- Plant it as a filled green primary button that stays green while focused (the
theme greys a focused button) and shows a spinner while planting, with Cancel
and Change disabled meanwhile
- an error panel with a warning icon that says the choice is kept for retrying
- the matches listed in the dialog rather than floating over its buttons
- a tick on the 'Planted ...' notice on the cards
- the shovel (spade-marker.svg, the map marker) in the dialog title
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Build the React bundle in CI and for fresh checkouts
app/assets/builds/react_islands.js is built by esbuild and not committed, so on
a fresh checkout pages that load it (the gardens index) fail with 'The asset
react_islands.js is not present in the asset pipeline'. The rspec CI job never
built it: only the browser-feature jobs did, through assets:precompile. Add a
yarn build step there, and have the specs build the bundle once if it is
missing so a local checkout doesn't fail either.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Add the missing 'View' translation
The planting quick-actions menu used t('view'), which has no translation. In a
view Rails hides that by showing a humanised 'View'; the card serializer uses
I18n.t, which showed 'Translation missing: en.view' in the menu. Add
buttons.view, use it in both places, and add a serializer spec that fails if
any card label is a missing translation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Fix two crop_jsonld_data specs that could not pass
The helper builds its hash with symbol keys, but the spec read 'data["@context"]'
with a string key. And 'caps posts and photos at 50' relied on
create(:post, crops: [crop]), which creates no crop_posts rows here, and on
crop.photo_associations.create!, which the Crop model's own association leaves
without a photographable. Link posts with CropPost and photos with
PhotoAssociation explicitly.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Run the helper and serializer specs in CI
The rspec job ran lib, services, models, controllers, views, routing and
requests, but not spec/helpers or spec/serializers, so those specs (including
the react_component helper and the card serializer) never ran there, and two
broken crops_helper specs went unnoticed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Tidy the garden cards
The cards were cluttered and misaligned. Now:
- the header has a smaller title with the owner under it, and the menu top right
- a smaller picture, and 'Perennials' and 'Annuals' headings instead of a
divider and a gap; 'Nothing planted here yet.' for an empty garden
- each annual planting is a row of three aligned columns: the crop with when it
was planted (which tells duplicates apart), then its badges and progress bar,
then a labelled three-dots menu in place of a bare chevron
- the note when there is nothing to predict from is one short muted line that
no longer repeats the crop name
- on a phone the picture and rows stack
Also restores the just-planted highlight styles, which a stylesheet edit had
dropped, and adds a spec that the highlight has a background, since the class
existing was all that was checked.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Make the planting menu button compact
The theme gives every .btn a 5.5rem minimum width, so the three-dots button's
hover background was a wide grey box. It is now a 2.25rem round button.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* Refactor Plantings to remove Elasticsearch dependency
This commit refactors the Plantings controller, model, and views to use
ActiveRecord instead of Searchkick/Elasticsearch.
Key changes:
- Refactored `PlantingsController#index` to use an ActiveRecord-based
`plantings` method.
- Moved `homepage_records` logic from `SearchPlantings` concern to the
`Planting` model using ActiveRecord scopes.
- Removed `SearchPlantings` concern and deleted the file.
- Updated `home/_plantings.html.haml` and `plantings/index.rss.haml` to
use dot notation for `Planting` object attributes.
- Updated specs to remove Searchkick-related setup and assertions.
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
* Fix Planting.reindex
* Fix test
* Mark test pending
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit introduces memoization to various methods in the Planting model,
PredictPlanting and PredictHarvest concerns, PlantingsHelper, and
PlantingsController.
Specifically:
- Memoized database-intensive lookups like `nearby_same_crop`, `first_harvest_date`,
and `last_harvest_date`.
- Memoized calculated fields like `finish_predicted_at`, `expected_lifespan`,
and `age_in_days`.
- Optimized `PlantingsHelper#transplantable_gardens_by_owner` using a hash
to cache results per planting instance within a request.
- Applied the `defined?(@variable)` pattern where appropriate to ensure
efficient handling of `nil` results.
These changes reduce redundant database queries and expensive calculations,
particularly during view rendering where these methods are frequently accessed.
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
* Register mime type
* Add rough first pass
* Index predictions, and add links
* Trailing space
* Fix implementation
* Fix names, make public
* Fix names, make public
* Fix
* Fix tyyos
* Add date
* If there are no predictions, keep growing
* Add a todo
* Fix factories
* Specs