Commit Graph
449 Commits
Author SHA1 Message Date
Brenda Wallace ecbbe6ae4b Merge branch 'main' into api/graphiti 2026-10-28 07:43:47 +13:00
google-labs-jules[bot]andCloCkWeRX c99a271fec Remove database_cleaner in favor of Rails transactional tests
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-10-27 09:56:15 +13:00
Brenda Wallace 75da93694a Merge branch 'main' into api/graphiti 2026-10-26 20:11:16 +13:00
Brenda Wallace 948cc59d1b Remove Sidekiq integration and update mailer delivery methods to deliver immediately 2026-10-26 19:38:38 +13:00
Daniel O'Connor 8de199bf53 Merge branch 'main' into api/graphiti 2026-10-26 12:47:17 +10:30
Brenda WallaceandDaniel O'Connor 8474bdd416 remove newsletter (#4974)
* Remove unused bluecloth gem

Last released in 2011. It was only required, never called; kramdown
renders the markdown.

* Add specs for Tilt markdown rendering and posts markdown partial

* Remove rails_12factor gem

Last released in 2014. Rails 5+ does this via RAILS_SERVE_STATIC_FILES
and RAILS_LOG_TO_STDOUT, which production.rb already reads.

* Remove memcachier gem from Gemfile and Gemfile.lock

* Remove unused webrat gem

Last released in 2011. Nothing requires it; the specs use Rails'
assert_select and Capybara matchers. Only generator comments mention it.

* Remove crowdin-cli gem

Last released in 2018. Crowdin now ships its own standalone CLI, which
reads crowdin.yml and doesn't need the gem. Also drops the dependencies
only it used (rest-client, gli, crowdin-api and friends).

* Removes the crowdin-cli gem (last released 2018), the dependencies only
it needed, and crowdin.yml. Crowdin was never set up: the config still
has a placeholder project ID and nothing else in the repo mentions it.

Assisted by Claude

* Remove newsletter functionality and associated views and tests

* Remove newsletter functionality and related code across the application

* keep the column

* Remove stale test step

* add back newsletter

* Add migration to update newsletter column comment in members table

---------

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
2026-10-26 11:48:36 +10:30
Brenda Wallace 200514c5cc Refactor API controllers and resources to remove redundant resource_class assignments and improve parameter handling in API documentation 2026-10-24 18:19:11 +13:00
Brenda Wallace c87a164b0a Refactor code structure for improved readability and maintainability 2026-10-24 18:19:11 +13:00
Brenda Wallace 73f62d4983 Add API resources for photos, plantings, and seeds; update application configuration
- Introduced `PhotoResource`, `PlantingResource`, and `SeedResource` to manage respective models.
- Updated application configuration to include API base URL.
- Modified production and test environments to set API base URL dynamically.
- Removed outdated JSONAPI resources initializers and patches.
- Refactored routes to use resourceful routing for API endpoints.
- Updated request specs to reflect changes in API responses and relationships.
- Added helper methods for generating related links in request specs.
2026-10-24 18:19:11 +13:00
Brenda Wallace 85b5ff9ecd Add feature flags, with job ideas as the first
Admins switch features on and off at /admin/features, kept in Flipper.
Job ideas (the page, the banners and the overlay) only show while its
flag is on. Features are off until switched on.

Closes #5050
2026-10-24 18:01:56 +13:00
Brenda Wallace 0d24f5c27d Drop the byebug (#5052) 2026-10-24 12:08:27 +10:30
Brenda Wallace ff1dd8bb05 adding coverage 2026-10-23 21:34:33 +13:00
4734702ba8 Update bin/dev and Procfile.dev for automatic asset watching (#5002)
* Add Procfile.dev and update bin/dev for dev asset watchers

- Create Procfile.dev to run web server and asset compilation watchers
  for JS (`yarn build:watch`) and CSS (`yarn build:css:watch`).
- Add `foreman` gem to `:development` group in Gemfile.
- Update `bin/dev` to run Procfile.dev using available process manager
  (overmind, hivemind, or foreman).
- Fix `build:css:watch` script in package.json to pass `--watch` to Sass.
- Update README.md to instruct running `bin/dev` in development.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Add Procfile.dev and update bin/dev for dev asset watchers

- Create Procfile.dev to run web server and asset compilation watchers
  for JS (`yarn build:watch`) and CSS (`yarn build:css:watch`).
- Add `foreman` gem to `:development` group in Gemfile and Gemfile.lock.
- Update `bin/dev` to run Procfile.dev using available process manager
  (overmind, hivemind, or foreman).
- Fix `build:css:watch` script in package.json to pass `--watch` to Sass.
- Update README.md to instruct running `bin/dev` in development.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Apply suggestion from @CloCkWeRX

* Apply suggestion from @CloCkWeRX

* Add Procfile.dev and update bin/dev for dev asset watchers

- Create Procfile.dev to run web server and asset compilation watchers
  for JS (`yarn build:watch`) and CSS (`yarn build:css:watch`).
- Add `foreman` gem to `:development` group in Gemfile and Gemfile.lock.
- Update `bin/dev` to run Procfile.dev using available process manager
  (overmind, hivemind, or foreman).
- Fix `build:css:watch` script in package.json to pass `--watch` to Sass.
- Update README.md to instruct running `bin/dev` in development.
- Keep .ruby-version unchanged.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Apply suggestion from @CloCkWeRX

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Brenda Wallace <brenda@wallace.net.nz>
2026-10-23 09:11:33 +10:30
Brenda Wallace 977a984c24 Remove Elasticsearch integration and related code
- 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.
2026-10-22 15:37:03 +13:00
Brenda Wallace e68c98fd38 Add JavaScript functionality for planting alternate names and tab navigation
- Implemented `planting_alternate_name.js` to load alternate names for crops in the planting form based on user input.
- Added `tab_navigation.js` to manage tab navigation and update the URL hash accordingly.

Update map rendering in member and place views

- Modified `_map.html.haml` to include a custom marker icon for member maps.
- Updated `index.html.haml` and `show.html.haml` to pass `places_map_data` to the map sections.

Refactor asset management in Rails application

- Removed Sprockets from the application configuration and adjusted asset paths.
- Updated asset precompilation settings and removed deprecated asset configurations from environment files.
- Added new build scripts for CSS and updated package dependencies in `package.json` for Bootstrap, Chart.js, and others.

Ensure React and CSS bundles are built before running tests

- Updated `react_bundle.rb` to check for the existence of both JavaScript and CSS bundles and build them if missing.
2026-10-20 23:55:33 +13:00
Brenda Wallace 79aca3f7fc Refactor JavaScript files: consolidate planting and seed finish logic, remove unused CoffeeScript files, and add new scientific name auto-suggest functionality
- Deleted `crops.js.coffee`, `finish_planting.js.coffee`, and `finish_seed.js.coffee` as they are no longer needed.
- Introduced `finish_toggle.js` to handle the finished state for both planting and seed in a unified manner.
- Added `planting_alternate_name.js` to manage alternate names for crops in the planting form.
- Created `scientific_name_auto_suggest.js` to implement auto-suggest functionality for scientific names.
- Removed outdated dependencies from `package.json` and `yarn.lock`.
2026-10-20 09:06:36 +13:00
Brenda Wallace 2e347e4668 Remove crowdin-cli gem (#4973)
* Remove crowdin-cli gem

Last released in 2018. Crowdin now ships its own standalone CLI, which
reads crowdin.yml and doesn't need the gem. Also drops the dependencies
only it used (rest-client, gli, crowdin-api and friends).

* Removes the crowdin-cli gem (last released 2018), the dependencies only
it needed, and crowdin.yml. Crowdin was never set up: the config still
has a placeholder project ID and nothing else in the repo mentions it.

Assisted by Claude
2026-10-19 21:00:14 +10:30
Brenda Wallace 5670ede0ec Remove unused webrat gem
Last released in 2011. Nothing requires it; the specs use Rails'
assert_select and Capybara matchers. Only generator comments mention it.
2026-10-19 23:23:33 +13:00
Brenda Wallace 8b6cf25375 Remove memcachier gem from Gemfile and Gemfile.lock 2026-10-19 22:51:14 +13:00
Brenda Wallace b912b13e40 Remove rails_12factor gem (#4969)
Last released in 2014. Rails 5+ does this via RAILS_SERVE_STATIC_FILES
and RAILS_LOG_TO_STDOUT, which production.rb already reads.
2026-10-19 19:58:47 +10:30
Brenda Wallace 793759c7af Remove unused bluecloth gem (#4968)
* Remove unused bluecloth gem

Last released in 2011. It was only required, never called; kramdown
renders the markdown.

* Add specs for Tilt markdown rendering and posts markdown partial
2026-10-19 19:36:32 +10:30
Brenda Wallace c46344f90a New menus: desktop bar, tablet and phone drawer, quick add, search (#4929)
* fixes to the menus

* Implement full screen search for mobile: add search functionality and styles

* more icons
2026-10-15 19:06:57 +10:30
dependabot[bot]andDaniel O'Connor 9aa54c0d2f Bump jquery-ui-rails from 413265e to be6cbf0 (#4858)
* Bump jquery-ui-rails from `413265e` to `be6cbf0`

Bumps [jquery-ui-rails](https://github.com/jquery-ui-rails/jquery-ui-rails) from `413265e` to `be6cbf0`.
- [Release notes](https://github.com/jquery-ui-rails/jquery-ui-rails/releases)
- [Commits](https://github.com/jquery-ui-rails/jquery-ui-rails/compare/413265e81f790f795239e07e7e25e01429b2f18d...be6cbf02091b2dbcea7d339ac58559745d249032)

---
updated-dependencies:
- dependency-name: jquery-ui-rails
  dependency-version: be6cbf02091b2dbcea7d339ac58559745d249032
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Pin JSON to < 3

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
2026-10-12 05:24:40 +10:30
39e65fd848 Remove CMS - use haml pages instead (#4899)
* Add support and terms of service pages with corresponding routes

- Created a new support page with frequently asked questions.
- Added a terms of service page outlining user agreements and policies.
- Removed old support index and CMS initializer files.
- Updated routes to include new policy and support paths.
- Implemented tests for new pages and footer links.
- Adjusted database migration for CMS content compatibility.

* Remove custom JavaScript file for the admin area

* Add kramdown gem for Markdown support in Haml

* Fix various typos and link formatting issues

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* remove reference to paid account

* Remove reference to paid accounts from support page

* Remove references to paid and permanent accounts from Terms of Service

* removing references to paid accounts

* Update contact email link format in TOS

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Add new pages and routes for About, Policies, and Copyright; update existing pages

* Fix typos and improve clarity in community guidelines, copyright policy, data use policy, privacy policy, support page, and terms of service

* Drop stale expectation

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
2026-10-12 03:05:12 +10:30
Brenda Wallace 53dbbbaf46 Remove ruby-units gem and implement weight unit conversion directly in Harvest model 2026-10-11 19:42:07 +13:00
Brenda WallaceandClaude Opus 5 7e181982ff Upgrade Font Awesome to 6.7.2 (#4846)
* 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>

* Upgrade Font Awesome from 5.15.1 to 6.7.2

Font names have moved on twice since this was pinned: the codebase still
carried Font Awesome 4 names that render as an empty box, and FA6 icons
such as fa-ellipsis-vertical were unavailable.

The 6.x gem no longer ships _font-awesome-sprockets.scss, but its
@font-face rules still call fa-font-path(), so application.scss defines
that against Sprockets' font-path helper. Its fonts live under
assets/fonts/font-awesome, which is already in the precompile list.

Icon names:
- The bare "fa" prefix is not a style in 6. Every "fa fa-<name>" becomes
  "fas fa-<name>" (38 call sites, all solid; the one brands icon already
  used fab).
- fa-sun-o was a Font Awesome 4 name and had been rendering as a box;
  now fa-sun.
- fa-pencil was likewise broken under 5, where it was fa-pencil-alt. It
  exists again in 6, so the existing name now works.
- activity_icon asked for 'fa-truck-pickup' through a helper that already
  adds the prefix, so it emitted "fa-fa-truck-pickup".

Verified that the solid, regular and brands fonts all resolve through
the asset pipeline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* couple more places to upgrade font awesome

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-24 13:39:38 +09:30
Brenda WallaceandClaude Opus 5 f1ce7e1d53 Take Leaflet.markercluster from npm instead of rails-assets.org
rails-assets.org is down, and bundler can't install anything while a
gem's source is unreachable, so CI fails for every branch before a
single spec runs. The one gem from there was
rails-assets-leaflet.markercluster; it now comes from npm, where the
React bundle's packages already come from, and node_modules is already
on the asset path. CI and Heroku both install npm packages.

That gem also brought in rails-assets-leaflet, a second copy of Leaflet
(1.5.1), which shadowed the leaflet-rails gem the Gemfile asks for. With
it gone, the maps get Leaflet 1.9.4 from leaflet-rails, as intended, so
the cluster plugin is its current release, 1.5.3, which supports it.
npm's peer dependency warning for leaflet is expected: Leaflet comes
from the gem, loaded before the plugin.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 18:39:48 +12:00
Brenda Wallace 2989dafc4c Merge dev into chore/bootstrap-5 2026-09-20 20:20:51 +12:00
Brenda WallaceandClaude Sonnet 5 9dae899693 Quick planting addition form (#4808)
* 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>
2026-09-20 16:04:15 +09:30
Brenda WallaceandClaude Sonnet 5 56525aace4 Replace material-sass (Bootstrap 4) with Bootstrap 5.3 SCSS
The CSS came from the material-sass gem, a Bootstrap 4 based Material Design
skin, while the JavaScript already came from the bootstrap gem (Bootstrap 5).
Import the bootstrap gem's SCSS instead and drop material-sass and its
'material' script.

Bootstrap 5 reads its settings from variables defined before it is imported,
so _variables.scss now sets the theme colours (primary/success green,
secondary blue, and so on), body colours, font and the site's own breakpoints
(lg 1200px, xl 1800px) in Bootstrap's terms, in place of the Material colour
maps. media-breakpoint-down(xs) is media-breakpoint-down(sm) in Bootstrap 5.

Class names from Bootstrap 3 and 4 that no longer exist are renamed in the
commits that follow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 18:00:13 +12:00
google-labs-jules[bot]andCloCkWeRX dc8503c20c Remove Unicorn dependency and enable Puma clustered workers with preloading
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-09-17 21:21:20 +00:00
google-labs-jules[bot]andCloCkWeRX 04d2d7364c Add require: false to aws-sdk-s3 in Gemfile
Prevents aws-sdk-s3, aws-sdk-core, and aws-sdk-kms from auto-loading
on application boot across web and worker processes. The gem is
required on-demand in config/sitemap.rb.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-09-17 12:43:34 +00:00
Daniel O'Connor 4754d10495 Document why we pin 2026-08-23 08:09:33 +00:00
Daniel O'Connor b323280de9 Bump oauth to 1.1.6 2026-08-23 08:08:32 +00:00
Daniel O'Connor c0c7fc0290 Bump oauth to 1.1.5 2026-08-23 08:07:58 +00:00
Daniel O'Connor 449bb4dd13 Bump oauth to 1.1.4 2026-08-23 08:06:54 +00:00
Daniel O'Connor 704665d259 Bump oauth to 1.1.3 2026-08-23 08:06:01 +00:00
Daniel O'Connor 5ec95c68fc Bump oauth to 1.1.2 2026-08-23 08:05:16 +00:00
Daniel O'Connor 1e9b2bd3c0 Bump oauth to 1.1.1 2026-08-23 07:28:53 +00:00
Daniel O'Connor 3a8f112932 Bump oauth to 1.1.0 because Showing 409 changed files with 44,667 additions and 5,609 deletions is obscene 2026-08-23 07:15:53 +00:00
Daniel O'Connor 932d36255e Bump oauth to 1.1.6 2026-08-23 07:13:04 +00:00
Daniel O'Connor f4d883fee2 Bump oauth to 1.0.1 2026-08-23 07:07:47 +00:00
Daniel O'Connor 29bd577dc7 Bump oauth from 0.5.14 to 0.6.2 2026-08-23 06:56:49 +00:00
4563df45d0 Upgrade to Rails 8.1 (#4685)
* Upgrade application to Rails 8.1

- Update rails gem to ~> 8.1.0
- Set config.load_defaults 8.1 in application.rb
- Add gem 'csv' for Ruby 3.4+ compatibility
- Replace deprecated 'render text:' with 'render plain:' in PagesController
- Add compatibility patch for jsonapi-resources routing in Rails 8.1
- Add compatibility patch for Faraday 2.x error constants
- Add Searchkick test stubs for environments without Elasticsearch
- Include required Active Storage update migrations

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Remove disabled searchkick

* Apply suggestion from @CloCkWeRX

* Delete config/initializers/faraday_patch.rb

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

* Remove modifications for tests without elasticsearch

* Remove psych gem and its dependencies

Removed psych gem version 5.4.0 and its dependencies.

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-08-09 22:53:15 +09:30
867c8b27fb Upgrade to Rails 8.0 (#4621)
* Upgrade application to Rails 8.0

- Updated Gemfile to rails ~> 8.0.0 and updated Gemfile.lock
- Set config.load_defaults 8.0 in config/application.rb
- Configured YAML as default_column_serializer for ActiveRecord serialization compatibility
- Added Faraday 2.x error constant compatibility shim in config/initializers/faraday_patch.rb
- Added Active Storage migrations and verified with db:migrate
- Added Rails 8 bin/dev and bin/rubocop scripts
- Maintained Ruby 3.4.9 compatibility in .ruby-version and Gemfile.lock

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Delete db/migrate/20241117032507_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb

* Delete db/migrate/20241117032505_add_service_name_to_active_storage_blobs.active_storage.rb

* Delete db/migrate/20241117032506_create_active_storage_variant_records.active_storage.rb

* Delete config/initializers/faraday_patch.rb

* Update schema

* Fix conflicts

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-23 20:43:40 +09:30
Daniel O'Connor 555d5ddf15 Revert "Replace Sidekiq with Solid Queue (#4619)" (#4620)
This reverts commit 4659ac5464.
2026-05-04 18:15:17 +09:30
4659ac5464 Replace Sidekiq with Solid Queue (#4619)
* Replace Sidekiq with Solid Queue

This commit transitions the background job processing from Sidekiq to
Solid Queue.

Changes:
- Replaced `sidekiq` gem with `solid_queue` in Gemfile.
- Updated `development.rb` and `production.rb` to use `:solid_queue` as
  the queue adapter.
- Added Solid Queue database tables via a new migration.
- Configured Solid Queue in `config/queue.yml` and `config/recurring.yml`.
- Integrated Solid Queue supervisor as a Puma plugin in `config/puma.rb`.
- Removed separate worker process from `Procfile`.
- Removed Sidekiq-specific configuration files.
- Updated Gemfile.lock to support both `ruby` and `x86_64-linux` platforms.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix regression in gemfiles

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-03 15:29:03 +09:30
Daniel O'Connor 9abb0d02b9 Merge pull request #4581 from Growstuff/add-rack-attack-protection-3014929071908440304
Add Rack::Attack rate limiting and Fail2Ban protection
2026-04-27 13:23:17 +09:30
Daniel O'Connor a38d99ed4a Rubocop: Bundler/OrderedGems 2026-04-23 13:07:38 +00:00
Daniel O'Connor b9dcd95c00 Rubocop: Layout/TrailingWhitespace 2026-04-23 12:27:06 +00:00