Merge pull request #256 from basecamp/wire-draft-comment

Include initial comment in the form for new & draft bubbles
This commit is contained in:
Kevin McConnell
2025-02-13 16:26:55 +00:00
committed by GitHub
7 changed files with 108 additions and 9 deletions
+1 -1
View File
@@ -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
@@ -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()
}
}
+26
View File
@@ -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
+5 -5
View File
@@ -8,14 +8,14 @@
<div>
<h1 class="bubble__title">
<% 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 %>
<div class="bubble__tags flex flex-wrap align-end justify-center gap-half txt-tight-lines flex-item-no-shrink pad-inline-double">
+14 -3
View File
@@ -92,17 +92,28 @@
<div class="bubble__perma flex justify-center center">
<%= render "bubbles/bubble", bubble: @bubble %>
</div>
<% unless @bubble.drafted? || @bubble.creating? %>
<%= render "bubbles/pop_toggle", bubble: @bubble %>
<% end %>
<div style="margin-block-start: calc(var(--block-space) * -1);">
<%= render "bubbles/messages", bubble: @bubble %>
<% if @bubble.published? %>
<%= render "bubbles/messages", bubble: @bubble %>
<% else %>
<div class="comments">
<div class="comment comment--new border-radius flex align-start full-width margin-block-double">
<form data-controller="remote-auto-save" data-remote-auto-save-auto-save-outlet="#bubble_form" class="flex flex-column gap full-width">
<%= 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" } %>
</form>
</div>
</div>
<% end %>
</div>
<% if @bubble.creating? %>
<div class="bubble__actions-container center border-radius pad flex align-center justify-space-between gap pad-inline-double" style="--bubble-color: <%= @bubble.color %>; margin-block-start: calc(var(--block-space) * -2);">
<div class="bubble__actions-container center border-radius pad flex align-center justify-space-between gap pad-inline-double" style="--bubble-color: <%= @bubble.color %>;">
<%= 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" %>
</div>
@@ -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
+46
View File
@@ -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