Task status selector in index
This commit is contained in:
@@ -75,3 +75,15 @@ form {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
details.dropdown {
|
||||||
|
td & {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.small {
|
||||||
|
--pico-form-element-spacing-vertical: 0.25em;
|
||||||
|
--pico-form-element-spacing-horizontal: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class TasksController < ApplicationController
|
class TasksController < ApplicationController
|
||||||
before_action :fetch_task, only: %w[show edit update delete]
|
before_action :fetch_task, only: %w[show edit update delete change_status]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
self.current_project = fetch_project
|
self.current_project = fetch_project
|
||||||
@@ -11,7 +11,7 @@ class TasksController < ApplicationController
|
|||||||
Task.all
|
Task.all
|
||||||
end
|
end
|
||||||
|
|
||||||
@tasks = @tasks.includes(:project, :status)
|
@tasks = @tasks.includes(:status, project: :task_statuses)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
@@ -49,6 +49,19 @@ class TasksController < ApplicationController
|
|||||||
redirect_to tasks_path(project: @task.project)
|
redirect_to tasks_path(project: @task.project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def change_status
|
||||||
|
@form = Tasks::ChangeStatus.new(params.expect(task: :status_id))
|
||||||
|
|
||||||
|
if @form.perform(@task)
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to task_path(@task) }
|
||||||
|
format.turbo_stream
|
||||||
|
end
|
||||||
|
else
|
||||||
|
head :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_project
|
def fetch_project
|
||||||
|
|||||||
@@ -15,4 +15,12 @@ module TasksHelper
|
|||||||
|
|
||||||
content_tag(:span, status.name, class: ['badge', 'task-status', status.category.dasherize])
|
content_tag(:span, status.name, class: ['badge', 'task-status', status.category.dasherize])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def task_status_selector(task, selector_class: '', id: nil, with_form: false)
|
||||||
|
# TODO: extract into a component probably
|
||||||
|
|
||||||
|
raise 'You should pass id if you want the form' if with_form && id.blank?
|
||||||
|
|
||||||
|
render partial: 'tasks/status_selector', locals: { task:, selector_class:, id:, with_form: }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
class StatusSelectorController extends Controller {
|
||||||
|
static targets = ['form', 'statusField']
|
||||||
|
|
||||||
|
changeStatus(event) {
|
||||||
|
let statusId = event.currentTarget.dataset.statusId
|
||||||
|
this.statusFieldTarget.value = statusId
|
||||||
|
this.formTarget.requestSubmit()
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize() {
|
||||||
|
this.element.open = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StatusSelectorController
|
||||||
@@ -4,8 +4,6 @@ class ApplicationService
|
|||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
include ActiveModel::Attributes
|
include ActiveModel::Attributes
|
||||||
|
|
||||||
attr_reader :errors
|
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
# Override this
|
# Override this
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Tasks
|
||||||
|
class ChangeStatus < ApplicationService
|
||||||
|
attribute :status_id, :integer
|
||||||
|
|
||||||
|
validates :status_id, presence: true
|
||||||
|
attr_reader :task
|
||||||
|
|
||||||
|
delegate :model_name, to: Task
|
||||||
|
|
||||||
|
def perform(task)
|
||||||
|
@task = task
|
||||||
|
@id = task.id
|
||||||
|
|
||||||
|
return false unless valid?
|
||||||
|
|
||||||
|
@task.status_id = status_id
|
||||||
|
save @task
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
details.dropdown class=selector_class id=id data-controller="tasks--status-selector"
|
||||||
|
= render partial: 'status_selector_inner', locals: {selector_id: id, task:, with_form:}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
summary= task_status_badge task.status
|
||||||
|
ul
|
||||||
|
- task.project.task_statuses.default_order.each do |status|
|
||||||
|
li
|
||||||
|
a href="#" data-status-id="#{status.id}" data-action="tasks--status-selector#changeStatus:prevent" = task_status_badge status
|
||||||
|
- if with_form
|
||||||
|
= form_with model: Tasks::ChangeStatus.new, url: change_status_task_path(task), method: :patch, data: {'tasks--status-selector-target': 'form', action: 'turbo:submit-end->tasks--status-selector#finalize'} do |f|
|
||||||
|
= hidden_field_tag :selector_id, selector_id
|
||||||
|
= f.hidden_field :status_id, data: {'tasks--status-selector-target': 'statusField'}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
- selector_id = params.fetch(:selector_id)
|
||||||
|
= turbo_stream.update selector_id, render(partial: 'status_selector_inner', locals: {selector_id:, task: @task, with_form: true})
|
||||||
@@ -11,7 +11,8 @@ h1= tasks_index_title
|
|||||||
- cache task do
|
- cache task do
|
||||||
tr
|
tr
|
||||||
td= link_to task.full_number, task_path(task)
|
td= link_to task.full_number, task_path(task)
|
||||||
td= task_status_badge task.status
|
td
|
||||||
|
= task_status_selector task, selector_class: 'small', id: "task_status_selector_#{task.id}", with_form: true
|
||||||
td= task.title
|
td= task.title
|
||||||
td
|
td
|
||||||
= link_to 'Edit', edit_task_path(task)
|
= link_to 'Edit', edit_task_path(task)
|
||||||
|
|||||||
+3
-1
@@ -17,5 +17,7 @@ Rails.application.routes.draw do
|
|||||||
# root "posts#index"
|
# root "posts#index"
|
||||||
|
|
||||||
resources :projects
|
resources :projects
|
||||||
resources :tasks
|
resources :tasks do
|
||||||
|
patch :change_status, on: :member
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user