Compare commits

..

7 Commits

Author SHA1 Message Date
Daniel O'Connor
d57ca1b4bb Merge branch 'dev' into fix-3278 2024-07-23 19:44:09 +09:30
Daniel O'Connor
dc4133abd2 Merge branch 'dev' into fix-3278 2024-07-17 20:06:48 +09:30
Daniel O'Connor
0b4bdc6946 Re-add expectation 2024-07-13 09:55:06 +00:00
Daniel O'Connor
3d308db0d9 'Only required for wrangers, and only when approving 2024-07-13 09:54:31 +00:00
Daniel O'Connor
bfa1ae3ae2 Require a name 2024-07-13 09:42:20 +00:00
Daniel O'Connor
71ef2c058b Require a URL 2024-07-13 09:41:35 +00:00
Daniel O'Connor
b42385be14 Fix #3278 by ensuring we rebuild names on error 2024-07-13 09:39:58 +00:00
175 changed files with 871 additions and 3038 deletions

47
.codeclimate.yml Normal file
View File

@@ -0,0 +1,47 @@
plugins:
brakeman:
enabled: false # codeclimate's brakeman is stuck in rails 5 rules
bundler-audit:
enabled: true
coffeelint:
enabled: true
duplication:
enabled: true
config:
languages:
- ruby
- javascript
editorconfig:
enabled: true
eslint:
enabled: true
fixme:
enabled: true
haml-lint:
enabled: true
nodesecurity:
enabled: true
rubocop:
enabled: true
channel: "rubocop-1-11"
scss-lint:
enabled: true
shellcheck:
enabled: true
ratings:
paths:
- "**.rb"
- "**.ru"
- "**.js"
- "**.coffee"
- "**.scss"
- "**.haml"
- Gemfile.lock
exclude_paths:
- config/
- db/
- spec/
- public/
- app/assets/stylesheets/bootstrap-accessibility.css
- app/assets/javascripts/bootstrap*
- app/assets/stylesheets/leaflet_overrides.scss

View File

@@ -13,4 +13,3 @@ updates:
interval: daily
time: "07:00"
open-pull-requests-limit: 10

40
.github/workflows/brakeman-analysis.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
# This workflow integrates Brakeman with GitHub's Code Scanning feature
# Brakeman is a static analysis security vulnerability scanner for Ruby on Rails applications
name: Brakeman Scan
# This section configures the trigger for the workflow. Feel free to customize depending on your convention
on:
pull_request:
branches: [ dev ]
jobs:
brakeman-scan:
name: Brakeman Scan
runs-on: ubuntu-latest
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout
uses: actions/checkout@v4
# Customize the ruby version depending on your needs
- name: Setup Ruby
uses: ruby/setup-ruby@v1
- name: Setup Brakeman
env:
BRAKEMAN_VERSION: '5.1.1' # SARIF support is provided in Brakeman version 4.10+
run: |
gem install brakeman --version $BRAKEMAN_VERSION
# Execute Brakeman CLI and generate a SARIF output with the security issues identified during the analysis
- name: Scan
continue-on-error: true
run: |
brakeman -f sarif -o output.sarif.json .
# Upload the SARIF file generated in the previous step
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: output.sarif.json

View File

@@ -1,102 +0,0 @@
name: CI Features - Admin
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (admin/)
run: bundle exec rspec spec/features/admin/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Comments
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (comments/)
run: bundle exec rspec spec/features/comments/ -fd -t ~@flaky

View File

@@ -1,103 +0,0 @@
name: CI Features - Conversations
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (conversations/)
run: bundle exec rspec spec/features/conversations/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Crops
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (crops/)
run: bundle exec rspec spec/features/crops/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Gardens
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (gardens/)
run: bundle exec rspec spec/features/gardens/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Harvests
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (harvests/)
run: bundle exec rspec spec/features/harvests/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Home
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (home/)
run: bundle exec rspec spec/features/home/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Members
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (members/)
run: bundle exec rspec spec/features/members/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Admin
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (places/)
run: bundle exec rspec spec/features/places/ -fd

View File

@@ -1,102 +0,0 @@
name: CI Features - Plantings
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (plantings/)
run: bundle exec rspec spec/features/plantings/ -fd

View File

@@ -1,102 +0,0 @@
name: CI Features - Admin
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (posts/)
run: bundle exec rspec spec/features/posts/ -fd

View File

@@ -1,102 +0,0 @@
name: CI Features - Seeds
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (seeds/)
run: bundle exec rspec spec/features/seeds/ -fd -t ~@flaky

View File

@@ -1,102 +0,0 @@
name: CI Features - Timeline
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (timeline/)
run: bundle exec rspec spec/features/timeline/ -fd -t ~@flaky

View File

@@ -1,111 +0,0 @@
name: CI Features
on: [pull_request]
jobs:
rspec:
runs-on: ubuntu-latest
services:
db:
image: postgres
env:
##
# The Postgres service fails its docker health check unless you
# specify these environment variables
#
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: growstuff_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
APP_DOMAIN_NAME: localhost:3000
APP_PROTOCOL: http
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test
DEVISE_SECRET_KEY: secret
ELASTIC_SEARCH_VERSION: "7.5.1-amd64"
GROWSTUFF_EMAIL: "noreply@test.growstuff.org"
GROWSTUFF_FLICKR_KEY: secretkey"
GROWSTUFF_FLICKR_SECRET: secretsecret
GROWSTUFF_SITE_NAME: "Growstuff (travis)"
RAILS_ENV: test
RAILS_SECRET_TOKEN: supersecret
steps:
- name: Checkout this repo
uses: actions/checkout@v5
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.5.1
##
# Cache Yarn modules
#
# See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details
#
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install required OS packages
run: |
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: '12'
- name: Install Ruby (version given by .ruby-version) and Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install required JS packages
run: yarn install
- name: install chrome
run: sudo apt-get install google-chrome-stable
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (*_spec)
run: bundle exec rspec spec/features/*_spec.rb -fd
- name: Run rspec (percy/)
run: bundle exec rspec spec/features/percy/ -fd
- name: Run rspec (photos/)
run: bundle exec rspec spec/features/photos/ -fd
- name: Run rspec (rss/)
run: bundle exec rspec spec/features/rss/ -fd

View File

@@ -6,7 +6,7 @@ jobs:
contributors:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Install ruby version specified in .ruby-version
uses: ruby/setup-ruby@v1
with:
@@ -53,7 +53,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Configure sysctl limits
run: |
@@ -106,25 +106,17 @@ jobs:
- name: Prepare database for testing
run: bundle exec rails db:prepare
- name: precompile assets
run: bundle exec rails assets:precompile
- name: index into elastic search
run: bundle exec rails search:reindex
- name: Run rspec (report results to Percy.io and CodeClimate)
run: bundle exec rspec spec -fd
- name: Run rspec (lib)
run: bundle exec rspec spec/lib/ -fd --fail-fast
- name: Run rspec (services)
run: bundle exec rspec spec/services/ -fd --fail-fast
- name: Run rspec (models)
run: bundle exec rspec spec/models/ -fd --fail-fast
- name: Run rspec (controllers)
run: bundle exec rspec spec/controllers/ -fd --fail-fast
- name: Run rspec (views)
run: bundle exec rspec spec/views/ -fd --fail-fast
- name: Run rspec (routing)
run: bundle exec rspec spec/routing/ -fd --fail-fast
- name: Run rspec (request)
run: bundle exec rspec spec/requests/ -fd --fail-fast
- name: Report to code climate
run: |
gem install codeclimate-test-reporter
codeclimate-test-reporter

View File

@@ -158,7 +158,7 @@ Metrics/BlockLength:
# Offense count: 7
# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
Max: 188
Max: 183
# Offense count: 6
# Configuration parameters: AllowedMethods, AllowedPatterns.

View File

@@ -1 +1 @@
3.3.8
3.3.4

View File

@@ -12,7 +12,6 @@ submit the change with your pull request.
- Miles Gould / [pozorvlak](https://github.com/pozorvlak)
- Mackenzie Morgan / [maco](https://github.com/maco)
- Brenda Wallace / [br3nda](https://github.com/br3nda)
- Daniel O'Connor / [CloCkWeRX](https://github.com/CloCkWeRX)
## Contributors
@@ -69,6 +68,7 @@ submit the change with your pull request.
- Jym Paul Carandang / [jacarandang](https://github.com/jacarandang)
- Anthony Atkinson / [sha1sum](https://github.com/sha1sum)
- Terence Conquest / [twconquest](https://github.com/twconquest)
- Daniel O'Connor / [CloCkWeRX](https://github.com/CloCkWeRX)
- DV Dasari / [dv2](https://github.com/dv2)
- Eric Tillberg / [Thrillberg](https://github.com/Thrillberg)
- Lucas Nogueira / [lucasnogueira](https://github.com/lucasnogueira)
@@ -95,11 +95,10 @@ submit the change with your pull request.
- Ítalo Pires / [italopires](https://github.com/italopires)
- Bennett Zink / [bennett-zink](https://github.com/bennett-zink)
- Dominick Thornton / [domthor](https://github.com/domthor)
## Bots
### Security and Dependency Updates
- `codefactor-io[bot]`
- DeppBot / [deppbot](https://github.com/deppbot)
- `dependabot[bot]` [dependabot](https://github.com/dependabot-bot) / [dependabot-preview](https://github.com/apps/dependabot-preview)
- [google-labs-jules[bot]](https://github.com/apps/google-labs-jules)

15
Gemfile
View File

@@ -5,13 +5,13 @@ source 'https://rubygems.org'
# Match ruby version in .ruby-version
ruby File.read('.ruby-version')
gem 'rails', '~> 7.2.0'
gem 'rails', '~> 7.1.0'
# Keeping old sprockets
# https://github.com/rails/sprockets-rails/issues/444#issuecomment-637817050
gem "sprockets", "<4"
gem 'bundler', '>= 2.4.22'
gem 'bundler', '>= 2.3.10'
gem 'coffee-rails'
gem 'haml'
@@ -91,9 +91,10 @@ gem 'bootstrap-datepicker-rails'
# DRY-er easier bootstrap 4 forms
gem "bootstrap_form", ">= 4.5.0"
# For connecting to other services (eg Flickr)
# For connecting to other services (eg Twitter)
gem 'omniauth', '~> 1.3'
gem 'omniauth-flickr', '>= 0.0.15'
gem 'omniauth-twitter'
# Pretty charts
gem "chartkick"
@@ -174,7 +175,6 @@ group :development, :test do
gem 'rubocop-rspec_rails'
gem 'webrat' # provides HTML matchers for view tests
gem 'crowdin-cli' # for translations
gem 'dotenv-rails'
# cli utils
@@ -188,18 +188,15 @@ end
group :test do
gem 'axe-core-capybara'
gem 'axe-core-rspec'
gem 'codeclimate-test-reporter', require: false
gem 'rails-controller-testing'
gem 'selenium-webdriver'
gem 'timecop'
gem 'vcr'
gem "rspec-rebound"
gem "percy-capybara", "~> 5.0.0"
end
group :travis do
gem 'platform-api'
end
gem "i18n_data", "~> 1.1"
gem "percy-capybara", "~> 5.0.0"

View File

@@ -33,46 +33,51 @@ GEM
GEM
remote: https://rubygems.org/
specs:
actioncable (7.2.2.2)
actionpack (= 7.2.2.2)
activesupport (= 7.2.2.2)
actioncable (7.1.3.4)
actionpack (= 7.1.3.4)
activesupport (= 7.1.3.4)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.2.2.2)
actionpack (= 7.2.2.2)
activejob (= 7.2.2.2)
activerecord (= 7.2.2.2)
activestorage (= 7.2.2.2)
activesupport (= 7.2.2.2)
mail (>= 2.8.0)
actionmailer (7.2.2.2)
actionpack (= 7.2.2.2)
actionview (= 7.2.2.2)
activejob (= 7.2.2.2)
activesupport (= 7.2.2.2)
mail (>= 2.8.0)
actionmailbox (7.1.3.4)
actionpack (= 7.1.3.4)
activejob (= 7.1.3.4)
activerecord (= 7.1.3.4)
activestorage (= 7.1.3.4)
activesupport (= 7.1.3.4)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.1.3.4)
actionpack (= 7.1.3.4)
actionview (= 7.1.3.4)
activejob (= 7.1.3.4)
activesupport (= 7.1.3.4)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.2)
actionpack (7.2.2.2)
actionview (= 7.2.2.2)
activesupport (= 7.2.2.2)
actionpack (7.1.3.4)
actionview (= 7.1.3.4)
activesupport (= 7.1.3.4)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4, < 3.2)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (7.2.2.2)
actionpack (= 7.2.2.2)
activerecord (= 7.2.2.2)
activestorage (= 7.2.2.2)
activesupport (= 7.2.2.2)
actiontext (7.1.3.4)
actionpack (= 7.1.3.4)
activerecord (= 7.1.3.4)
activestorage (= 7.1.3.4)
activesupport (= 7.1.3.4)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.2.2.2)
activesupport (= 7.2.2.2)
actionview (7.1.3.4)
activesupport (= 7.1.3.4)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
@@ -80,69 +85,64 @@ GEM
active_link_to (1.0.5)
actionpack
addressable
active_median (0.6.0)
activesupport (>= 7.1)
active_median (0.4.1)
activesupport (>= 6.1)
active_record_union (1.3.0)
activerecord (>= 4.0)
active_utils (3.5.0)
active_utils (3.4.1)
activesupport (>= 4.2)
i18n
activejob (7.2.2.2)
activesupport (= 7.2.2.2)
activejob (7.1.3.4)
activesupport (= 7.1.3.4)
globalid (>= 0.3.6)
activemodel (7.2.2.2)
activesupport (= 7.2.2.2)
activerecord (7.2.2.2)
activemodel (= 7.2.2.2)
activesupport (= 7.2.2.2)
activemodel (7.1.3.4)
activesupport (= 7.1.3.4)
activerecord (7.1.3.4)
activemodel (= 7.1.3.4)
activesupport (= 7.1.3.4)
timeout (>= 0.4.0)
activestorage (7.2.2.2)
actionpack (= 7.2.2.2)
activejob (= 7.2.2.2)
activerecord (= 7.2.2.2)
activesupport (= 7.2.2.2)
activestorage (7.1.3.4)
actionpack (= 7.1.3.4)
activejob (= 7.1.3.4)
activerecord (= 7.1.3.4)
activesupport (= 7.1.3.4)
marcel (~> 1.0)
activesupport (7.2.2.2)
activesupport (7.1.3.4)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
mutex_m
tzinfo (~> 2.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
ast (2.4.3)
ast (2.4.2)
autoprefixer-rails (10.4.16.0)
execjs (~> 2)
axe-core-api (4.10.3)
axe-core-api (4.9.1)
dumb_delegator
ostruct
virtus
axe-core-capybara (4.10.3)
axe-core-api (= 4.10.3)
axe-core-capybara (4.9.1)
axe-core-api (= 4.9.1)
dumb_delegator
axe-core-rspec (4.10.3)
axe-core-api (= 4.10.3)
axe-core-rspec (4.9.1)
axe-core-api (= 4.9.1)
dumb_delegator
ostruct
virtus
axiom-types (0.1.1)
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
base64 (0.3.0)
base64 (0.2.0)
bcrypt (3.1.20)
benchmark (0.4.1)
better_errors (2.10.1)
erubi (>= 1.0.0)
rack (>= 0.9.0)
rouge (>= 1.0.0)
bigdecimal (3.2.2)
bigdecimal (3.1.8)
bluecloth (2.2.0)
bonsai-elasticsearch-rails (7.0.1)
elasticsearch-model (< 8)
@@ -156,10 +156,10 @@ GEM
actionpack (>= 6.1)
activemodel (>= 6.1)
builder (3.3.0)
bullet (8.0.8)
bullet (7.2.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (12.0.0)
byebug (11.1.3)
cancancan (3.6.1)
capybara (3.40.0)
addressable
@@ -183,8 +183,10 @@ GEM
image_processing (~> 1.1)
marcel (~> 1.0.0)
ssrf_filter (~> 1.0)
chartkick (5.1.5)
chartkick (5.0.7)
childprocess (5.0.0)
codeclimate-test-reporter (1.0.9)
simplecov (<= 0.13)
coderay (1.1.3)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
@@ -197,29 +199,20 @@ GEM
coffee-script-source (1.12.2)
comfy_bootstrap_form (4.0.9)
rails (>= 5.0.0)
concurrent-ruby (1.3.5)
connection_pool (2.5.3)
concurrent-ruby (1.3.3)
connection_pool (2.4.1)
crass (1.0.6)
crowdin-api (1.12.0)
open-uri (>= 0.1.0, < 0.2.0)
rest-client (>= 2.0.0, < 2.2.0)
crowdin-cli (0.2.2)
crowdin-api (>= 0.2.0)
gli (>= 2.7.0)
i18n (>= 0.6.4)
rubyzip (>= 1.0.0)
csv (3.3.1)
csv_shaper (1.4.0)
csv (3.3.0)
csv_shaper (1.3.2)
activesupport (>= 3.0.0)
csv
dalli (3.2.8)
database_cleaner (2.1.0)
database_cleaner (2.0.2)
database_cleaner-active_record (>= 2, < 3)
database_cleaner-active_record (2.2.0)
database_cleaner-active_record (2.1.0)
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
date (3.4.1)
date (3.3.4)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
devise (4.9.4)
@@ -228,16 +221,16 @@ GEM
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
diff-lcs (1.6.2)
discard (1.4.0)
activerecord (>= 4.2, < 9.0)
domain_name (0.6.20240107)
dotenv (3.1.8)
dotenv-rails (3.1.8)
dotenv (= 3.1.8)
diff-lcs (1.5.1)
discard (1.3.0)
activerecord (>= 4.2, < 8)
docile (1.1.5)
dotenv (3.1.2)
dotenv-rails (3.1.2)
dotenv (= 3.1.2)
railties (>= 6.1)
drb (2.2.3)
dumb_delegator (1.1.0)
drb (2.2.1)
dumb_delegator (1.0.0)
elasticsearch (7.0.0)
elasticsearch-api (= 7.0.0)
elasticsearch-transport (= 7.0.0)
@@ -251,25 +244,22 @@ GEM
elasticsearch-transport (7.0.0)
faraday
multi_json
erb (5.0.2)
erubi (1.13.1)
erubi (1.13.0)
erubis (2.7.0)
excon (1.2.5)
logger
execjs (2.10.0)
factory_bot (6.5.4)
activesupport (>= 6.1.0)
factory_bot_rails (6.5.0)
factory_bot (~> 6.5)
railties (>= 6.1.0)
faker (3.5.2)
excon (0.110.0)
execjs (2.9.1)
factory_bot (6.4.6)
activesupport (>= 5.0.0)
factory_bot_rails (6.4.3)
factory_bot (~> 6.4)
railties (>= 5.0.0)
faker (3.4.2)
i18n (>= 1.8.11, < 2)
faraday (2.13.4)
faraday-net_http (>= 2.0, < 3.5)
json
faraday (2.10.0)
faraday-net_http (>= 2.0, < 3.2)
logger
faraday-net_http (3.4.1)
net-http (>= 0.5.0)
faraday-net_http (3.1.0)
net-http
ffi (1.16.3)
flickraw (0.9.10)
font-awesome-sass (5.15.1)
@@ -277,14 +267,12 @@ GEM
friendly_id (5.5.1)
activerecord (>= 4.0.0)
gbifrb (0.2.0)
geocoder (1.8.5)
geocoder (1.8.3)
base64 (>= 0.1.0)
csv (>= 3.0.0)
gibbon (1.2.1)
httparty
multi_json (>= 1.9.0)
gli (2.22.2)
ostruct
globalid (1.2.1)
activesupport (>= 6.1)
gravatar-ultimate (2.0.0)
@@ -305,32 +293,27 @@ GEM
activesupport (>= 5.1)
haml (>= 4.0.6)
railties (>= 5.1)
haml_lint (0.66.0)
haml_lint (0.58.0)
haml (>= 5.0)
parallel (~> 1.10)
rainbow
rubocop (>= 1.0)
sysexits (~> 1.1)
hashie (5.0.0)
heroics (0.1.3)
base64
heroics (0.1.2)
erubis (~> 2.0)
excon
moneta
multi_json (>= 1.9.2)
webrick
highline (3.1.2)
reline
http-accept (1.7.0)
http-cookie (1.0.8)
domain_name (~> 0.5)
highline (3.0.1)
httparty (0.22.0)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.14.7)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.15)
i18n-tasks (1.0.14)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
erubi
@@ -339,32 +322,25 @@ GEM
parser (>= 3.2.2.1)
rails-i18n
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.8, >= 1.8.1)
terminal-table (>= 1.5.1)
i18n_data (1.1.0)
simple_po_parser (~> 1.1)
icalendar (2.11.2)
base64
icalendar (2.10.2)
ice_cube (~> 0.16)
logger
ostruct
ice_cube (0.17.0)
ice_nine (0.11.2)
image_processing (1.12.2)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
io-console (0.8.1)
irb (1.15.2)
pp (>= 0.6.0)
io-console (0.7.2)
irb (1.14.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jquery-rails (4.6.0)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.13.2)
json-schema (5.1.0)
addressable (~> 2.8)
json (2.7.2)
json-schema (4.1.1)
addressable (>= 2.8)
jsonapi-resources (0.10.7)
activerecord (>= 4.1)
concurrent-ruby
@@ -373,7 +349,7 @@ GEM
kgio (2.11.4)
kramdown (2.4.0)
rexml
language_server-protocol (3.17.0.5)
language_server-protocol (3.17.0.3)
launchy (3.0.1)
addressable (~> 2.8)
childprocess (~> 5.0)
@@ -382,12 +358,11 @@ GEM
railties (>= 4.2.0)
letter_opener (1.10.0)
launchy (>= 2.2, < 4)
lint_roller (1.1.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logger (1.7.0)
loofah (2.24.1)
logger (1.6.0)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.8.1)
@@ -406,45 +381,40 @@ GEM
railties (>= 3.2)
matrix (0.4.2)
memcachier (0.0.2)
method_source (1.1.0)
mime-types (3.7.0)
logger
mime-types-data (~> 3.2025, >= 3.2025.0507)
mime-types-data (3.2025.0805)
method_source (1.0.0)
mimemagic (0.4.3)
nokogiri (~> 1)
rake
mini_magick (4.12.0)
mini_mime (1.1.5)
mini_portile2 (2.8.9)
minitest (5.25.5)
mini_portile2 (2.8.7)
minitest (5.24.1)
moneta (1.0.0)
msgpack (1.8.0)
msgpack (1.7.2)
multi_json (1.15.0)
multi_xml (0.7.1)
bigdecimal (~> 3.1)
net-http (0.6.0)
mutex_m (0.2.0)
net-http (0.4.1)
uri
net-imap (0.5.9)
net-imap (0.4.11)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.2)
timeout
net-smtp (0.5.1)
net-smtp (0.5.0)
net-protocol
netrc (0.11.0)
nio4r (2.7.4)
nokogiri (1.18.9)
nio4r (2.7.3)
nokogiri (1.16.6)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
nokogiri (1.16.6-x86_64-linux)
racc (~> 1.4)
oauth (0.5.6)
oj (3.16.11)
oj (3.16.4)
bigdecimal (>= 3.0)
ostruct (>= 0.2)
omniauth (1.9.2)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
@@ -454,38 +424,33 @@ GEM
omniauth-oauth (1.1.0)
oauth
omniauth (~> 1.0)
open-uri (0.1.0)
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
orm_adapter (0.5.0)
ostruct (0.6.3)
parallel (1.27.0)
parser (3.3.9.0)
parallel (1.25.1)
parser (3.3.4.0)
ast (~> 2.4.1)
racc
percy-capybara (5.0.0)
capybara (>= 3)
pg (1.6.1)
pg (1.6.1-x86_64-linux)
platform-api (3.8.0)
pg (1.5.6)
platform-api (3.7.0)
heroics (~> 0.1.1)
moneta (~> 1.0.0)
rate_throttle_client (~> 0.1.0)
popper_js (2.11.8)
pp (0.6.2)
prettyprint
prettyprint (0.2.0)
prism (1.4.0)
pry (0.15.2)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
psych (5.2.6)
date
psych (5.1.2)
stringio
public_suffix (6.0.1)
puma (6.6.1)
public_suffix (6.0.0)
puma (6.4.2)
nio4r (~> 2.0)
query_diet (0.7.2)
racc (1.8.1)
rack (2.2.17)
query_diet (0.7.1)
racc (1.8.0)
rack (2.2.9)
rack-cors (2.0.2)
rack (>= 2.0.0)
rack-protection (3.2.0)
@@ -493,37 +458,37 @@ GEM
rack (~> 2.2, >= 2.2.4)
rack-session (1.0.2)
rack (< 3)
rack-test (2.2.0)
rack-test (2.1.0)
rack (>= 1.3)
rackup (1.0.1)
rackup (1.0.0)
rack (< 3)
webrick
rails (7.2.2.2)
actioncable (= 7.2.2.2)
actionmailbox (= 7.2.2.2)
actionmailer (= 7.2.2.2)
actionpack (= 7.2.2.2)
actiontext (= 7.2.2.2)
actionview (= 7.2.2.2)
activejob (= 7.2.2.2)
activemodel (= 7.2.2.2)
activerecord (= 7.2.2.2)
activestorage (= 7.2.2.2)
activesupport (= 7.2.2.2)
rails (7.1.3.4)
actioncable (= 7.1.3.4)
actionmailbox (= 7.1.3.4)
actionmailer (= 7.1.3.4)
actionpack (= 7.1.3.4)
actiontext (= 7.1.3.4)
actionview (= 7.1.3.4)
activejob (= 7.1.3.4)
activemodel (= 7.1.3.4)
activerecord (= 7.1.3.4)
activestorage (= 7.1.3.4)
activesupport (= 7.1.3.4)
bundler (>= 1.15.0)
railties (= 7.2.2.2)
railties (= 7.1.3.4)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
activesupport (>= 5.0.1.rc1)
rails-dom-testing (2.3.0)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2)
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails-i18n (7.0.10)
nokogiri (~> 1.14)
rails-i18n (7.0.9)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails_12factor (0.0.3)
@@ -531,123 +496,108 @@ GEM
rails_stdout_logging
rails_serve_static_assets (0.0.5)
rails_stdout_logging (0.0.5)
railties (7.2.2.2)
actionpack (= 7.2.2.2)
activesupport (= 7.2.2.2)
irb (~> 1.13)
railties (7.1.3.4)
actionpack (= 7.1.3.4)
activesupport (= 7.1.3.4)
irb
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
raindrops (0.20.1)
rake (13.3.0)
rake (13.2.1)
rate_throttle_client (0.1.2)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rdoc (6.14.2)
erb
rdoc (6.7.0)
psych (>= 4.0.0)
recaptcha (5.20.1)
redis-client (0.23.2)
recaptcha (5.17.0)
redis-client (0.22.2)
connection_pool
regexp_parser (2.11.2)
reline (0.6.2)
regexp_parser (2.9.2)
reline (0.5.9)
io-console (~> 0.5)
responders (3.1.1)
actionpack (>= 5.2)
railties (>= 5.2)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rexml (3.4.1)
rexml (3.3.2)
strscan
rouge (4.1.2)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-activemodel-mocks (1.3.0)
rspec-activemodel-mocks (1.2.0)
activemodel (>= 3.0)
activesupport (>= 3.0)
rspec-mocks (>= 2.99, < 4.0)
rspec-core (3.13.5)
rspec-core (3.13.0)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.5)
rspec-expectations (3.13.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.5)
rspec-mocks (3.13.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (8.0.2)
actionpack (>= 7.2)
activesupport (>= 7.2)
railties (>= 7.2)
rspec-rails (6.1.3)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-rebound (0.2.1)
rspec-core (~> 3.3)
rspec-support (3.13.4)
rspectre (0.2.0)
parser (>= 3.3.7.1)
prism (~> 1.3)
rspec (~> 3.10)
rswag-api (2.16.0)
activesupport (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rswag-specs (2.16.0)
activesupport (>= 5.2, < 8.1)
json-schema (>= 2.2, < 6.0)
railties (>= 5.2, < 8.1)
rspec-support (3.13.1)
rspectre (0.1.0)
parser (>= 3.2.2.1)
rspec (~> 3.9)
rswag-api (2.13.0)
activesupport (>= 3.1, < 7.2)
railties (>= 3.1, < 7.2)
rswag-specs (2.13.0)
activesupport (>= 3.1, < 7.2)
json-schema (>= 2.2, < 5.0)
railties (>= 3.1, < 7.2)
rspec-core (>= 2.14)
rswag-ui (2.16.0)
actionpack (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rubocop (1.80.0)
rswag-ui (2.13.0)
actionpack (>= 3.1, < 7.2)
railties (>= 3.1, < 7.2)
rubocop (1.65.0)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.46.0, < 2.0)
regexp_parser (>= 2.4, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.46.0)
parser (>= 3.3.7.2)
prism (~> 1.4)
rubocop-capybara (2.22.1)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-factory_bot (2.27.1)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rails (2.33.3)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.3)
parser (>= 3.3.1.0)
rubocop-capybara (2.21.0)
rubocop (~> 1.41)
rubocop-factory_bot (2.26.1)
rubocop (~> 1.61)
rubocop-rails (2.25.1)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.44.0, < 2.0)
rubocop-rake (0.7.1)
lint_roller (~> 1.1)
rubocop (>= 1.72.1)
rubocop-rspec (3.6.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec_rails (2.31.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec (~> 3.5)
rubocop (>= 1.33.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rake (0.6.0)
rubocop (~> 1.0)
rubocop-rspec (3.0.3)
rubocop (~> 1.61)
rubocop-rspec_rails (2.30.0)
rubocop (~> 1.61)
rubocop-rspec (~> 3, >= 3.0.1)
ruby-progressbar (1.13.0)
ruby-units (4.1.0)
ruby-units (4.0.3)
ruby-vips (2.2.1)
ffi (~> 1.12)
rubyzip (3.0.1)
rubyzip (2.3.2)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
@@ -661,26 +611,29 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
scout_apm (5.7.1)
scout_apm (5.3.8)
parser
searchkick (5.3.1)
activemodel (>= 6.1)
hashie
securerandom (0.4.1)
selenium-webdriver (4.35.0)
selenium-webdriver (4.23.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 4.0)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
sidekiq (7.3.9)
base64
sidekiq (7.3.0)
concurrent-ruby (< 2)
connection_pool (>= 2.3.0)
logger
rack (>= 2.2.4)
redis-client (>= 0.22.2)
simple_po_parser (1.1.6)
sprockets (3.7.5)
simplecov (0.13.0)
docile (~> 1.1.0)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
sprockets (3.7.3)
base64
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
@@ -689,35 +642,32 @@ GEM
activesupport (>= 5.2)
sprockets (>= 3.0.0)
ssrf_filter (1.1.2)
stringio (3.1.7)
stringio (3.1.1)
strscan (3.1.0)
sysexits (1.2.0)
temple (0.10.4)
terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4)
terser (1.2.5)
temple (0.10.3)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
terser (1.2.3)
execjs (>= 0.3.0, < 3)
thor (1.4.0)
thor (1.3.1)
thread_safe (0.3.6)
tilt (2.6.1)
tilt (2.4.0)
timecop (0.9.10)
timeout (0.4.3)
timeout (0.4.1)
trollop (1.16.2)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (3.1.5)
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
unicode-display_width (2.5.0)
unicorn (6.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
uniform_notifier (1.17.0)
uri (1.0.3)
useragent (0.16.11)
uniform_notifier (1.16.0)
uri (0.13.0)
validate_url (1.0.15)
activemodel (>= 3.0.0)
public_suffix
vcr (6.3.1)
base64
vcr (6.2.0)
virtus (2.0.0)
axiom-types (~> 0.1)
coercible (~> 1.0)
@@ -728,10 +678,9 @@ GEM
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
webrick (1.9.1)
webrick (1.8.1)
websocket (1.2.11)
websocket-driver (0.8.0)
base64
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
will_paginate (4.0.1)
@@ -741,7 +690,7 @@ GEM
webrick
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.7.3)
zeitwerk (2.6.16)
PLATFORMS
ruby
@@ -760,16 +709,16 @@ DEPENDENCIES
bootstrap-datepicker-rails
bootstrap_form (>= 4.5.0)
bullet
bundler (>= 2.4.22)
bundler (>= 2.3.10)
byebug
cancancan
capybara
capybara-email
capybara-screenshot
chartkick
codeclimate-test-reporter
coffee-rails
comfortable_mexican_sofa!
crowdin-cli
csv_shaper
dalli
database_cleaner
@@ -793,7 +742,6 @@ DEPENDENCIES
haml_lint (>= 0.25.1)
hashie (>= 3.5.3)
i18n-tasks
i18n_data (~> 1.1)
icalendar
jquery-rails
jquery-ui-rails!
@@ -811,6 +759,7 @@ DEPENDENCIES
oj
omniauth (~> 1.3)
omniauth-flickr (>= 0.0.15)
omniauth-twitter
percy-capybara (~> 5.0.0)
pg
platform-api
@@ -819,7 +768,7 @@ DEPENDENCIES
query_diet
rack-cors
rack-protection (>= 2.0.1)
rails (~> 7.2.0)
rails (~> 7.1.0)
rails-assets-leaflet.markercluster!
rails-controller-testing
rails_12factor
@@ -828,7 +777,6 @@ DEPENDENCIES
responders
rspec-activemodel-mocks
rspec-rails
rspec-rebound
rspectre
rswag-api
rswag-specs
@@ -858,7 +806,7 @@ DEPENDENCIES
xmlrpc
RUBY VERSION
ruby 3.3.8p144
ruby 3.3.4p94
BUNDLED WITH
2.4.22

View File

@@ -1,6 +1,7 @@
# 🌱 Growstuff
![Build status](https://github.com/Growstuff/growstuff/workflows/CI/badge.svg)
[![Code Climate](https://codeclimate.com/github/Growstuff/growstuff/badges/gpa.svg)](https://codeclimate.com/github/Growstuff/growstuff)
Welcome to the Growstuff project.
@@ -62,3 +63,5 @@ For more information about this project, contact [info@growstuff.org](mailto:inf
Security Issues: If you find an authorization bypass or data breach, please contact our maintainers directly at [maintainers@growstuff.org](mailto:maintainers@growstuff.org).
You can also contact us on [Twitter](http://twitter.com/growstufforg/) or
[Facebook](https://www.facebook.com/pages/Growstuff/1531133417099494) or [Github](https://github.com/Growstuff/growstuff/issues)..

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,19 +1,11 @@
$(document).ready(function() {
$('.like-btn').show();
/**
* Handles the result of an ajax call and updates UI
*
* @param {object} data JSON data from ajax response
* @param {string} type object type (ie: post, activity, etc)
*/
var likeableSuccess = function(data, type) {
var target = '.' + type + '-' + data.id;
var objectClass = type.charAt(0).toUpperCase() + type.slice(1);
var likeButton = $(target + ' .' + type + '-like');
var likeBadge = $(target + ' .like-badge');
$('.post-like').on('ajax:success', function(event, data) {
var likeButton = $('#post-' + data.id + ' .post-like');
var likeBadge = $('#post-'+ data.id + ' .like-badge');
$(target + ' .like-count').text(data.like_count);
$('#post-' + data.id + ' .like-count').text(data.like_count);
if (data.liked_by_member) {
likeBadge.addClass('liked');
likeButton.data('method', 'delete');
@@ -22,26 +14,11 @@ $(document).ready(function() {
} else {
likeBadge.removeClass('liked');
likeButton.data('method', 'post');
likeButton.attr('href', '/likes.json?type=' + objectClass + '&id=' + data.id);
likeButton.attr('href', '/likes.json?type=Post&id=' + data.id);
likeButton.text('Like');
}
};
$('.post-like').on('ajax:success', function(event, data) {
likeableSuccess(data, 'post');
});
$('.activity-like').on('ajax:success', function(event, data) {
likeableSuccess(data, 'activity');
});
$('.planting-like').on('ajax:success', function(event, data) {
likeableSuccess(data, 'planting');
});
$('.harvest-like').on('ajax:success', function(event, data) {
likeableSuccess(data, 'harvest');
});
$('.photo-like').on('ajax:success', function(event, data) {
var likeBadge = $('#photo-'+ data.id + ' .like-badge');

View File

@@ -33,6 +33,13 @@
}
}
.location-not-set {
background-image: image-url("location-not-set.en.png");
background-position: center;
background-repeat: no-repeat;
height: 250px;
width: 100%;
}
.card {
.badge-location {
background-color: darken($blue, 10%);

View File

@@ -47,13 +47,4 @@
margin-left: auto;
}
}
.card-footer {
max-height: 2em;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 0.5em;
padding-top: 0;
}
}

View File

@@ -30,7 +30,3 @@
@import "predictions";
@import "homepage";
@import "maps";
@view-transition {
navigation: auto;
}

View File

@@ -8,9 +8,6 @@ body {
font-family: $default-font;
}
.navbar {
flex-wrap: nowrap;
}
.navbar-brand {
.site-name {
font-family: "Modak", cursive;
@@ -19,7 +16,7 @@ body {
}
img {
height: 100%;
height: 60px;
}
}

View File

@@ -29,8 +29,7 @@ class ActivitiesController < DataController
def new
@activity = Activity.new(
owner: current_member,
due_date: Date.today
owner: current_member
)
if params[:garden_id]
@activity.garden = Garden.find_by(

View File

@@ -57,6 +57,6 @@ class AlternateNamesController < ApplicationController
private
def alternate_name_params
params.require(:alternate_name).permit(:crop_id, :name, :creator_id, :language)
params.require(:alternate_name).permit(:crop_id, :name, :creator_id)
end
end

View File

@@ -78,7 +78,6 @@ class ApplicationController < ActionController::Base
:tos_agreement,
# profile stuff
:bio, :location, :latitude, :longitude,
:website_url, :instagram_handle, :facebook_handle, :bluesky_handle, :other_url,
# email settings
:show_email, :newsletter, :send_notification_email, :send_planting_reminder,
# update password

View File

@@ -13,55 +13,43 @@ class CommentsController < ApplicationController
end
def new
@commentable = find_commentable
@comment = Comment.new
if @commentable
@comments = @commentable.comments
@post = Post.find_by(id: params[:post_id])
if @post
@comments = @post.comments
respond_with(@comments)
else
redirect_to(request.referer || root_url,
alert: "Can't post a comment on a non-existent commentable")
alert: "Can't post a comment on a non-existent post")
end
end
def edit
# TODO: Why does this need a collection of comments?
@comments = @comment.commentable.comments
@commentable = @comment.commentable
@comments = @comment.post.comments
end
def create
@comment = Comment.new(comment_params)
@commentable = @comment.commentable
@comment.author = current_member
@comment.save
respond_with @comment, location: @commentable
respond_with @comment, location: @comment.post
end
def update
@comment.update(body: comment_params['body'])
respond_with @comment, location: @comment.commentable
respond_with @comment, location: @comment.post
end
def destroy
@commentable = @comment.commentable
@post = @comment.post
@comment.destroy
respond_with(@commentable)
respond_with(@post)
end
private
def find_commentable
return unless params[:comment]
if params[:comment][:commentable_type] == 'Photo'
Photo.find(params[:comment][:commentable_id])
elsif params[:comment][:commentable_type] == 'Post'
Post.find(params[:comment][:commentable_id])
end
end
def comment_params
params.require(:comment).permit(:body, :commentable_id, :commentable_type)
params.require(:comment).permit(:body, :post_id)
end
end

View File

@@ -166,7 +166,7 @@ class CropsController < ApplicationController
end
def save_crop_names
AlternateName.create!(names_params(:alt_name).map { |n| { name: n, creator_id: current_member.id, crop_id: @crop.id, language: "EN" } })
AlternateName.create!(names_params(:alt_name).map { |n| { name: n, creator_id: current_member.id, crop_id: @crop.id } })
ScientificName.create!(names_params(:sci_name).map { |n| { name: n, creator_id: current_member.id, crop_id: @crop.id } })
end
@@ -181,18 +181,20 @@ class CropsController < ApplicationController
def recreate_names(param_name, name_type)
return if params[param_name].blank?
@crop.send("#{name_type}_names").each(&:destroy)
destroy_names(name_type)
params[param_name].each_value do |value|
next if value.empty?
if name_type == 'alternate'
@crop.send("#{name_type}_names").create!(name: value, creator_id: current_member.id, language: "EN")
else
@crop.send("#{name_type}_names").create!(name: value, creator_id: current_member.id)
end
create_name!(name_type, value) unless value.empty?
end
end
def destroy_names(name_type)
@crop.send("#{name_type}_names").each(&:destroy)
end
def create_name!(name_type, value)
@crop.send("#{name_type}_names").create!(name: value, creator_id: current_member.id)
end
def crop_params
params.require(:crop).permit(
:name, :en_wikipedia_url,
@@ -214,12 +216,12 @@ class CropsController < ApplicationController
def crop_json_fields
{
include: {
plantings: {
plantings: {
include: {
owner: { only: %i(id login_name location latitude longitude) }
}
},
scientific_names: { only: [:name] }, alternate_names: { only: %i(name language) }
scientific_names: { only: [:name] }, alternate_names: { only: [:name] }
}
}
end

View File

@@ -1,87 +0,0 @@
# frozen_string_literal: true
class GardenCollaboratorsController < ApplicationController
before_action :authenticate_member!, except: %i(index show)
before_action :load_garden
load_and_authorize_resource id_param: :slug
respond_to :html
responders :flash
def index
@garden_collaborators = @garden.garden_collaborators.paginate(page: params[:page])
respond_with(@garden_collaborators)
end
def show
@garden_collaborator = GardenCollaborator.find(params[:garden_collaborator_id])
respond_with(@garden_collaborator)
end
def new
@garden_collaborator = GardenCollaborator.new(garden: @garden)
authorize! :create, @garden_collaborator
respond_with(@garden_collaborator)
end
def edit
@garden_collaborator = GardenCollaborator.find(params[:id])
authorize! :update, @garden_collaborator
respond_with(@garden_collaborator)
end
def create
@garden_collaborator = GardenCollaborator.new(garden: @garden)
authorize! :create, @garden_collaborator
@member = Member.find_by(slug: params[:garden_collaborator][:member_slug])
@garden_collaborator.member = @member
if @garden_collaborator.save
redirect_to garden_garden_collaborators_path(@garden)
else
respond_with(@garden_collaborator)
end
end
def update
@garden_collaborator = GardenCollaborator.find(params[:id])
authorize! :update, @garden_collaborator
@member = Member.find_by(slug: params[:garden_collaborator][:member_slug])
@garden_collaborator.member = @member
@garden_collaborator.save
respond_with(@garden_collaborator)
end
def destroy
@garden_collaborator = GardenCollaborator.find(params[:id])
authorize! :destroy, @garden_collaborator
if @garden_collaborator.destroy
redirect_to garden_garden_collaborators_path(@garden)
else
respond_with(@garden_collaborator)
end
end
private
def load_garden
@garden = Garden.find_by(slug: params[:garden_slug])
end
def garden_collaborator_params
params.require(:garden_collaborator).permit(
:member_slug
)
end
end

View File

@@ -8,10 +8,7 @@ class GardensController < DataController
@gardens = @gardens.includes(:owner)
@gardens = @gardens.active unless @show_all
if @owner.present?
@gardens = @gardens.left_joins(:garden_collaborators)
@gardens = @gardens.where(owner: @owner).or(@gardens.where(garden_collaborators: { member: @owner }))
end
@gardens = @gardens.where(owner: @owner) if @owner.present?
@gardens = @gardens.where.not(members: { confirmed_at: nil })
.order(:name).paginate(page: params[:page])
respond_with(@gardens)

View File

@@ -16,6 +16,7 @@ class MembersController < ApplicationController
def show
@member = Member.confirmed.kept.find_by!(slug: params[:slug])
@twitter_auth = @member.auth('twitter')
@flickr_auth = @member.auth('flickr')
@posts = @member.posts

View File

@@ -28,7 +28,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
@authentication = action.establish_authentication(auth, member)
if action.member_created?
raise "Invalid provider" unless %w(flickr).index(auth['provider'].to_s)
raise "Invalid provider" unless %w(twitter flickr).index(auth['provider'].to_s)
session["devise.#{auth['provider']}_data"] = request.env["omniauth.auth"]
sign_in member

View File

@@ -21,7 +21,6 @@ class PhotosController < ApplicationController
def show
@crops = Crop.distinct.joins(:photo_associations).where(photo_associations: { photo: @photo })
@comment = Comment.new(commentable: @photo)
respond_with(@photo)
end

View File

@@ -91,32 +91,6 @@ class PlantingsController < DataController
respond_with @planting, location: @planting.garden
end
def transplant
# The `load_and_authorize_resource` in DataController will handle finding the
# planting and authorizing the action.
# We still need to authorize the new garden
new_garden = Garden.find(params[:garden_id])
authorize! :update, new_garden
# Mark original planting as finished
@planting.update(finished: true, finished_at: Time.zone.now)
# Create a new planting
new_planting = @planting.dup
new_planting.garden = new_garden
new_planting.slug = nil # let friendly_id generate a new slug
new_planting.finished = false
new_planting.finished_at = nil
if new_planting.save
redirect_to edit_planting_path(new_planting), notice: 'Planting was successfully transplanted.'
else
# if the save fails, we should probably roll back the finishing of the original planting
@planting.update(finished: false, finished_at: nil)
redirect_to @planting, alert: "There was an error transplanting the planting: #{new_planting.errors.full_messages.to_sentence}"
end
end
private
def update_crop_medians
@@ -133,7 +107,7 @@ class PlantingsController < DataController
:crop_id, :description, :garden_id, :planted_at,
:parent_seed_id,
:quantity, :sunniness, :planted_from, :finished,
:finished_at, :failed
:finished_at
)
end

View File

@@ -6,6 +6,7 @@ class RegistrationsController < Devise::RegistrationsController
prepend_before_action :check_captcha, only: [:create] # Change this to be any actions you want to protect with recaptcha.
def edit
@twitter_auth = current_member.auth('twitter')
@flickr_auth = current_member.auth('flickr')
render "edit"
end

View File

@@ -19,10 +19,6 @@ class SeedsController < DataController
where['parent_planting'] = @planting.id
end
if params[:tradeable_to].present?
where['tradeable_to'] = params[:tradeable_to]
end
@show_all = (params[:all] == '1')
where['finished'] = false unless @show_all

View File

@@ -28,6 +28,12 @@ module ApplicationHelper
"#{klass.name.downcase.pluralize}/#{identifier}-#{count}-#{max_updated_at}"
end
def required_field_help_text
asterisk = tag.span('*', class: ['red'])
text = tag.em('denotes a required field')
tag.div(asterisk + ' '.html_safe + text, class: ['margin-bottom'])
end
# A helper to replace the complex template compilation mess
# of HAML, Tilt, and dynamic compilation with interpolated ruby.
def markdownify(text)
@@ -50,6 +56,7 @@ module ApplicationHelper
uri.query = "&width=#{size}&height=#{size}" if uri.host == 'graph.facebook.com'
# TODO: Assess twitter - https://dev.twitter.com/overview/general/user-profile-images-and-banners
# TODO: Assess flickr - https://www.flickr.com/services/api/misc.buddyicons.html
return uri.to_s

View File

@@ -13,7 +13,7 @@ module AutoSuggestHelper
resource = resource.class.name.downcase
source_path = Rails.application.routes.url_helpers.send("search_#{source}s_path", format: :json)
%(
<input id="#{source}" class="auto-suggest #{options[:class]}" #{options[:required] ? 'required="required"' : ''}
<input id="#{source}" class="auto-suggest #{options[:class]}"
type="text" value="#{default}" data-source-url="#{source_path}",
placeholder="e.g. lettuce">
<noscript class="text-warning">

View File

@@ -2,7 +2,6 @@
module ButtonsHelper
include IconsHelper
def garden_plant_something_button(garden, classes: "btn btn-default")
return unless can? :edit, garden
@@ -98,7 +97,7 @@ module ButtonsHelper
end
def planting_finish_button(planting, classes: 'btn btn-default btn-secondary')
return unless can?(:edit, planting) || planting.finished || planting.failed
return unless can?(:edit, planting) || planting.finished
link_to planting_path(slug: planting.slug, planting: { finished: 1 }),
method: :put, class: "#{classes} append-date" do
@@ -106,15 +105,6 @@ module ButtonsHelper
end
end
def planting_failed_button(planting, classes: 'btn btn-default btn-secondary')
return unless can?(:edit, planting) || planting.finished || planting.failed
link_to planting_path(slug: planting.slug, planting: { failed: 1 }),
method: :put, class: "#{classes}" do
finished_icon + ' ' + t('buttons.mark_as_failed')
end
end
def seed_finish_button(seed, classes: 'btn btn-default')
return unless can?(:create, Planting) && seed.active
@@ -132,7 +122,7 @@ module ButtonsHelper
end
def planting_save_seeds_button(planting, classes: 'btn btn-default')
return unless can?(:edit, planting) && !planting.failed?
return unless can?(:edit, planting)
link_to new_planting_seed_path(planting_slug: planting.slug), class: classes do
seed_icon + ' ' + t('buttons.save_seeds')

View File

@@ -43,14 +43,6 @@ module PlantingsHelper
(planting.first_harvest_predicted_at - Time.zone.today).to_i
end
# Returns a list of gardens the planting can be transplanted to
# based on the planting's owner.
def transplantable_gardens_by_owner(planting)
garden_ids = planting.owner.gardens.select(:id).to_a + GardenCollaborator.where(member_id: planting.owner.id).select(:garden_id).to_a
Garden.active.where.not(id: planting.garden_id).where(id: garden_ids)
end
def days_from_now_to_last_harvest(planting)
return unless planting.planted_at.present? && planting.last_harvest_predicted_at.present?

View File

@@ -108,42 +108,16 @@ class Ability
can :create, Planting
can :update, Planting, garden: { owner_id: member.id }, crop: { approval_status: 'approved' }
can :destroy, Planting, garden: { owner_id: member.id }, crop: { approval_status: 'approved' }
can :update, Planting do |planting|
planting.garden.garden_collaborators.where(member_id: member.id).any?
end
can :transplant, Planting, garden: { owner_id: member.id }
can :transplant, Planting do |planting|
planting.garden.garden_collaborators.where(member_id: member.id).any?
end
can :destroy, Planting do |planting|
planting.garden.garden_collaborators.where(member_id: member.id).any?
end
can :create, GardenCollaborator, garden: { owner_id: member.id }
can :update, GardenCollaborator, garden: { owner_id: member.id }
can :destroy, GardenCollaborator, garden: { owner_id: member.id }
can :create, Activity
can :update, Activity, owner_id: member.id
can :destroy, Activity, owner_id: member.id
can :update, Activity do |activity|
activity.garden&.garden_collaborators&.where(member_id: member.id)&.any?
end
can :destroy, Activity do |activity|
activity.garden&.garden_collaborators&.where(member_id: member.id)&.any?
end
can :create, Harvest
can :update, Harvest, owner_id: member.id
can :destroy, Harvest, owner_id: member.id
can :update, Harvest, owner_id: member.id, planting: { owner_id: member.id }
can :destroy, Harvest, owner_id: member.id, planting: { owner_id: member.id }
can :update, Harvest do |harvest|
harvest.planting&.garden&.garden_collaborators&.where(member_id: member.id)&.any?
end
can :destroy, Harvest do |harvest|
harvest.planting&.garden&.garden_collaborators&.where(member_id: member.id)&.any?
end
can :create, Photo
can :update, Photo, owner_id: member.id

View File

@@ -5,7 +5,6 @@ class Activity < ApplicationRecord
include Ownable
include Finishable
include SearchActivities
include Likeable
belongs_to :garden, optional: true
belongs_to :planting, optional: true

View File

@@ -5,7 +5,6 @@ class AlternateName < ApplicationRecord
belongs_to :creator, class_name: 'Member', inverse_of: :created_alternate_names
validates :name, presence: true
validates :crop, presence: true
validates :language, presence: true
after_commit :reindex

View File

@@ -2,27 +2,26 @@
class Comment < ApplicationRecord
belongs_to :author, class_name: 'Member', inverse_of: :comments
belongs_to :commentable, polymorphic: true, counter_cache: true
# validates :body, presence: true
belongs_to :post, counter_cache: true
scope :post_order, -> { order(created_at: :asc) } # for display on post page
after_create do
recipient = commentable.author.id
recipient = post.author.id
sender = author.id
# don't send notifications to yourself
if recipient != sender
Notification.create(
recipient_id: recipient,
sender_id: sender,
subject: "#{author} commented on #{commentable.subject}",
subject: "#{author} commented on #{post.subject}",
body:,
notifiable: commentable
post_id: post.id
)
end
end
def to_s
"#{author.login_name} commented on #{commentable.subject}"
"#{author.login_name} commented on #{post.subject}"
end
end

View File

@@ -8,12 +8,7 @@ module Finishable
scope :current, -> { where.not(finished: true) }
def active
# Plantings can fail. At the moment, activities and seeds cannot.
if respond_to?(:failed)
!finished && !failed
else
!finished
end
!finished
end
end
end

View File

@@ -38,7 +38,7 @@ module PredictHarvest
# status
def harvest_time?
return false if crop.perennial || finished || failed
return false if crop.perennial || finished
# We have harvests but haven't finished
harvests.size.positive? ||

View File

@@ -8,12 +8,12 @@ module PredictPlanting
before_save :calculate_lifespan
def calculate_lifespan
self.lifespan = (planted_at.present? && finished_at.present? && !failed? ? finished_at - planted_at : nil)
self.lifespan = (planted_at.present? && finished_at.present? ? finished_at - planted_at : nil)
end
# dates
def finish_predicted_at
if planted_at.blank? || failed?
if planted_at.blank?
nil
elsif crop.median_lifespan.present?
planted_at + crop.median_lifespan.days
@@ -34,18 +34,15 @@ module PredictPlanting
end
def actual_lifespan
return unless planted_at.present? && finished_at.present? && !failed?
return unless planted_at.present? && finished_at.present?
(finished_at - planted_at).to_i
end
def age_in_days
return if planted_at.blank?
return if failed?
known_last_day ||= finished_at || Time.zone.today
known_last_day = Time.zone.today if known_last_day > Time.zone.today
(known_last_day - planted_at).to_i
end
@@ -53,9 +50,9 @@ module PredictPlanting
Rails.cache.fetch("#{cache_key_with_version}/percentage_grown", expires_in: 8.hours) do
if finished?
100
elsif !planted? || failed?
elsif !planted?
0
elsif crop.perennial || (finish_predicted_at.nil? && finished_at.nil?) # This covers future dated finished_at that hasn't occurrred yet.
elsif crop.perennial || finish_predicted_at.nil?
nil
else
calculate_percentage_grown
@@ -74,7 +71,7 @@ module PredictPlanting
end
def late?
crop.annual? && !finished && !failed &&
crop.annual? && !finished &&
planted_at.present? &&
finish_predicted_at.present? &&
finish_predicted_at <= Time.zone.today

View File

@@ -30,7 +30,6 @@ module SearchPlantings
quantity:,
sunniness:,
garden_id:,
garden_slug: garden&.garden_slug,
garden_name: garden&.name,
description:,

View File

@@ -59,7 +59,7 @@ class CsvImporter
alternate_names.split(/,\s*/).each do |name|
altname = AlternateName.find_by(name:, crop: @crop)
altname ||= AlternateName.create! name:, crop: @crop, language: "EN", creator: cropbot
altname ||= AlternateName.create! name:, crop: @crop, creator: cropbot
@crop.alternate_names << altname
end
end

View File

@@ -10,8 +10,7 @@ class Follow < ApplicationRecord
recipient_id: followed_id,
sender_id: follower_id,
subject: "#{follower.login_name} is now following you",
body: "#{follower.login_name} just followed you on #{ENV.fetch('GROWSTUFF_SITE_NAME', nil)}. ",
notifiable: self
body: "#{follower.login_name} just followed you on #{ENV.fetch('GROWSTUFF_SITE_NAME', nil)}. "
)
end
end

View File

@@ -5,13 +5,11 @@ class Garden < ApplicationRecord
include Geocodable
include PhotoCapable
include Ownable
friendly_id :garden_slug, use: %i(slugged finders)
has_many :plantings, dependent: :destroy
has_many :crops, through: :plantings
has_many :activities, dependent: :destroy
has_many :garden_collaborators, dependent: :destroy
belongs_to :garden_type, optional: true
@@ -45,7 +43,6 @@ class Garden < ApplicationRecord
.where.not(gardens: { latitude: nil })
.where.not(gardens: { longitude: nil })
}
AREA_UNITS_VALUES = {
"square metres" => "square metre",
"square feet" => "square foot",

View File

@@ -1,24 +0,0 @@
# frozen_string_literal: true
class GardenCollaborator < ApplicationRecord
belongs_to :member
belongs_to :garden
validates :member_id, uniqueness: { scope: :garden }
validate :not_garden_owner
def not_garden_owner
return unless member
return unless garden
errors.add(:member_id, "cannot be the garden owner") if garden.owner == member
end
def member_slug
@member&.slug
end
def member_slug=(_slug)
member_slug
end
end

View File

@@ -6,7 +6,6 @@ class Harvest < ApplicationRecord
include PhotoCapable
include Ownable
include SearchHarvests
include Likeable
friendly_id :harvest_slug, use: %i(slugged finders)
@@ -153,10 +152,7 @@ class Harvest < ApplicationRecord
def owner_must_match_planting
return if planting.blank? # only check if we are linked to a planting
return if owner == planting.owner || planting.garden.garden_collaborators.where(member_id: owner).any?
errors.add(:owner,
"of harvest must be the same as planting, or a collaborator on that garden")
errors.add(:owner, "of harvest must be the same as planting") unless owner == planting.owner
end
def harvest_must_be_after_planting

View File

@@ -91,9 +91,6 @@ class Member < ApplicationRecord
uniqueness: {
case_sensitive: false
}
validates :website_url, format: { with: /\Ahttps?:\/\//, message: "must start with http:// or https://" }, allow_blank: true
validates :other_url, format: { with: /\Ahttps?:\/\//, message: "must start with http:// or https://" }, allow_blank: true
validates :instagram_handle, :facebook_handle, :bluesky_handle, format: { without: %r{\Ahttps?:\/\/|\/}, message: "should be a handle, not a URL" }, allow_blank: true
#
# Triggers

View File

@@ -3,7 +3,7 @@
class Notification < ApplicationRecord
belongs_to :sender, class_name: 'Member', inverse_of: :sent_notifications
belongs_to :recipient, class_name: 'Member', inverse_of: :notifications
belongs_to :notifiable, polymorphic: true
belongs_to :post, optional: true
validates :subject, length: { maximum: 255 }

View File

@@ -8,7 +8,6 @@ class Photo < ApplicationRecord
PHOTO_CAPABLE = %w(Garden Planting Harvest Seed Post Crop).freeze
has_many :photo_associations, dependent: :delete_all, inverse_of: :photo
has_many :comments, as: :commentable, dependent: :destroy
# This doesn't work, ActiveRecord tries to use the polymoriphic photographable
# relationship instead.
@@ -84,14 +83,6 @@ class Photo < ApplicationRecord
"#{title} by #{owner.login_name}"
end
def subject
title
end
def author
owner
end
def flickr_photo_id
source_id if source == 'flickr'
end

View File

@@ -8,7 +8,6 @@ class Planting < ApplicationRecord
include PredictPlanting
include PredictHarvest
include SearchPlantings
include Likeable
friendly_id :planting_slug, use: %i(slugged finders)
@@ -43,8 +42,7 @@ class Planting < ApplicationRecord
.where.not(gardens: { latitude: nil })
.where.not(gardens: { longitude: nil })
}
scope :active, -> { where(finished: false, failed: false).where('finished_at IS NULL OR finished_at < ?', Time.zone.now) }
scope :failed, -> { where(failed: true) }
scope :active, -> { where('finished <> true').where('finished_at IS NULL OR finished_at < ?', Time.zone.now) }
scope :annual, -> { joins(:crop).where(crops: { perennial: false }) }
scope :perennial, -> { joins(:crop).where(crops: { perennial: true }) }
scope :interesting, -> { has_photos.one_per_owner.order(planted_at: :desc) }
@@ -62,7 +60,6 @@ class Planting < ApplicationRecord
to: :crop, prefix: true
delegate :login_name, :slug, :location, to: :owner, prefix: true
delegate :slug, to: :planting, prefix: true
delegate :slug, :name, to: :garden, prefix: true
delegate :annual?, :perennial?, :svg_icon, to: :crop
delegate :location, :longitude, :latitude, to: :garden
@@ -73,7 +70,6 @@ class Planting < ApplicationRecord
validates :crop, presence: true, approved: { message: "must be present and exist in our database" }
validate :finished_must_be_after_planted
validate :owner_must_match_garden_owner
validate :cannot_be_finished_and_failed
validates :quantity, allow_nil: true, numericality: {
only_integer: true, greater_than_or_equal_to: 0
}
@@ -98,11 +94,7 @@ class Planting < ApplicationRecord
end
def finished?
(finished || (finished_at.present? && finished_at <= Time.zone.today)) && !failed?
end
def failed?
failed
finished || (finished_at.present? && finished_at <= Time.zone.today)
end
def planted?
@@ -126,10 +118,6 @@ class Planting < ApplicationRecord
private
def cannot_be_finished_and_failed
errors.add(:failed, "can't be true if planting is also finished") if finished && failed
end
# check that any finished_at date occurs after planted_at
def finished_must_be_after_planted
return unless planted_at && finished_at # only check if we have both
@@ -138,9 +126,6 @@ class Planting < ApplicationRecord
end
def owner_must_match_garden_owner
return if owner == garden.owner || garden.garden_collaborators.where(member_id: owner).any?
errors.add(:owner,
"must be the same as garden, or a collaborator on that garden")
errors.add(:owner, "must be the same as garden") unless owner == garden.owner
end
end

View File

@@ -3,7 +3,6 @@
class Post < ApplicationRecord
extend FriendlyId
include Likeable
friendly_id :author_date_subject, use: %i(slugged finders)
include PhotoCapable
@@ -11,10 +10,9 @@ class Post < ApplicationRecord
# Relationships
belongs_to :author, class_name: 'Member', inverse_of: :posts
belongs_to :forum, optional: true
has_many :comments, as: :commentable, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :crop_posts, dependent: :delete_all
has_many :crops, through: :crop_posts
has_many :notifications, as: :notifiable, dependent: :destroy
after_create :send_notification
#
@@ -97,7 +95,6 @@ class Post < ApplicationRecord
Notification.create(
recipient_id:,
sender_id: sender,
notifiable: self,
subject: "#{author} mentioned you in their post #{subject}",
body:
)

View File

@@ -13,7 +13,6 @@ module Api
attribute :slug
attribute :planted_at
attribute :failed
attribute :finished
attribute :finished_at
attribute :quantity
@@ -38,7 +37,9 @@ module Api
filter :finished
attribute :percentage_grown
delegate :percentage_grown, to: :@model
def percentage_grown
@model.percentage_grown
end
attribute :crop_name
attribute :crop_slug

View File

@@ -1,5 +1,5 @@
- if can?(:edit, activity)
%span.dropdown.activity-actions
.dropdown.activity-actions
%a#activity-actions-button.btn.btn-info.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-bs-toggle" => "dropdown", type: "button", href: '#'} Actions
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "planting-actions-button"}
= activity_edit_button(activity, classes: 'dropdown-item')

View File

@@ -6,6 +6,7 @@
%strong=yield :title
= bootstrap_form_for(@activity) do |f|
.card-body
= required_field_help_text
- if @activity.errors.any?
#error_explanation
%h2
@@ -39,15 +40,15 @@
= link_to "Add a planting.", new_planting_path
.col-md-4
= f.date_field :due_date,
= f.text_field :due_date,
value: @activity.due_date ? @activity.due_date.to_fs(:ymd) : '',
label: 'When?'
class: 'add-datepicker', label: 'When?'
%hr
.row
.col-md-6
= f.check_box :finished, label: t('buttons.mark_as_finished')
= f.check_box :finished, label: 'Mark as finished'
%span.help-block= t('.finish_helper')
.card-footer

View File

@@ -22,17 +22,19 @@
%small.text-muted= @activity.category
%tt
= @activity.due_date
- if @activity.description.present?
:markdown
#{strip_tags markdownify(@activity.description)}
= render 'likes/likes', object: @activity
= render 'activities/actions', activity: @activity
.col-md-4.col-xs-12
= render 'activities/owner', planting: @activity
.col-md-8.col-xs-12
- if @activity.description.present?
= cute_icon
.card
.card-header
%h2 Description
.card-body
:markdown
#{strip_tags markdownify(@activity.description)}
- if @activity.garden
%section.gardens
@@ -46,3 +48,4 @@
.col-md-4.col-xs-12
= render 'activities/actions', activity: @activity

View File

@@ -31,8 +31,7 @@
= f.label :name, class: 'control-label col-md-2'
.col-md-8
= f.text_field :name, class: 'form-control'
.col-md-8
= f.select :language, I18nData.languages.map {|code, name| [name.split(";").first, code] }, class: 'form-control'
.form-group
.form-actions.col-md-offset-2.col-md-8
= f.submit 'Save', class: 'btn btn-primary'

View File

@@ -1 +1 @@
#{link_to 'commented', event_model} on #{link_to event_model.commentable, event_model.commentable}
#{link_to 'commented', event_model} on #{link_to event_model.post, event_model.post}

View File

@@ -1,4 +1,3 @@
- @comment ||= Comment.new(commentable: @commentable)
.card.col-md-8.col-lg-7.mx-auto.float-none.white.z-depth-1.py-2.px-2
.card-body
- if content_for? :title
@@ -15,13 +14,13 @@
%li= msg
.md-form
= f.text_area :body, rows: 6, class: 'form-control md-textarea', autofocus: 'autofocus', required: true, pattern: '\w+'
= f.text_area :body, rows: 6, class: 'form-control md-textarea', autofocus: 'autofocus'
= f.label :body, "Your comment:"
%span.help-block
= render partial: "shared/markdown_help"
.actions.text-right
= f.submit 'Post comment', class: 'btn btn-primary'
.field
= f.hidden_field :commentable_id, value: @commentable.id
= f.hidden_field :commentable_type, value: @commentable.class.name
- if defined?(@post)
.field
= f.hidden_field :post_id, value: @post.id

View File

@@ -2,6 +2,6 @@
%p
Editing comment on
= link_to @comment.commentable.subject, @comment.commentable
= link_to @comment.post.subject, @comment.post
= render 'form', locals: { comment: @comment, commentable: @comment.commentable }
= render 'form'

View File

@@ -5,18 +5,17 @@
%link= comments_url
- @comments.each do |comment|
%item
%title Comment by #{comment.author.login_name} on #{comment.commentable.subject}
%title Comment by #{comment.author.login_name} on #{comment.post.subject}
%description
:escaped_markdown
<p>
Comment on
#{ link_to comment.commentable.subject, polymorphic_url(comment.commentable) }
#{ link_to comment.post.subject, post_url(comment.post) }
</p>
:escaped_markdown
#{ strip_tags markdownify(comment.body) }
%pubdate= comment.created_at.to_fs(:rfc822)
%link= polymorphic_url(comment.commentable)
%link= post_url(comment.post)
%guid= comment_url(comment)

View File

@@ -1,17 +1,11 @@
= content_for :title, "New comment"
- if @commentable.is_a?(Post)
%section.blog-post
.card.post{ id: "post-#{@commentable.id}" }
.card-header
%h2.display-3= @commentable.subject
.card-body= render "posts/single", post: @commentable || @comment.commentable, subject: true
- elsif @commentable.is_a?(Photo)
%section.blog-post
.card.photo{ id: "photo-#{@commentable.id}" }
.card-header
%h2.display-3= @commentable.subject
.card-body= render "photos/card", photo: @commentable || @comment.commentable, subject: true
= render partial: "comments/comments", locals: { commentable: @commentable || @comment.commentable }
%section.blog-post
.card.post{ id: "post-#{@post.id}" }
.card-header
%h2.display-3= @post.subject
.card-body= render "posts/single", post: @post || @comment.post, subject: true
= render 'form', locals: { comment: @comment, commentable: @commentable || @comment.commentable }
= render partial: "posts/comments", locals: { post: @post || @comment.post }
= render 'form'

View File

@@ -5,7 +5,7 @@
- if can? :edit, an
.dropdown.planting-actions
%a#crop-actions-altnames.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-bs-toggle" => "dropdown", :type => "button", :href => '#'}
= "#{an.name} (#{an.language})"
= an.name
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "crop-actions-altnames"}
- if can? :edit, an
= link_to edit_alternate_name_path(an), class: 'dropdown-item' do
@@ -16,7 +16,7 @@
= delete_icon
= t('.delete')
- else
.badge= "#{an.name} (#{an.language})"
.badge= an.name
%p.text-right

View File

@@ -3,6 +3,19 @@
html: { method: :put, class: 'form-horizontal' }) do |_f|
%br/
= render 'devise/shared/error_messages', resource: resource
.row
.col-md-12
%p
= image_tag "twitter_32.png", size: "32x32", alt: 'Twitter logo'
- if @twitter_auth
You are connected to Twitter as
= link_to @twitter_auth.name, "https://twitter.com/#{@twitter_auth.name}"
= link_to "Disconnect", @twitter_auth,
confirm: "Are you sure you want to remove this connection?",
method: :delete, class: "remove btn btn-danger"
- else
= link_to 'Connect to Twitter', '/members/auth/twitter', class: 'btn'
.row
.col-md-12
%p

View File

@@ -13,32 +13,7 @@
.form-group
= f.label :bio, class: 'control-label col-md-2'
.col-md-8
= f.text_area :bio, rows: 6, class: 'form-control', placeholder: "I'm am XYZ gardener interested in A, B, C"
.form-group
= f.label :website_url, 'Website', class: 'control-label col-md-2'
.col-md-8
= f.url_field :website_url, class: 'form-control', placeholder: "https://you.example.com/"
.form-group
= f.label :instagram_handle, 'Instagram', class: 'control-label col-md-2'
.col-md-8
= f.text_field :instagram_handle, class: 'form-control', placeholder: 'your_handle'
.form-group
= f.label :facebook_handle, 'Facebook', class: 'control-label col-md-2'
.col-md-8
= f.text_field :facebook_handle, class: 'form-control', placeholder: 'your_handle'
.form-group
= f.label :bluesky_handle, 'Bluesky', class: 'control-label col-md-2'
.col-md-8
= f.text_field :bluesky_handle, class: 'form-control', placeholder: 'your_handle'
.form-group
= f.label :other_url, 'Other URL', class: 'control-label col-md-2'
.col-md-8
= f.url_field :other_url, class: 'form-control', placeholder: "https://you.example.com/"
= f.text_area :bio, rows: 6, class: 'form-control'
.form-group
%label.control-label.col-md-2

View File

@@ -1,18 +0,0 @@
.card.col-md-8.col-lg-7.mx-auto.float-none.white.z-depth-1.py-2.px-2
= bootstrap_form_for(@garden_collaborator.new_record? ? [@garden, @garden_collaborator] : garden_garden_collaborator_path(@garden, @garden_collaborator)) do |f|
.card-body
- if @garden_collaborator.errors.any?
#error_explanation.alert.alert-warning{:role => "alert"}
%h4.alert-heading
= pluralize(@garden_collaborator.errors.size, "error")
prohibited this garden collaborator from being saved
%ul
- @garden_collaborator.errors.full_messages.each do |msg|
%li= msg
.alert.alert-info
Ask your friend, family member or community garden member for their growstuff username to add them as a collaborator on your garden.
= f.text_field :member_slug, maxlength: 255, required: true
.row
.card-footer
.text-right= f.submit 'Save Collaboator'

View File

@@ -1,3 +0,0 @@
- content_for :title, "Edit garden collaborator"
= render 'form'

View File

@@ -1,72 +0,0 @@
- content_for :title, "#{@garden} collaborators"
%h1= "#{@garden} collaborators"
- content_for :breadcrumbs do
%li.breadcrumb-item= link_to 'Gardens', gardens_path
%li.breadcrumb-item.active= link_to @garden, gardens_path(@garden)
.row
.col-md-2
- if current_member.present?
.flex-column.nav-pills.layout-nav{"role" => "tablist", "aria-orientation"=>"vertical"}
- if can?(:create, GardenCollaborator.new(garden: @garden))
= link_to url_for([@garden, GardenCollaborator.new(garden: @garden), action: :new]), class: 'btn' do
Add a #{GardenCollaborator.new(garden: @garden).model_name.human}
- else
= render 'shared/signin_signup', to: "record your #{model.to_s.pluralize.downcase}"
%hr/
%p.text-center
#{ENV['GROWSTUFF_SITE_NAME']} helps you track what you're
harvesting from your home garden and see how productive it is.
.col-md-10
- if @garden_collaborators.empty?
%p There are no collaborators to display.
- if can?(:create, GardenCollaborator) && @owner == current_member
= link_to 'Add a garden collaborator', new_garden_garden_collaborator_path, class: 'btn btn-primary'
- else
%section
%h2= page_entries_info @garden_collaborators
= will_paginate @garden_collaborators
- @garden_collaborators.each do |garden_collaborator|
- member = garden_collaborator.member
- cache member do
.card
.card-body
- if can?(:destroy, garden_collaborator)
%div{"style": "float: right"}
= link_to garden_garden_collaborator_path(@garden, garden_collaborator), method: :delete, class: "btn btn-danger" do
Remove access
%h4.login-name= link_to member, member
%div
= render "members/avatar", member: member
%div
= link_to "view all #{member}'s gardens", member_gardens_path(member)
%p
%small
Joined
= distance_of_time_in_words(member.created_at, Time.zone.now)
ago.
- if member.location.present?
= link_to member.location, place_path(member.location)
.card-footer
%ul.nav.nav-justified.small
%li.nav-item.border-right
= link_to member_plantings_path(member) do
= localize_plural(member.plantings.active, Planting)
%li.nav-item.border-right
= link_to member_harvests_path(member) do
= localize_plural(member.harvests, Harvest)
%li.nav-item
= link_to member_seeds_path(member) do
= localize_plural(member.seeds.active, Seed)
.row
.col-12= page_entries_info @garden_collaborators
.col-12= will_paginate @garden_collaborators

View File

@@ -1,3 +0,0 @@
- content_for :title, "New garden collaborator"
= render 'form'

View File

@@ -5,6 +5,7 @@
%h1.h2-responsive.text-center
%strong=yield :title
.card-body
= required_field_help_text
- if @garden.errors.any?
#error_explanation.alert.alert-warning{:role => "alert"}
%h4.alert-heading
@@ -15,7 +16,7 @@
%li= msg
= f.text_field :name, maxlength: 255, required: true
= f.text_area :description, rows: 6, placeholder: "Tell us about this garden - where is it located? What does it look like? Do you have a link to a photo? Do you have irrigation? What are your plans?"
= f.text_area :description, rows: 6
= f.text_field :location,
value: @garden.location || current_member.location,
class: 'form-control', maxlength: 255
@@ -26,7 +27,7 @@
- else
= link_to "Change your location.", edit_member_registration_path
.row
.col-md-5.col-12= f.number_field :area, class: 'input-small', step: "any", min: 0
.col-md-5.col-12= f.number_field :area, class: 'input-small', step: "any"
.col-md-7.col-12= f.select(:area_unit, Garden::AREA_UNITS_VALUES, { include_blank: false })
.col-12= f.select(:garden_type_id, GardenType.all.order(:name).pluck(:name, :id),
selected: @garden.garden_type_id, include_blank: true)

View File

@@ -31,7 +31,7 @@
%p
:markdown
#{strip_tags markdownify(@garden.description)}
- unless @garden.description.present?
- unless @garden.description
.row-fluid
%p No description available yet.
@@ -39,13 +39,8 @@
%p
Why not
= link_to 'tell us more.', edit_garden_path(@garden)
- else
- if can? :edit, @garden
%p
Did you want to
= link_to 'update this description.', edit_garden_path(@garden)
- if @garden.plantings.active.any?
- if @garden.plantings.where.not(planted_at: nil).any?
%section.card
%h2 Garden progress
.card-body
@@ -60,14 +55,6 @@
- else
.col-md-12
%p Nothing is currently planted here.
- if can?(:edit, @garden)
.col-md-12
= garden_plant_something_button(@garden)
- if can?(:destroy, @garden)
.dropdown-divider
= delete_button(@garden, classes: 'dropdown-item text-danger',
message: 'All plantings associated with this garden will also be deleted. Are you sure?')
%section
%h2 Current activities in garden
@@ -78,9 +65,6 @@
- else
.col-md-12
%p Nothing is currently planned here.
- if can?(:edit, @garden)
.col-md-12
= garden_plan_something_button(@garden)
- if @suggested_companions.any?
%section.companions
@@ -99,17 +83,6 @@
%p
%strong Owner:
= link_to @garden.owner, @garden.owner
%p
%strong Collaborators:
- if can?(:create, GardenCollaborator.new(garden: @garden))
= link_to "Manage", garden_garden_collaborators_path(@garden)
- if @garden.garden_collaborators.any?
%ul
- @garden.garden_collaborators.each do |collabator|
%li= link_to collabator.member, collabator.member
- else
None
- if @garden.location.present?
%p
%strong Location:

View File

@@ -1,5 +1,5 @@
- if can?(:edit, harvest)
%span.dropdown.harvest-actions
.dropdown.harvest-actions
%a#harvest-actions-button.btn.btn-info.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-bs-toggle" => "dropdown", type: "button", href: '#'} Actions
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "harvest-actions-button"}
= harvest_edit_button(harvest, classes: 'dropdown-item')

View File

@@ -7,6 +7,7 @@
= harvest_icon
%strong=yield :title
.card-body
= required_field_help_text
- if @harvest.errors.any?
#error_explanation
%h2 #{pluralize(@harvest.errors.size, "error")} prohibited this harvest from being saved:"
@@ -30,7 +31,8 @@
= link_to "Request new crops.", new_crop_path
.col-md-4
= f.date_field :harvested_at, value: @harvest.harvested_at ? @harvest.harvested_at.to_fs(:ymd) : '', label: 'When?'
= f.text_field :harvested_at, value: @harvest.harvested_at ? @harvest.harvested_at.to_fs(:ymd) : '',
class: 'add-datepicker', label: 'When?'
.col-12
= f.form_group :plant_part_id, label: { text: "Harvested Plant Part" } do
.row
@@ -42,7 +44,7 @@
-# http://blog.isotoma.com/2012/03/html5-input-typenumber-and-decimalsfloats-in-chrome/
.row
.col-md-4
= f.number_field :quantity, class: 'input-small form-control', step: 'any', label: 'How many?', min: 1
= f.number_field :quantity, class: 'input-small form-control', step: 'any', label: 'How many?'
.col-md-8
= f.select(:unit, Harvest::UNITS_VALUES, { include_blank: false }, class: 'input-medium form-control')
.row

View File

@@ -15,26 +15,13 @@
.harvest
.row
.col-md-8.col-xs-12
.jumbotron
.d-flex.justify-content-between
%h1.display-3
= harvest_icon
%strong= @harvest.crop
%small.text-muted
harvested by
= @harvest.owner
- if @harvest.description.present?
:markdown
#{strip_tags markdownify(@harvest.description)}
= render partial: 'planting'
= render 'likes/likes', object: @harvest
= render 'harvests/actions', harvest: @harvest
%h1
= harvest_icon
#{@harvest.crop} harvested by #{@harvest.owner}
.col-md-4.col-xs-12
= render 'harvests/owner', harvest: @harvest
= render 'harvests/actions', harvest: @harvest
.col-md-8.col-xs-12
= render partial: 'planting'
.index-cards.facts
- if @harvest.plant_part
.card
@@ -66,5 +53,14 @@
Havested from
= link_to @harvest.planting, @harvest.planting
- if @harvest.description.present?
.card
.card-header
%h2 Notes
.card-body
:markdown
#{strip_tags markdownify(@harvest.description)}
.col-md-4.col-xs-12
= render 'harvests/owner', harvest: @harvest
= render @harvest.crop

View File

@@ -51,8 +51,7 @@
%section.seeds
= cute_icon
= render 'seeds'
%p.text-right
= link_to "#{t('home.seeds.view_all')} »", seeds_path(tradeable_to: ['locally', 'nationally', 'internationally']), class: 'btn btn-block'
%p.text-right= link_to "#{t('home.seeds.view_all')} »", seeds_path, class: 'btn btn-block'
.col-12.col-lg-6
%section.discussion.text-center
= cute_icon

View File

@@ -1,4 +1,4 @@
%span.badge.like-badge{class: liked ? 'liked' : ''}
= like_icon
&nbsp;
%span.like-count{title: t('buttons.total_likes')}= likeable.likes_count
%span.like-count= likeable.likes_count

View File

@@ -1,18 +0,0 @@
%span.likes
- if member_signed_in? && can?(:new, Like)
- if !object.liked_by?(current_member)
= link_to likes_path(type: object.class.name, id: object.id, format: :json),
title: t('buttons.like'),
method: :post,
remote: true,
class: "#{object.class.name.downcase}-#{object.id} #{object.class.name.downcase}-like like-btn btn" do
= render 'likes/count', likeable: object, liked: false
- else
= link_to likes_path(type: object.class.name, id: object.id, format: :json),
title: t('buttons.unlike'),
method: :delete,
remote: true,
class: "#{object.class.name.downcase}-#{object.id} #{object.class.name.downcase}-like like-btn btn" do
= render 'likes/count', likeable: object, liked: true
- else
= render 'likes/count', likeable: object, liked: member_signed_in? && object.liked_by?(current_member)

View File

@@ -1 +1,13 @@
%h2 All about #{member.login_name}
%p
%small
%a{href: "#content"}
Skip to main content
- if member.bio.blank?
- if can? :edit, member
= link_to "Add a bio to complete your profile.", edit_member_registration_path
- else
#{member.login_name} hasn't written a bio yet.
- else
:markdown
#{ strip_tags markdownify(member.bio) }

View File

@@ -1,37 +1,17 @@
- if member.website_url.present? || member.instagram_handle.present? || member.facebook_handle.present? || member.bluesky_handle.present? || member.other_url.present? || flickr_auth || member.show_email
- if twitter_auth || flickr_auth || member.show_email
%h4 Contact
- if member.website_url.present?
- if twitter_auth
%p
= icon 'fas', 'globe', class: 'fa-fw'
= link_to "Website", member.website_url, target: '_blank', rel: 'noopener noreferrer'
- if member.instagram_handle.present?
%p
= icon 'fab', 'instagram', class: 'fa-fw'
= link_to member.instagram_handle, "https://instagram.com/#{member.instagram_handle}", target: '_blank', rel: 'noopener noreferrer'
- if member.facebook_handle.present?
%p
= icon 'fab', 'facebook', class: 'fa-fw'
= link_to member.facebook_handle, "https://facebook.com/#{member.facebook_handle}", target: '_blank', rel: 'noopener noreferrer'
- if member.bluesky_handle.present?
%p
= icon 'fas', 'comment-dots', class: 'fa-fw'
= link_to member.bluesky_handle, "https://bsky.app/profile/#{member.bluesky_handle}", target: '_blank', rel: 'noopener noreferrer'
- if member.other_url.present?
%p
= icon 'fas', 'link', class: 'fa-fw'
= link_to "More...", member.other_url, target: '_blank', rel: 'noopener noreferrer'
= image_tag "twitter_32.png", size: "32x32", alt: 'Twitter logo'
= link_to twitter_auth.name, "https://twitter.com/#{twitter_auth.name}"
- if flickr_auth
%p
= image_tag "flickr_32.png", size: "32x32", alt: 'Flickr logo'
= link_to flickr_auth.name, "https://flickr.com/photos/#{flickr_auth.uid}", target: '_blank', rel: 'noopener noreferrer'
= link_to flickr_auth.name, "https://flickr.com/photos/#{flickr_auth.uid}"
- if member.show_email
%p
= icon 'fas', 'envelope', class: 'fa-fw'
Email:
= mail_to member.email

View File

@@ -5,5 +5,5 @@
= link_to member.location, place_path(member.location, anchor: "members")
- else
.location-not-set
%h1 Location not known or geocodable
%p We can't show you what's nearby
.sr-only Location not known
.sr-only We can't show you what's nearby

View File

@@ -21,21 +21,6 @@
.row
.col= render "bio", member: @member
.col= render "avatar", member: @member
.row
.col
%p
%small
%a{href: "#content"}
Skip to main content
- if @member.bio.blank?
- if can? :edit, @member
= link_to "Add a bio to complete your profile.", edit_member_registration_path
- else
#{@member.login_name} hasn't written a bio yet.
- else
:markdown
#{ strip_tags markdownify(@member.bio) }
- if @member.roles.any?
%p
- @member.roles.each do |role|
@@ -45,16 +30,12 @@
= icon 'fas', 'map-marker'
= truncate(@member.location, length: 15, separator: ' ', omission: '... ')
%p
%small
%strong Member since
%br
= @member.created_at.to_fs(:date)
%strong Member since
= @member.created_at.to_fs(:date)
- if @member.last_sign_in_at
%p
%small
%strong Last Login
%br
= @member.last_sign_in_at&.to_fs(:default)
%strong Last Login
= @member.last_sign_in_at&.to_fs(:default)
- if can? :update, @member
= link_to edit_member_registration_path, class: 'btn btn-block' do
@@ -77,7 +58,8 @@
= render "stats", member: @member
.card-footer
= render "contact", member: @member, flickr_auth: @flickr_auth
= render "contact", member: @member, twitter_auth: @twitter_auth,
flickr_auth: @flickr_auth
.col-md-10#content
.row

View File

@@ -1,7 +1,7 @@
- if can?(:edit, @photo) && can?(:destroy, @photo)
.dropdown.float-right.photo-actions
%a#photo-actions-button.btn.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-bs-toggle" => "dropdown", type: "button", href: '#'} Actions
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "photo-actions-button"}
%a#harvest-actions-button.btn.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-bs-toggle" => "dropdown", type: "button", href: '#'} Actions
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "harvest-actions-button"}
= edit_button(edit_photo_path(@photo), classes: 'dropdown-item')
.dropdown-divider
= delete_button(@photo, classes: 'dropdown-item text-danger')

View File

@@ -28,12 +28,12 @@
= render 'crops/thumbnail', crop: crop
.col-md-3
%p
%span.btn= render 'photos/likes', photo: @photo
= render 'photos/actions', photo: @photo
= link_to @photo.link_url, class: 'btn btn-info' do
- if @photo.source == 'flickr'
= icon 'fab', 'flickr'
View on #{@photo.source.titleize}
%span.btn= render 'photos/likes', photo: @photo
- if @photo.date_taken.present?
%h3 Taken on #{I18n.l @photo.date_taken.to_date}
@@ -46,12 +46,4 @@
- else
= @photo.license_name
= render "associations", photo: @photo
.row
- if can? :create, Comment
= link_to new_comment_path(comment: { commentable_type: 'Photo', commentable_id: @photo.id }), class: 'btn' do
= icon 'fas', 'comment'
Comment
.row
.col-md-9
= render 'comments/comments', commentable: @photo
= render "associations", photo: @photo

View File

@@ -1,5 +1,5 @@
- if can?(:edit, planting)
%span.dropdown.planting-actions
.dropdown.planting-actions
%a#planting-actions-button.btn.btn-info.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-bs-toggle" => "dropdown", type: "button", href: '#'} Actions
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "planting-actions-button"}
= planting_edit_button(planting, classes: 'dropdown-item')
@@ -7,16 +7,7 @@
- if planting.active
= planting_plan_something_button(planting, classes: 'dropdown-item')
= planting_finish_button(planting, classes: 'dropdown-item')
= planting_failed_button(planting, classes: 'dropdown-item')
= planting_harvest_button(planting, classes: 'dropdown-item')
= planting_save_seeds_button(planting, classes: 'dropdown-item')
- if can?(:transplant, planting) && planting.active && transplantable_gardens_by_owner(planting).any?
.dropdown-divider
.px-2
= form_tag transplant_planting_path(planting), method: :post do
.form-group
= label_tag :garden_id, 'Transplant to:'
= select_tag :garden_id, options_from_collection_for_select(transplantable_gardens_by_owner(planting), :id, :name), class: 'form-control form-control-sm'
= submit_tag 'Transplant', class: 'btn btn-sm btn-primary mt-2'
.dropdown-divider
= delete_button(planting, classes: 'dropdown-item text-danger')

View File

@@ -19,7 +19,6 @@
- if planting.active
= planting_finish_button(planting, classes: 'dropdown-item')
= planting_failed_button(planting, classes: 'dropdown-item')
= planting_harvest_button(planting, classes: 'dropdown-item')
= planting_save_seeds_button(planting, classes: 'dropdown-item')
@@ -32,10 +31,7 @@
.text-center= render 'plantings/badges', planting: planting
= render 'plantings/progress', planting: planting
.card-footer
%small
Planted by
= link_to member_path(slug: planting.owner_slug), class: "owner-link" do
= planting.owner_login_name
in
= link_to garden_path(slug: planting.garden_slug), class: "garden-link" do
= planting.garden_name
.float-right
%span.chip.member-chip
= link_to member_path(slug: planting.owner_slug) do
= planting.owner_login_name

Some files were not shown because too many files have changed in this diff Show More