From 8cf0d0e67720922cf04e7b1583d78ab0b01ef2d5 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 10 Mar 2024 09:32:33 -0400 Subject: [PATCH 01/51] Ran: rails generate scaffold FieldSlip observation_id:integer project_id:integer identifier:string --- app/controllers/field_slips_controller.rb | 70 +++++++++++++++++++ app/helpers/field_slips_helper.rb | 2 + app/models/field_slip.rb | 2 + app/views/field_slips/_field_slip.html.erb | 17 +++++ .../field_slips/_field_slip.json.jbuilder | 2 + app/views/field_slips/_form.html.erb | 32 +++++++++ app/views/field_slips/edit.html.erb | 10 +++ app/views/field_slips/index.html.erb | 14 ++++ app/views/field_slips/index.json.jbuilder | 1 + app/views/field_slips/new.html.erb | 9 +++ app/views/field_slips/show.html.erb | 10 +++ app/views/field_slips/show.json.jbuilder | 1 + .../20240310132813_create_field_slips.rb | 11 +++ .../field_slips_controller_test.rb | 48 +++++++++++++ test/fixtures/field_slips.yml | 11 +++ test/models/field_slip_test.rb | 7 ++ test/system/field_slips_test.rb | 45 ++++++++++++ 17 files changed, 292 insertions(+) create mode 100644 app/controllers/field_slips_controller.rb create mode 100644 app/helpers/field_slips_helper.rb create mode 100644 app/models/field_slip.rb create mode 100644 app/views/field_slips/_field_slip.html.erb create mode 100644 app/views/field_slips/_field_slip.json.jbuilder create mode 100644 app/views/field_slips/_form.html.erb create mode 100644 app/views/field_slips/edit.html.erb create mode 100644 app/views/field_slips/index.html.erb create mode 100644 app/views/field_slips/index.json.jbuilder create mode 100644 app/views/field_slips/new.html.erb create mode 100644 app/views/field_slips/show.html.erb create mode 100644 app/views/field_slips/show.json.jbuilder create mode 100644 db/migrate/20240310132813_create_field_slips.rb create mode 100644 test/controllers/field_slips_controller_test.rb create mode 100644 test/fixtures/field_slips.yml create mode 100644 test/models/field_slip_test.rb create mode 100644 test/system/field_slips_test.rb diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb new file mode 100644 index 0000000000..0280a1dac5 --- /dev/null +++ b/app/controllers/field_slips_controller.rb @@ -0,0 +1,70 @@ +class FieldSlipsController < ApplicationController + before_action :set_field_slip, only: %i[ show edit update destroy ] + + # GET /field_slips or /field_slips.json + def index + @field_slips = FieldSlip.all + end + + # GET /field_slips/1 or /field_slips/1.json + def show + end + + # GET /field_slips/new + def new + @field_slip = FieldSlip.new + end + + # GET /field_slips/1/edit + def edit + end + + # POST /field_slips or /field_slips.json + def create + @field_slip = FieldSlip.new(field_slip_params) + + respond_to do |format| + if @field_slip.save + format.html { redirect_to field_slip_url(@field_slip), notice: "Field slip was successfully created." } + format.json { render :show, status: :created, location: @field_slip } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @field_slip.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /field_slips/1 or /field_slips/1.json + def update + respond_to do |format| + if @field_slip.update(field_slip_params) + format.html { redirect_to field_slip_url(@field_slip), notice: "Field slip was successfully updated." } + format.json { render :show, status: :ok, location: @field_slip } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @field_slip.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /field_slips/1 or /field_slips/1.json + def destroy + @field_slip.destroy! + + respond_to do |format| + format.html { redirect_to field_slips_url, notice: "Field slip was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_field_slip + @field_slip = FieldSlip.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def field_slip_params + params.require(:field_slip).permit(:observation_id, :project_id, :identifier) + end +end diff --git a/app/helpers/field_slips_helper.rb b/app/helpers/field_slips_helper.rb new file mode 100644 index 0000000000..e34335068e --- /dev/null +++ b/app/helpers/field_slips_helper.rb @@ -0,0 +1,2 @@ +module FieldSlipsHelper +end diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb new file mode 100644 index 0000000000..1566da1900 --- /dev/null +++ b/app/models/field_slip.rb @@ -0,0 +1,2 @@ +class FieldSlip < ApplicationRecord +end diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/field_slips/_field_slip.html.erb new file mode 100644 index 0000000000..383444dc8d --- /dev/null +++ b/app/views/field_slips/_field_slip.html.erb @@ -0,0 +1,17 @@ +
+

+ Observation: + <%= field_slip.observation_id %> +

+ +

+ Project: + <%= field_slip.project_id %> +

+ +

+ Identifier: + <%= field_slip.identifier %> +

+ +
diff --git a/app/views/field_slips/_field_slip.json.jbuilder b/app/views/field_slips/_field_slip.json.jbuilder new file mode 100644 index 0000000000..aa892c410e --- /dev/null +++ b/app/views/field_slips/_field_slip.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! field_slip, :id, :observation_id, :project_id, :identifier, :created_at, :updated_at +json.url field_slip_url(field_slip, format: :json) diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb new file mode 100644 index 0000000000..485c9ef810 --- /dev/null +++ b/app/views/field_slips/_form.html.erb @@ -0,0 +1,32 @@ +<%= form_with(model: field_slip) do |form| %> + <% if field_slip.errors.any? %> +
+

<%= pluralize(field_slip.errors.count, "error") %> prohibited this field_slip from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :observation_id, style: "display: block" %> + <%= form.number_field :observation_id %> +
+ +
+ <%= form.label :project_id, style: "display: block" %> + <%= form.number_field :project_id %> +
+ +
+ <%= form.label :identifier, style: "display: block" %> + <%= form.text_field :identifier %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/field_slips/edit.html.erb b/app/views/field_slips/edit.html.erb new file mode 100644 index 0000000000..a01a18affd --- /dev/null +++ b/app/views/field_slips/edit.html.erb @@ -0,0 +1,10 @@ +

Editing field slip

+ +<%= render "form", field_slip: @field_slip %> + +
+ +
+ <%= link_to "Show this field slip", @field_slip %> | + <%= link_to "Back to field slips", field_slips_path %> +
diff --git a/app/views/field_slips/index.html.erb b/app/views/field_slips/index.html.erb new file mode 100644 index 0000000000..de116a18ee --- /dev/null +++ b/app/views/field_slips/index.html.erb @@ -0,0 +1,14 @@ +

<%= notice %>

+ +

Field slips

+ +
+ <% @field_slips.each do |field_slip| %> + <%= render field_slip %> +

+ <%= link_to "Show this field slip", field_slip %> +

+ <% end %> +
+ +<%= link_to "New field slip", new_field_slip_path %> diff --git a/app/views/field_slips/index.json.jbuilder b/app/views/field_slips/index.json.jbuilder new file mode 100644 index 0000000000..4cf81e9115 --- /dev/null +++ b/app/views/field_slips/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @field_slips, partial: "field_slips/field_slip", as: :field_slip diff --git a/app/views/field_slips/new.html.erb b/app/views/field_slips/new.html.erb new file mode 100644 index 0000000000..eec5347fa1 --- /dev/null +++ b/app/views/field_slips/new.html.erb @@ -0,0 +1,9 @@ +

New field slip

+ +<%= render "form", field_slip: @field_slip %> + +
+ +
+ <%= link_to "Back to field slips", field_slips_path %> +
diff --git a/app/views/field_slips/show.html.erb b/app/views/field_slips/show.html.erb new file mode 100644 index 0000000000..0017610a0c --- /dev/null +++ b/app/views/field_slips/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @field_slip %> + +
+ <%= link_to "Edit this field slip", edit_field_slip_path(@field_slip) %> | + <%= link_to "Back to field slips", field_slips_path %> + + <%= button_to "Destroy this field slip", @field_slip, method: :delete %> +
diff --git a/app/views/field_slips/show.json.jbuilder b/app/views/field_slips/show.json.jbuilder new file mode 100644 index 0000000000..823c9b75cc --- /dev/null +++ b/app/views/field_slips/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "field_slips/field_slip", field_slip: @field_slip diff --git a/db/migrate/20240310132813_create_field_slips.rb b/db/migrate/20240310132813_create_field_slips.rb new file mode 100644 index 0000000000..39f4daa8c1 --- /dev/null +++ b/db/migrate/20240310132813_create_field_slips.rb @@ -0,0 +1,11 @@ +class CreateFieldSlips < ActiveRecord::Migration[7.1] + def change + create_table :field_slips do |t| + t.integer :observation_id + t.integer :project_id + t.string :identifier + + t.timestamps + end + end +end diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb new file mode 100644 index 0000000000..44daf2295c --- /dev/null +++ b/test/controllers/field_slips_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class FieldSlipsControllerTest < ActionDispatch::IntegrationTest + setup do + @field_slip = field_slips(:one) + end + + test "should get index" do + get field_slips_url + assert_response :success + end + + test "should get new" do + get new_field_slip_url + assert_response :success + end + + test "should create field_slip" do + assert_difference("FieldSlip.count") do + post field_slips_url, params: { field_slip: { identifier: @field_slip.identifier, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } + end + + assert_redirected_to field_slip_url(FieldSlip.last) + end + + test "should show field_slip" do + get field_slip_url(@field_slip) + assert_response :success + end + + test "should get edit" do + get edit_field_slip_url(@field_slip) + assert_response :success + end + + test "should update field_slip" do + patch field_slip_url(@field_slip), params: { field_slip: { identifier: @field_slip.identifier, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } + assert_redirected_to field_slip_url(@field_slip) + end + + test "should destroy field_slip" do + assert_difference("FieldSlip.count", -1) do + delete field_slip_url(@field_slip) + end + + assert_redirected_to field_slips_url + end +end diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml new file mode 100644 index 0000000000..8c6fbd4640 --- /dev/null +++ b/test/fixtures/field_slips.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + observation_id: 1 + project_id: 1 + identifier: MyString + +two: + observation_id: 1 + project_id: 1 + identifier: MyString diff --git a/test/models/field_slip_test.rb b/test/models/field_slip_test.rb new file mode 100644 index 0000000000..73a5d550ff --- /dev/null +++ b/test/models/field_slip_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class FieldSlipTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/field_slips_test.rb b/test/system/field_slips_test.rb new file mode 100644 index 0000000000..1f91f15e3c --- /dev/null +++ b/test/system/field_slips_test.rb @@ -0,0 +1,45 @@ +require "application_system_test_case" + +class FieldSlipsTest < ApplicationSystemTestCase + setup do + @field_slip = field_slips(:one) + end + + test "visiting the index" do + visit field_slips_url + assert_selector "h1", text: "Field slips" + end + + test "should create field slip" do + visit field_slips_url + click_on "New field slip" + + fill_in "Identifier", with: @field_slip.identifier + fill_in "Observation", with: @field_slip.observation_id + fill_in "Project", with: @field_slip.project_id + click_on "Create Field slip" + + assert_text "Field slip was successfully created" + click_on "Back" + end + + test "should update Field slip" do + visit field_slip_url(@field_slip) + click_on "Edit this field slip", match: :first + + fill_in "Identifier", with: @field_slip.identifier + fill_in "Observation", with: @field_slip.observation_id + fill_in "Project", with: @field_slip.project_id + click_on "Update Field slip" + + assert_text "Field slip was successfully updated" + click_on "Back" + end + + test "should destroy Field slip" do + visit field_slip_url(@field_slip) + click_on "Destroy this field slip", match: :first + + assert_text "Field slip was successfully destroyed" + end +end From 1d5c4ef739873debbb85cab1340ddb658c39a036 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Mon, 11 Mar 2024 18:50:14 -0400 Subject: [PATCH 02/51] Switch from identifier to code and add routes --- app/controllers/field_slips_controller.rb | 2 +- app/views/field_slips/_field_slip.html.erb | 4 ++-- app/views/field_slips/_field_slip.json.jbuilder | 2 +- app/views/field_slips/_form.html.erb | 4 ++-- config/routes.rb | 5 +++++ db/migrate/20240310132813_create_field_slips.rb | 2 +- db/schema.rb | 2 +- test/controllers/field_slips_controller_test.rb | 4 ++-- test/fixtures/field_slips.yml | 4 ++-- test/system/field_slips_test.rb | 4 ++-- 10 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index 0280a1dac5..cd57e7fc52 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -65,6 +65,6 @@ def set_field_slip # Only allow a list of trusted parameters through. def field_slip_params - params.require(:field_slip).permit(:observation_id, :project_id, :identifier) + params.require(:field_slip).permit(:observation_id, :project_id, :code) end end diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/field_slips/_field_slip.html.erb index 383444dc8d..8f43b4e675 100644 --- a/app/views/field_slips/_field_slip.html.erb +++ b/app/views/field_slips/_field_slip.html.erb @@ -10,8 +10,8 @@

- Identifier: - <%= field_slip.identifier %> + Code: + <%= field_slip.code %>

diff --git a/app/views/field_slips/_field_slip.json.jbuilder b/app/views/field_slips/_field_slip.json.jbuilder index aa892c410e..5d3fa43823 100644 --- a/app/views/field_slips/_field_slip.json.jbuilder +++ b/app/views/field_slips/_field_slip.json.jbuilder @@ -1,2 +1,2 @@ -json.extract! field_slip, :id, :observation_id, :project_id, :identifier, :created_at, :updated_at +json.extract! field_slip, :id, :observation_id, :project_id, :code, :created_at, :updated_at json.url field_slip_url(field_slip, format: :json) diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index 485c9ef810..6afddc9991 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -22,8 +22,8 @@
- <%= form.label :identifier, style: "display: block" %> - <%= form.text_field :identifier %> + <%= form.label :code, style: "display: block" %> + <%= form.text_field :code %>
diff --git a/config/routes.rb b/config/routes.rb index 4175fd9e02..c4bfdb74bf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -23,6 +23,7 @@ comments: {}, external_links: {}, external_sites: {}, + field_slips: {}, herbaria: {}, herbarium_records: {}, images: {}, @@ -40,6 +41,7 @@ comments: {}, external_links: {}, external_sites: {}, + field_slips: {}, herbaria: {}, herbarium_records: {}, images: {}, @@ -394,6 +396,9 @@ def route_actions_hash get("glossary_terms/:id/versions", to: "glossary_terms/versions#show", as: "glossary_term_versions") + # ----- Field Slip Records: standard actions -------------------------------- + resources :field_slips + # ----- Herbaria: standard actions ------------------------------------------- namespace :herbaria do resources :curator_requests, only: [:new, :create] diff --git a/db/migrate/20240310132813_create_field_slips.rb b/db/migrate/20240310132813_create_field_slips.rb index 39f4daa8c1..64d150ce04 100644 --- a/db/migrate/20240310132813_create_field_slips.rb +++ b/db/migrate/20240310132813_create_field_slips.rb @@ -3,7 +3,7 @@ def change create_table :field_slips do |t| t.integer :observation_id t.integer :project_id - t.string :identifier + t.string :code t.timestamps end diff --git a/db/schema.rb b/db/schema.rb index 198d4a8e96..0a627c9107 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -496,7 +496,7 @@ t.integer "project_id", null: false end - create_table "project_members", charset: "utf8mb3", force: :cascade do |t| + create_table "project_members", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.integer "project_id" t.integer "user_id" t.datetime "created_at", null: false diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index 44daf2295c..e8cafe60ae 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -17,7 +17,7 @@ class FieldSlipsControllerTest < ActionDispatch::IntegrationTest test "should create field_slip" do assert_difference("FieldSlip.count") do - post field_slips_url, params: { field_slip: { identifier: @field_slip.identifier, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } + post field_slips_url, params: { field_slip: { code: @field_slip.code, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } end assert_redirected_to field_slip_url(FieldSlip.last) @@ -34,7 +34,7 @@ class FieldSlipsControllerTest < ActionDispatch::IntegrationTest end test "should update field_slip" do - patch field_slip_url(@field_slip), params: { field_slip: { identifier: @field_slip.identifier, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } + patch field_slip_url(@field_slip), params: { field_slip: { code: @field_slip.code, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } assert_redirected_to field_slip_url(@field_slip) end diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index 8c6fbd4640..a9363b44c2 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -3,9 +3,9 @@ one: observation_id: 1 project_id: 1 - identifier: MyString + code: MyString two: observation_id: 1 project_id: 1 - identifier: MyString + code: MyString diff --git a/test/system/field_slips_test.rb b/test/system/field_slips_test.rb index 1f91f15e3c..edd4eeaf02 100644 --- a/test/system/field_slips_test.rb +++ b/test/system/field_slips_test.rb @@ -14,7 +14,7 @@ class FieldSlipsTest < ApplicationSystemTestCase visit field_slips_url click_on "New field slip" - fill_in "Identifier", with: @field_slip.identifier + fill_in "Code", with: @field_slip.code fill_in "Observation", with: @field_slip.observation_id fill_in "Project", with: @field_slip.project_id click_on "Create Field slip" @@ -27,7 +27,7 @@ class FieldSlipsTest < ApplicationSystemTestCase visit field_slip_url(@field_slip) click_on "Edit this field slip", match: :first - fill_in "Identifier", with: @field_slip.identifier + fill_in "Code", with: @field_slip.code fill_in "Observation", with: @field_slip.observation_id fill_in "Project", with: @field_slip.project_id click_on "Update Field slip" From b49ad4554c0ef4a6017126763d6820e8dd3c437e Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Mon, 11 Mar 2024 20:18:44 -0400 Subject: [PATCH 03/51] Add field_slips table --- db/schema.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 0a627c9107..4d5fb8a8f2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_03_07_020000) do +ActiveRecord::Schema[7.1].define(version: 2024_03_10_132813) do create_table "api_keys", id: :integer, charset: "utf8mb3", force: :cascade do |t| t.datetime "created_at", precision: nil t.datetime "last_used", precision: nil @@ -85,6 +85,14 @@ t.integer "project_id" end + create_table "field_slips", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.integer "observation_id" + t.integer "project_id" + t.string "code" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "glossary_term_images", charset: "utf8mb3", force: :cascade do |t| t.integer "image_id" t.integer "glossary_term_id" From 1cc330bdb03ff93220370310ad7bd5cdf0de611f Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Mon, 11 Mar 2024 20:32:37 -0400 Subject: [PATCH 04/51] Rubocop --- app/controllers/field_slips_controller.rb | 60 ++++++++++++------- app/helpers/field_slips_helper.rb | 2 + app/models/field_slip.rb | 2 + config/locales/en.txt | 10 ++++ .../20240310132813_create_field_slips.rb | 10 ++-- .../field_slips_controller_test.rb | 12 +++- test/models/field_slip_test.rb | 2 + test/system/field_slips_test.rb | 2 + 8 files changed, 71 insertions(+), 29 deletions(-) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index cd57e7fc52..1359645930 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + class FieldSlipsController < ApplicationController - before_action :set_field_slip, only: %i[ show edit update destroy ] + before_action :set_field_slip, only: [:show, :edit, :update, :destroy] # GET /field_slips or /field_slips.json def index @@ -7,8 +9,7 @@ def index end # GET /field_slips/1 or /field_slips/1.json - def show - end + def show; end # GET /field_slips/new def new @@ -16,8 +17,7 @@ def new end # GET /field_slips/1/edit - def edit - end + def edit; end # POST /field_slips or /field_slips.json def create @@ -25,11 +25,16 @@ def create respond_to do |format| if @field_slip.save - format.html { redirect_to field_slip_url(@field_slip), notice: "Field slip was successfully created." } - format.json { render :show, status: :created, location: @field_slip } + format.html do + redirect_to(field_slip_url(@field_slip), + notice: field_slip_created.t) + end + format.json { render(:show, status: :created, location: @field_slip) } else - format.html { render :new, status: :unprocessable_entity } - format.json { render json: @field_slip.errors, status: :unprocessable_entity } + format.html { render(:new, status: :unprocessable_entity) } + format.json do + render(json: @field_slip.errors, status: :unprocessable_entity) + end end end end @@ -38,11 +43,16 @@ def create def update respond_to do |format| if @field_slip.update(field_slip_params) - format.html { redirect_to field_slip_url(@field_slip), notice: "Field slip was successfully updated." } - format.json { render :show, status: :ok, location: @field_slip } + format.html do + redirect_to(field_slip_url(@field_slip), + notice: field_slip_updated.t) + end + format.json { render(:show, status: :ok, location: @field_slip) } else - format.html { render :edit, status: :unprocessable_entity } - format.json { render json: @field_slip.errors, status: :unprocessable_entity } + format.html { render(:edit, status: :unprocessable_entity) } + format.json do + render(json: @field_slip.errors, status: :unprocessable_entity) + end end end end @@ -52,19 +62,23 @@ def destroy @field_slip.destroy! respond_to do |format| - format.html { redirect_to field_slips_url, notice: "Field slip was successfully destroyed." } - format.json { head :no_content } + format.html do + redirect_to(field_slips_url, + notice: field_slip_destroyed.t) + end + format.json { head(:no_content) } end end private - # Use callbacks to share common setup or constraints between actions. - def set_field_slip - @field_slip = FieldSlip.find(params[:id]) - end - # Only allow a list of trusted parameters through. - def field_slip_params - params.require(:field_slip).permit(:observation_id, :project_id, :code) - end + # Use callbacks to share common setup or constraints between actions. + def set_field_slip + @field_slip = FieldSlip.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def field_slip_params + params.require(:field_slip).permit(:observation_id, :project_id, :code) + end end diff --git a/app/helpers/field_slips_helper.rb b/app/helpers/field_slips_helper.rb index e34335068e..9e83ab6111 100644 --- a/app/helpers/field_slips_helper.rb +++ b/app/helpers/field_slips_helper.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + module FieldSlipsHelper end diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index 1566da1900..3e1f7305ed 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class FieldSlip < ApplicationRecord end diff --git a/config/locales/en.txt b/config/locales/en.txt index 25d68d96b8..4799622a59 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -262,6 +262,10 @@ external_site: external site EXTERNAL_SITES: External Sites external_sites: external sites + FIELD_SLIP: Field Slip + field_slip: field slip + FIELD_SLIPS: Field Slips + field_slips: field groups IMAGE: Image image: image IMAGES: Images @@ -2737,6 +2741,12 @@ # visual_models/destroy destroy_visual_model_success: "[:VISUAL_MODEL] [:destroyed]" + + # Field Slips + field_slip_created: "Field slip was successfully created." + field_slip_updated: "Field slip was successfully updated." + field_slip_destoryed: "Field slip was successfully destroyed." + ############################################################################## # LESS POPULAR PAGES diff --git a/db/migrate/20240310132813_create_field_slips.rb b/db/migrate/20240310132813_create_field_slips.rb index 64d150ce04..f944ae6b18 100644 --- a/db/migrate/20240310132813_create_field_slips.rb +++ b/db/migrate/20240310132813_create_field_slips.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + class CreateFieldSlips < ActiveRecord::Migration[7.1] def change - create_table :field_slips do |t| - t.integer :observation_id - t.integer :project_id - t.string :code + create_table(:field_slips) do |t| + t.integer(:observation_id) + t.integer(:project_id) + t.string(:code) t.timestamps end diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index e8cafe60ae..ceae712db3 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class FieldSlipsControllerTest < ActionDispatch::IntegrationTest @@ -17,7 +19,10 @@ class FieldSlipsControllerTest < ActionDispatch::IntegrationTest test "should create field_slip" do assert_difference("FieldSlip.count") do - post field_slips_url, params: { field_slip: { code: @field_slip.code, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } + post field_slips_url, + params: { field_slip: { code: @field_slip.code, + observation_id: @field_slip.observation_id, + project_id: @field_slip.project_id } } end assert_redirected_to field_slip_url(FieldSlip.last) @@ -34,7 +39,10 @@ class FieldSlipsControllerTest < ActionDispatch::IntegrationTest end test "should update field_slip" do - patch field_slip_url(@field_slip), params: { field_slip: { code: @field_slip.code, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } } + patch field_slip_url(@field_slip), + params: { field_slip: { code: @field_slip.code, + observation_id: @field_slip.observation_id, + project_id: @field_slip.project_id } } assert_redirected_to field_slip_url(@field_slip) end diff --git a/test/models/field_slip_test.rb b/test/models/field_slip_test.rb index 73a5d550ff..2e931cbf29 100644 --- a/test/models/field_slip_test.rb +++ b/test/models/field_slip_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "test_helper" class FieldSlipTest < ActiveSupport::TestCase diff --git a/test/system/field_slips_test.rb b/test/system/field_slips_test.rb index edd4eeaf02..6f9728bc50 100644 --- a/test/system/field_slips_test.rb +++ b/test/system/field_slips_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "application_system_test_case" class FieldSlipsTest < ApplicationSystemTestCase From 4dea784ea7dc3a6180504088748610537473e4ed Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Mon, 11 Mar 2024 20:58:10 -0400 Subject: [PATCH 05/51] Enable field slip show to take a code and to take the user to the new field slip page with the appropriate code if the code doesn't exist yet. --- app/controllers/field_slips_controller.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index 1359645930..55cfb5731f 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class FieldSlipsController < ApplicationController - before_action :set_field_slip, only: [:show, :edit, :update, :destroy] + before_action :set_field_slip, only: [:edit, :update, :destroy] # GET /field_slips or /field_slips.json def index @@ -9,11 +9,19 @@ def index end # GET /field_slips/1 or /field_slips/1.json - def show; end + def show + if params[:id].match(/^\d+$/) + set_field_slip + else + @field_slip = FieldSlip.find_by(code: params[:id]) + end + redirect_to(new_field_slip_url(code: params[:id])) unless @field_slip + end # GET /field_slips/new def new @field_slip = FieldSlip.new + @field_slip.code = params[:code] if params.include?(:code) end # GET /field_slips/1/edit From 22c8d567a0c0d6faeb192d3c26187cc6bd28ce34 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Mon, 11 Mar 2024 21:08:55 -0400 Subject: [PATCH 06/51] Require login for FieldSlip actions other than show --- app/controllers/field_slips_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index 55cfb5731f..c15bfba875 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -2,6 +2,7 @@ class FieldSlipsController < ApplicationController before_action :set_field_slip, only: [:edit, :update, :destroy] + before_action :login_required, except: [:show] # GET /field_slips or /field_slips.json def index From fe453e1aea3ebb4a1e1697a2ea84f73119cfadf9 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Tue, 12 Mar 2024 07:50:20 -0400 Subject: [PATCH 07/51] Initial show field slips improvements --- app/models/field_slip.rb | 2 ++ app/views/field_slips/_field_slip.html.erb | 15 +++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index 3e1f7305ed..7978708794 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -1,4 +1,6 @@ # frozen_string_literal: true class FieldSlip < ApplicationRecord + belongs_to :observation + belongs_to :project end diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/field_slips/_field_slip.html.erb index 8f43b4e675..a769d8f483 100644 --- a/app/views/field_slips/_field_slip.html.erb +++ b/app/views/field_slips/_field_slip.html.erb @@ -1,17 +1,16 @@

Observation: - <%= field_slip.observation_id %> -

- -

+ <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %> +
Project: - <%= field_slip.project_id %> -

- -

+ <%= link_to_object(field_slip.project) %> +
Code: <%= field_slip.code %>

+ + <%= render(partial: "shared/matrix_box", + locals: { object: field_slip.observation }) %>
From 0589d1b98c5db7b115ca6e397bf683a8bd9c4441 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Thu, 14 Mar 2024 07:31:35 -0400 Subject: [PATCH 08/51] Add field_slip_prefix to Projects --- app/classes/api2/project_api.rb | 5 +++- app/classes/query/project_base.rb | 5 ++++ app/classes/query/project_pattern_search.rb | 3 ++- app/controllers/field_slips_controller.rb | 12 ++++----- app/controllers/projects_controller.rb | 3 ++- app/models/field_slip.rb | 6 +++++ app/models/project.rb | 26 +++++++++++++------ .../controllers/api2/_project.json.jbuilder | 1 + .../controllers/api2/_project.xml.builder | 1 + app/views/controllers/projects/_form.html.erb | 3 +++ app/views/controllers/projects/show.html.erb | 1 + config/locales/en.txt | 3 +++ .../20240310132813_create_field_slips.rb | 3 ++- db/schema.rb | 7 +++-- test/controllers/projects_controller_test.rb | 1 + test/fixtures/projects.yml | 3 +++ 16 files changed, 63 insertions(+), 20 deletions(-) diff --git a/app/classes/api2/project_api.rb b/app/classes/api2/project_api.rb index 12dcad5cf4..7a0438f232 100644 --- a/app/classes/api2/project_api.rb +++ b/app/classes/api2/project_api.rb @@ -43,6 +43,7 @@ def query_params has_summary: parse(:boolean, :has_summary), title_has: parse(:string, :title_has, help: 1), summary_has: parse(:string, :summary_has, help: 1), + field_slip_prefix_has: parse(:string, :field_slip_prefix_has, help: 1), comments_has: parse(:string, :comments_has, help: 1) } end @@ -52,6 +53,7 @@ def create_params { title: parse(:string, :title, limit: 100), summary: parse(:string, :summary, default: ""), + field_slip_prefix: parse(:string, :field_slip_prefix, default: ""), user: @user } end @@ -60,7 +62,8 @@ def update_params parse_update_params { title: parse(:string, :set_title, limit: 100, not_blank: true), - summary: parse(:string, :set_summary) + summary: parse(:string, :set_summary), + field_slip_prefix: parse(:string, :set_field_slip_prefix) } end diff --git a/app/classes/query/project_base.rb b/app/classes/query/project_base.rb index 0a8a73eb4e..294eb87a05 100644 --- a/app/classes/query/project_base.rb +++ b/app/classes/query/project_base.rb @@ -17,6 +17,7 @@ def parameter_declarations has_summary?: :boolean, title_has?: :string, summary_has?: :string, + field_slip_prefix_has?: :string, comments_has?: :string, member?: User ) @@ -59,6 +60,10 @@ def initialize_search_parameters "projects.summary", params[:summary_has] ) + add_search_condition( + "projects.field_slip_prefix", + params[:field_slip_prefix_has] + ) add_search_condition( "CONCAT(comments.summary,COALESCE(comments.comment,''))", params[:comments_has], diff --git a/app/classes/query/project_pattern_search.rb b/app/classes/query/project_pattern_search.rb index aff4d7ce11..b951128798 100644 --- a/app/classes/query/project_pattern_search.rb +++ b/app/classes/query/project_pattern_search.rb @@ -15,7 +15,8 @@ def initialize_flavor def search_fields "CONCAT(" \ "projects.title," \ - "COALESCE(projects.summary,'')" \ + "COALESCE(projects.summary,'')," \ + "COALESCE(projects.field_slip_prefix,'')" \ ")" end end diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index c15bfba875..5b7ff974f3 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -14,15 +14,15 @@ def show if params[:id].match(/^\d+$/) set_field_slip else - @field_slip = FieldSlip.find_by(code: params[:id]) + @field_slip = FieldSlip.find_by(code: params[:id].upcase) end - redirect_to(new_field_slip_url(code: params[:id])) unless @field_slip + redirect_to(new_field_slip_url(code: params[:id].upcase)) unless @field_slip end # GET /field_slips/new def new @field_slip = FieldSlip.new - @field_slip.code = params[:code] if params.include?(:code) + @field_slip.code = params[:code].upcase if params.include?(:code) end # GET /field_slips/1/edit @@ -36,7 +36,7 @@ def create if @field_slip.save format.html do redirect_to(field_slip_url(@field_slip), - notice: field_slip_created.t) + notice: :field_slip_created.t) end format.json { render(:show, status: :created, location: @field_slip) } else @@ -54,7 +54,7 @@ def update if @field_slip.update(field_slip_params) format.html do redirect_to(field_slip_url(@field_slip), - notice: field_slip_updated.t) + notice: :field_slip_updated.t) end format.json { render(:show, status: :ok, location: @field_slip) } else @@ -73,7 +73,7 @@ def destroy respond_to do |format| format.html do redirect_to(field_slips_url, - notice: field_slip_destroyed.t) + notice: :field_slip_destroyed.t) end format.json { head(:no_content) } end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 58ab03a813..df05e9b94e 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -102,6 +102,7 @@ def update upload_image_if_present @summary = params[:project][:summary] + @field_slip_prefix = params[:project][:field_slip_prefix] if valid_title && valid_where && valid_dates if @project.update(project_create_params) override_fixed_dates @@ -244,7 +245,7 @@ def show_selected_projects(query, args = {}) def project_create_params params.require(:project). - permit(:title, :summary, :open_membership, + permit(:title, :summary, :open_membership, :field_slip_prefix, "start_date(1i)", "start_date(2i)", "start_date(3i)", "end_date(1i)", "end_date(2i)", "end_date(3i)") end diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index 7978708794..bb0e08bf8d 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -3,4 +3,10 @@ class FieldSlip < ApplicationRecord belongs_to :observation belongs_to :project + + validates :code, uniqueness: true + + def code=(val) + self[:code] = val.upcase + end end diff --git a/app/models/project.rb b/app/models/project.rb index 06de5815b9..a1ed120ee2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -10,14 +10,15 @@ # # == Attributes # -# id:: Locally unique numerical id, starting at 1. -# created_at:: Date/time it was first created. -# updated_at:: Date/time it was last updated. -# user:: User that created it. -# admin_group:: UserGroup of admins. -# user_group:: UserGroup of members. -# title:: Title string. -# summary:: Summary of purpose. +# id:: Locally unique numerical id, starting at 1. +# created_at:: Date/time it was first created. +# updated_at:: Date/time it was last updated. +# user:: User that created it. +# admin_group:: UserGroup of admins. +# user_group:: UserGroup of members. +# title:: Title string. +# summary:: Summary of purpose. +# field_slip_prefix:: Prefix for associated field slip codes # open_membership Enable users to add themselves, disable shared editing # # == Methods @@ -74,6 +75,7 @@ class Project < AbstractModel # rubocop:disable Metrics/ClassLength has_many :species_lists, through: :project_species_lists before_destroy :orphan_drafts + validates :field_slip_prefix, uniqueness: true, allow_blank: true scope :show_includes, lambda { strict_loading.includes( @@ -91,6 +93,14 @@ def text_name title.to_s end + # Ensure that field_slip_prefix is uppercase and at most 60 + # characters so in the worst case the prefix plus 5 single byte + # characters is under 255 bytes (limit in SQL assuming all prefix + # characters are 4-byte unicode). + def field_slip_prefix=(val) + self[:field_slip_prefix] = val.strip.upcase[0, 60] + end + # Same as +text_name+ but with id tacked on to make unique. def unique_text_name "#{text_name} (#{id || "?"})" diff --git a/app/views/controllers/api2/_project.json.jbuilder b/app/views/controllers/api2/_project.json.jbuilder index aea0882d8c..9206c80476 100644 --- a/app/views/controllers/api2/_project.json.jbuilder +++ b/app/views/controllers/api2/_project.json.jbuilder @@ -4,6 +4,7 @@ json.id(object.id) json.type("project") json.title(object.title.to_s) json.summary(object.summary.to_s.tpl_nodiv) if object.summary.present? +json.title(object.field_slip_prefix.to_s) if object.field_slip_prefix.present? json.created_at(object.created_at.try(&:utc)) json.updated_at(object.updated_at.try(&:utc)) if detail diff --git a/app/views/controllers/api2/_project.xml.builder b/app/views/controllers/api2/_project.xml.builder index 8aa73f69e3..b05f0c623c 100644 --- a/app/views/controllers/api2/_project.xml.builder +++ b/app/views/controllers/api2/_project.xml.builder @@ -8,6 +8,7 @@ xml.tag!( ) do xml_string(xml, :title, object.title) xml_html_string(xml, :summary, object.summary.to_s.tpl_nodiv) + xml_string(xml, :field_slip_prefix, object.field_slip_prefix) xml_datetime(xml, :created_at, object.created_at) xml_datetime(xml, :updated_at, object.updated_at) if detail diff --git a/app/views/controllers/projects/_form.html.erb b/app/views/controllers/projects/_form.html.erb index 11e86bd301..f881c2fef4 100644 --- a/app/views/controllers/projects/_form.html.erb +++ b/app/views/controllers/projects/_form.html.erb @@ -12,6 +12,9 @@ <%= text_area_with_label(form: f, field: :summary, rows: 5, label: :SUMMARY.t + ":") %> + <%= text_field_with_label(form: f, field: :field_slip_prefix, + label: :FIELD_SLIP_PREFIX.t + ":") %> + <%= render(partial: "shared/textilize_help") %> <%= autocompleter_field(form: f, field: :place_name, label: :WHERE.t + ":", diff --git a/app/views/controllers/projects/show.html.erb b/app/views/controllers/projects/show.html.erb index c47e316a23..4ca5650ad5 100644 --- a/app/views/controllers/projects/show.html.erb +++ b/app/views/controllers/projects/show.html.erb @@ -29,6 +29,7 @@ add_project_banner(@project) <% end %>

<%= :show_project_created_at.t %>: <%= @project.created_at.web_date %>

+

<%= :show_project_field_slip_prefix.t %>: <%= @project.field_slip_prefix %>

<% if @project.observations.any? %> <%= link_to("#{@project.observations.length} #{:OBSERVATIONS.t}", diff --git a/config/locales/en.txt b/config/locales/en.txt index 4799622a59..89b9ca40d8 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -493,6 +493,8 @@ email_address: email address EMAIL_ADDRESSS: Email Addresses email_addresss: email addresses + FIELD_SLIP_PREFIX: Field Slip Prefix + field_slip_prefix: field slip prefix FULL_NAME: Full Name full_name: full name FULL_NAMES: Full Names @@ -3244,6 +3246,7 @@ show_project_destroy: Destroy Project show_project_drafts: Drafts show_project_edit: Edit Project + show_project_field_slip_prefix: Field Slip Prefix show_project_join: Join Project show_project_location: Location show_project_leave: Leave Project diff --git a/db/migrate/20240310132813_create_field_slips.rb b/db/migrate/20240310132813_create_field_slips.rb index f944ae6b18..3ddfa757f0 100644 --- a/db/migrate/20240310132813_create_field_slips.rb +++ b/db/migrate/20240310132813_create_field_slips.rb @@ -5,9 +5,10 @@ def change create_table(:field_slips) do |t| t.integer(:observation_id) t.integer(:project_id) - t.string(:code) + t.string(:code, null: false) t.timestamps end + add_index(:field_slips, :code, unique: true) end end diff --git a/db/schema.rb b/db/schema.rb index 4d5fb8a8f2..b385a34db7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_03_10_132813) do +ActiveRecord::Schema[7.1].define(version: 2024_03_12_231729) do create_table "api_keys", id: :integer, charset: "utf8mb3", force: :cascade do |t| t.datetime "created_at", precision: nil t.datetime "last_used", precision: nil @@ -88,9 +88,10 @@ create_table "field_slips", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.integer "observation_id" t.integer "project_id" - t.string "code" + t.string "code", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["code"], name: "index_field_slips_on_code", unique: true end create_table "glossary_term_images", charset: "utf8mb3", force: :cascade do |t| @@ -536,6 +537,8 @@ t.integer "image_id" t.date "start_date" t.date "end_date" + t.string "field_slip_prefix" + t.index ["field_slip_prefix"], name: "index_projects_on_field_slip_prefix", unique: true end create_table "publications", id: :integer, charset: "utf8mb3", force: :cascade do |t| diff --git a/test/controllers/projects_controller_test.rb b/test/controllers/projects_controller_test.rb index 5b2f57d5ee..026dd3bc28 100644 --- a/test/controllers/projects_controller_test.rb +++ b/test/controllers/projects_controller_test.rb @@ -11,6 +11,7 @@ def build_params( project: { title: title, summary: summary, + field_slip_prefix: "", place_name: "", open_membership: false, "start_date(1i)" => start_date&.year, diff --git a/test/fixtures/projects.yml b/test/fixtures/projects.yml index f459f71217..a2a82d7486 100644 --- a/test/fixtures/projects.yml +++ b/test/fixtures/projects.yml @@ -21,6 +21,7 @@ eol_project: admin_group: eol_admins title: EOL Project summary: Project to make names for EOL + field_slip_prefix: EOL created_at: 2008-09-24 21:33:30 updated_at: 2008-09-24 21:33:30 open_membership: false @@ -39,6 +40,7 @@ bolete_project: admin_group: bolete_admins title: Bolete Project summary: Project about Boletes + field_slip_prefix: BLT created_at: 2008-09-25 07:00:50 updated_at: 2008-09-25 07:00:55 images: in_situ_image, turned_over_image @@ -73,6 +75,7 @@ open_membership_project: admin_group: burbank_admins title: Burbank Project summary: Project about Fungi of Burbank + field_slip_prefix: BURB created_at: 2008-09-25 07:00:50 updated_at: 2008-09-25 07:00:55 observations: owner_accepts_general_questions, unknown_with_lat_long, trusted_hidden, untrusted_hidden, reused_observation From f3b1b7441361e0a0cbab13f36e28b0ffe08e1793 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Fri, 15 Mar 2024 08:26:25 -0400 Subject: [PATCH 09/51] Allow for empty string input for field_slip_prefix --- app/models/project.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index a1ed120ee2..3f5e036df2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -98,7 +98,9 @@ def text_name # characters is under 255 bytes (limit in SQL assuming all prefix # characters are 4-byte unicode). def field_slip_prefix=(val) - self[:field_slip_prefix] = val.strip.upcase[0, 60] + self[:field_slip_prefix] = if val && val.strip != "" + val.strip.upcase[0, 60] + end end # Same as +text_name+ but with id tacked on to make unique. From 0bede7bd4289f3bc100a8cf5e884b312664b8078 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Fri, 15 Mar 2024 08:27:17 -0400 Subject: [PATCH 10/51] Field slip ERB and language tag cleanup --- app/views/field_slips/_form.html.erb | 7 +++++-- app/views/field_slips/index.html.erb | 6 +++--- app/views/field_slips/show.html.erb | 8 ++++---- config/locales/en.txt | 15 ++++++++++++--- test/controllers/field_slips_controller_test.rb | 2 +- test/fixtures/field_slips.yml | 8 ++++---- 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index 6afddc9991..e562bcb0a4 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -1,7 +1,10 @@ <%= form_with(model: field_slip) do |form| %> <% if field_slip.errors.any? %> -

-

<%= pluralize(field_slip.errors.count, "error") %> prohibited this field_slip from being saved:

+
+

+ <%= "#{pluralize(field_slip.errors.count, + :error.t, plural: :errors.t)} #{:field_slip_errors.t}" %> +

    <% field_slip.errors.each do |error| %> diff --git a/app/views/field_slips/index.html.erb b/app/views/field_slips/index.html.erb index de116a18ee..e477bcda2e 100644 --- a/app/views/field_slips/index.html.erb +++ b/app/views/field_slips/index.html.erb @@ -1,4 +1,4 @@ -

    <%= notice %>

    +

    <%= notice %>

    Field slips

    @@ -6,9 +6,9 @@ <% @field_slips.each do |field_slip| %> <%= render field_slip %>

    - <%= link_to "Show this field slip", field_slip %> + <%= link_to :field_slip_show.t, field_slip %>

    <% end %>
-<%= link_to "New field slip", new_field_slip_path %> +<%= link_to :field_slip_new.t, new_field_slip_path %> diff --git a/app/views/field_slips/show.html.erb b/app/views/field_slips/show.html.erb index 0017610a0c..2f4a97d32e 100644 --- a/app/views/field_slips/show.html.erb +++ b/app/views/field_slips/show.html.erb @@ -1,10 +1,10 @@ -

<%= notice %>

+

<%= notice %>

<%= render @field_slip %>
- <%= link_to "Edit this field slip", edit_field_slip_path(@field_slip) %> | - <%= link_to "Back to field slips", field_slips_path %> + <%= link_to :field_slip_edit.t, edit_field_slip_path(@field_slip) %> | + <%= link_to :field_slip_index.t, field_slips_path %> - <%= button_to "Destroy this field slip", @field_slip, method: :delete %> + <%= button_to :field_slip_destroy.t, @field_slip, method: :delete %>
diff --git a/config/locales/en.txt b/config/locales/en.txt index 89b9ca40d8..6b7dc7ea39 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -254,6 +254,8 @@ draft: draft DRAFTS: Drafts drafts: drafts + error: error + errors: errors EXTERNAL_LINK: External Link external_link: external link EXTERNAL_LINKS: External Links @@ -2745,9 +2747,15 @@ # Field Slips - field_slip_created: "Field slip was successfully created." - field_slip_updated: "Field slip was successfully updated." - field_slip_destoryed: "Field slip was successfully destroyed." + field_slip_created: Field slip was successfully created. + field_slip_updated: Field slip was successfully updated. + field_slip_destroyed: Field slip was successfully destroyed. + field_slip_errors: "prohibited this field_slip from being saved:" + field_slip_show: Show this field slip + field_slip_new: New field slip + field_slip_edit: Edit this field slip + field_slip_index: Back to field slips + field_slip_destroy: Destroy this field slip ############################################################################## @@ -4107,6 +4115,7 @@ api_help_create_key: if you pass in your app name here it will create an api key for the user for your app to use api_help_creator: creator api_help_east: max longitude + api_help_field_slip_prefix_has: search within field slip prefix api_help_first_user: creator / first to use api_help_has_notes_field: is given observation notes template field filled in? api_help_has_obs_notes: observation has notes? diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index ceae712db3..9030ee0530 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -4,7 +4,7 @@ class FieldSlipsControllerTest < ActionDispatch::IntegrationTest setup do - @field_slip = field_slips(:one) + @field_slip = field_slips(:field_slip_one) end test "should get index" do diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index a9363b44c2..3ec09b53de 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -1,11 +1,11 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -one: +field_slip_one: observation_id: 1 project_id: 1 - code: MyString + code: MOTEST-0001 -two: +field_slip_two: observation_id: 1 project_id: 1 - code: MyString + code: MOTEST-0002 From 8f5b0614d070158e699a2e82b6bc8fc99a534342 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Fri, 15 Mar 2024 08:27:52 -0400 Subject: [PATCH 11/51] Add field_slip_prefix migration --- .../20240312231729_add_field_slip_prefix_to_projects.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 db/migrate/20240312231729_add_field_slip_prefix_to_projects.rb diff --git a/db/migrate/20240312231729_add_field_slip_prefix_to_projects.rb b/db/migrate/20240312231729_add_field_slip_prefix_to_projects.rb new file mode 100644 index 0000000000..d82c3d1a65 --- /dev/null +++ b/db/migrate/20240312231729_add_field_slip_prefix_to_projects.rb @@ -0,0 +1,6 @@ +class AddFieldSlipPrefixToProjects < ActiveRecord::Migration[7.1] + def change + add_column :projects, :field_slip_prefix, :string + add_index(:projects, :field_slip_prefix, unique: true) + end +end From f5ecc8e2367cae8593b3441d34cb15963b5f9aff Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Fri, 15 Mar 2024 20:12:00 -0400 Subject: [PATCH 12/51] Test the tests passing --- app/views/field_slips/_field_slip.html.erb | 16 +++++---- config/locales/en.txt | 2 ++ .../field_slips_controller_test.rb | 35 ++++++++++++------- test/fixtures/field_slips.yml | 8 ++--- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/field_slips/_field_slip.html.erb index a769d8f483..fcaba9a19a 100644 --- a/app/views/field_slips/_field_slip.html.erb +++ b/app/views/field_slips/_field_slip.html.erb @@ -1,16 +1,20 @@

Observation: - <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %> + <% if field_slip.observation %> + <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %> + <% else %> + <%= :field_slip_no_observation.t %> + <% end %>
Project: - <%= link_to_object(field_slip.project) %> + <% if field_slip.project %> + <%= link_to_object(field_slip.project) %> + <% else %> + <%= :field_slip_no_project.t %> + <% end %>
Code: <%= field_slip.code %>

- - - <%= render(partial: "shared/matrix_box", - locals: { object: field_slip.observation }) %>
diff --git a/config/locales/en.txt b/config/locales/en.txt index 6b7dc7ea39..53a2265081 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2756,6 +2756,8 @@ field_slip_edit: Edit this field slip field_slip_index: Back to field slips field_slip_destroy: Destroy this field slip + field_slip_no_observation: Observation not found + field_slip_no_project: Project not found ############################################################################## diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index 9030ee0530..b823fdfe36 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -2,53 +2,62 @@ require "test_helper" -class FieldSlipsControllerTest < ActionDispatch::IntegrationTest +class FieldSlipsControllerTest < FunctionalTestCase setup do @field_slip = field_slips(:field_slip_one) end test "should get index" do - get field_slips_url + requires_login(:index) assert_response :success end test "should get new" do - get new_field_slip_url + requires_login(:new) assert_response :success end test "should create field_slip" do + login assert_difference("FieldSlip.count") do - post field_slips_url, - params: { field_slip: { code: @field_slip.code, - observation_id: @field_slip.observation_id, - project_id: @field_slip.project_id } } + post(:create, + params: { + field_slip: { + code: "X#{@field_slip.code}", + observation: observations(:coprinus_comatus_obs), + project: projects(:eol_project) + } + }) end assert_redirected_to field_slip_url(FieldSlip.last) end test "should show field_slip" do - get field_slip_url(@field_slip) + get(:show, params: { id: @field_slip.id }) assert_response :success end test "should get edit" do - get edit_field_slip_url(@field_slip) + login + get(:edit, params: { id: @field_slip.id }) assert_response :success end test "should update field_slip" do - patch field_slip_url(@field_slip), - params: { field_slip: { code: @field_slip.code, + login + patch(:update, + params: { id: @field_slip.id, + field_slip: { code: @field_slip.code, observation_id: @field_slip.observation_id, - project_id: @field_slip.project_id } } + project_id: @field_slip.project_id } }) assert_redirected_to field_slip_url(@field_slip) end test "should destroy field_slip" do + login assert_difference("FieldSlip.count", -1) do - delete field_slip_url(@field_slip) + delete(:destroy, params: { id: @field_slip.id }) end assert_redirected_to field_slips_url diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index 3ec09b53de..2f6e6912bc 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -1,11 +1,11 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html field_slip_one: - observation_id: 1 - project_id: 1 + observation: minimal_unknown_obs + project: eol_project code: MOTEST-0001 field_slip_two: - observation_id: 1 - project_id: 1 + observation_id: detailed_unknown_obs + project_id: eol_project code: MOTEST-0002 From 17206a9e7bc9fda1d8e32bfe910aaa114a9bf653 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 16 Mar 2024 08:00:46 -0400 Subject: [PATCH 13/51] Avoid showing a success box if there are no notices --- app/views/field_slips/index.html.erb | 4 +++- app/views/field_slips/show.html.erb | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/views/field_slips/index.html.erb b/app/views/field_slips/index.html.erb index e477bcda2e..897883a1e6 100644 --- a/app/views/field_slips/index.html.erb +++ b/app/views/field_slips/index.html.erb @@ -1,4 +1,6 @@ -

<%= notice %>

+<% if notice %> +

<%= notice %>

+<% end %>

Field slips

diff --git a/app/views/field_slips/show.html.erb b/app/views/field_slips/show.html.erb index 2f4a97d32e..46d00decaa 100644 --- a/app/views/field_slips/show.html.erb +++ b/app/views/field_slips/show.html.erb @@ -1,4 +1,6 @@ -

<%= notice %>

+<% if notice %> +

<%= notice %>

+<% end %> <%= render @field_slip %> From beacedfb83cfd41b42cfaee6e6548b1869e3ba75 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 16 Mar 2024 09:00:59 -0400 Subject: [PATCH 14/51] Coverage and edge cases --- app/models/field_slip.rb | 6 +++ .../controllers/visual_models/_form.html.erb | 4 +- app/views/field_slips/_form.html.erb | 7 +-- config/locales/en.txt | 15 +++--- .../field_slips_controller_test.rb | 53 +++++++++++++++++++ 5 files changed, 72 insertions(+), 13 deletions(-) diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index bb0e08bf8d..78e9a053b3 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -5,6 +5,12 @@ class FieldSlip < ApplicationRecord belongs_to :project validates :code, uniqueness: true + validates :code, presence: true + validate do |field_slip| + unless field_slip.code.match(/[^\d.-]/) + errors.add :code, :format, message: :field_slip_code_format_error.t + end + end def code=(val) self[:code] = val.upcase diff --git a/app/views/controllers/visual_models/_form.html.erb b/app/views/controllers/visual_models/_form.html.erb index c3d0884057..5caf2e75f2 100644 --- a/app/views/controllers/visual_models/_form.html.erb +++ b/app/views/controllers/visual_models/_form.html.erb @@ -1,8 +1,8 @@ <%= form_with(model: visual_model) do |f| %> <% if visual_model.errors.any? %>
-

<%= pluralize(visual_model.errors.count, "error") %> prohibited this visual_model from being saved:

- + <%= "#{pluralize(visual_model.errors.count, + :error.t, plural: :errors.t)} #{:visual_model_errors.t}" %>:
    <% visual_model.errors.each do |error| %>
  • <%= error.full_message %>
  • diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index e562bcb0a4..acba6395e3 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -1,11 +1,8 @@ <%= form_with(model: field_slip) do |form| %> <% if field_slip.errors.any? %>
    -

    - <%= "#{pluralize(field_slip.errors.count, - :error.t, plural: :errors.t)} #{:field_slip_errors.t}" %> -

    - + <%= "#{pluralize(field_slip.errors.count, + :error.t, plural: :errors.t)} #{:field_slip_errors.t}" %>:
      <% field_slip.errors.each do |error| %>
    • <%= error.full_message %>
    • diff --git a/config/locales/en.txt b/config/locales/en.txt index 53a2265081..18f7cf8805 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2742,22 +2742,25 @@ show_visual_model_edit: "[:EDIT] [:VISUAL_MODEL]" show_visual_model_index: "[:VISUAL_MODEL] [:INDEX]" + # Visual Models + visual_model_errors: prohibited this visual_model from being saved + # visual_models/destroy destroy_visual_model_success: "[:VISUAL_MODEL] [:destroyed]" - # Field Slips + field_slip_code_format_error: code must have non-numeric characters other than period (.) and dash (-) field_slip_created: Field slip was successfully created. - field_slip_updated: Field slip was successfully updated. + field_slip_destroy: Destroy this field slip field_slip_destroyed: Field slip was successfully destroyed. - field_slip_errors: "prohibited this field_slip from being saved:" - field_slip_show: Show this field slip - field_slip_new: New field slip field_slip_edit: Edit this field slip + field_slip_errors: prohibited this field_slip from being saved field_slip_index: Back to field slips - field_slip_destroy: Destroy this field slip + field_slip_new: New field slip field_slip_no_observation: Observation not found field_slip_no_project: Project not found + field_slip_show: Show this field slip + field_slip_updated: Field slip was successfully updated. ############################################################################## diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index b823fdfe36..23d405804f 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -33,11 +33,43 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_redirected_to field_slip_url(FieldSlip.last) end + test "should fail to create field_slip" do + login + post(:create, + params: { + field_slip: { + code: "#{@field_slip.code}", + observation: observations(:coprinus_comatus_obs), + project: projects(:eol_project) + } + }) + assert_response 422 + end + + test "json should fail to create field_slip" do + login + post(:create, + format: :json, + params: { + field_slip: { + code: "#{@field_slip.code}", + observation: observations(:coprinus_comatus_obs), + project: projects(:eol_project) + } + }) + assert_response 422 + end + test "should show field_slip" do get(:show, params: { id: @field_slip.id }) assert_response :success end + test "should show field_slip by code" do + get(:show, params: { id: @field_slip.code }) + assert_response :success + end + test "should get edit" do login get(:edit, params: { id: @field_slip.id }) @@ -54,6 +86,27 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_redirected_to field_slip_url(@field_slip) end + test "should fail to update field_slip" do + login + patch(:update, + params: { id: @field_slip.id, + field_slip: { code: "-3.14", + observation_id: @field_slip.observation_id, + project_id: @field_slip.project_id } }) + assert_response 422 + end + + test "json should fail to update field_slip" do + login + patch(:update, + format: :json, + params: { id: @field_slip.id, + field_slip: { code: "-3.14", + observation_id: @field_slip.observation_id, + project_id: @field_slip.project_id } }) + assert_response 422 + end + test "should destroy field_slip" do login assert_difference("FieldSlip.count", -1) do From f4e5006bb84930dc363dbfb39968ca28a2af9cf2 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 16 Mar 2024 09:34:50 -0400 Subject: [PATCH 15/51] Hookup a FieldSlip to a Project based on the field slip prefix --- app/models/field_slip.rb | 6 ++++++ test/controllers/field_slips_controller_test.rb | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index 78e9a053b3..72e0256570 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -14,5 +14,11 @@ class FieldSlip < ApplicationRecord def code=(val) self[:code] = val.upcase + unless project + prefix_match = code.match(/(^.+)[ -]\d+$/) + if prefix_match + self.project = Project.find_by(field_slip_prefix: prefix_match[1]) + end + end end end diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index 23d405804f..e44bf6a6ba 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -33,6 +33,22 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_redirected_to field_slip_url(FieldSlip.last) end + test "should create field_slip in project from code" do + login + project = projects(:eol_project) + code = "#{project.field_slip_prefix}-1234" + assert_difference("FieldSlip.count") do + post(:create, + params: { + field_slip: { + code: code + } + }) + end + field_slip = FieldSlip.find_by(code: code) + assert_equal(field_slip.project, project) + end + test "should fail to create field_slip" do login post(:create, From 74da15b7b215c08e7e4740dc887b63639a9debfa Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 17 Mar 2024 15:52:43 -0400 Subject: [PATCH 16/51] /qr/ route for field_slips#show --- config/routes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/routes.rb b/config/routes.rb index 4fba5a6416..a9f05ef596 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -398,6 +398,7 @@ def route_actions_hash # ----- Field Slip Records: standard actions -------------------------------- resources :field_slips + get("qr/:id", to: "field_slips#show", id: /.*[^\d].*/) # ----- Herbaria: standard actions ------------------------------------------- namespace :herbaria do From a63eeb3cf45fb4f8aebb62ea2166f3cdf171b928 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 17 Mar 2024 15:55:06 -0400 Subject: [PATCH 17/51] Add . and - to qr regex --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index a9f05ef596..f9d3083f3c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -398,7 +398,7 @@ def route_actions_hash # ----- Field Slip Records: standard actions -------------------------------- resources :field_slips - get("qr/:id", to: "field_slips#show", id: /.*[^\d].*/) + get("qr/:id", to: "field_slips#show", id: /.*[^\d.-].*/) # ----- Herbaria: standard actions ------------------------------------------- namespace :herbaria do From 56232dbd86150dfd76774733dd5dadafbaf180ac Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Tue, 19 Mar 2024 21:22:19 -0400 Subject: [PATCH 18/51] Add Field Slip to Observation#show page --- app/models/field_slip.rb | 22 +++++++++++-------- app/models/observation.rb | 8 +++++-- .../show/_observation_details.erb | 14 ++++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index 72e0256570..fa21fb6dcd 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -1,24 +1,28 @@ # frozen_string_literal: true -class FieldSlip < ApplicationRecord +class FieldSlip < AbstractModel belongs_to :observation belongs_to :project validates :code, uniqueness: true validates :code, presence: true validate do |field_slip| - unless field_slip.code.match(/[^\d.-]/) - errors.add :code, :format, message: :field_slip_code_format_error.t + unless field_slip.code.match?(/[^\d.-]/) + errors.add(:code, :format, message: :field_slip_code_format_error.t) end end def code=(val) self[:code] = val.upcase - unless project - prefix_match = code.match(/(^.+)[ -]\d+$/) - if prefix_match - self.project = Project.find_by(field_slip_prefix: prefix_match[1]) - end - end + return if project + + prefix_match = code.match(/(^.+)[ -]\d+$/) + return unless prefix_match + + self.project = Project.find_by(field_slip_prefix: prefix_match[1]) + end + + def title + code end end diff --git a/app/models/observation.rb b/app/models/observation.rb index 4ea81e7c84..d2c2d68c30 100644 --- a/app/models/observation.rb +++ b/app/models/observation.rb @@ -199,6 +199,7 @@ class Observation < AbstractModel # rubocop:disable Metrics/ClassLength has_many :observation_collection_numbers, dependent: :destroy has_many :collection_numbers, through: :observation_collection_numbers + has_many :field_slips, dependent: :destroy has_many :observation_herbarium_records, dependent: :destroy has_many :herbarium_records, through: :observation_herbarium_records @@ -503,6 +504,7 @@ class Observation < AbstractModel # rubocop:disable Metrics/ClassLength scope :show_includes, lambda { strict_loading.includes( :collection_numbers, + :field_slips, { comments: :user }, { external_links: { external_site: { project: :user_group } } }, { herbarium_records: [{ herbarium: :curators }, :user] }, @@ -1076,8 +1078,9 @@ def add_image(img) def remove_image(img) if images.include?(img) || thumb_image_id == img.id images.delete(img) - update(thumb_image: images.empty? ? nil : images.first) \ - if thumb_image_id == img.id + if thumb_image_id == img.id + update(thumb_image: images.empty? ? nil : images.first) + end notify_users(:removed_image) end img @@ -1105,6 +1108,7 @@ def turn_off_specimen_if_no_more_records return unless collection_numbers.empty? return unless herbarium_records.empty? return unless sequences.empty? + return unless field_slips.empty? update(specimen: false) end diff --git a/app/views/controllers/observations/show/_observation_details.erb b/app/views/controllers/observations/show/_observation_details.erb index e78db2ae9b..b2ebdf8d39 100644 --- a/app/views/controllers/observations/show/_observation_details.erb +++ b/app/views/controllers/observations/show/_observation_details.erb @@ -16,6 +16,20 @@ end end %> + <% if obs.field_slips.present? %> + <%= tag.div(class: "obs-field-slips", id: "observation_field_slips") do + if obs.field_slips.count == 1 + concat(tag.span("#{:FIELD_SLIP.t}: ")) + concat(link_to_object(obs.field_slips[0])) + else + concat([tag.span("#{:FIELD_SLIPS.t}:"), tag.br].safe_join) + obs.field_slips.each do |field_slip| + concat(tag.div(link_to_object(field_slip), class: "indent")) + end + end + end %> + <% end %> + <%= tag.p(class: "obs-specimen", id: "observation_specimen_available") do if obs.specimen :show_observation_specimen_available.t From e759358533cd05898a8eab103cabef89fbe2edd9 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Thu, 21 Mar 2024 21:07:18 -0400 Subject: [PATCH 19/51] Enable edit/create to lead to create workflow or to use last viewed observation. Show/index cleanup. --- app/controllers/field_slips_controller.rb | 32 +++++++++++++++---- .../observations_controller/new_and_create.rb | 10 ++++++ app/helpers/field_slips_helper.rb | 5 +++ app/models/observation_view.rb | 5 +++ .../controllers/observations/_form.html.erb | 2 ++ app/views/field_slips/_field_slip.html.erb | 21 ++++++------ app/views/field_slips/_form.html.erb | 27 ++++++++++++---- app/views/field_slips/index.html.erb | 9 +++--- app/views/field_slips/show.html.erb | 2 ++ config/locales/en.txt | 3 ++ 10 files changed, 89 insertions(+), 27 deletions(-) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index 5b7ff974f3..4817a1a594 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -11,12 +11,18 @@ def index # GET /field_slips/1 or /field_slips/1.json def show - if params[:id].match(/^\d+$/) + obs = nil + if params[:id].match?(/^\d+$/) set_field_slip else @field_slip = FieldSlip.find_by(code: params[:id].upcase) + obs = @field_slip&.observation + end + if @field_slip + redirect_to(observation_url(id: obs.id)) if obs + else + redirect_to(new_field_slip_url(code: params[:id].upcase)) end - redirect_to(new_field_slip_url(code: params[:id].upcase)) unless @field_slip end # GET /field_slips/new @@ -33,10 +39,17 @@ def create @field_slip = FieldSlip.new(field_slip_params) respond_to do |format| + if params[:commit] == :field_slip_last_obs.t + @field_slip.observation = ObservationView.last(User.current) + end if @field_slip.save format.html do - redirect_to(field_slip_url(@field_slip), - notice: :field_slip_created.t) + if params[:commit] == :field_slip_create_obs.t + redirect_to(new_observation_url(field_code: @field_slip.code)) + else + redirect_to(field_slip_url(@field_slip), + notice: :field_slip_created.t) + end end format.json { render(:show, status: :created, location: @field_slip) } else @@ -51,10 +64,17 @@ def create # PATCH/PUT /field_slips/1 or /field_slips/1.json def update respond_to do |format| + if params[:commit] == :field_slip_last_obs.t + @field_slip.observation = ObservationView.last(User.current) + end if @field_slip.update(field_slip_params) format.html do - redirect_to(field_slip_url(@field_slip), - notice: :field_slip_updated.t) + if params[:commit] == :field_slip_create_obs.t + redirect_to(new_observation_url(field_code: @field_slip.code)) + else + redirect_to(field_slip_url(@field_slip), + notice: :field_slip_updated.t) + end end format.json { render(:show, status: :ok, location: @field_slip) } else diff --git a/app/controllers/observations_controller/new_and_create.rb b/app/controllers/observations_controller/new_and_create.rb index 2bbd133d9e..f2c2447220 100644 --- a/app/controllers/observations_controller/new_and_create.rb +++ b/app/controllers/observations_controller/new_and_create.rb @@ -46,6 +46,7 @@ def new @reasons = @naming.init_reasons @images = [] @good_images = [] + @field_code = params[:field_code] init_specimen_vars init_project_vars_for_create init_list_vars @@ -102,6 +103,7 @@ def create success = false if @name && !@vote.value.nil? && !validate_object(@vote) success = false if @bad_images != [] success = false if success && !save_observation(@observation) + update_field_slip(@observation, params[:field_code]) # Once observation is saved we can save everything else. if success @@ -315,4 +317,12 @@ def reload_new_form(reasons) init_list_vars_for_reload(@observation) render(action: :new, location: new_observation_path(q: get_query_param)) end + + def update_field_slip(observation, field_code) + field_slip = FieldSlip.find_by(code: field_code) + return unless field_slip + + field_slip.observation = observation + field_slip.save + end end diff --git a/app/helpers/field_slips_helper.rb b/app/helpers/field_slips_helper.rb index 9e83ab6111..2663a6b811 100644 --- a/app/helpers/field_slips_helper.rb +++ b/app/helpers/field_slips_helper.rb @@ -1,4 +1,9 @@ # frozen_string_literal: true module FieldSlipsHelper + def last_observation + return unless User.current + + ObservationView.last(User.current) + end end diff --git a/app/models/observation_view.rb b/app/models/observation_view.rb index 0d78793dec..d8ffaba26f 100644 --- a/app/models/observation_view.rb +++ b/app/models/observation_view.rb @@ -30,4 +30,9 @@ def self.update_view_stats(obs_id, user_id, reviewed = nil) create!(args) end end + + def self.last(user) + view = ObservationView.where(user:).order(last_view: :desc).first + view&.observation + end end diff --git a/app/views/controllers/observations/_form.html.erb b/app/views/controllers/observations/_form.html.erb index 9c6586f20e..10654dc267 100644 --- a/app/views/controllers/observations/_form.html.erb +++ b/app/views/controllers/observations/_form.html.erb @@ -31,6 +31,8 @@ image_upload_localization = { } ) do |f| %> + <%= hidden_field_tag(:field_code, @field_code) %> + <%= submit_button(form: f, button: button_name, center: true) %> <%= render(partial: "observations/form/when", locals: { f: f }) %> diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/field_slips/_field_slip.html.erb index fcaba9a19a..78daee4e2b 100644 --- a/app/views/field_slips/_field_slip.html.erb +++ b/app/views/field_slips/_field_slip.html.erb @@ -1,20 +1,21 @@

      - Observation: - <% if field_slip.observation %> - <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %> - <% else %> - <%= :field_slip_no_observation.t %> - <% end %> -
      - Project: + <%= :PROJECT.t %>: <% if field_slip.project %> <%= link_to_object(field_slip.project) %> <% else %> <%= :field_slip_no_project.t %> <% end %>
      - Code: - <%= field_slip.code %> + <%= :OBSERVATION.t %>: + <% if field_slip.observation %> + <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %> +

        + <%= render(partial: "shared/matrix_box", + locals: { object: field_slip.observation, columns: "col-xs-12" }) %> +
      + <% else %> + <%= :field_slip_no_observation.t %> + <% end %>

      diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index acba6395e3..0486bdd5c0 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -12,8 +12,8 @@ <% end %>
      - <%= form.label :observation_id, style: "display: block" %> - <%= form.number_field :observation_id %> + <%= form.label :code, style: "display: block" %> + <%= form.text_field :code %>
      @@ -21,12 +21,25 @@ <%= form.number_field :project_id %>
      -
      - <%= form.label :code, style: "display: block" %> - <%= form.text_field :code %> -
      +
      - <%= form.submit %> + <%= form.submit :field_slip_create_obs.t %>
      + +
      +
      + + <% obs = last_observation + if obs %> +
      + Last Observation: <%= link_to(obs.unique_format_name.t, observation_path(obs)) %> +
      + +
      + +
      + <%= form.submit :field_slip_last_obs.t %> +
      + <% end %> <% end %> diff --git a/app/views/field_slips/index.html.erb b/app/views/field_slips/index.html.erb index 897883a1e6..aba67f2024 100644 --- a/app/views/field_slips/index.html.erb +++ b/app/views/field_slips/index.html.erb @@ -2,14 +2,15 @@

      <%= notice %>

      <% end %> -

      Field slips

      +

      <%= :FIELD_SLIPS.t %>

      <% @field_slips.each do |field_slip| %> + <%= :field_slip_code.t %>: + <%= field_slip.code %> <%= render field_slip %> -

      - <%= link_to :field_slip_show.t, field_slip %> -

      + <%= link_to :field_slip_show.t, field_slip %> +
      <% end %>
      diff --git a/app/views/field_slips/show.html.erb b/app/views/field_slips/show.html.erb index 46d00decaa..08161cc74b 100644 --- a/app/views/field_slips/show.html.erb +++ b/app/views/field_slips/show.html.erb @@ -2,6 +2,8 @@

      <%= notice %>

      <% end %> +

      <%= "#{:FIELD_SLIP.t}: #{@field_slip.code}" %>

      + <%= render @field_slip %>
      diff --git a/config/locales/en.txt b/config/locales/en.txt index 6380a2bbeb..a7ef7b982a 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2756,13 +2756,16 @@ destroy_visual_model_success: "[:VISUAL_MODEL] [:destroyed]" # Field Slips + field_slip_code: Code field_slip_code_format_error: code must have non-numeric characters other than period (.) and dash (-) field_slip_created: Field slip was successfully created. + field_slip_create_obs: Create New Observation field_slip_destroy: Destroy this field slip field_slip_destroyed: Field slip was successfully destroyed. field_slip_edit: Edit this field slip field_slip_errors: prohibited this field_slip from being saved field_slip_index: Back to field slips + field_slip_last_obs: Use Last Observation field_slip_new: New field slip field_slip_no_observation: Observation not found field_slip_no_project: Project not found From d212a27f98e38df0c73ed6a7dee5e9aa6bd448bc Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Thu, 21 Mar 2024 21:17:08 -0400 Subject: [PATCH 20/51] Add thumbail of last image --- app/views/field_slips/_form.html.erb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index 0486bdd5c0..971ffd54ef 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -32,8 +32,10 @@ <% obs = last_observation if obs %> -
      - Last Observation: <%= link_to(obs.unique_format_name.t, observation_path(obs)) %> +
      + Last Observation:
      + <%= image_tag(Image.url(:thumbnail, obs.thumb_image_id)) %>
      + <%= link_to(obs.unique_format_name.t, observation_path(obs)) %>

      @@ -41,5 +43,6 @@
      <%= form.submit :field_slip_last_obs.t %>
      + <% end %> <% end %> From f55cb7ebc9b1d4688de561709a5ff86168039627 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Fri, 22 Mar 2024 19:25:59 -0400 Subject: [PATCH 21/51] String and test cleanup --- app/views/field_slips/edit.html.erb | 6 +++--- config/locales/en.txt | 1 + test/controllers/field_slips_controller_test.rb | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/views/field_slips/edit.html.erb b/app/views/field_slips/edit.html.erb index a01a18affd..7c410a1b98 100644 --- a/app/views/field_slips/edit.html.erb +++ b/app/views/field_slips/edit.html.erb @@ -1,10 +1,10 @@ -

      Editing field slip

      +

      <%= :field_slip_editing.t %>

      <%= render "form", field_slip: @field_slip %>
      - <%= link_to "Show this field slip", @field_slip %> | - <%= link_to "Back to field slips", field_slips_path %> + <%= link_to :field_slip_show.t, @field_slip %> | + <%= link_to :field_slip_index.t, field_slips_path %>
      diff --git a/config/locales/en.txt b/config/locales/en.txt index a7ef7b982a..3c931c40f6 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2763,6 +2763,7 @@ field_slip_destroy: Destroy this field slip field_slip_destroyed: Field slip was successfully destroyed. field_slip_edit: Edit this field slip + field_slip_editing: Editing Field Slip field_slip_errors: prohibited this field_slip from being saved field_slip_index: Back to field slips field_slip_last_obs: Use Last Observation diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index e44bf6a6ba..dab6e11e1e 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -54,7 +54,7 @@ class FieldSlipsControllerTest < FunctionalTestCase post(:create, params: { field_slip: { - code: "#{@field_slip.code}", + code: @field_slip.code.to_s, observation: observations(:coprinus_comatus_obs), project: projects(:eol_project) } @@ -68,7 +68,7 @@ class FieldSlipsControllerTest < FunctionalTestCase format: :json, params: { field_slip: { - code: "#{@field_slip.code}", + code: @field_slip.code.to_s, observation: observations(:coprinus_comatus_obs), project: projects(:eol_project) } @@ -83,7 +83,7 @@ class FieldSlipsControllerTest < FunctionalTestCase test "should show field_slip by code" do get(:show, params: { id: @field_slip.code }) - assert_response :success + assert_redirected_to observation_url(@field_slip.observation) end test "should get edit" do From 522672675b58b587cb666ec44aa90543b607e66b Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Fri, 22 Mar 2024 19:28:16 -0400 Subject: [PATCH 22/51] Add user_id to FieldSlips --- db/migrate/20240322232703_add_user_id_to_field_slips.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240322232703_add_user_id_to_field_slips.rb diff --git a/db/migrate/20240322232703_add_user_id_to_field_slips.rb b/db/migrate/20240322232703_add_user_id_to_field_slips.rb new file mode 100644 index 0000000000..37aa2209b4 --- /dev/null +++ b/db/migrate/20240322232703_add_user_id_to_field_slips.rb @@ -0,0 +1,5 @@ +class AddUserIdToFieldSlips < ActiveRecord::Migration[7.1] + def change + add_column :field_slips, :user_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 8d38a14026..1417ac8df2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_03_12_231729) do +ActiveRecord::Schema[7.1].define(version: 2024_03_22_232703) do create_table "api_keys", id: :integer, charset: "utf8mb3", force: :cascade do |t| t.datetime "created_at", precision: nil t.datetime "last_used", precision: nil @@ -91,6 +91,7 @@ t.string "code", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "user_id" t.index ["code"], name: "index_field_slips_on_code", unique: true end From dcaae8217c51f91d32c9d28de350ca51ac515cec Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Fri, 22 Mar 2024 20:55:54 -0400 Subject: [PATCH 23/51] Add User to FieldSlips --- app/controllers/field_slips_controller.rb | 11 +++- app/models/field_slip.rb | 1 + app/views/field_slips/show.html.erb | 7 ++- .../field_slips_controller_test.rb | 60 ++++++++++++++++++- test/fixtures/field_slips.yml | 2 + 5 files changed, 75 insertions(+), 6 deletions(-) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index 4817a1a594..c34fb35f7a 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -32,7 +32,11 @@ def new end # GET /field_slips/1/edit - def edit; end + def edit + return unless @field_slip.user != User.current + + redirect_to(field_slip_url(id: @field_slip.id)) + end # POST /field_slips or /field_slips.json def create @@ -88,6 +92,11 @@ def update # DELETE /field_slips/1 or /field_slips/1.json def destroy + if @field_slip.user != User.current + redirect_to(field_slip_url(id: @field_slip.id)) + return + end + @field_slip.destroy! respond_to do |format| diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index fa21fb6dcd..4e608799a6 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -3,6 +3,7 @@ class FieldSlip < AbstractModel belongs_to :observation belongs_to :project + belongs_to :user validates :code, uniqueness: true validates :code, presence: true diff --git a/app/views/field_slips/show.html.erb b/app/views/field_slips/show.html.erb index 08161cc74b..938ec309dc 100644 --- a/app/views/field_slips/show.html.erb +++ b/app/views/field_slips/show.html.erb @@ -7,8 +7,9 @@ <%= render @field_slip %>
      - <%= link_to :field_slip_edit.t, edit_field_slip_path(@field_slip) %> | <%= link_to :field_slip_index.t, field_slips_path %> - - <%= button_to :field_slip_destroy.t, @field_slip, method: :delete %> + <% if @field_slip.user == User.current %> + | <%= link_to :field_slip_edit.t, edit_field_slip_path(@field_slip) %> + | <%= button_to :field_slip_destroy.t, @field_slip, method: :delete %> + <% end %>
      diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index dab6e11e1e..3c360b7802 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -33,6 +33,41 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_redirected_to field_slip_url(FieldSlip.last) end + test "should create field_slip with last viewed obs" do + login(@field_slip.user.login) + ObservationView.update_view_stats(@field_slip.observation_id, + @field_slip.user_id) + assert_difference("FieldSlip.count") do + post(:create, + params: { + commit: :field_slip_last_obs.t, + field_slip: { + code: "Y#{@field_slip.code}", + project: projects(:eol_project) + } + }) + end + + assert_redirected_to field_slip_url(FieldSlip.last) + assert_equal(FieldSlip.last.observation, ObservationView.last(User.current)) + end + + test "should create field_slip and redirect to create obs" do + login(@field_slip.user.login) + assert_difference("FieldSlip.count") do + post(:create, + params: { + commit: :field_slip_create_obs.t, + field_slip: { + code: "Z#{@field_slip.code}", + project: projects(:eol_project) + } + }) + end + + assert_redirected_to new_observation_url(field_code: FieldSlip.last.code) + end + test "should create field_slip in project from code" do login project = projects(:eol_project) @@ -86,12 +121,24 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_redirected_to observation_url(@field_slip.observation) end + test "should redirect to get new" do + code = "M0-1234" + get(:show, params: { id: code }) + assert_redirected_to new_field_slip_url(code: code) + end + test "should get edit" do - login + login(@field_slip.user.login) get(:edit, params: { id: @field_slip.id }) assert_response :success end + test "should get not edit" do + login + get(:edit, params: { id: @field_slip.id }) + assert_redirected_to field_slip_url(@field_slip) + end + test "should update field_slip" do login patch(:update, @@ -124,11 +171,20 @@ class FieldSlipsControllerTest < FunctionalTestCase end test "should destroy field_slip" do - login + login(@field_slip.user.login) assert_difference("FieldSlip.count", -1) do delete(:destroy, params: { id: @field_slip.id }) end assert_redirected_to field_slips_url end + + test "should not destroy field_slip" do + login + assert_difference("FieldSlip.count", 0) do + delete(:destroy, params: { id: @field_slip.id }) + end + + assert_redirected_to field_slip_url(@field_slip) + end end diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index 2f6e6912bc..e744152233 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -4,8 +4,10 @@ field_slip_one: observation: minimal_unknown_obs project: eol_project code: MOTEST-0001 + user: mary field_slip_two: observation_id: detailed_unknown_obs project_id: eol_project code: MOTEST-0002 + user: mary From 371aaf19e068dd4a4e46e7ceacfe4f858ee5ddb5 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 04:48:36 -0400 Subject: [PATCH 24/51] Edit field slip can keep current image. Test coverage. --- app/views/field_slips/_form.html.erb | 15 +++++++ config/locales/en.txt | 1 + .../field_slips_controller_test.rb | 44 ++++++++++++------- test/fixtures/field_slips.yml | 2 +- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index 971ffd54ef..d282c9dacd 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -23,6 +23,21 @@
      + <% if field_slip&.observation + current = field_slip.observation %> +
      + Current Observation:
      + <%= image_tag(Image.url(:thumbnail, current.thumb_image_id)) %>
      + <%= link_to(current.unique_format_name.t, observation_path(current)) %> +
      +
      + <%= form.submit :field_slip_keep_obs.t %> +
      +
      + <% end %> + +
      +
      <%= form.submit :field_slip_create_obs.t %>
      diff --git a/config/locales/en.txt b/config/locales/en.txt index 3c931c40f6..fbfa5a806d 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2766,6 +2766,7 @@ field_slip_editing: Editing Field Slip field_slip_errors: prohibited this field_slip from being saved field_slip_index: Back to field slips + field_slip_keep_obs: Keep Above field_slip_last_obs: Use Last Observation field_slip_new: New field slip field_slip_no_observation: Observation not found diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index 3c360b7802..127a2ebaff 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -17,22 +17,6 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_response :success end - test "should create field_slip" do - login - assert_difference("FieldSlip.count") do - post(:create, - params: { - field_slip: { - code: "X#{@field_slip.code}", - observation: observations(:coprinus_comatus_obs), - project: projects(:eol_project) - } - }) - end - - assert_redirected_to field_slip_url(FieldSlip.last) - end - test "should create field_slip with last viewed obs" do login(@field_slip.user.login) ObservationView.update_view_stats(@field_slip.observation_id, @@ -64,7 +48,6 @@ class FieldSlipsControllerTest < FunctionalTestCase } }) end - assert_redirected_to new_observation_url(field_code: FieldSlip.last.code) end @@ -141,12 +124,39 @@ class FieldSlipsControllerTest < FunctionalTestCase test "should update field_slip" do login + initial = @field_slip.observation_id patch(:update, params: { id: @field_slip.id, + commit: :field_slip_keep_obs.t, field_slip: { code: @field_slip.code, observation_id: @field_slip.observation_id, project_id: @field_slip.project_id } }) assert_redirected_to field_slip_url(@field_slip) + assert_equal(@field_slip.observation_id, initial) + end + + test "should update field_slip with last viewed obs" do + login(@field_slip.user.login) + obs = observations(:minimal_unknown_obs) + ObservationView.update_view_stats(obs.id, @field_slip.user_id) + patch(:update, + params: { id: @field_slip.id, + commit: :field_slip_last_obs.t, + field_slip: { code: @field_slip.code, + project_id: @field_slip.project_id } }) + assert_redirected_to field_slip_url(@field_slip) + assert_equal(@field_slip.observation, ObservationView.last(User.current)) + end + + test "should update field_slip and redirect to create obs" do + login + patch(:update, + params: { id: @field_slip.id, + commit: :field_slip_create_obs.t, + field_slip: { code: @field_slip.code, + observation_id: @field_slip.observation_id, + project_id: @field_slip.project_id } }) + assert_redirected_to new_observation_url(field_code: @field_slip.code) end test "should fail to update field_slip" do diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index e744152233..8634902b79 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -7,7 +7,7 @@ field_slip_one: user: mary field_slip_two: - observation_id: detailed_unknown_obs + observation_id: owner_accepts_general_questions project_id: eol_project code: MOTEST-0002 user: mary From ce40e76325bd4b95127efc61f1f496a39b92713a Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 05:28:11 -0400 Subject: [PATCH 25/51] Use the FieldSlip code for default_accession_number --- .../herbarium_records_controller.rb | 4 ++- .../herbarium_records_controller_test.rb | 30 ++++++++++++++++++- test/fixtures/field_slips.yml | 2 +- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/app/controllers/herbarium_records_controller.rb b/app/controllers/herbarium_records_controller.rb index 3c48599eac..53026ec630 100644 --- a/app/controllers/herbarium_records_controller.rb +++ b/app/controllers/herbarium_records_controller.rb @@ -194,7 +194,9 @@ def default_herbarium_record end def default_accession_number - if @observation.collection_numbers.length == 1 + if @observation.field_slips.length == 1 + @observation.field_slips.first.code + elsif @observation.collection_numbers.length == 1 @observation.collection_numbers.first.format_name else "MO #{@observation.id}" diff --git a/test/controllers/herbarium_records_controller_test.rb b/test/controllers/herbarium_records_controller_test.rb index 6b48ba37bb..581af3f8ff 100644 --- a/test/controllers/herbarium_records_controller_test.rb +++ b/test/controllers/herbarium_records_controller_test.rb @@ -164,7 +164,7 @@ def test_next_and_prev_herbarium_record end def test_new_herbarium_record - obs_id = observations(:coprinus_comatus_obs).id + obs_id = observations(:unknown_with_no_naming).id get(:new, params: { observation_id: obs_id }) assert_response(:redirect) @@ -172,7 +172,35 @@ def test_new_herbarium_record get(:new, params: { observation_id: obs_id }) assert_template("new") assert_template("shared/_matrix_box") + assert_equal(assigns(:herbarium_record).accession_number, "MO #{obs_id}") + end + + def test_new_herbarium_record_with_collection_number + obs = observations(:coprinus_comatus_obs) + get(:new, params: { observation_id: obs.id }) + assert_response(:redirect) + + login("rolf") + get(:new, params: { observation_id: obs.id }) + assert_template("new") + assert_template("shared/_matrix_box") + assert(assigns(:herbarium_record)) + assert_equal(assigns(:herbarium_record).accession_number, + obs.collection_numbers.first.format_name) + end + + def test_new_herbarium_record_with_field_slip + obs = observations(:owner_accepts_general_questions) + get(:new, params: { observation_id: obs.id }) + assert_response(:redirect) + + login("rolf") + get(:new, params: { observation_id: obs.id }) + assert_template("new") + assert_template("shared/_matrix_box") assert(assigns(:herbarium_record)) + assert_equal(assigns(:herbarium_record).accession_number, + obs.field_slips.first.code) end def test_create_herbarium_record diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index 8634902b79..3628b97a9b 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -7,7 +7,7 @@ field_slip_one: user: mary field_slip_two: - observation_id: owner_accepts_general_questions + observation: owner_accepts_general_questions project_id: eol_project code: MOTEST-0002 user: mary From bf134e6a380c9c5356eafcf1169b2fd81d89701e Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 10:22:29 -0400 Subject: [PATCH 26/51] Add project drop down to field slip form --- app/models/field_slip.rb | 13 +++++++++++++ app/views/field_slips/_form.html.erb | 9 +++++---- test/controllers/field_slips_controller_test.rb | 13 ++++++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index 4e608799a6..9d80ca5d01 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -26,4 +26,17 @@ def code=(val) def title code end + + def projects + @projects ||= find_projects + end + + def find_projects + result = Project.includes(:project_members).where( + project_members: { user: User.current } + ).order(:title).pluck(:title, :id) + return unless project && result.exclude?([project.title, project.id]) + + result.unshift([project.title, project.id]) + end end diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index d282c9dacd..df88104e1d 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -14,15 +14,16 @@
      <%= form.label :code, style: "display: block" %> <%= form.text_field :code %> +

      - <%= form.label :project_id, style: "display: block" %> - <%= form.number_field :project_id %> + <% if @field_slip.projects %> + <%= form.select :project_id, @field_slip.projects %> + <% end %> +
      -
      - <% if field_slip&.observation current = field_slip.observation %>
      diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index 127a2ebaff..eb80da1333 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -17,6 +17,15 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_response :success end + test "should get new with unknown code" do + login + project = projects(:bolete_project) + code = "#{project.field_slip_prefix}-1234" + get(:new, params: { code: code }) + assert_response :success + assert(response.body.include?(project.title)) + end + test "should create field_slip with last viewed obs" do login(@field_slip.user.login) ObservationView.update_view_stats(@field_slip.observation_id, @@ -105,7 +114,9 @@ class FieldSlipsControllerTest < FunctionalTestCase end test "should redirect to get new" do - code = "M0-1234" + login + project = projects(:bolete_project) + code = "#{project.field_slip_prefix}-1235" get(:show, params: { id: code }) assert_redirected_to new_field_slip_url(code: code) end From 68526ed9c0be412a74fbd20bc6afc6c188a57b32 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 11:55:54 -0400 Subject: [PATCH 27/51] Add the field slip project to create checkboxes plus some more coverage --- .../observations_controller/new_and_create.rb | 9 +++++++++ .../observations_controller_test.rb | 20 +++++++++++++++++++ test/fixtures/field_slips.yml | 11 +++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/controllers/observations_controller/new_and_create.rb b/app/controllers/observations_controller/new_and_create.rb index f2c2447220..3dd93287c6 100644 --- a/app/controllers/observations_controller/new_and_create.rb +++ b/app/controllers/observations_controller/new_and_create.rb @@ -51,6 +51,7 @@ def new init_project_vars_for_create init_list_vars defaults_from_last_observation_created + add_field_slip_project(@field_code) end ############################################################################## @@ -84,6 +85,14 @@ def defaults_from_last_observation_created end end + def add_field_slip_project(code) + project = FieldSlip.find_by(code: code)&.project + return unless project + return unless project&.member?(User.current) + + @project_checks[project.id] = true + end + ############################################################################## public diff --git a/test/controllers/observations_controller_test.rb b/test/controllers/observations_controller_test.rb index 10eaf72d3f..be85f2d1e5 100644 --- a/test/controllers/observations_controller_test.rb +++ b/test/controllers/observations_controller_test.rb @@ -1478,6 +1478,18 @@ def test_construct_observation_approved_place_name assert_equal("mo_website", obs.source) end + def test_create_observation_with_field_slip + generic_construct_observation( + { observation: { specimen: "1" }, + field_code: field_slips(:field_slip_no_obs).code, + naming: { name: "Coprinus comatus" } }, + 1, 1, 0 + ) + obs = assigns(:observation) + assert(obs.specimen) + assert(obs.field_slips.count == 1) + end + def test_create_observation_with_collection_number generic_construct_observation( { observation: { specimen: "1" }, @@ -2929,6 +2941,14 @@ def test_inital_project_checkboxes ) end + def test_field_slip_project_checkbox + login("katrina") + slip = field_slips(:field_slip_no_obs) + get(:new, params: { field_code: slip.code }) + + assert_project_checks(slip.project.id => :checked) + end + def test_project_checkboxes_in_create_observation init_for_project_checkbox_tests diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index 3628b97a9b..d2b12bba8a 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -3,11 +3,16 @@ field_slip_one: observation: minimal_unknown_obs project: eol_project - code: MOTEST-0001 + code: EOL-0001 user: mary field_slip_two: observation: owner_accepts_general_questions - project_id: eol_project - code: MOTEST-0002 + project: eol_project + code: EOL-0002 + user: mary + +field_slip_no_obs: + project: eol_project + code: EOL-0003 user: mary From 0e32716bf1c2bac4b9ec452a79f44bebf69bbe11 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 13:57:57 -0400 Subject: [PATCH 28/51] Automatically add users to open projects when they create an associated field slip --- app/controllers/field_slips_controller.rb | 9 ++++++++ app/views/field_slips/_field_slip.html.erb | 2 ++ config/locales/en.txt | 2 ++ .../field_slips_controller_test.rb | 22 +++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index c34fb35f7a..00830c3b22 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -43,6 +43,7 @@ def create @field_slip = FieldSlip.new(field_slip_params) respond_to do |format| + check_project_membership(@field_slip) if params[:commit] == :field_slip_last_obs.t @field_slip.observation = ObservationView.last(User.current) end @@ -119,4 +120,12 @@ def set_field_slip def field_slip_params params.require(:field_slip).permit(:observation_id, :project_id, :code) end + + def check_project_membership(slip) + project = slip&.project + return unless project&.can_join?(User.current) + + project.user_group.users << User.current + flash_notice(:field_slip_welcome.t(title: project.title)) + end end diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/field_slips/_field_slip.html.erb index 78daee4e2b..65a30a8c26 100644 --- a/app/views/field_slips/_field_slip.html.erb +++ b/app/views/field_slips/_field_slip.html.erb @@ -7,6 +7,8 @@ <%= :field_slip_no_project.t %> <% end %>
      + <%= :field_slip_creator.t %>: + <%= link_to(field_slip.user.legal_name, user_path(field_slip.user_id)) %>
      <%= :OBSERVATION.t %>: <% if field_slip.observation %> <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %> diff --git a/config/locales/en.txt b/config/locales/en.txt index fbfa5a806d..58dc861f68 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2760,6 +2760,7 @@ field_slip_code_format_error: code must have non-numeric characters other than period (.) and dash (-) field_slip_created: Field slip was successfully created. field_slip_create_obs: Create New Observation + field_slip_creator: Creator field_slip_destroy: Destroy this field slip field_slip_destroyed: Field slip was successfully destroyed. field_slip_edit: Edit this field slip @@ -2773,6 +2774,7 @@ field_slip_no_project: Project not found field_slip_show: Show this field slip field_slip_updated: Field slip was successfully updated. + field_slip_welcome: "Welcome to the [TITLE] project!" ############################################################################## diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index eb80da1333..13cc53b74b 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -45,6 +45,28 @@ class FieldSlipsControllerTest < FunctionalTestCase assert_equal(FieldSlip.last.observation, ObservationView.last(User.current)) end + test "should create field_slip and join project" do + user = @field_slip.user + login(user.login) + project = projects(:open_membership_project) + assert_not(project.member?(user)) + ObservationView.update_view_stats(@field_slip.observation_id, + @field_slip.user_id) + assert_difference("FieldSlip.count") do + post(:create, + params: { + commit: :field_slip_last_obs.t, + field_slip: { + code: "#{project.field_slip_prefix}-0001", + project: project + } + }) + end + + assert_redirected_to field_slip_url(FieldSlip.last) + assert(project.member?(user)) + end + test "should create field_slip and redirect to create obs" do login(@field_slip.user.login) assert_difference("FieldSlip.count") do From ef9cf8b0a24a91aeb2e84a57ba86ec222f0bc5a6 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 14:01:03 -0400 Subject: [PATCH 29/51] Typo --- config/locales/en.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.txt b/config/locales/en.txt index 58dc861f68..f8ed25ec98 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -268,7 +268,7 @@ FIELD_SLIP: Field Slip field_slip: field slip FIELD_SLIPS: Field Slips - field_slips: field groups + field_slips: field slips IMAGE: Image image: image IMAGES: Images From bdfb1c69537232a9de6734ef4e8dfb6a4b3e71c7 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 14:04:12 -0400 Subject: [PATCH 30/51] Rubocop on app/views/field_slips/show.json.jbuilder --- app/views/field_slips/show.json.jbuilder | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/field_slips/show.json.jbuilder b/app/views/field_slips/show.json.jbuilder index 823c9b75cc..1fb4d693be 100644 --- a/app/views/field_slips/show.json.jbuilder +++ b/app/views/field_slips/show.json.jbuilder @@ -1 +1,3 @@ -json.partial! "field_slips/field_slip", field_slip: @field_slip +# frozen_string_literal: true + +json.partial!("field_slips/field_slip", field_slip: @field_slip) From d71f1c7e6135efbba0c14c02370303c8c2771476 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 14:28:01 -0400 Subject: [PATCH 31/51] Switch to with_label helpers and fixed a bug --- app/models/field_slip.rb | 2 +- app/views/field_slips/_form.html.erb | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/app/models/field_slip.rb b/app/models/field_slip.rb index 9d80ca5d01..85e56a96c9 100644 --- a/app/models/field_slip.rb +++ b/app/models/field_slip.rb @@ -35,7 +35,7 @@ def find_projects result = Project.includes(:project_members).where( project_members: { user: User.current } ).order(:title).pluck(:title, :id) - return unless project && result.exclude?([project.title, project.id]) + return result unless project && result.exclude?([project.title, project.id]) result.unshift([project.title, project.id]) end diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index df88104e1d..ff3bfb389b 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -12,17 +12,14 @@ <% end %>
      - <%= form.label :code, style: "display: block" %> - <%= form.text_field :code %> -

      + <%= text_field_with_label(form: form, field: :code) %>
      -
      - <% if @field_slip.projects %> - <%= form.select :project_id, @field_slip.projects %> - <% end %> -
      -
      + <% if @field_slip.projects %> +
      + <%= select_with_label(form: form, field: :project_id, options: @field_slip.projects) %> +
      + <% end %> <% if field_slip&.observation current = field_slip.observation %> @@ -32,7 +29,7 @@ <%= link_to(current.unique_format_name.t, observation_path(current)) %>

      - <%= form.submit :field_slip_keep_obs.t %> + <%= submit_button(form: form, button: :field_slip_keep_obs.t) %>

      <% end %> @@ -40,7 +37,7 @@
      - <%= form.submit :field_slip_create_obs.t %> + <%= submit_button(form: form, button: :field_slip_create_obs.t) %>

      @@ -57,7 +54,7 @@
      - <%= form.submit :field_slip_last_obs.t %> + <%= submit_button(form: form, button: :field_slip_last_obs.t) %>
      <% end %> From 2aa921aa02e2c38636ac012e98f919fdc700fe35 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 14:41:54 -0400 Subject: [PATCH 32/51] Rubocop --- app/views/field_slips/index.json.jbuilder | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/field_slips/index.json.jbuilder b/app/views/field_slips/index.json.jbuilder index 4cf81e9115..374336fa00 100644 --- a/app/views/field_slips/index.json.jbuilder +++ b/app/views/field_slips/index.json.jbuilder @@ -1 +1,3 @@ -json.array! @field_slips, partial: "field_slips/field_slip", as: :field_slip +# frozen_string_literal: true + +json.array!(@field_slips, partial: "field_slips/field_slip", as: :field_slip) From 68218c378ea55fac14e3e73f34b6cc17cde34d6b Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 14:45:19 -0400 Subject: [PATCH 33/51] Rubocop --- app/views/field_slips/_field_slip.json.jbuilder | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/field_slips/_field_slip.json.jbuilder b/app/views/field_slips/_field_slip.json.jbuilder index 5d3fa43823..37c5521152 100644 --- a/app/views/field_slips/_field_slip.json.jbuilder +++ b/app/views/field_slips/_field_slip.json.jbuilder @@ -1,2 +1,5 @@ -json.extract! field_slip, :id, :observation_id, :project_id, :code, :created_at, :updated_at -json.url field_slip_url(field_slip, format: :json) +# frozen_string_literal: true + +json.extract!(field_slip, :id, :observation_id, :project_id, :code, + :created_at, :updated_at) +json.url(field_slip_url(field_slip, format: :json)) From 44e094079599bbafc072c8eba2838d68a5b18a52 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 15:45:30 -0400 Subject: [PATCH 34/51] Adding SpeciesList as a language tag because of the GitHub CI/CD system not because I understand why it thinks we need it --- config/locales/en.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/en.txt b/config/locales/en.txt index f8ed25ec98..6c31929086 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -387,6 +387,7 @@ species_list: species list SPECIES_LISTS: Species Lists species_lists: species lists + SpeciesList: Species List SPECIMEN: Specimen specimen: specimen SPECIMENS: Specimens From 70bc537d7ade95e999d8df9d97b46f14efd1fbd7 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 15:46:51 -0400 Subject: [PATCH 35/51] Fix bad fixture --- test/system/field_slips_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/system/field_slips_test.rb b/test/system/field_slips_test.rb index 6f9728bc50..ae12c5948c 100644 --- a/test/system/field_slips_test.rb +++ b/test/system/field_slips_test.rb @@ -4,7 +4,7 @@ class FieldSlipsTest < ApplicationSystemTestCase setup do - @field_slip = field_slips(:one) + @field_slip = field_slips(:field_slip_one) end test "visiting the index" do From 06ca76378b84a089cf89eca9a4f3e4af8030b009 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sat, 23 Mar 2024 16:35:58 -0400 Subject: [PATCH 36/51] Bullet time --- app/controllers/field_slips_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index 00830c3b22..7d770be0ea 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -6,7 +6,10 @@ class FieldSlipsController < ApplicationController # GET /field_slips or /field_slips.json def index - @field_slips = FieldSlip.all + @field_slips = FieldSlip.includes( + [{ observation: [:location, :name, :namings, :rss_log, :user] }, + :project, :user] + ) end # GET /field_slips/1 or /field_slips/1.json From e0ab307308e0f50ac7b2f57ff140242c63898b3f Mon Sep 17 00:00:00 2001 From: Joe Cohen Date: Sat, 23 Mar 2024 20:31:21 -0700 Subject: [PATCH 37/51] Test (red) exposing qr-new obs-violation bug Exposes a bug when: - scanning Field Slip - choosing to Create New Observation - completing Observation fields with Constraint Violation(s) - then clicking Create See https://github.com/MushroomObserver/mushroom-observer/pull/2024#issuecomment-2016604962 et seq. --- test/fixtures/field_slips.yml | 4 +++ test/fixtures/projects.yml | 1 + .../capybara/field_slips_integration_test.rb | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 test/integration/capybara/field_slips_integration_test.rb diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index d2b12bba8a..221ab368c5 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -16,3 +16,7 @@ field_slip_no_obs: project: eol_project code: EOL-0003 user: mary + +field_slip_falmouth_one: + project: falmouth_2023_09_project + code: FAL-0001 diff --git a/test/fixtures/projects.yml b/test/fixtures/projects.yml index 481b02c94e..d30617d7a6 100644 --- a/test/fixtures/projects.yml +++ b/test/fixtures/projects.yml @@ -232,6 +232,7 @@ falmouth_2023_09_project: user: dick admin_group: dick_only user_group: falmouth_2023_09_users + field_slip_prefix: FAL start_date: 2023-09-01 end_date: 2023-09-30 location: falmouth diff --git a/test/integration/capybara/field_slips_integration_test.rb b/test/integration/capybara/field_slips_integration_test.rb new file mode 100644 index 0000000000..3abf656626 --- /dev/null +++ b/test/integration/capybara/field_slips_integration_test.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require("test_helper") + +# Test relating to projects +class FieldSlipsIntegrationTest < CapybaraIntegrationTestCase + + def test_new_observation_violates_project_constraints + project = projects(:falmouth_2023_09_project) + user = users(:roy) + assert(project.member?(user), + "Test needs user who is member of #{project.title} Project") + + login(user) + visit("/qr/NFAL-0001") + click_on(:field_slip_create_obs.l) + + fill_in(:WHERE.l, with: locations(:albion).name) + assert_no_difference( + "Observation.count", + "Observation shouldn't be created before confirming constraint violation" + ) do + first(:button, "Create").click + end + end +end From 0d60cd2a3d4c340f219e4903957425dcd85599ac Mon Sep 17 00:00:00 2001 From: Joe Cohen Date: Sat, 23 Mar 2024 20:44:44 -0700 Subject: [PATCH 38/51] Remove empty line at class body beginning --- test/integration/capybara/field_slips_integration_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/capybara/field_slips_integration_test.rb b/test/integration/capybara/field_slips_integration_test.rb index 3abf656626..62932c2690 100644 --- a/test/integration/capybara/field_slips_integration_test.rb +++ b/test/integration/capybara/field_slips_integration_test.rb @@ -4,7 +4,6 @@ # Test relating to projects class FieldSlipsIntegrationTest < CapybaraIntegrationTestCase - def test_new_observation_violates_project_constraints project = projects(:falmouth_2023_09_project) user = users(:roy) From 18a713110957fa48fd6670b7b26bdb3ef47f2ad0 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 24 Mar 2024 09:52:46 -0400 Subject: [PATCH 39/51] Start fixing test/system/field_slips_test.rb --- app/views/field_slips/new.html.erb | 4 ++-- test/system/field_slips_test.rb | 20 +++++++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/views/field_slips/new.html.erb b/app/views/field_slips/new.html.erb index eec5347fa1..58db5e77bf 100644 --- a/app/views/field_slips/new.html.erb +++ b/app/views/field_slips/new.html.erb @@ -1,9 +1,9 @@ -

      New field slip

      +

      <%= :field_slip_new.t %>

      <%= render "form", field_slip: @field_slip %>
      - <%= link_to "Back to field slips", field_slips_path %> + <%= link_to :field_slip_index.t, field_slips_path %>
      diff --git a/test/system/field_slips_test.rb b/test/system/field_slips_test.rb index ae12c5948c..078da77d62 100644 --- a/test/system/field_slips_test.rb +++ b/test/system/field_slips_test.rb @@ -8,24 +8,21 @@ class FieldSlipsTest < ApplicationSystemTestCase end test "visiting the index" do + login!(mary) visit field_slips_url - assert_selector "h1", text: "Field slips" + assert_selector "h1", text: :FIELD_SLIPS.t end - test "should create field slip" do + test "navigate to should field slip" do + login!(mary) visit field_slips_url - click_on "New field slip" - - fill_in "Code", with: @field_slip.code - fill_in "Observation", with: @field_slip.observation_id - fill_in "Project", with: @field_slip.project_id - click_on "Create Field slip" - - assert_text "Field slip was successfully created" + click_on :field_slip_show.t + assert_text :field_slip_index.t click_on "Back" end test "should update Field slip" do + login!(mary) visit field_slip_url(@field_slip) click_on "Edit this field slip", match: :first @@ -39,8 +36,9 @@ class FieldSlipsTest < ApplicationSystemTestCase end test "should destroy Field slip" do + login!(mary) visit field_slip_url(@field_slip) - click_on "Destroy this field slip", match: :first + click_on :field_slip_destroy.t, match: :first assert_text "Field slip was successfully destroyed" end From 13bd9acaf10139b2e25cf6936e8cc8f4bd68663f Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 24 Mar 2024 10:09:33 -0400 Subject: [PATCH 40/51] Fix for double observation bug --- app/controllers/observations_controller/new_and_create.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/observations_controller/new_and_create.rb b/app/controllers/observations_controller/new_and_create.rb index 3dd93287c6..da6cb5630d 100644 --- a/app/controllers/observations_controller/new_and_create.rb +++ b/app/controllers/observations_controller/new_and_create.rb @@ -112,7 +112,7 @@ def create success = false if @name && !@vote.value.nil? && !validate_object(@vote) success = false if @bad_images != [] success = false if success && !save_observation(@observation) - update_field_slip(@observation, params[:field_code]) + update_field_slip(@observation, params[:field_code]) if success # Once observation is saved we can save everything else. if success @@ -320,6 +320,7 @@ def reload_new_form(reasons) @reasons = @naming.init_reasons(reasons) @images = @bad_images @new_image.when = @observation.when + @field_code = params[:field_code] init_specimen_vars_for_reload init_project_vars_for_create init_project_vars_for_reload(@observation) From ed0dcda96e0377a5179dd97120433f4b4fb5cbee Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 24 Mar 2024 10:33:52 -0400 Subject: [PATCH 41/51] Fix field slip page titles and check that the observation has a thumbnail --- app/views/field_slips/_form.html.erb | 8 ++++++-- app/views/field_slips/edit.html.erb | 2 +- app/views/field_slips/index.html.erb | 4 ++-- app/views/field_slips/new.html.erb | 2 +- app/views/field_slips/show.html.erb | 2 ++ config/locales/en.txt | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb index ff3bfb389b..67f9c2e83b 100644 --- a/app/views/field_slips/_form.html.erb +++ b/app/views/field_slips/_form.html.erb @@ -25,7 +25,9 @@ current = field_slip.observation %>
      Current Observation:
      - <%= image_tag(Image.url(:thumbnail, current.thumb_image_id)) %>
      + <% if current.thumb_image_id %> + <%= image_tag(Image.url(:thumbnail, current.thumb_image_id)) %>
      + <% end %> <%= link_to(current.unique_format_name.t, observation_path(current)) %>

      @@ -47,7 +49,9 @@ if obs %>
      Last Observation:
      - <%= image_tag(Image.url(:thumbnail, obs.thumb_image_id)) %>
      + <% if obs.thumb_image_id %> + <%= image_tag(Image.url(:thumbnail, obs.thumb_image_id)) %>
      + <% end %> <%= link_to(obs.unique_format_name.t, observation_path(obs)) %>
      diff --git a/app/views/field_slips/edit.html.erb b/app/views/field_slips/edit.html.erb index 7c410a1b98..06277d96bc 100644 --- a/app/views/field_slips/edit.html.erb +++ b/app/views/field_slips/edit.html.erb @@ -1,4 +1,4 @@ -

      <%= :field_slip_editing.t %>

      +<% add_page_title(:field_slip_editing.t) %> <%= render "form", field_slip: @field_slip %> diff --git a/app/views/field_slips/index.html.erb b/app/views/field_slips/index.html.erb index aba67f2024..7d5d005e47 100644 --- a/app/views/field_slips/index.html.erb +++ b/app/views/field_slips/index.html.erb @@ -1,9 +1,9 @@ +<% add_page_title(:FIELD_SLIPS.t) %> + <% if notice %>

      <%= notice %>

      <% end %> -

      <%= :FIELD_SLIPS.t %>

      -
      <% @field_slips.each do |field_slip| %> <%= :field_slip_code.t %>: diff --git a/app/views/field_slips/new.html.erb b/app/views/field_slips/new.html.erb index 58db5e77bf..8bffb043e0 100644 --- a/app/views/field_slips/new.html.erb +++ b/app/views/field_slips/new.html.erb @@ -1,4 +1,4 @@ -

      <%= :field_slip_new.t %>

      +<% add_page_title(:field_slip_new.t) %> <%= render "form", field_slip: @field_slip %> diff --git a/app/views/field_slips/show.html.erb b/app/views/field_slips/show.html.erb index 938ec309dc..217f358a5e 100644 --- a/app/views/field_slips/show.html.erb +++ b/app/views/field_slips/show.html.erb @@ -1,3 +1,5 @@ +<% add_page_title(@field_slip.code) %> + <% if notice %>

      <%= notice %>

      <% end %> diff --git a/config/locales/en.txt b/config/locales/en.txt index a0c8a4426e..30c5802271 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2772,7 +2772,7 @@ field_slip_index: Back to field slips field_slip_keep_obs: Keep Above field_slip_last_obs: Use Last Observation - field_slip_new: New field slip + field_slip_new: Record Field Slip field_slip_no_observation: Observation not found field_slip_no_project: Project not found field_slip_show: Show this field slip From c22e89890b44def2543e785673da96f89b0d0cd3 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 24 Mar 2024 11:03:54 -0400 Subject: [PATCH 42/51] Fix test/system/field_slips_test.rb tests --- app/views/field_slips/_field_slip.html.erb | 6 ++++-- test/fixtures/field_slips.yml | 1 + test/system/field_slips_test.rb | 21 +++++++++------------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/field_slips/_field_slip.html.erb index 65a30a8c26..eb797180c4 100644 --- a/app/views/field_slips/_field_slip.html.erb +++ b/app/views/field_slips/_field_slip.html.erb @@ -7,8 +7,10 @@ <%= :field_slip_no_project.t %> <% end %>
      - <%= :field_slip_creator.t %>: - <%= link_to(field_slip.user.legal_name, user_path(field_slip.user_id)) %>
      + <% if field_slip.user %> + <%= :field_slip_creator.t %>: + <%= link_to(field_slip.user.legal_name, user_path(field_slip.user_id)) %>
      + <% end %> <%= :OBSERVATION.t %>: <% if field_slip.observation %> <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %> diff --git a/test/fixtures/field_slips.yml b/test/fixtures/field_slips.yml index 221ab368c5..ad8d396b19 100644 --- a/test/fixtures/field_slips.yml +++ b/test/fixtures/field_slips.yml @@ -20,3 +20,4 @@ field_slip_no_obs: field_slip_falmouth_one: project: falmouth_2023_09_project code: FAL-0001 + user: rolf diff --git a/test/system/field_slips_test.rb b/test/system/field_slips_test.rb index 078da77d62..c5dcb78c8a 100644 --- a/test/system/field_slips_test.rb +++ b/test/system/field_slips_test.rb @@ -16,30 +16,27 @@ class FieldSlipsTest < ApplicationSystemTestCase test "navigate to should field slip" do login!(mary) visit field_slips_url - click_on :field_slip_show.t + find(:xpath, '//*[@id="field_slips"]/a[1]').click assert_text :field_slip_index.t - click_on "Back" end - test "should update Field slip" do + test "should update field slip" do login!(mary) visit field_slip_url(@field_slip) - click_on "Edit this field slip", match: :first + click_on :field_slip_edit.t, match: :first - fill_in "Code", with: @field_slip.code - fill_in "Observation", with: @field_slip.observation_id - fill_in "Project", with: @field_slip.project_id - click_on "Update Field slip" + fill_in :field_slip_code.t, with: @field_slip.code + select(@field_slip.project.title, from: :PROJECT.t) + click_on :field_slip_keep_obs.t - assert_text "Field slip was successfully updated" - click_on "Back" + assert_text :field_slip_updated.t end - test "should destroy Field slip" do + test "should destroy field slip" do login!(mary) visit field_slip_url(@field_slip) click_on :field_slip_destroy.t, match: :first - assert_text "Field slip was successfully destroyed" + assert_text :field_slip_destroyed.t end end From 2914b7fd34b9f62c543e11b727231102c829195a Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 24 Mar 2024 11:06:23 -0400 Subject: [PATCH 43/51] Rubocop --- app/controllers/observations_controller/new_and_create.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/observations_controller/new_and_create.rb b/app/controllers/observations_controller/new_and_create.rb index da6cb5630d..165b3c4322 100644 --- a/app/controllers/observations_controller/new_and_create.rb +++ b/app/controllers/observations_controller/new_and_create.rb @@ -320,7 +320,7 @@ def reload_new_form(reasons) @reasons = @naming.init_reasons(reasons) @images = @bad_images @new_image.when = @observation.when - @field_code = params[:field_code] + @field_code = params[:field_code] init_specimen_vars_for_reload init_project_vars_for_create init_project_vars_for_reload(@observation) From e492cd7af6aab71eb25a821e7052015813974a00 Mon Sep 17 00:00:00 2001 From: andrew nimmo Date: Sun, 24 Mar 2024 14:52:49 -0700 Subject: [PATCH 44/51] Adjust form templates, use simplified matrix boxes for "current"/"last" --- .../field_slips/_field_slip.html.erb | 3 +- .../field_slips/_field_slip.json.jbuilder | 0 .../controllers/field_slips/_form.html.erb | 49 ++++++++++++++ .../field_slips/edit.html.erb | 0 .../field_slips/index.html.erb | 0 .../field_slips/index.json.jbuilder | 0 .../field_slips/new.html.erb | 0 .../field_slips/show.html.erb | 0 .../field_slips/show.json.jbuilder | 0 app/views/controllers/shared/_matrix_box.erb | 6 +- app/views/field_slips/_form.html.erb | 65 ------------------- 11 files changed, 55 insertions(+), 68 deletions(-) rename app/views/{ => controllers}/field_slips/_field_slip.html.erb (87%) rename app/views/{ => controllers}/field_slips/_field_slip.json.jbuilder (100%) create mode 100644 app/views/controllers/field_slips/_form.html.erb rename app/views/{ => controllers}/field_slips/edit.html.erb (100%) rename app/views/{ => controllers}/field_slips/index.html.erb (100%) rename app/views/{ => controllers}/field_slips/index.json.jbuilder (100%) rename app/views/{ => controllers}/field_slips/new.html.erb (100%) rename app/views/{ => controllers}/field_slips/show.html.erb (100%) rename app/views/{ => controllers}/field_slips/show.json.jbuilder (100%) delete mode 100644 app/views/field_slips/_form.html.erb diff --git a/app/views/field_slips/_field_slip.html.erb b/app/views/controllers/field_slips/_field_slip.html.erb similarity index 87% rename from app/views/field_slips/_field_slip.html.erb rename to app/views/controllers/field_slips/_field_slip.html.erb index eb797180c4..1b38068074 100644 --- a/app/views/field_slips/_field_slip.html.erb +++ b/app/views/controllers/field_slips/_field_slip.html.erb @@ -16,7 +16,8 @@ <%= link_to(field_slip.observation.unique_format_name.t, observation_path(field_slip.observation)) %>
        <%= render(partial: "shared/matrix_box", - locals: { object: field_slip.observation, columns: "col-xs-12" }) %> + locals: { object: field_slip.observation, + columns: "col-xs-12" }) %>
      <% else %> <%= :field_slip_no_observation.t %> diff --git a/app/views/field_slips/_field_slip.json.jbuilder b/app/views/controllers/field_slips/_field_slip.json.jbuilder similarity index 100% rename from app/views/field_slips/_field_slip.json.jbuilder rename to app/views/controllers/field_slips/_field_slip.json.jbuilder diff --git a/app/views/controllers/field_slips/_form.html.erb b/app/views/controllers/field_slips/_form.html.erb new file mode 100644 index 0000000000..689a3678c1 --- /dev/null +++ b/app/views/controllers/field_slips/_form.html.erb @@ -0,0 +1,49 @@ +<%= form_with(model: field_slip) do |form| %> + <% if field_slip.errors.any? %> +
      + <%= "#{pluralize(field_slip.errors.count, + :error.t, plural: :errors.t)} #{:field_slip_errors.t}" %>: +
        + <% field_slip.errors.each do |error| %> +
      • <%= error.full_message %>
      • + <% end %> +
      +
      + <% end %> + + <%= text_field_with_label(form: form, field: :code) %> + + <% if @field_slip.projects %> + <%= select_with_label(form: form, field: :project_id, + options: @field_slip.projects) %> + <% end %> + +
      + <% if field_slip.observation %> +
      + <% btn = submit_button(form: form, button: :field_slip_keep_obs.t) %> +
        + <%= render(partial: "shared/matrix_box", + locals: { object: field_slip.observation, votes: false, + footer: panel_block_footer(footer: btn), + columns: "col-xs-12" }) %> +
      +
      + <% end %> + <% if last_observation %> +
      + <% btn = submit_button(form: form, button: :field_slip_last_obs.t) %> +
        + <%= render(partial: "shared/matrix_box", + locals: { object: last_observation, votes: false, + footer: panel_block_footer(footer: btn), + columns: "col-xs-12" }) %> +
      +
      + <% end %> +
      + + <%= submit_button(form: form, button: :field_slip_create_obs.t, + class: "my-5") %> + +<% end %> diff --git a/app/views/field_slips/edit.html.erb b/app/views/controllers/field_slips/edit.html.erb similarity index 100% rename from app/views/field_slips/edit.html.erb rename to app/views/controllers/field_slips/edit.html.erb diff --git a/app/views/field_slips/index.html.erb b/app/views/controllers/field_slips/index.html.erb similarity index 100% rename from app/views/field_slips/index.html.erb rename to app/views/controllers/field_slips/index.html.erb diff --git a/app/views/field_slips/index.json.jbuilder b/app/views/controllers/field_slips/index.json.jbuilder similarity index 100% rename from app/views/field_slips/index.json.jbuilder rename to app/views/controllers/field_slips/index.json.jbuilder diff --git a/app/views/field_slips/new.html.erb b/app/views/controllers/field_slips/new.html.erb similarity index 100% rename from app/views/field_slips/new.html.erb rename to app/views/controllers/field_slips/new.html.erb diff --git a/app/views/field_slips/show.html.erb b/app/views/controllers/field_slips/show.html.erb similarity index 100% rename from app/views/field_slips/show.html.erb rename to app/views/controllers/field_slips/show.html.erb diff --git a/app/views/field_slips/show.json.jbuilder b/app/views/controllers/field_slips/show.json.jbuilder similarity index 100% rename from app/views/field_slips/show.json.jbuilder rename to app/views/controllers/field_slips/show.json.jbuilder diff --git a/app/views/controllers/shared/_matrix_box.erb b/app/views/controllers/shared/_matrix_box.erb index ba3b65c23e..d8dba76437 100644 --- a/app/views/controllers/shared/_matrix_box.erb +++ b/app/views/controllers/shared/_matrix_box.erb @@ -18,6 +18,9 @@ if presenter else image_args = {} end + footer_components = passed_args[:footer].presence || + [matrix_box_log_footer(presenter), + matrix_box_identify_footer(identify, presenter.id)] %> <%= matrix_box(columns: columns, id: object_id) do @@ -29,8 +32,7 @@ if presenter matrix_box_details(presenter, object_id, identify), ].safe_join end, - matrix_box_log_footer(presenter), - matrix_box_identify_footer(identify, presenter.id) + *footer_components ].safe_join end end %> diff --git a/app/views/field_slips/_form.html.erb b/app/views/field_slips/_form.html.erb deleted file mode 100644 index 67f9c2e83b..0000000000 --- a/app/views/field_slips/_form.html.erb +++ /dev/null @@ -1,65 +0,0 @@ -<%= form_with(model: field_slip) do |form| %> - <% if field_slip.errors.any? %> -
      - <%= "#{pluralize(field_slip.errors.count, - :error.t, plural: :errors.t)} #{:field_slip_errors.t}" %>: -
        - <% field_slip.errors.each do |error| %> -
      • <%= error.full_message %>
      • - <% end %> -
      -
      - <% end %> - -
      - <%= text_field_with_label(form: form, field: :code) %> -
      - - <% if @field_slip.projects %> -
      - <%= select_with_label(form: form, field: :project_id, options: @field_slip.projects) %> -
      - <% end %> - - <% if field_slip&.observation - current = field_slip.observation %> -
      - Current Observation:
      - <% if current.thumb_image_id %> - <%= image_tag(Image.url(:thumbnail, current.thumb_image_id)) %>
      - <% end %> - <%= link_to(current.unique_format_name.t, observation_path(current)) %> -
      -
      - <%= submit_button(form: form, button: :field_slip_keep_obs.t) %> -
      -
      - <% end %> - -
      - -
      - <%= submit_button(form: form, button: :field_slip_create_obs.t) %> -
      - -
      -
      - - <% obs = last_observation - if obs %> -
      - Last Observation:
      - <% if obs.thumb_image_id %> - <%= image_tag(Image.url(:thumbnail, obs.thumb_image_id)) %>
      - <% end %> - <%= link_to(obs.unique_format_name.t, observation_path(obs)) %> -
      - -
      - -
      - <%= submit_button(form: form, button: :field_slip_last_obs.t) %> -
      - - <% end %> -<% end %> From dbd283517a0c7b5d3c756b85b4d2e9bc57e9bcd6 Mon Sep 17 00:00:00 2001 From: andrew nimmo Date: Sun, 24 Mar 2024 15:13:30 -0700 Subject: [PATCH 45/51] Update _matrix_box.erb Make header/footer more flexible --- app/views/controllers/shared/_matrix_box.erb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/views/controllers/shared/_matrix_box.erb b/app/views/controllers/shared/_matrix_box.erb index d8dba76437..2559af3fdb 100644 --- a/app/views/controllers/shared/_matrix_box.erb +++ b/app/views/controllers/shared/_matrix_box.erb @@ -18,14 +18,21 @@ if presenter else image_args = {} end - footer_components = passed_args[:footer].presence || - [matrix_box_log_footer(presenter), - matrix_box_identify_footer(identify, presenter.id)] + header_components = passed_args[:header].presence || [] + footer_components = + if passed_args[:footer] == false + [] + else + passed_args[:footer].presence || + [matrix_box_log_footer(presenter), + matrix_box_identify_footer(identify, presenter.id)] + end %> <%= matrix_box(columns: columns, id: object_id) do tag.div(class: "panel panel-default") do [ + *header_components, tag.div(class: "panel-sizing") do [ matrix_box_image(image, **image_args), From 46539b38861b7cfcbe59e63910208d1af69685e1 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 24 Mar 2024 18:26:42 -0400 Subject: [PATCH 46/51] Tighten up new_and_create.rb code --- .../observations_controller/new_and_create.rb | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/app/controllers/observations_controller/new_and_create.rb b/app/controllers/observations_controller/new_and_create.rb index 165b3c4322..cb0594b75e 100644 --- a/app/controllers/observations_controller/new_and_create.rb +++ b/app/controllers/observations_controller/new_and_create.rb @@ -112,21 +112,14 @@ def create success = false if @name && !@vote.value.nil? && !validate_object(@vote) success = false if @bad_images != [] success = false if success && !save_observation(@observation) - update_field_slip(@observation, params[:field_code]) if success - - # Once observation is saved we can save everything else. - if success - @observation.log(:log_observation_created) - # should always succeed - save_everything_else(params.dig(:naming, :reasons)) - strip_images! if @observation.gps_hidden - flash_notice(:runtime_observation_success.t(id: @observation.id)) - redirect_to_next_page - - # If anything failed reload the form. - else - reload_new_form(params.dig(:naming, :reasons)) - end + return reload_new_form(params.dig(:naming, :reasons)) unless success + + @observation.log(:log_observation_created) + save_everything_else(params.dig(:naming, :reasons)) + strip_images! if @observation.gps_hidden + update_field_slip(@observation, params[:field_code]) + flash_notice(:runtime_observation_success.t(id: @observation.id)) + redirect_to_next_page end ############################################################################## From 9ee319c1173cf7a454e711be0da4ea699d34a683 Mon Sep 17 00:00:00 2001 From: andrew nimmo Date: Sun, 24 Mar 2024 15:54:57 -0700 Subject: [PATCH 47/51] Use simpler markup, but DRY --- .../controllers/field_slips/_obs_thumbnail.erb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/views/controllers/field_slips/_obs_thumbnail.erb diff --git a/app/views/controllers/field_slips/_obs_thumbnail.erb b/app/views/controllers/field_slips/_obs_thumbnail.erb new file mode 100644 index 0000000000..bde2bc60e4 --- /dev/null +++ b/app/views/controllers/field_slips/_obs_thumbnail.erb @@ -0,0 +1,14 @@ + <%= tag.div(class: "panel panel-default") do + [ + panel_block_heading( + heading: submit_button(form: form, button: button) + ), + tag.div(class: "thumbnail-container") do + interactive_image(obs.thumb_image_id, votes: false, + class: "img-responsive") + end, + tag.div(class: "panel-body") do + link_to(obs.unique_format_name.t, observation_path(obs)) + end + ].safe_join + end %> From 09f445855fae8f38ae545dc073e9001e990a7597 Mon Sep 17 00:00:00 2001 From: andrew nimmo Date: Sun, 24 Mar 2024 15:55:05 -0700 Subject: [PATCH 48/51] Update _form.html.erb --- .../controllers/field_slips/_form.html.erb | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/app/views/controllers/field_slips/_form.html.erb b/app/views/controllers/field_slips/_form.html.erb index 689a3678c1..5cc8ace361 100644 --- a/app/views/controllers/field_slips/_form.html.erb +++ b/app/views/controllers/field_slips/_form.html.erb @@ -18,32 +18,24 @@ options: @field_slip.projects) %> <% end %> + <%= submit_button(form: form, button: :field_slip_create_obs.t, + class: "my-5") %> +
      <% if field_slip.observation %>
      - <% btn = submit_button(form: form, button: :field_slip_keep_obs.t) %> -
        - <%= render(partial: "shared/matrix_box", - locals: { object: field_slip.observation, votes: false, - footer: panel_block_footer(footer: btn), - columns: "col-xs-12" }) %> -
      + <%= render(partial: "field_slips/obs_thumbnail", + locals: { obs: field_slip.observation, form: form, + button: :field_slip_keep_obs.t }) %>
      <% end %> <% if last_observation %>
      - <% btn = submit_button(form: form, button: :field_slip_last_obs.t) %> -
        - <%= render(partial: "shared/matrix_box", - locals: { object: last_observation, votes: false, - footer: panel_block_footer(footer: btn), - columns: "col-xs-12" }) %> -
      + <%= render(partial: "field_slips/obs_thumbnail", + locals: { obs: last_observation, form: form, + button: :field_slip_last_obs.t }) %>
      <% end %>
      - <%= submit_button(form: form, button: :field_slip_create_obs.t, - class: "my-5") %> - <% end %> From e81abcd7a5a6b917450efd8051a26db3ba8c2134 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Sun, 24 Mar 2024 20:12:43 -0400 Subject: [PATCH 49/51] Change the name of the link due to the page rearrangement --- config/locales/en.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.txt b/config/locales/en.txt index 4b81c3093b..6756b855bd 100644 --- a/config/locales/en.txt +++ b/config/locales/en.txt @@ -2772,7 +2772,7 @@ field_slip_editing: Editing Field Slip field_slip_errors: prohibited this field_slip from being saved field_slip_index: Back to field slips - field_slip_keep_obs: Keep Above + field_slip_keep_obs: Keep Current field_slip_last_obs: Use Last Observation field_slip_new: Record Field Slip field_slip_no_observation: Observation not found From 0702ccd4c5e5f9ec0669175c2a93e8bf591517de Mon Sep 17 00:00:00 2001 From: andrew nimmo Date: Sun, 24 Mar 2024 23:21:44 -0700 Subject: [PATCH 50/51] Different order for new/edit, fix image link bug --- .../controllers/field_slips/_form.html.erb | 11 ++++++++-- .../field_slips/_obs_thumbnail.erb | 22 +++++++++---------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/views/controllers/field_slips/_form.html.erb b/app/views/controllers/field_slips/_form.html.erb index 5cc8ace361..59bc645288 100644 --- a/app/views/controllers/field_slips/_form.html.erb +++ b/app/views/controllers/field_slips/_form.html.erb @@ -1,3 +1,7 @@ +<% +action = controller.action_name +%> + <%= form_with(model: field_slip) do |form| %> <% if field_slip.errors.any? %>
      @@ -19,9 +23,9 @@ <% end %> <%= submit_button(form: form, button: :field_slip_create_obs.t, - class: "my-5") %> + class: "mt-5") if action == "new" %> -
      +
      <% if field_slip.observation %>
      <%= render(partial: "field_slips/obs_thumbnail", @@ -38,4 +42,7 @@ <% end %>
      + <%= submit_button(form: form, button: :field_slip_create_obs.t, + class: "my-5") if action == "edit" %> + <% end %> diff --git a/app/views/controllers/field_slips/_obs_thumbnail.erb b/app/views/controllers/field_slips/_obs_thumbnail.erb index bde2bc60e4..92683315e8 100644 --- a/app/views/controllers/field_slips/_obs_thumbnail.erb +++ b/app/views/controllers/field_slips/_obs_thumbnail.erb @@ -1,14 +1,12 @@ <%= tag.div(class: "panel panel-default") do - [ - panel_block_heading( - heading: submit_button(form: form, button: button) - ), - tag.div(class: "thumbnail-container") do - interactive_image(obs.thumb_image_id, votes: false, - class: "img-responsive") - end, - tag.div(class: "panel-body") do - link_to(obs.unique_format_name.t, observation_path(obs)) - end - ].safe_join + concat(panel_block_heading( + heading: submit_button(form: form, button: button) + )) + concat(tag.div(class: "thumbnail-container") do + interactive_image(obs.thumb_image_id, votes: false, + image_link: observation_path(obs)) + end) if obs.thumb_image_id.present? + concat(tag.div(class: "panel-body") do + link_to(obs.unique_format_name.t, observation_path(obs)) + end) end %> From 87c26c048c4963641d8c92d18d34ffe7d0bb0bf1 Mon Sep 17 00:00:00 2001 From: Nathan Wilson Date: Mon, 25 Mar 2024 07:37:48 -0400 Subject: [PATCH 51/51] Add last observation to field slip project if appropriate --- app/controllers/field_slips_controller.rb | 22 ++++++++++++++----- .../field_slips_controller_test.rb | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/controllers/field_slips_controller.rb b/app/controllers/field_slips_controller.rb index 7d770be0ea..1c241a9605 100644 --- a/app/controllers/field_slips_controller.rb +++ b/app/controllers/field_slips_controller.rb @@ -46,7 +46,8 @@ def create @field_slip = FieldSlip.new(field_slip_params) respond_to do |format| - check_project_membership(@field_slip) + check_project_membership + check_for_last_obs if params[:commit] == :field_slip_last_obs.t @field_slip.observation = ObservationView.last(User.current) end @@ -72,9 +73,7 @@ def create # PATCH/PUT /field_slips/1 or /field_slips/1.json def update respond_to do |format| - if params[:commit] == :field_slip_last_obs.t - @field_slip.observation = ObservationView.last(User.current) - end + check_for_last_obs if @field_slip.update(field_slip_params) format.html do if params[:commit] == :field_slip_create_obs.t @@ -124,11 +123,22 @@ def field_slip_params params.require(:field_slip).permit(:observation_id, :project_id, :code) end - def check_project_membership(slip) - project = slip&.project + def check_project_membership + project = @field_slip&.project return unless project&.can_join?(User.current) project.user_group.users << User.current flash_notice(:field_slip_welcome.t(title: project.title)) end + + def check_for_last_obs + return unless params[:commit] == :field_slip_last_obs.t + + obs = ObservationView.last(User.current) + @field_slip.observation = obs + project = @field_slip.project + return unless obs && project&.user_can_add_observation?(obs, User.current) + + project.add_observation(obs) + end end diff --git a/test/controllers/field_slips_controller_test.rb b/test/controllers/field_slips_controller_test.rb index 13cc53b74b..bbf93ed9c6 100644 --- a/test/controllers/field_slips_controller_test.rb +++ b/test/controllers/field_slips_controller_test.rb @@ -179,6 +179,7 @@ class FieldSlipsControllerTest < FunctionalTestCase project_id: @field_slip.project_id } }) assert_redirected_to field_slip_url(@field_slip) assert_equal(@field_slip.observation, ObservationView.last(User.current)) + assert(@field_slip.project.observations.include?(obs)) end test "should update field_slip and redirect to create obs" do