Statuses in task - db field and forms

This commit is contained in:
2025-10-25 17:41:06 +03:00
parent b08468568b
commit ba2aad93af
12 changed files with 86 additions and 13 deletions
+5 -4
View File
@@ -17,11 +17,12 @@ class TasksController < ApplicationController
def show; end
def new
@form = Tasks::Create.new(project_id: fetch_project&.id)
@project = fetch_project || Project.order(:name).first
@form = Tasks::Create.new(project_id: @project.id)
end
def create
@form = Tasks::Create.new(params.expect(task: %i[project_id title description]))
@form = Tasks::Create.new(params.expect(task: %i[project_id title description status_id]))
if @form.perform
redirect_to tasks_path(project: @form.project)
else
@@ -30,11 +31,11 @@ class TasksController < ApplicationController
end
def edit
@form = Tasks::Update.new(id: @task.id, title: @task.title, description: @task.description)
@form = Tasks::Update.new(@task.attributes.slice(*Tasks::Update.attribute_names))
end
def update
@form = Tasks::Update.new(params.expect(task: %i[title description]))
@form = Tasks::Update.new(params.expect(task: %i[title description status_id]))
if @form.perform(@task)
redirect_to task_path(@task)
@@ -0,0 +1,22 @@
import { Controller } from '@hotwired/stimulus'
// TODO: unite with ProjectsSelectorController?
class FormProjectsSelectorController extends Controller {
static values = {
frame: String
}
connect() {
console.log("Connected", this.element)
}
changeProject(event) {
const loc = new URL(location)
const selected = event.target.selectedOptions[0]
const code = selected.dataset.code
loc.searchParams.set('project', code)
Turbo.visit(loc.toString(), {frame: this.frameValue})
}
}
export default FormProjectsSelectorController
+10
View File
@@ -2,9 +2,11 @@
class Task < ApplicationRecord
belongs_to :project
belongs_to :status, class_name: 'TaskStatus'
validates :number, :title, presence: true
validates :number, numericality: { greater_than: 0 }
validate :associations_should_have_same_project
has_rich_text :description
@@ -25,4 +27,12 @@ class Task < ApplicationRecord
project = Project.find_by!(code: project_code.downcase)
find_by!(project:, number:)
end
private
def associations_should_have_same_project
return if status&.project == project
errors.add(:status, "Doesn't belong in the same project")
end
end
+2
View File
@@ -7,4 +7,6 @@ class TaskStatus < ApplicationRecord
validates :name, presence: true, uniqueness: { scope: :project }
validates :category, presence: true
scope :default_order, -> { order(:category, :name) }
end
+8 -5
View File
@@ -5,18 +5,21 @@ module Tasks
attribute :project_id, :integer
attribute :title, :string
attribute :description, :string
attribute :status_id, :integer
validates :project_id, :title, presence: true
delegate :model_name, to: Task
attr_reader :project, :task
attr_reader :task
def project
@project ||= Project.find(project_id)
end
def perform
@project = Project.find(project_id)
@task = @project.tasks.build(title:, description:, number: @project.next_task_number)
@task.save.tap { @errors = @task.errors }
@task = project.tasks.build(title:, description:, status_id:, number: @project.next_task_number)
save @task
end
end
end
+2 -1
View File
@@ -5,6 +5,7 @@ module Tasks
attribute :id, :integer
attribute :title, :string
attribute :description, :string
attribute :status_id, :integer
validates :title, presence: true
@@ -15,7 +16,7 @@ module Tasks
def perform(task)
@task = task
@id = task.id
@task.assign_attributes(title:, description:)
@task.assign_attributes(title:, description:, status_id:)
save @task
end
end
+3
View File
@@ -3,6 +3,9 @@ h1
=< @task.full_number
= form_with model: @form do |form|
.field
= form.label :status_id
= form.select :status_id, current_project.task_statuses.default_order.map { |ts| [ts.name, ts.id] }
.field
= form.label :title
= form.text_field :title
+6 -2
View File
@@ -1,9 +1,13 @@
h1 New task
= form_with model: @form do |form|
= form_with model: @form, data: {controller: 'form-projects-selector', 'form-projects-selector-frame-value' => 'status_select'} do |form|
.field
= form.label :project_id
= form.select :project_id, Project.order(:name).map { |p| [p.name, p.id] }
= form.select :project_id, Project.order(:name).map { |p| [p.name, p.id, {'data-code': p.code}] }, {}, data: {action: 'form-projects-selector#changeProject'}
= turbo_frame_tag :status_select do
.field
= form.label :status_id
= form.select :status_id, TaskStatus.where(project: @form.project).default_order.map { |ts| [ts.name, ts.id] }
.field
= form.label :title
= form.text_field :title