From 56dd76c033f5980f8f12211a87460ee4ab7c8e79 Mon Sep 17 00:00:00 2001 From: Kevin Mulhern Date: Tue, 4 Jul 2023 19:19:23 +0100 Subject: [PATCH] Feature: Edit and Delete Submission with Hotwire (#3907) Because: * We are moving our project submissions feature to Hotwire This commit: * Add action menu to every project submission. The users submission will display edit and delete links, everyone else's will have the report link (yet to be implemented) * Add edit and update actions/views for v2 project submissions * Add delete action for v2 project submissions --- app/assets/images/icons/pencil-square.svg | 3 + .../item_component.html.erb | 61 ++++++++++++++----- .../project_submissions/item_component.rb | 11 ++-- .../v2_project_submissions_controller.rb | 24 ++++++++ .../v2_project_submissions/_form.html.erb | 2 +- .../create.turbo_stream.erb | 2 +- .../v2_project_submissions/edit.html.erb | 3 + .../v2_project_submissions/index.html.erb | 4 +- .../v2_project_submissions/new.html.erb | 2 +- .../update.turbo_stream.erb | 3 + config/routes.rb | 2 +- .../delete_submission_spec.rb | 38 ++++++++++++ .../edit_submission_spec.rb | 47 ++++++++++++++ 13 files changed, 177 insertions(+), 25 deletions(-) create mode 100644 app/assets/images/icons/pencil-square.svg create mode 100644 app/views/lessons/v2_project_submissions/edit.html.erb create mode 100644 app/views/lessons/v2_project_submissions/update.turbo_stream.erb create mode 100644 spec/system/v2_lesson_project_submissions/delete_submission_spec.rb create mode 100644 spec/system/v2_lesson_project_submissions/edit_submission_spec.rb diff --git a/app/assets/images/icons/pencil-square.svg b/app/assets/images/icons/pencil-square.svg new file mode 100644 index 0000000000..59e73daca7 --- /dev/null +++ b/app/assets/images/icons/pencil-square.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/components/project_submissions/item_component.html.erb b/app/components/project_submissions/item_component.html.erb index c71500c3e4..46f2efd718 100644 --- a/app/components/project_submissions/item_component.html.erb +++ b/app/components/project_submissions/item_component.html.erb @@ -1,21 +1,52 @@ -
+<%= turbo_frame_tag project_submission do %> +
-
+
- + -

<%= item.user.username %>

-
+

<%= project_submission.user.username %>

+
+ +
+ <%= link_to 'View code', project_submission.repo_url, target: '_blank', rel: 'noreferrer', class: 'button button--gray font-semibold md:mr-4', data: { test_id: 'view-code-btn' } %> + <%= link_to 'Live preview', project_submission.live_preview_url, target: '_blank', rel: 'noreferrer', class: 'button button--gray font-semibold mt-5 md:mt-0 md:mr-4', data: { test_id: 'live-preview-btn' } %> + +
+ + + - +
-
+<% end %> diff --git a/app/components/project_submissions/item_component.rb b/app/components/project_submissions/item_component.rb index 9f9ea84476..47cf993067 100644 --- a/app/components/project_submissions/item_component.rb +++ b/app/components/project_submissions/item_component.rb @@ -1,15 +1,18 @@ module ProjectSubmissions class ItemComponent < ApplicationComponent - def initialize(item:) - @item = item + with_collection_parameter :project_submission + + def initialize(project_submission:, current_user:) + @project_submission = project_submission + @current_user = current_user end def render? - item.present? + project_submission.present? end private - attr_reader :item + attr_reader :project_submission, :current_user end end diff --git a/app/controllers/lessons/v2_project_submissions_controller.rb b/app/controllers/lessons/v2_project_submissions_controller.rb index e619885295..bd90a8f4ce 100644 --- a/app/controllers/lessons/v2_project_submissions_controller.rb +++ b/app/controllers/lessons/v2_project_submissions_controller.rb @@ -12,6 +12,10 @@ def new @project_submission = current_user.project_submissions.new(lesson: @lesson) end + def edit + @project_submission = current_user.project_submissions.find(params[:id]) + end + def create @project_submission = current_user.project_submissions.new(project_submission_params.merge(lesson: @lesson)) @@ -25,6 +29,26 @@ def create end end + def update + @project_submission = current_user.project_submissions.find(params[:id]) + + respond_to do |format| + if @project_submission.update!(project_submission_params) + format.html { redirect_to lesson_path(@lesson), notice: 'Project updated' } + format.turbo_stream + else + format.html { render :edit, status: :unprocessable_entity } + end + end + end + + def destroy + @project_submission = current_user.project_submissions.find(params[:id]) + @project_submission.destroy + + render turbo_stream: turbo_stream.remove(@project_submission) + end + private def project_submissions_query diff --git a/app/views/lessons/v2_project_submissions/_form.html.erb b/app/views/lessons/v2_project_submissions/_form.html.erb index 123e7b677f..9afc48d7a3 100644 --- a/app/views/lessons/v2_project_submissions/_form.html.erb +++ b/app/views/lessons/v2_project_submissions/_form.html.erb @@ -1,5 +1,5 @@ <%= turbo_frame_tag 'project_submission_form', class: 'w-full' do %> - <%= form_with url: lesson_v2_project_submissions_path(lesson.id), model: project_submission, builder: TailwindFormBuilder do |form| %> + <%= form_with url:, model: project_submission, builder: TailwindFormBuilder do |form| %>
diff --git a/app/views/lessons/v2_project_submissions/create.turbo_stream.erb b/app/views/lessons/v2_project_submissions/create.turbo_stream.erb index 51640738e2..eb1006bd27 100644 --- a/app/views/lessons/v2_project_submissions/create.turbo_stream.erb +++ b/app/views/lessons/v2_project_submissions/create.turbo_stream.erb @@ -1,5 +1,5 @@ <%= turbo_stream.prepend "submissions-list" do %> - <%= render ProjectSubmissions::ItemComponent.new(item: @project_submission) %> + <%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user: current_user) %> <% end %> <%= turbo_stream.remove "add-submission-button" %> diff --git a/app/views/lessons/v2_project_submissions/edit.html.erb b/app/views/lessons/v2_project_submissions/edit.html.erb new file mode 100644 index 0000000000..b89db18b18 --- /dev/null +++ b/app/views/lessons/v2_project_submissions/edit.html.erb @@ -0,0 +1,3 @@ +<%= render ModalComponent.new(title: 'Update your project') do %> + <%= render 'lessons/v2_project_submissions/form', project_submission: @project_submission, url: lesson_v2_project_submission_path(@lesson, @project_submission) %> +<% end %> diff --git a/app/views/lessons/v2_project_submissions/index.html.erb b/app/views/lessons/v2_project_submissions/index.html.erb index 1d51ab4173..9ee9496f06 100644 --- a/app/views/lessons/v2_project_submissions/index.html.erb +++ b/app/views/lessons/v2_project_submissions/index.html.erb @@ -24,8 +24,8 @@ <%= turbo_frame_tag 'submissions-list', data: { test_id: 'submissions-list' } do %> - <%= render ProjectSubmissions::ItemComponent.new(item: @current_user_submission) %> - <%= render ProjectSubmissions::ItemComponent.with_collection(@project_submissions) %> + <%= render ProjectSubmissions::ItemComponent.new(project_submission: @current_user_submission, current_user:) %> + <%= render ProjectSubmissions::ItemComponent.with_collection(@project_submissions, current_user:) %> <% end %>
<% end %> diff --git a/app/views/lessons/v2_project_submissions/new.html.erb b/app/views/lessons/v2_project_submissions/new.html.erb index ed4435641c..b78d1eecdb 100644 --- a/app/views/lessons/v2_project_submissions/new.html.erb +++ b/app/views/lessons/v2_project_submissions/new.html.erb @@ -1,3 +1,3 @@ <%= render ModalComponent.new(title: 'Submit your project') do %> - <%= render 'lessons/v2_project_submissions/form', lesson: @lesson, project_submission: @project_submission %> + <%= render 'lessons/v2_project_submissions/form', project_submission: @project_submission, url: lesson_v2_project_submissions_path(@lesson) %> <% end %> diff --git a/app/views/lessons/v2_project_submissions/update.turbo_stream.erb b/app/views/lessons/v2_project_submissions/update.turbo_stream.erb new file mode 100644 index 0000000000..8669c54adb --- /dev/null +++ b/app/views/lessons/v2_project_submissions/update.turbo_stream.erb @@ -0,0 +1,3 @@ +<%= turbo_stream.replace @project_submission do %> + <%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user: current_user) %> +<% end %> diff --git a/config/routes.rb b/config/routes.rb index d89f88f429..71f91be328 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -94,7 +94,7 @@ resources :lessons, only: :show do resources :project_submissions, only: %i[index], controller: 'lessons/project_submissions' - resources :v2_project_submissions, only: %i[index new create], controller: 'lessons/v2_project_submissions' + resources :v2_project_submissions, controller: 'lessons/v2_project_submissions' resource :completion, only: %i[create destroy], controller: 'lessons/completions' end diff --git a/spec/system/v2_lesson_project_submissions/delete_submission_spec.rb b/spec/system/v2_lesson_project_submissions/delete_submission_spec.rb new file mode 100644 index 0000000000..885fedcb7d --- /dev/null +++ b/spec/system/v2_lesson_project_submissions/delete_submission_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' + +RSpec.describe 'Deleting a Project Submission' do + let(:user) { create(:user) } + let(:lesson) { create(:lesson, :project) } + + before do + Flipper.enable(:v2_project_submissions) + + sign_in(user) + visit lesson_path(lesson) + Pages::ProjectSubmissions::Form.new.open.fill_in.submit + end + + after do + Flipper.disable(:v2_project_submissions) + end + + it 'removes a submission' do + users_submission = first(:test_id, 'submission-item') + + within(:test_id, 'submissions-list') do + expect(page).to have_content(user.username) + end + + within(users_submission) do + find(:test_id, 'submission-action-menu-btn').click + + page.accept_confirm do + find(:test_id, 'delete-submission').click + end + end + + within(:test_id, 'submissions-list') do + expect(page).not_to have_content(user.username) + end + end +end diff --git a/spec/system/v2_lesson_project_submissions/edit_submission_spec.rb b/spec/system/v2_lesson_project_submissions/edit_submission_spec.rb new file mode 100644 index 0000000000..22024d9aea --- /dev/null +++ b/spec/system/v2_lesson_project_submissions/edit_submission_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +RSpec.describe 'Editing a Project Submission' do + let(:user) { create(:user) } + let(:lesson) { create(:lesson, :project) } + let(:edited_field_values) do + { + repo_url: 'https://github.com/edited-project-repo-url', + live_preview_url: 'http://edited-live-preview-url.com' + } + end + + before do + Flipper.enable(:v2_project_submissions) + + sign_in(user) + visit lesson_path(lesson) + Pages::ProjectSubmissions::Form.new.open.fill_in.submit + end + + after do + Flipper.disable(:v2_project_submissions) + end + + it 'successfully edits a submission' do + users_submission = first(:test_id, 'submission-item') + + within(users_submission) do + find(:test_id, 'submission-action-menu-btn').click + find(:test_id, 'edit-submission').click + end + + Pages::ProjectSubmissions::Form.new(**edited_field_values).tap do |form| + form.fill_in + form.submit + end + + # We need to find the user submission again because it is replaced by a turbo stream + users_submission = first(:test_id, 'submission-item') + + within(users_submission) do + expect(users_submission).to have_content(user.username) + expect(users_submission.find(:test_id, 'view-code-btn')['href']).to eq('https://github.com/edited-project-repo-url') + expect(users_submission.find(:test_id, 'live-preview-btn')['href']).to eq('http://edited-live-preview-url.com/') + end + end +end