Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Move Dashboard project solutions to Hotwire. #3967

Merged
merged 1 commit into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/components/project_submissions/item_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<div id="<%= dom_id(project_submission) %>" data-id="<%= project_submission.id %>" data-sort-target="item" data-sort-code="<%= sort_code %>">
<div data-test-id="submission-item" class="relative py-6 border-solid border-t border-gray-300 flex flex-col md:flex-row justify-between md:items-center">

<div class="flex items-center mb-6 md:mb-0">
<%= render ProjectSubmissions::LikeComponent.new(project_submission) %>
<p class="truncate max-w-xs lgs:max-w-lg font-medium text-lg break-words"><%= project_submission.user.username %></p>
<div class="flex items-center mb-4 md:mb-0">
<%= render ProjectSubmissions::LikeComponent.new(project_submission:, current_users_submission: current_users_submission?) %>
<%= title %>
</div>

<div class="flex flex-row md:items-center">
Expand All @@ -30,7 +30,7 @@
class="hidden absolute right-0 z-10 mt-2 w-32 origin-top-right rounded-md bg-white dark:bg-gray-700 py-2 shadow-lg ring-1 ring-gray-900/5 dark:ring-gray-300/5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="options-menu-0-button" tabindex="-1">

<% if project_submission.user == current_user %>
<%= link_to edit_lesson_v2_project_submission_path(project_submission.lesson, project_submission), class: 'text-gray-700 dark:text-gray-300 group flex items-center px-4 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 hover:text-gray-900 dark:hover:text-gray-200', role: 'menuitem', tabindex: '-1', data: { turbo_frame: 'modal', test_id: 'edit-submission', action: 'click->visibility#off'} do %>
<%= link_to edit_path, class: 'text-gray-700 dark:text-gray-300 group flex items-center px-4 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 hover:text-gray-900 dark:hover:text-gray-200', role: 'menuitem', tabindex: '-1', data: { turbo_frame: 'modal', test_id: 'edit-submission', action: 'click->visibility#off'} do %>
<%= inline_svg_tag 'icons/pencil-square.svg', class: 'mr-3 h-4 w-4 text-gray-400 group-hover:text-gray-500 dark:group-hover:text-gray-300', aria: true, title: 'edit', desc: 'edit icon' %>
Edit
<% end %>
Expand Down
16 changes: 14 additions & 2 deletions app/components/project_submissions/item_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ class ItemComponent < ApplicationComponent
CURRENT_USER_SORT_CODE = 10_000_000 # current user's submission should always be first

with_collection_parameter :project_submission
renders_one :title, ProjectSubmissions::TitleComponent

def initialize(project_submission:, current_user:)
def initialize(project_submission:, current_user:, edit_path: nil)
@project_submission = project_submission
@current_user = current_user
@edit_path = edit_path
end

def render?
Expand All @@ -17,10 +19,20 @@ def render?

attr_reader :project_submission, :current_user

def current_users_submission?
project_submission.user == current_user
end

def sort_code
return CURRENT_USER_SORT_CODE if project_submission.user == current_user
return CURRENT_USER_SORT_CODE if current_users_submission?

project_submission.cached_votes_total
end

def edit_path
return @edit_path if @edit_path.present?

edit_lesson_v2_project_submission_path(project_submission.lesson, project_submission)
end
end
end
2 changes: 1 addition & 1 deletion app/components/project_submissions/like_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= turbo_frame_tag dom_id(project_submission, :likes) do %>
<%= button_to project_submission_v2_like_path(project_submission), method: http_action, class: 'text-gray-400 mr-4 flex items-center hint--top', data: { test_id: 'like-submission' }, aria: { label: 'Like submission' } do %>
<%= button_to project_submission_v2_like_path(project_submission), method: http_action, disabled: current_users_submission, class: "text-gray-400 mr-4 flex items-center #{'hint--top' unless current_users_submission}", data: { test_id: 'like-submission' }, aria: { label: 'Like submission' } do %>
<span class="mr-1" data-test-id="like-count"><%= project_submission.cached_votes_total %></span>
<%= inline_svg_tag 'icons/heart.svg', class: "h-5 w-5 #{bg_color_class}", aria: true, title: 'heart', desc: 'heart icon' %>
<% end %>
Expand Down
9 changes: 6 additions & 3 deletions app/components/project_submissions/like_component.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
module ProjectSubmissions
class LikeComponent < ApplicationComponent
def initialize(project_submission)
def initialize(project_submission:, current_users_submission: false)
@project_submission = project_submission
@current_users_submission = current_users_submission
end

private

attr_reader :project_submission
attr_reader :project_submission, :current_users_submission

def http_action
project_submission.liked? ? :delete : :post
end

def bg_color_class
project_submission.liked? ? 'text-teal-700' : 'text-gray-400'
return 'text-teal-700' if current_users_submission || project_submission.liked?

'text-gray-400'
end
end
end
5 changes: 5 additions & 0 deletions app/components/project_submissions/title_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<% if url.present? %>
<%= link_to title, url, class: 'truncate max-w-xs lgs:max-w-lg font-medium text-lg break-words hover:text-gray-800', data: { turbo_frame: '_top' } %>
<% else %>
<p class="truncate max-w-xs lgs:max-w-lg font-medium text-lg break-words"><%= title %></p>
<% end %>
12 changes: 12 additions & 0 deletions app/components/project_submissions/title_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module ProjectSubmissions
class TitleComponent < ApplicationComponent
def initialize(title:, url: nil)
@title = title
@url = url
end

private

attr_reader :title, :url
end
end
2 changes: 2 additions & 0 deletions app/controllers/lessons/v2_project_submissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def create

respond_to do |format|
if @project_submission.save
@project_submission.like!(current_user)

format.html { redirect_to lesson_path(@lesson), notice: 'Project submitted' }
format.turbo_stream
else
Expand Down
27 changes: 27 additions & 0 deletions app/controllers/users/project_submissions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Users
class ProjectSubmissionsController < ApplicationController
before_action :authenticate_user!

def edit
@project_submission = current_user.project_submissions.find(params[:id])
end

def update
@project_submission = current_user.project_submissions.find(params[:id])

respond_to do |format|
if @project_submission.update(project_submission_params)
format.turbo_stream
else
format.html { render :edit, status: :unprocessable_entity }
end
end
end

private

def project_submission_params
params.require(:project_submission).permit(:repo_url, :live_preview_url, :is_public)
end
end
end
1 change: 1 addition & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ class UsersController < ApplicationController

def show
@courses = current_user.path.courses
@project_submissions = current_user.project_submissions.includes(:lesson).order(created_at: :desc)
end
end
1 change: 1 addition & 0 deletions app/queries/lesson_project_submissions_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def current_user_submission
def public_submissions
lesson.project_submissions
.only_public
.includes(:user)
.not_removed_by_admin
.where.not(user: current_user)
.order(cached_votes_total: :desc, created_at: :desc)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<%= turbo_stream.prepend 'submissions-list' do %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user:) %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user:) do |component| %>
<%= component.with_title(title: current_user.username, url: dashboard_path) %>
<% end %>
<% end %>

<%= turbo_stream.remove 'project-solutions-blank-state' %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/lessons/v2_project_submissions/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +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) %>
<%= render 'project_submissions/form', project_submission: @project_submission, url: lesson_v2_project_submission_path(@lesson, @project_submission) %>
<% end %>
11 changes: 9 additions & 2 deletions app/views/lessons/v2_project_submissions/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@

<%= turbo_frame_tag 'submissions-list', data: { test_id: 'submissions-list', controller: 'sort' } do %>
<% if @lesson.project_submissions.any? %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @current_user_submission, current_user:) %>
<%= render ProjectSubmissions::ItemComponent.with_collection(@project_submissions, current_user:) %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @current_user_submission, current_user:) do |component| %>
<%= component.with_title(title: current_user.username, url: dashboard_path) %>
<% end %>

<% @project_submissions.each do |project_submission| %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission:, current_user:) do |component| %>
<%= component.with_title(title: project_submission.user.username) %>
<% end %>
<% end %>
<% else %>
<% render 'lessons/v2_project_submissions/blank_state' %>
<% end %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/lessons/v2_project_submissions/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<%= render ModalComponent.new(title: 'Submit your project') do %>
<%= render 'lessons/v2_project_submissions/form', project_submission: @project_submission, url: lesson_v2_project_submissions_path(@lesson) %>
<%= render 'project_submissions/form', project_submission: @project_submission, url: lesson_v2_project_submissions_path(@lesson) %>
<% end %>
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<%= turbo_stream.replace @project_submission do %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user:) %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user:) do |component| %>
<%= component.with_title(title: current_user.username, url: dashboard_path) %>
<% end %>
<% end %>
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<%= turbo_stream.replace @project_submission do %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user:) %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user:) do |component| %>
<%= component.with_title(title: @project_submission.user.username) %>
<% end %>
<% end %>
28 changes: 19 additions & 9 deletions app/views/users/_project_submissions.html.erb
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
<div class="mb-12">
<h2 class="text-gray-700 text-2xl font-medium text-center mb-4 dark:text-gray-300">Project Submissions</h2>

<% if project_submissions.any? %>
<%= react_component(
'project-submissions/user-project-submissions',
{
userId: current_user&.id,
submissions: project_submissions.map { |submission| ProjectSubmissionSerializer.as_json(submission, current_user) },
}
) %>
<% if project_submissions.any? %>
<% if Feature.enabled?(:v2_project_submissions, current_user) %>
<div data-test-id="user-submissions-list">
<% project_submissions.each do |project_submission| %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission:, current_user:, edit_path: edit_users_project_submission_path(project_submission)) do |component| %>
<%= component.with_title(title: project_submission.lesson.display_title, url: lesson_path(project_submission.lesson)) %>
<% end %>
<% end %>
</div>
<% else %>
<h3 class="text-gray-500 text-center text-lg dark:text-gray-400">No submissions yet</h3>
<%= react_component(
'project-submissions/user-project-submissions',
{
userId: current_user&.id,
submissions: project_submissions.map { |submission| ProjectSubmissionSerializer.as_json(submission, current_user) },
}
) %>
<% end %>
<% else %>
<h3 class="text-gray-500 text-center text-lg dark:text-gray-400">No submissions yet</h3>
<% end %>
</div>
3 changes: 3 additions & 0 deletions app/views/users/project_submissions/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= render ModalComponent.new(title: 'Update your project') do %>
<%= render 'project_submissions/form', project_submission: @project_submission, url: users_project_submission_path(@project_submission) %>
<% end %>
5 changes: 5 additions & 0 deletions app/views/users/project_submissions/update.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= turbo_stream.replace @project_submission do %>
<%= render ProjectSubmissions::ItemComponent.new(project_submission: @project_submission, current_user:, edit_path: edit_users_project_submission_path(@project_submission)) do |component| %>
<%= component.with_title(title: @project_submission.lesson.display_title, url: lesson_path(@project_submission.lesson)) %>
<% end %>
<% end %>
2 changes: 1 addition & 1 deletion app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<%= render partial: 'skill', collection: @courses, as: :course %>
</div>

<%= render 'project_submissions', project_submissions: current_user.project_submissions %>
<%= render 'project_submissions', project_submissions: @project_submissions %>
</div>

<%= render 'shared/bottom_cta',
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
resources :paths, only: :create
resources :progress, only: :destroy
resource :profile, only: %i[edit update]
resources :project_submissions, only: %i[edit update]
end

namespace :lessons do
Expand Down
75 changes: 20 additions & 55 deletions spec/system/v2_lesson_project_submissions/like_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,32 @@
let(:user) { create(:user) }
let(:lesson) { create(:lesson, :project) }

context "when liking other users' submissions" do
before do
Flipper.enable(:v2_project_submissions)
create(:project_submission, lesson:)
before do
Flipper.enable(:v2_project_submissions)
create(:project_submission, lesson:)

sign_in(user)
visit lesson_path(lesson)
end

after do
Flipper.disable(:v2_project_submissions)
end

it 'you can like another users submission' do
within(:test_project_submission, 1) do
expect(find(:test_id, 'like-count')).to have_content('0')
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('1')
end
end

it 'you can unlike another users submission' do
within(:test_project_submission, 1) do
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('1')
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('0')
end
end
sign_in(user)
visit lesson_path(lesson)
end

context 'when liking your own submission' do
before do
Flipper.enable(:v2_project_submissions)
create(:project_submission, lesson:, user:)

sign_in(user)
visit lesson_path(lesson)
end

after do
Flipper.disable(:v2_project_submissions)
end
after do
Flipper.disable(:v2_project_submissions)
end

it 'you can like your submission' do
within(:test_project_submission, 1) do |submission|
expect(submission).to have_content(user.username)
expect(find(:test_id, 'like-count')).to have_content('0')
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('1')
end
it 'you can like another users submission' do
within(:test_project_submission, 1) do
expect(find(:test_id, 'like-count')).to have_content('0')
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('1')
end
end

it 'you can unlike your submission' do
within(:test_project_submission, 1) do |submission|
expect(submission).to have_content(user.username)
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('1')
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('0')
end
it 'you can unlike another users submission' do
within(:test_project_submission, 1) do
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('1')
find(:test_id, 'like-submission').click
expect(find(:test_id, 'like-count')).to have_content('0')
end
end
end
35 changes: 35 additions & 0 deletions spec/system/v2_user_project_submissions/delete_submission_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'rails_helper'

RSpec.describe 'Deleting a Project Submission on the Dashboard' do
let(:user) { create(:user) }
let(:lesson) { create(:lesson, :project) }

before do
Flipper.enable(:v2_project_submissions)

create(:project_submission, user:, lesson:)
sign_in(user)
visit dashboard_path
end

after do
Flipper.disable(:v2_project_submissions)
end

it 'successfully deletes a submission' do
sleep 0.1 # it will not open the dropdown without this
within(:test_id, 'user-submissions-list') do
expect(page).to have_content(lesson.title)
end

find(:test_id, 'submission-action-menu-btn').click

page.accept_confirm do
find(:test_id, 'delete-submission').click
end

within(:test_id, 'user-submissions-list') do
expect(page).not_to have_content(lesson.title)
end
end
end
Loading