Merge branch 'main' into two-columns-refactor
* main: Fix image icons Revert "Merge pull request #345 from basecamp/cascade-layers" Fine tune notifications states Remove empty helper Use an icon for the button Show button on collection page and notif settings Add involvement types to accesses Extract a couple components Add cascade layers to all CSS files
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<svg enable-background="new 0 0 24 24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m15.9 19.5-11-11c-.3.8-.4 1.7-.4 2.6v4.9c0 .8-.7 1.5-1.5 1.5-.6 0-1 .4-1 1s.4 1 1 1z"/><path d="m9.5 21.2v.3c0 1.4 1.1 2.5 2.5 2.5s2.5-1.1 2.5-2.5c0-.1 0-.2 0-.3s-.1-.2-.2-.2h-4.5c-.2 0-.3.1-.3.2z"/><path d="m23.7 23.7c.4-.4.4-1 0-1.4l-2.8-2.8h.1c.6 0 1-.4 1-1s-.4-1-1-1c-.8 0-1.5-.7-1.5-1.5v-4.9c.1-3.9-2.6-7.4-6.5-8.1v-2c0-.6-.4-1-1-1s-1 .4-1 1v2.1c-1.6.3-3.1 1-4.3 2.3l-5-5c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4l22 22c.2.2.4.3.7.3.3-.1.5-.2.7-.4z"/></svg>
|
||||
|
After Width: | Height: | Size: 557 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m21 17.5a1.5 1.5 0 0 1 -1.5-1.5v-4.862a7.957 7.957 0 0 0 -6.5-8.065v-2.073a1 1 0 0 0 -2 0v2.073a7.957 7.957 0 0 0 -6.5 8.065v4.862a1.5 1.5 0 0 1 -1.5 1.5 1 1 0 0 0 0 2h18a1 1 0 0 0 0-2z"/><path d="m14.236 21h-4.472a.25.25 0 0 0 -.248.222 2.319 2.319 0 0 0 -.016.278 2.5 2.5 0 1 0 5 0 2.319 2.319 0 0 0 -.016-.278.248.248 0 0 0 -.248-.222z"/></svg>
|
||||
|
After Width: | Height: | Size: 416 B |
@@ -0,0 +1 @@
|
||||
<svg enable-background="new 0 0 24 24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m7 16.4c0-5 4-9 9-9 1.1 0 2.2.2 3.2.6-.6-1.8-1.8-3.3-3.3-4.4-.7-.5-1.5-.8-2.3-.9v-1.2c-.1-.8-.8-1.5-1.6-1.5s-1.5.7-1.5 1.5v1.1c-1 .2-2 .6-2.9 1.3-2.2 1.8-3.4 4.4-3.3 7.2v.8c0 2.5-.6 5.1-1.7 7.3-.1.2 0 .5.2.7 0 .1.1.1.2.1h4.7c-.4-1.1-.7-2.3-.7-3.6z"/><path d="m22.1 11.4c-1.6-1.6-3.9-2.4-6.2-2.3-4.1 0-7.4 3.3-7.4 7.4s3.3 7.4 7.4 7.4c.7 0 1.5-.1 2.2-.3.5-.1.8-.7.6-1.2s-.7-.8-1.2-.6c-2.9.9-6-.7-6.9-3.6s.7-6 3.6-6.9c.5-.2 1.1-.2 1.6-.2 1.8-.1 3.5.5 4.8 1.7.9.9 1.4 2.1 1.4 3.4s-.6 2.6-1.5 2.6c-.1 0-.2 0-.3 0v-5c0-.5-.4-.9-.9-.9-.3 0-.6.2-.8.5-.7-.6-1.6-.9-2.5-.9-2.3 0-4.1 1.8-4.1 4.1s1.8 4.1 4.1 4.1c1 0 1.9-.3 2.6-1 .1.2.2.3.3.4.5.4 1.1.6 1.7.6 2 0 3.4-1.9 3.4-4.5 0-1.8-.7-3.5-1.9-4.8zm-6.2 7.4c-1.2 0-2.2-1-2.2-2.2s1-2.2 2.2-2.2 2.2 1 2.2 2.2-1 2.2-2.2 2.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 873 B |
@@ -12,6 +12,10 @@
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
img.icon {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.icon--activity { --svg: url("activity.svg "); }
|
||||
.icon--add { --svg: url("add.svg "); }
|
||||
.icon--alert { --svg: url("alert.svg "); }
|
||||
@@ -49,6 +53,9 @@
|
||||
.icon--logout { --svg: url("logout.svg "); }
|
||||
.icon--menu-dots-horizontal { --svg: url("menu-dots-horizontal.svg "); }
|
||||
.icon--minus { --svg: url("minus.svg "); }
|
||||
.icon--notification-bell-access-only { --svg: url("notification-bell-access-only.svg "); }
|
||||
.icon--notification-bell-everything { --svg: url("notification-bell-everything.svg "); }
|
||||
.icon--notification-bell-watching { --svg: url("notification-bell-watching.svg "); }
|
||||
.icon--password { --svg: url("password.svg "); }
|
||||
.icon--pencil { --svg: url("pencil.svg "); }
|
||||
.icon--person { --svg: url("person.svg "); }
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
class Bubbles::WatchesController < ApplicationController
|
||||
include BubbleScoped, BucketScoped
|
||||
|
||||
def show
|
||||
@watchers = @bubble.watchers_and_subscribers.sorted_with_user_first(Current.user)
|
||||
end
|
||||
|
||||
def create
|
||||
set_watching_and_redirect(true)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class Buckets::InvolvementsController < ApplicationController
|
||||
include BucketScoped
|
||||
|
||||
def update
|
||||
@bucket.access_for(Current.user).update!(involvement: params[:involvement])
|
||||
end
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
class Buckets::SubscriptionsController < ApplicationController
|
||||
include BucketScoped
|
||||
|
||||
def update
|
||||
if params[:subscribed]
|
||||
@bucket.subscribe(Current.user)
|
||||
else
|
||||
@bucket.unsubscribe(Current.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -12,4 +12,36 @@ module AccessesHelper
|
||||
locals: { selected: selected },
|
||||
cached: ->(user) { [ user, selected ] }
|
||||
end
|
||||
|
||||
def access_involvement_advance_button(bucket, user)
|
||||
access = bucket.access_for(user)
|
||||
|
||||
turbo_frame_tag dom_id(bucket, :involvement_button) do
|
||||
button_to bucket_involvement_path(bucket), method: :put,
|
||||
aria: { labelledby: dom_id(bucket, :involvement_label) },
|
||||
class: [ "btn", { "btn--reversed": access.involvement == "watching" || access.involvement == "everything" } ],
|
||||
params: { involvement: next_involvement(access.involvement) },
|
||||
title: involvement_access_label(bucket, access.involvement) do
|
||||
icon_tag("notification-bell-#{access.involvement.dasherize}") +
|
||||
tag.span(involvement_access_label(bucket, access.involvement), class: "for-screen-reader", id: dom_id(bucket, :involvement_label))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def next_involvement(involvement)
|
||||
order = %w[ everything watching access_only ]
|
||||
order[(order.index(involvement.to_s) + 1) % order.size]
|
||||
end
|
||||
|
||||
def involvement_access_label(bucket, involvement)
|
||||
case involvement
|
||||
when "access_only"
|
||||
"Notifications are off for #{bucket.name}"
|
||||
when "everything"
|
||||
"Notifying me about everything in #{bucket.name}"
|
||||
when "watching"
|
||||
"Notifying me only about @mentions and new items in #{bucket.name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,7 +18,7 @@ module TranslationsHelper
|
||||
def translation_button(translation_key)
|
||||
tag.div(class: "position-relative", data: { controller: "popover", action: "keydown.esc->popover#close click@document->popover#closeOnClickOutside", popover_orientation_top_class: "popover-orientation-top" }) do
|
||||
tag.button(type: "button", class: "btn", tabindex: -1, data: { action: "popover#toggle" }) do
|
||||
concat image_tag("globe.svg", size: 20, role: "presentation")
|
||||
concat image_tag("globe.svg", class: "icon", role: "presentation")
|
||||
concat tag.span("Translate", class: "for-screen-reader")
|
||||
end +
|
||||
tag.dialog(class: "lanuage-list-menu popover shadow", data: { popover_target: "menu" }) do
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Access < ApplicationRecord
|
||||
belongs_to :bucket
|
||||
belongs_to :user
|
||||
|
||||
enum :involvement, %i[ access_only watching everything ].index_by(&:itself)
|
||||
end
|
||||
|
||||
@@ -9,15 +9,18 @@ module Bubble::Watchable
|
||||
end
|
||||
|
||||
def watched_by?(user)
|
||||
watchers_and_subscribers.include?(user)
|
||||
watchers_and_subscribers(include_only_watching: true).include?(user)
|
||||
end
|
||||
|
||||
def set_watching(user, watching)
|
||||
watches.where(user: user).first_or_create.update!(watching: watching)
|
||||
end
|
||||
|
||||
def watchers_and_subscribers
|
||||
User.where(id: bucket.subscribers.pluck(:id) +
|
||||
def watchers_and_subscribers(include_only_watching: false)
|
||||
involvements = include_only_watching ? [ :watching, :everything ] : :everything
|
||||
subscribers = bucket.users.where(accesses: { involvement: involvements })
|
||||
|
||||
User.where(id: subscribers.pluck(:id) +
|
||||
watches.watching.pluck(:user_id) - watches.not_watching.pluck(:user_id))
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Bucket < ApplicationRecord
|
||||
include Accessible, Broadcastable, Filterable, Subscribable
|
||||
include Accessible, Broadcastable, Filterable
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :creator, class_name: "User", default: -> { Current.user }
|
||||
|
||||
@@ -20,6 +20,7 @@ module Bucket::Accessible
|
||||
end
|
||||
|
||||
has_many :users, through: :accesses
|
||||
has_many :access_only_users, -> { merge(Access.access_only) }, through: :accesses, source: :user
|
||||
|
||||
scope :all_access, -> { where(all_access: true) }
|
||||
|
||||
@@ -27,6 +28,10 @@ module Bucket::Accessible
|
||||
after_save_commit :grant_access_to_everyone
|
||||
end
|
||||
|
||||
def access_for(user)
|
||||
accesses.find_by(user: user)
|
||||
end
|
||||
|
||||
private
|
||||
def grant_access_to_everyone
|
||||
accesses.grant_to(account.users) if all_access_previously_changed?(to: true)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
module Subscribable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
TYPES = %w[ Bucket ]
|
||||
|
||||
included do
|
||||
has_many :subscriptions, as: :subscribable, dependent: :destroy
|
||||
has_many :subscribers, through: :subscriptions, source: :user
|
||||
end
|
||||
|
||||
def subscribe(user)
|
||||
subscriptions.create_or_find_by!(user: user)
|
||||
end
|
||||
|
||||
def unsubscribe(user)
|
||||
subscriptions.find_by(user: user)&.destroy!
|
||||
end
|
||||
|
||||
def subscribed_by?(user)
|
||||
subscriptions.exists?(user: user)
|
||||
end
|
||||
end
|
||||
@@ -27,7 +27,7 @@ class Notifier
|
||||
end
|
||||
|
||||
def recipients
|
||||
bubble.watchers.without(creator)
|
||||
bubble.watchers_and_subscribers.without(creator)
|
||||
end
|
||||
|
||||
def resource
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Notifier::Assigned < Notifier
|
||||
private
|
||||
def recipients
|
||||
event.assignees
|
||||
event.assignees.excluding(bubble.bucket.access_only_users)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Notifier::Published < Notifier
|
||||
private
|
||||
def recipients
|
||||
bubble.watchers_and_subscribers.without(creator)
|
||||
bubble.watchers_and_subscribers(include_only_watching: true).without(creator)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
class Subscription < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
delegated_type :subscribable, types: Subscribable::TYPES, inverse_of: :subscription
|
||||
end
|
||||
@@ -9,7 +9,6 @@ class User < ApplicationRecord
|
||||
has_many :accesses, dependent: :destroy
|
||||
has_many :buckets, through: :accesses
|
||||
has_many :accessible_bubbles, through: :buckets, source: :bubbles
|
||||
has_many :subscriptions, dependent: :destroy
|
||||
|
||||
has_many :filters, foreign_key: :creator_id, inverse_of: :creator, dependent: :destroy
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<%= access_involvement_advance_button(@bucket, Current.user) %>
|
||||
@@ -1,18 +1,13 @@
|
||||
<%= turbo_frame_tag dom_id(bucket, :subscription) do %>
|
||||
<%= form_with url: bucket_subscriptions_path(bucket), method: :put, data: { controller: "form"} do |form| %>
|
||||
<div class="flex align-center gap-half pad-inline">
|
||||
<h2 class="txt-medium overflow-ellipsis">
|
||||
<%= bucket.name %>
|
||||
</h2>
|
||||
<%= turbo_frame_tag dom_id(bucket, :involvement) do %>
|
||||
<div class="flex align-center gap-half pad-inline">
|
||||
<h2 class="txt-medium overflow-ellipsis">
|
||||
<%= bucket.name %>
|
||||
</h2>
|
||||
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true">
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true">
|
||||
|
||||
<label class="switch flex-item-no-shrink">
|
||||
<%= form.checkbox :subscribed, checked: bucket.subscribed_by?(user), id: dom_id(bucket, :subscribed),
|
||||
class: "switch__input", include_hidden: false, data: { action: "form#submit" } %>
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">Enable notifications for this bucket</span>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
<label class="switch flex-item-no-shrink">
|
||||
<%= access_involvement_advance_button(bucket, user) %>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -36,6 +36,7 @@ Rails.application.routes.draw do
|
||||
scope module: :buckets do
|
||||
resource :subscriptions
|
||||
resource :workflow, only: :update
|
||||
resource :involvement
|
||||
end
|
||||
|
||||
resources :bubbles do
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class AddInvolvementToAccesses < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_table :accesses do |t|
|
||||
t.string :involvement, null: false, default: "watching"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
class DropSubscriptions < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
execute "
|
||||
update accesses set involvement = 'access_only'
|
||||
"
|
||||
execute "
|
||||
update accesses set involvement = 'watching'
|
||||
from (select user_id, subscribable_id as bucket_id from subscriptions) as subscriptions
|
||||
where subscriptions.user_id = accesses.user_id and subscriptions.bucket_id = accesses.bucket_id
|
||||
"
|
||||
|
||||
drop_table :subscriptions
|
||||
end
|
||||
end
|
||||
Generated
+2
-12
@@ -14,6 +14,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_03_094604) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
t.integer "bucket_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "involvement", default: "watching", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.index ["bucket_id", "user_id"], name: "index_accesses_on_bucket_id_and_user_id", unique: true
|
||||
@@ -229,6 +230,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_03_094604) do
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.index ["bubble_id", "user_id"], name: "index_pins_on_bubble_id_and_user_id", unique: true
|
||||
t.index ["bubble_id"], name: "index_pins_on_bubble_id"
|
||||
t.index ["user_id"], name: "index_pins_on_user_id"
|
||||
end
|
||||
@@ -261,17 +263,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_03_094604) do
|
||||
t.index ["user_id"], name: "index_sessions_on_user_id"
|
||||
end
|
||||
|
||||
create_table "subscriptions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "subscribable_id", null: false
|
||||
t.string "subscribable_type", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.index ["subscribable_type", "subscribable_id", "user_id"], name: "idx_on_subscribable_type_subscribable_id_user_id_81936d569b", unique: true
|
||||
t.index ["subscribable_type", "subscribable_id"], name: "index_subscriptions_on_subscribable"
|
||||
t.index ["user_id"], name: "index_subscriptions_on_user_id"
|
||||
end
|
||||
|
||||
create_table "taggings", force: :cascade do |t|
|
||||
t.integer "bubble_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -344,7 +335,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_03_094604) do
|
||||
add_foreign_key "pops", "bubbles"
|
||||
add_foreign_key "pops", "users"
|
||||
add_foreign_key "sessions", "users"
|
||||
add_foreign_key "subscriptions", "users"
|
||||
add_foreign_key "taggings", "bubbles"
|
||||
add_foreign_key "taggings", "tags"
|
||||
add_foreign_key "users", "accounts"
|
||||
|
||||
+31
-83
@@ -70,12 +70,9 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
accounts:
|
||||
- *5
|
||||
- *6
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: join_code
|
||||
name: involvement
|
||||
cast_type: &7 !ruby/object:ActiveModel::Type::String
|
||||
true: t
|
||||
false: f
|
||||
@@ -88,6 +85,19 @@ columns:
|
||||
limit:
|
||||
precision:
|
||||
scale:
|
||||
'null': false
|
||||
default: watching
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
accounts:
|
||||
- *5
|
||||
- *6
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: join_code
|
||||
cast_type: *7
|
||||
sql_type_metadata: *8
|
||||
'null': true
|
||||
default:
|
||||
default_function:
|
||||
@@ -833,31 +843,6 @@ columns:
|
||||
collation:
|
||||
comment:
|
||||
- *30
|
||||
subscriptions:
|
||||
- *5
|
||||
- *6
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: subscribable_id
|
||||
cast_type: *1
|
||||
sql_type_metadata: *2
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: subscribable_type
|
||||
cast_type: *7
|
||||
sql_type_metadata: *8
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *9
|
||||
- *30
|
||||
taggings:
|
||||
- *5
|
||||
- *25
|
||||
@@ -982,7 +967,6 @@ primary_keys:
|
||||
reactions: id
|
||||
schema_migrations: version
|
||||
sessions: id
|
||||
subscriptions: id
|
||||
taggings: id
|
||||
tags: id
|
||||
users: id
|
||||
@@ -1018,7 +1002,6 @@ data_sources:
|
||||
reactions: true
|
||||
schema_migrations: true
|
||||
sessions: true
|
||||
subscriptions: true
|
||||
taggings: true
|
||||
tags: true
|
||||
users: true
|
||||
@@ -1801,6 +1784,23 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: pins
|
||||
name: index_pins_on_bubble_id_and_user_id
|
||||
unique: true
|
||||
columns:
|
||||
- bubble_id
|
||||
- user_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
pops:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: pops
|
||||
@@ -1885,58 +1885,6 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
subscriptions:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: subscriptions
|
||||
name: index_subscriptions_on_user_id
|
||||
unique: false
|
||||
columns:
|
||||
- user_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: subscriptions
|
||||
name: index_subscriptions_on_subscribable
|
||||
unique: false
|
||||
columns:
|
||||
- subscribable_type
|
||||
- subscribable_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: subscriptions
|
||||
name: idx_on_subscribable_type_subscribable_id_user_id_81936d569b
|
||||
unique: true
|
||||
columns:
|
||||
- subscribable_type
|
||||
- subscribable_id
|
||||
- user_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
taggings:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: taggings
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
require "test_helper"
|
||||
|
||||
class Buckets::InvolvementsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "update" do
|
||||
bucket = buckets(:writebook)
|
||||
bucket.access_for(users(:kevin)).access_only!
|
||||
|
||||
assert_changes -> { bucket.access_for(users(:kevin)).involvement }, from: "access_only", to: "watching" do
|
||||
put bucket_involvement_url(bucket, involvement: "watching")
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
@@ -1,25 +0,0 @@
|
||||
require "test_helper"
|
||||
|
||||
class Buckets::SubscriptionsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :david
|
||||
end
|
||||
|
||||
test "subscribing to a bucket" do
|
||||
assert_changes -> { buckets(:writebook).subscribed_by?(users(:david)) }, from: false, to: true do
|
||||
put bucket_subscriptions_url(buckets(:writebook)), params: { subscribed: "1" }
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "unsubscribing from a bucket" do
|
||||
buckets(:writebook).subscribe(users(:david))
|
||||
|
||||
assert_changes -> { buckets(:writebook).subscribed_by?(users(:david)) }, from: true, to: false do
|
||||
put bucket_subscriptions_url(buckets(:writebook))
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
writebook_kevin:
|
||||
subscribable: writebook (Bucket)
|
||||
user: kevin
|
||||
|
||||
writebook_jz:
|
||||
subscribable: writebook (Bucket)
|
||||
user: jz
|
||||
@@ -2,7 +2,7 @@ require "test_helper"
|
||||
|
||||
class Bubble::CommentableTest < ActiveSupport::TestCase
|
||||
test "creating a comment on a bubble makes the creator watch the bubble" do
|
||||
buckets(:writebook).subscriptions.destroy_all
|
||||
buckets(:writebook).access_for(users(:kevin)).access_only!
|
||||
assert_not bubbles(:text).watched_by?(users(:kevin))
|
||||
|
||||
with_current_user(:kevin) do
|
||||
|
||||
@@ -3,7 +3,7 @@ require "test_helper"
|
||||
class Bubble::WatchableTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
Watch.destroy_all
|
||||
Subscription.destroy_all
|
||||
Access.all.update!(involvement: :access_only)
|
||||
end
|
||||
|
||||
test "watched_by?" do
|
||||
@@ -16,9 +16,8 @@ class Bubble::WatchableTest < ActiveSupport::TestCase
|
||||
assert_not bubbles(:logo).watched_by?(users(:kevin))
|
||||
end
|
||||
|
||||
test "watched_by? when subscribed to the bucket" do
|
||||
buckets(:writebook).subscribe(users(:kevin))
|
||||
|
||||
test "watched_by? when notifications are set on the bucket" do
|
||||
buckets(:writebook).access_for(users(:kevin)).watching!
|
||||
assert bubbles(:text).watched_by?(users(:kevin))
|
||||
|
||||
bubbles(:logo).set_watching(users(:kevin), false)
|
||||
@@ -26,16 +25,14 @@ class Bubble::WatchableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "bubbles are initially watched by their creator" do
|
||||
buckets(:writebook).unsubscribe(users(:kevin))
|
||||
|
||||
bubble = buckets(:writebook).bubbles.create!(creator: users(:kevin))
|
||||
|
||||
assert bubble.watched_by?(users(:kevin))
|
||||
end
|
||||
|
||||
test "watchers_and_subscribers" do
|
||||
buckets(:writebook).subscribe(users(:kevin))
|
||||
buckets(:writebook).subscribe(users(:jz))
|
||||
buckets(:writebook).access_for(users(:kevin)).watching!
|
||||
buckets(:writebook).access_for(users(:jz)).everything!
|
||||
|
||||
bubbles(:logo).set_watching(users(:kevin), true)
|
||||
bubbles(:logo).set_watching(users(:jz), false)
|
||||
|
||||
@@ -28,6 +28,14 @@ class NotifierTest < ActiveSupport::TestCase
|
||||
assert_equal [ users(:kevin) ], notifications.map(&:user)
|
||||
end
|
||||
|
||||
test "does not create a notification for access-only users" do
|
||||
buckets(:writebook).access_for(users(:kevin)).access_only!
|
||||
|
||||
notifications = Notifier.for(events(:layout_commented)).generate
|
||||
|
||||
assert_equal [ users(:kevin) ], notifications.map(&:user)
|
||||
end
|
||||
|
||||
test "the published event creates notifications for subscribers as well as watchers" do
|
||||
notifications = Notifier.for(events(:logo_published)).generate
|
||||
|
||||
@@ -40,9 +48,20 @@ class NotifierTest < ActiveSupport::TestCase
|
||||
assert_equal bubbles(:logo), Notification.last.resource
|
||||
end
|
||||
|
||||
test "for assignment events only create a notification for the assignee" do
|
||||
test "assignment events only create a notification for the assignee" do
|
||||
buckets(:writebook).access_for(users(:jz)).watching!
|
||||
buckets(:writebook).access_for(users(:kevin)).everything!
|
||||
|
||||
notifications = Notifier.for(events(:logo_assignment_jz)).generate
|
||||
|
||||
assert_equal [ users(:jz) ], notifications.map(&:user)
|
||||
end
|
||||
|
||||
test "assignment events do not notify users who are access-only for the collection" do
|
||||
buckets(:writebook).access_for(users(:jz)).access_only!
|
||||
|
||||
notifications = Notifier.for(events(:logo_assignment_jz)).generate
|
||||
|
||||
assert_empty notifications
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user