Merge pull request #1128 from basecamp/collection=settings

Fixes for editing users in collection
This commit is contained in:
Jorge Manrubia
2025-09-17 19:41:06 +02:00
committed by GitHub
7 changed files with 68 additions and 6 deletions
+5 -2
View File
@@ -20,8 +20,11 @@ class CollectionsController < ApplicationController
def update
@collection.update! collection_params
@collection.accesses.revise granted: grantees, revoked: revokees if grantees_changed?
redirect_to edit_collection_path(@collection), notice: "Saved"
if @collection.accessible_to?(Current.user)
redirect_to edit_collection_path(@collection), notice: "Saved"
else
redirect_to root_path, notice: "Saved (you were removed from the collection)"
end
end
def destroy
@@ -0,0 +1,21 @@
import { Controller } from "@hotwired/stimulus"
import { nextEventLoopTick } from "helpers/timing_helpers";
export default class extends Controller {
static targets = ["meCheckbox"]
static values = { selfRemovalPromptMessage: { type: String, default: "Are you sure?" } }
async submitWithWarning(event) {
if (this.hasMeCheckboxTarget && !this.meCheckboxTarget.checked && !this.confirmed) {
event.detail.formSubmission.stop()
const message = this.selfRemovalPromptMessageValue
if (confirm(message)) {
await nextEventLoopTick()
this.confirmed = true
this.element.requestSubmit()
}
}
}
}
@@ -2,6 +2,7 @@ import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static classes = [ "toggle" ]
static targets = [ "checkbox" ]
toggle() {
this.element.classList.toggle(this.toggleClass)
@@ -14,4 +15,16 @@ export default class extends Controller {
remove() {
this.element.classList.remove(this.toggleClass)
}
checkAll() {
this.checkboxTargets.forEach(checkbox => {
checkbox.checked = true
})
}
checkNone() {
this.checkboxTargets.forEach(checkbox => {
checkbox.checked = false
})
}
}
+3 -1
View File
@@ -9,7 +9,9 @@
<%= icon_tag "check", class: "toggler__visible-when-on margin-inline-end" %>
<label class="switch toggler__visible-when-off flex-item-no-shrink">
<%= check_box_tag "user_ids[]", user.id, selected, class: "switch__input", id: nil %>
<% checkbox_data = { toggle_class_target: "checkbox" } %>
<% checkbox_data[:collections_form_target] = "meCheckbox" if user == Current.user %>
<%= check_box_tag "user_ids[]", user.id, selected, class: "switch__input", id: nil, data: checkbox_data %>
<span class="switch__btn round"></span>
<span class="for-screen-reader">Give <%= user.name %> access</span>
</label>
+4 -1
View File
@@ -21,7 +21,10 @@
<div>Choose who can access this Collection</div>
</header>
<%= form_with model: @collection, class: "display-contents", data: { controller: "form" } do |form| %>
<%= form_with model: @collection, class: "display-contents", data: {
controller: "form collections-form",
collections_form_self_removal_prompt_message_value: "Are you sure you want to remove yourself from this collection? You wont be able to get back in unless someone invites you.",
action: "turbo:submit-start->collections-form#submitWithWarning" } do |form| %>
<%= render "collections/edit/name", form: form %>
<%= render "collections/edit/users", collection: @collection, selected_users: @selected_users, unselected_users: @unselected_users, form: form %>
@@ -20,6 +20,14 @@
<input placeholder="Filter…" class="input input--transparent full-width" type="search" autocorrect="off" autocomplete="off" data-1p-ignore="true" data-filter-target="input" data-action="input->filter#filter">
<div class="toggler__visible-when-off">
<div class="flex align-center justify-end gap-half">
<button type="button" class="btn btn--plain txt-x-small txt-link font-weight-normal" data-action="click->toggle-class#checkAll">Select all</button>
<span class="txt-subtle">&middot;</span>
<button type="button" class="btn btn--plain txt-x-small txt-link font-weight-normal" data-action="click->toggle-class#checkNone">Select none</button>
</div>
</div>
<ul class="settings__user-list" data-filter-target="list">
<%= access_toggles_for selected_users, selected: true %>
<%= access_toggles_for unselected_users, selected: false %>
@@ -34,17 +34,29 @@ class CollectionsControllerTest < ActionDispatch::IntegrationTest
auto_close_period: 1.day,
auto_reconsider_period: 2.days
},
user_ids: users(:david, :jz).pluck(:id)
user_ids: users(:kevin, :jz).pluck(:id)
}
assert_redirected_to edit_collection_path(collections(:writebook))
assert_equal "Writebook bugs", collections(:writebook).reload.name
assert_equal users(:david, :jz).sort, collections(:writebook).users.sort
assert_equal users(:kevin, :jz).sort, collections(:writebook).users.sort
assert_equal 1.day, entropy_configurations(:writebook_collection).auto_close_period
assert_equal 2.days, entropy_configurations(:writebook_collection).auto_reconsider_period
assert_not collections(:writebook).all_access?
end
test "update redirects to root when user removes themselves from collection" do
collection = collections(:writebook)
patch collection_path(collection), params: {
collection: { name: "Updated name", all_access: false },
user_ids: users(:david, :jz).pluck(:id)
}
assert_redirected_to root_path
assert_not collection.reload.users.include?(users(:kevin))
end
test "update collection with granular permissions, submitting no user ids" do
assert_not collections(:private).all_access?