diff --git a/app/assets/stylesheets/bubbles.css b/app/assets/stylesheets/bubbles.css index 91b65091e..9b7f88d5e 100644 --- a/app/assets/stylesheets/bubbles.css +++ b/app/assets/stylesheets/bubbles.css @@ -443,6 +443,10 @@ border: var(--bubble-border-width) solid var(--bubble-color); } + .bubble.drafted & { + border-style: dashed; + } + .bubble:has(.bubble__link) & { z-index: -1; } diff --git a/app/controllers/bubbles/publishes_controller.rb b/app/controllers/bubbles/publishes_controller.rb new file mode 100644 index 000000000..947311bd6 --- /dev/null +++ b/app/controllers/bubbles/publishes_controller.rb @@ -0,0 +1,8 @@ +class Bubbles::PublishesController < ApplicationController + include BubbleScoped, BucketScoped + + def create + @bubble.published! + redirect_to @bubble + end +end diff --git a/app/controllers/bubbles_controller.rb b/app/controllers/bubbles_controller.rb index 920b8b181..8aa6850d8 100644 --- a/app/controllers/bubbles_controller.rb +++ b/app/controllers/bubbles_controller.rb @@ -7,7 +7,7 @@ class BubblesController < ApplicationController before_action :set_bubble, only: %i[ show edit update destroy ] def index - @bubbles = @filter.bubbles + @bubbles = @filter.bubbles.published_or_drafted_by(Current.user) end def create diff --git a/app/models/bubble.rb b/app/models/bubble.rb index 5b6a0ec93..5313038ed 100644 --- a/app/models/bubble.rb +++ b/app/models/bubble.rb @@ -1,5 +1,6 @@ class Bubble < ApplicationRecord - include Assignable, Boostable, Colored, Commentable, Eventable, Messages, Notifiable, Poppable, Searchable, Staged, Taggable + include Assignable, Boostable, Colored, Commentable, Draftable, + Eventable, Messages, Notifiable, Poppable, Searchable, Staged, Taggable belongs_to :bucket, touch: true belongs_to :creator, class_name: "User", default: -> { Current.user } diff --git a/app/models/bubble/draftable.rb b/app/models/bubble/draftable.rb new file mode 100644 index 000000000..8d50c6be4 --- /dev/null +++ b/app/models/bubble/draftable.rb @@ -0,0 +1,9 @@ +module Bubble::Draftable + extend ActiveSupport::Concern + + included do + enum :status, %w[ drafted published ].index_by(&:itself) + + scope :published_or_drafted_by, ->(user) { where(status: :published).or(where(creator: user)) } + end +end diff --git a/app/views/bubbles/_bubble.html.erb b/app/views/bubbles/_bubble.html.erb index f00d502ff..be53dffda 100644 --- a/app/views/bubbles/_bubble.html.erb +++ b/app/views/bubbles/_bubble.html.erb @@ -1,5 +1,5 @@ <% cache bubble do %> -
" style="view-transition-name: bubble-<%= bubble.id -%>; --bubble-color: <%= bubble.color %>; <%= bubble_rotation(bubble) %> <%= bubble_size(bubble) %>" data-controller="animation upload-preview" data-animation-play-class="bubble--wobble" diff --git a/app/views/bubbles/_publish.html.erb b/app/views/bubbles/_publish.html.erb new file mode 100644 index 000000000..0f7af76c3 --- /dev/null +++ b/app/views/bubbles/_publish.html.erb @@ -0,0 +1,4 @@ +<%= button_to bucket_bubble_publish_path(bubble.bucket, bubble), class: "btn btn--positive full-width justify-start borderless" do %> + <%= image_tag "alert.svg", aria: { hidden: true }, size: 24 %> + Publish +<% end %> diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb index 8ecd07f4f..2ce7194fe 100644 --- a/app/views/bubbles/show.html.erb +++ b/app/views/bubbles/show.html.erb @@ -56,12 +56,16 @@ <% end %>
- <%= render "bubbles/pop_toggle", bubble: @bubble %> + <% if @bubble.drafted? %> + <%= render "bubbles/publish", bubble: @bubble %> + <% else %> + <%= render "bubbles/pop_toggle", bubble: @bubble %> + + <% end %> - <%= button_to bucket_bubble_path(@bubble.bucket, @bubble), method: :delete, diff --git a/config/routes.rb b/config/routes.rb index ad0d9a2cf..f122bb209 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -29,6 +29,7 @@ Rails.application.routes.draw do scope module: :bubbles do resource :image resource :pop + resource :publish resource :stage_picker resources :stagings end diff --git a/db/migrate/20250107165422_add_status_to_bubbles.rb b/db/migrate/20250107165422_add_status_to_bubbles.rb new file mode 100644 index 000000000..abe8b481f --- /dev/null +++ b/db/migrate/20250107165422_add_status_to_bubbles.rb @@ -0,0 +1,5 @@ +class AddStatusToBubbles < ActiveRecord::Migration[8.1] + def change + add_column :bubbles, :status, :text, default: :drafted, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index b50200c5c..b10589aaa 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -106,6 +106,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_01_09_153649) do t.integer "stage_id" t.integer "comments_count", default: 0, null: false t.integer "activity_score", default: 0, null: false + t.text "status", default: "drafted", null: false t.index ["bucket_id"], name: "index_bubbles_on_bucket_id" t.index ["stage_id"], name: "index_bubbles_on_stage_id" end diff --git a/test/fixtures/bubbles.yml b/test/fixtures/bubbles.yml index 556637e7c..8bbde128f 100644 --- a/test/fixtures/bubbles.yml +++ b/test/fixtures/bubbles.yml @@ -8,6 +8,7 @@ logo: boosts_count: 5 comments_count: 2 activity_score: 7 + status: published layout: bucket: writebook @@ -17,6 +18,7 @@ layout: created_at: <%= 1.week.ago %> comments_count: 1 activity_score: 1 + status: published text: bucket: writebook @@ -24,6 +26,7 @@ text: title: The text is too small color: "#3B4B59" created_at: <%= 1.week.ago %> + status: published shipping: bucket: writebook @@ -31,3 +34,4 @@ shipping: title: We need to ship the app color: "#ED8008" created_at: <%= 1.week.ago %> + status: published diff --git a/test/models/bubble/draftable_test.rb b/test/models/bubble/draftable_test.rb new file mode 100644 index 000000000..5a13f1f66 --- /dev/null +++ b/test/models/bubble/draftable_test.rb @@ -0,0 +1,20 @@ +require "test_helper" + +class Bubble::DraftableTest < ActiveSupport::TestCase + test "bubbles are only visible to the creator by default" do + bubble = buckets(:writebook).bubbles.create! creator: users(:kevin), title: "Drafted Bubble" + + assert bubble.drafted? + assert_includes Bubble.published_or_drafted_by(users(:kevin)), bubble + assert_not_includes Bubble.published_or_drafted_by(users(:jz)), bubble + end + + test "bubbles are visible to everyone when published" do + bubble = buckets(:writebook).bubbles.create! creator: users(:kevin), title: "Drafted Bubble" + bubble.published! + + assert bubble.published? + assert_includes Bubble.published_or_drafted_by(users(:kevin)), bubble + assert_includes Bubble.published_or_drafted_by(users(:jz)), bubble + end +end