From 6e9d223cff5d6d9ad3aeea49db05e61d70cdfd37 Mon Sep 17 00:00:00 2001 From: fujiwara-e Date: Sat, 4 Apr 2026 13:19:52 +0900 Subject: [PATCH 1/3] Update task card interactivity with Turbo Streams --- app/assets/stylesheets/tasks.scss | 1 + app/controllers/tasks_controller.rb | 1 + app/views/tasks/_task.html.erb | 54 ++++++++++++------------- app/views/tasks/update.turbo_stream.erb | 3 ++ 4 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 app/views/tasks/update.turbo_stream.erb diff --git a/app/assets/stylesheets/tasks.scss b/app/assets/stylesheets/tasks.scss index 73efd615..165d744e 100644 --- a/app/assets/stylesheets/tasks.scss +++ b/app/assets/stylesheets/tasks.scss @@ -40,6 +40,7 @@ .task-card { margin: 0; + transition: opacity 0.3s ease; } .task-state-btn i { diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index cc71570e..90c5b4d4 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -75,6 +75,7 @@ def update end respond_to do |format| + format.turbo_stream { render :update } format.html { redirect_to @task, notice: "タスクを更新しました." } format.json { render :show, status: :ok, location: @task } end diff --git a/app/views/tasks/_task.html.erb b/app/views/tasks/_task.html.erb index 1b8fb68a..f57a6c20 100644 --- a/app/views/tasks/_task.html.erb +++ b/app/views/tasks/_task.html.erb @@ -1,17 +1,16 @@ -
-
-
- <%= turbo_frame_tag "task_#{task.id}" do %> +<%= turbo_frame_tag "task_card_#{task.id}" do %> +
+
+
<% if task.completed? %> <%= button_to task, method: :patch, params: { task: { task_state_id: TaskState.todo.id } }, class: "btn btn-link p-0 border-0 task-state-btn" do %> <% end %> <% else %> - <%= button_to task, method: :patch, params: { task: { task_state_id: TaskState.todo.id } }, class: "btn btn-link p-0 border-0 task-state-btn" do %> + <%= button_to task, method: :patch, params: { task: { task_state_id: TaskState.done.id } }, class: "btn btn-link p-0 border-0 task-state-btn" do %> <% end %> <% end %> - <% end %> <% unless task.completed? %> <% if task.overdue? %>

期限切れです!

@@ -19,30 +18,31 @@

<%= days_to_deadline_as_string task %>

<% end %> <% end %> - - - <%= link_to task.assigner.name, task.assigner, class: "text-muted text-decoration-none" %> - -
+ + + <%= link_to task.assigner.name, task.assigner, class: "text-muted text-decoration-none" %> + +
-
-
- <%= link_to task.content.truncate(30), task, class: "text-black text-decoration-none card-link" %> -
+
+
+ <%= link_to task.content.truncate(30), task, class: "text-black text-decoration-none card-link" %> +
-
-
- <% if task.project %> - <%= link_to task.project.name, task.project, class: "task-project-badge" %> - <% end %> -
-
- <% task.tags.each do |tag| %> - <%= link_to tag.name, tag, class: "task-tag-badge" %> - <% end %> +
+
+ <% if task.project %> + <%= link_to task.project.name, task.project, class: "task-project-badge" %> + <% end %> +
+
+ <% task.tags.each do |tag| %> + <%= link_to tag.name, tag, class: "task-tag-badge" %> + <% end %> +
+ <%= task.show_days_ago.round.to_s + "日前" %>
- <%= task.show_days_ago.round.to_s + "日前" %>
-
+<% end %> diff --git a/app/views/tasks/update.turbo_stream.erb b/app/views/tasks/update.turbo_stream.erb new file mode 100644 index 00000000..248990bb --- /dev/null +++ b/app/views/tasks/update.turbo_stream.erb @@ -0,0 +1,3 @@ +<%= turbo_stream.replace "task_card_#{@task.id}" do %> + <%= render partial: "task", locals: { task: @task } %> +<% end %> From 2703ae79f08bc1a8c0b765e08cb7343fbbbbdeb2 Mon Sep 17 00:00:00 2001 From: fujiwara-e Date: Sat, 4 Apr 2026 13:58:38 +0900 Subject: [PATCH 2/3] Fix response for Turbo Frame requests --- app/controllers/tasks_controller.rb | 8 +++- app/views/tasks/_task.html.erb | 64 ++++++++++++++--------------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index 90c5b4d4..f9ba077e 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -75,7 +75,13 @@ def update end respond_to do |format| - format.turbo_stream { render :update } + format.turbo_stream do + if turbo_frame_request? + render :update + else + redirect_to @task, notice: "タスクを更新しました." + end + end format.html { redirect_to @task, notice: "タスクを更新しました." } format.json { render :show, status: :ok, location: @task } end diff --git a/app/views/tasks/_task.html.erb b/app/views/tasks/_task.html.erb index f57a6c20..3755230b 100644 --- a/app/views/tasks/_task.html.erb +++ b/app/views/tasks/_task.html.erb @@ -1,7 +1,7 @@ -<%= turbo_frame_tag "task_card_#{task.id}" do %> -
-
-
+
+
+
+ <%= turbo_frame_tag "task_state_btn_#{task.id}" do %> <% if task.completed? %> <%= button_to task, method: :patch, params: { task: { task_state_id: TaskState.todo.id } }, class: "btn btn-link p-0 border-0 task-state-btn" do %> @@ -11,38 +11,38 @@ <% end %> <% end %> - <% unless task.completed? %> - <% if task.overdue? %> -

期限切れです!

- <% else %> -

<%= days_to_deadline_as_string task %>

- <% end %> + <% end %> + <% unless task.completed? %> + <% if task.overdue? %> +

期限切れです!

+ <% else %> +

<%= days_to_deadline_as_string task %>

<% end %> - - - <%= link_to task.assigner.name, task.assigner, class: "text-muted text-decoration-none" %> - -
+ <% end %> + + + <%= link_to task.assigner.name, task.assigner, class: "text-muted text-decoration-none" %> + +
-
-
- <%= link_to task.content.truncate(30), task, class: "text-black text-decoration-none card-link" %> -
+
+
+ <%= link_to task.content.truncate(30), task, class: "text-black text-decoration-none card-link" %> +
-
-
- <% if task.project %> - <%= link_to task.project.name, task.project, class: "task-project-badge" %> - <% end %> -
-
- <% task.tags.each do |tag| %> - <%= link_to tag.name, tag, class: "task-tag-badge" %> - <% end %> -
- <%= task.show_days_ago.round.to_s + "日前" %> +
+
+ <% if task.project %> + <%= link_to task.project.name, task.project, class: "task-project-badge" %> + <% end %> +
+
+ <% task.tags.each do |tag| %> + <%= link_to tag.name, tag, class: "task-tag-badge" %> + <% end %>
+ <%= task.show_days_ago.round.to_s + "日前" %>
-<% end %> +
From bb76d913fdf6cb887e549bc9db01ecd8608cbf78 Mon Sep 17 00:00:00 2001 From: fujiwara-e Date: Sat, 4 Apr 2026 14:10:41 +0900 Subject: [PATCH 3/3] Enhance Turbo Stream responses for task updates and error handling --- app/controllers/tasks_controller.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index f9ba077e..68cc1243 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -89,15 +89,29 @@ def update flash.now[:danger] = 'このタスクは他のユーザーによって更新されました.' get_form_data respond_to do |format| + format.turbo_stream do + if turbo_frame_request? + render turbo_stream: turbo_stream.replace("task_card_#{@task.id}", partial: "tasks/task", locals: { task: @task }), status: :conflict + else + render :edit, status: :conflict + end + end format.html { render :edit, status: :conflict } - format.json { render json: { error: flash[:error] }, status: :conflict } + format.json { render json: { error: flash.now[:danger] }, status: :conflict } end rescue flash.now[:danger] = 'タスクの更新に失敗しました.' get_form_data respond_to do |format| + format.turbo_stream do + if turbo_frame_request? + render turbo_stream: turbo_stream.replace("task_card_#{@task.id}", partial: "tasks/task", locals: { task: @task }), status: :unprocessable_entity + else + render :edit, status: :unprocessable_entity + end + end format.html { render :edit, status: :unprocessable_entity } - format.json { render json: @document.errors, status: :unprocessable_entity } + format.json { render json: @task.errors, status: :unprocessable_entity } end end