Merge pull request #256 from basecamp/wire-draft-comment
Include initial comment in the form for new & draft bubbles
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user