diff --git a/app/controllers/bubbles_controller.rb b/app/controllers/bubbles_controller.rb index 226980d23..d8a642d3c 100644 --- a/app/controllers/bubbles_controller.rb +++ b/app/controllers/bubbles_controller.rb @@ -40,7 +40,7 @@ class BubblesController < ApplicationController end def bubble_params - params.expect(bubble: [ :status, :title, :color, :due_on, :image, tag_ids: [] ]) + params.expect(bubble: [ :status, :title, :color, :due_on, :image, :draft_comment, tag_ids: [] ]) end def deleted_notice diff --git a/app/javascript/controllers/remote_auto_save_controller.js b/app/javascript/controllers/remote_auto_save_controller.js new file mode 100644 index 000000000..7ba4a6d5e --- /dev/null +++ b/app/javascript/controllers/remote_auto_save_controller.js @@ -0,0 +1,13 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static outlets = [ "auto-save" ] + + change(event) { + this.autoSaveOutlet.change(event) + } + + submit() { + this.autoSaveOutlet.submit() + } +} diff --git a/app/models/bubble/messages.rb b/app/models/bubble/messages.rb index 552f2f483..e30f3dc62 100644 --- a/app/models/bubble/messages.rb +++ b/app/models/bubble/messages.rb @@ -3,9 +3,35 @@ module Bubble::Messages included do has_many :messages, -> { chronologically }, dependent: :destroy + after_save :capture_draft_comment end def capture(messageable) messages.create! messageable: messageable end + + def draft_comment + find_or_build_initial_comment.body_plain_text + end + + def draft_comment=(body) + if body.present? + @draft_comment = body + else + messages.comments.destroy_all + end + end + + private + def find_or_build_initial_comment + message = messages.comments.first || messages.new(messageable: Comment.new) + message.comment + end + + def capture_draft_comment + if @draft_comment.present? + find_or_build_initial_comment.update! body: @draft_comment, creator: creator + end + @draft_comment = nil + end end diff --git a/app/views/bubbles/_bubble.html.erb b/app/views/bubbles/_bubble.html.erb index db59e48f1..ea8833e50 100644 --- a/app/views/bubbles/_bubble.html.erb +++ b/app/views/bubbles/_bubble.html.erb @@ -8,14 +8,14 @@

- <% if bubble.creating? %> - <%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), data: { controller: "auto-save" } do |form| %> - <%= form.text_area :title, placeholder: "Name it…", class: "input input--textara txt-align-center full-width borderless bubble__title-rendered", autofocus: bubble.title.blank?, data: { action: "auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %> - <% end %> - <% else %> + <% if bubble.published? %> <%= turbo_frame_tag bubble, :edit do %> <%= link_to bubble_title(bubble), edit_bucket_bubble_path(bubble.bucket, bubble), class: "txt-undecorated bubble__title-rendered" %> <% end %> + <% else %> + <%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), id: "bubble_form", data: { controller: "auto-save" } do |form| %> + <%= form.text_area :title, placeholder: "Name it…", class: "input input--textara txt-align-center full-width borderless bubble__title-rendered", autofocus: bubble.title.blank?, data: { action: "auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %> + <% end %> <% end %>
diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb index 5e13be7d8..18126f584 100644 --- a/app/views/bubbles/show.html.erb +++ b/app/views/bubbles/show.html.erb @@ -92,17 +92,28 @@
<%= render "bubbles/bubble", bubble: @bubble %>
- + <% unless @bubble.drafted? || @bubble.creating? %> <%= render "bubbles/pop_toggle", bubble: @bubble %> <% end %>
- <%= render "bubbles/messages", bubble: @bubble %> + <% if @bubble.published? %> + <%= render "bubbles/messages", bubble: @bubble %> + <% else %> +
+
+
+ <%= tag.house_md @bubble.draft_comment, name: "bubble[draft_comment]", class: "input comment__input", form: "bubble_form", placeholder: new_comment_placeholder(@bubble), + data: { action: "house-md:change->remote-auto-save#change focusout->remote-auto-save#submit" } %> +
+
+
+ <% end %>
<% if @bubble.creating? %> -
+
<%= button_to "Save as draft", bucket_bubble_path(@bubble.bucket, @bubble), name: "bubble[status]", value: "drafted", method: :put, class: "btn btn--plain borderless fill-transparent" %> <%= button_to "Create bubble", bucket_bubble_publish_path(@bubble.bucket, @bubble), class: "btn btn--reversed" %>
diff --git a/test/controllers/bubbles_controller_test.rb b/test/controllers/bubbles_controller_test.rb index ccbe1c573..84dbb06ea 100644 --- a/test/controllers/bubbles_controller_test.rb +++ b/test/controllers/bubbles_controller_test.rb @@ -39,6 +39,7 @@ class BubblesControllerTest < ActionDispatch::IntegrationTest color: "#000000", due_on: 1.week.from_now, image: fixture_file_upload("moon.jpg", "image/jpeg"), + draft_comment: "Something more in-depth", tag_ids: [ tags(:mobile).id ] } } assert_redirected_to bucket_bubble_url(buckets(:writebook), bubbles(:logo)) @@ -48,6 +49,8 @@ class BubblesControllerTest < ActionDispatch::IntegrationTest assert_equal 1.week.from_now.to_date, bubble.due_on assert_equal "moon.jpg", bubble.image.filename.to_s assert_equal [ tags(:mobile) ], bubble.tags + + assert_equal "Something more in-depth", bubble.messages.comments.first.comment.body_plain_text.strip end test "users can only see bubbles in buckets they have access to" do diff --git a/test/models/bubble/messages_test.rb b/test/models/bubble/messages_test.rb new file mode 100644 index 000000000..d507ebd69 --- /dev/null +++ b/test/models/bubble/messages_test.rb @@ -0,0 +1,46 @@ +require "test_helper" + +class Bubble::MessagesTest < ActiveSupport::TestCase + test "creating a bubble does not create a message by default" do + bubble = buckets(:writebook).bubbles.create! creator: users(:kevin), title: "New" + + assert_empty bubble.messages + end + + test "creating a bubble with an initial draft comment" do + bubble = buckets(:writebook).bubbles.create! creator: users(:kevin), title: "New", + draft_comment: "This is a comment" + + assert_equal 1, bubble.messages.count + assert_equal "This is a comment", bubble.draft_comment.strip + end + + test "updating the draft comment" do + bubble = buckets(:writebook).bubbles.create! creator: users(:kevin), title: "New", + draft_comment: "This is a comment" + + bubble.update! draft_comment: "This is an updated comment" + + assert_equal 1, bubble.messages.count + assert_equal "This is an updated comment", bubble.draft_comment.strip + end + + test "setting the draft comment to be blank removes it" do + bubble = buckets(:writebook).bubbles.create! creator: users(:kevin), title: "New", + draft_comment: "This is a comment" + + bubble.update! draft_comment: " " + + assert bubble.messages.first.nil? + end + + test "omitting the draft comment does not remove it" do + bubble = buckets(:writebook).bubbles.create! creator: users(:kevin), title: "New", + draft_comment: "This is a comment" + + bubble.update! title: "Newer" + + assert_equal 1, bubble.messages.count + assert_equal "This is a comment", bubble.draft_comment.strip + end +end