From c4ca5d34e48007fc73448b0ff7ebc8fa9dbea877 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 29 May 2025 21:41:29 -0500 Subject: [PATCH 1/8] Allow cards to be moved to another collection --- app/assets/stylesheets/card-perma.css | 11 ++++++ app/assets/stylesheets/cards.css | 2 +- app/controllers/cards_controller.rb | 6 ++- app/views/cards/_container.html.erb | 7 +--- app/views/cards/display/_preview.html.erb | 6 +-- .../cards/display/common/_collection.html.erb | 6 +++ .../cards/display/perma/_collection.html.erb | 38 +++++++++++++++++++ .../display/preview/_collection.html.erb | 1 + 8 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 app/views/cards/display/common/_collection.html.erb create mode 100644 app/views/cards/display/perma/_collection.html.erb create mode 100644 app/views/cards/display/preview/_collection.html.erb diff --git a/app/assets/stylesheets/card-perma.css b/app/assets/stylesheets/card-perma.css index 59cb99900..27b096f29 100644 --- a/app/assets/stylesheets/card-perma.css +++ b/app/assets/stylesheets/card-perma.css @@ -41,6 +41,17 @@ max-inline-size: 32ch; } + .collection-picker__button { + --btn-border-size: 0; + + font-size: 0.5em; + margin-inline-start: 1ch; + + + .panel { + --panel-size: 18ch; + } + } + @media (max-width: 800px) { --padding-inline: 3cqmin; diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 53315b8a6..2ad8423e6 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -82,7 +82,6 @@ color: var(--color-ink-inverted); font-weight: 800; padding: var(--block-space-half) var(--inline-space) var(--block-space-half) var(--inline-space-double); - text-transform: uppercase; .cards--considering & { background-color: var(--color-canvas); @@ -107,6 +106,7 @@ display: inline-flex; margin-inline-start: var(--inline-space-half); padding-inline-start: calc(var(--inline-space) * 0.75); + text-transform: uppercase; .cards--considering & { border-inline-start: 1px solid color-mix(in srgb, var(--color-ink) 33%, var(--color-canvas)); diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index d535f26d9..8993fdb2c 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -28,7 +28,9 @@ class CardsController < ApplicationController def update @card.update! card_params - if @card.published? + if params[:card][:collection_id].present? + redirect_to collection_card_path(@card.collection, @card) + elsif @card.published? render_card_replacement else redirect_to @card @@ -54,7 +56,7 @@ class CardsController < ApplicationController end def card_params - params.expect(card: [ :status, :title, :description, :image, tag_ids: [] ]) + params.expect(card: [ :collection_id, :status, :title, :description, :image, tag_ids: [] ]) end def render_card_replacement diff --git a/app/views/cards/_container.html.erb b/app/views/cards/_container.html.erb index 83242589a..9d326af6a 100644 --- a/app/views/cards/_container.html.erb +++ b/app/views/cards/_container.html.erb @@ -10,12 +10,7 @@
<%= card_article_tag card, class: "card" do %>
- - <%= card.id %> - <%= link_to card.collection.name, cards_path(collection_ids: [ card.collection ]), - class: "card__collection-name overflow-ellipsis" %> - - + <%= render "cards/display/perma/collection", card: card %> <%= render "cards/display/perma/tags", card: card %>
diff --git a/app/views/cards/display/_preview.html.erb b/app/views/cards/display/_preview.html.erb index 4bdccb6bb..bc27a29f9 100644 --- a/app/views/cards/display/_preview.html.erb +++ b/app/views/cards/display/_preview.html.erb @@ -3,11 +3,7 @@
- - <%= card.id %> - <%= link_to card.collection.name, cards_path(collection_ids: [ card.collection ]), - class: "card__collection-name txt-uppercase overflow-ellipsis" %> - + <%= render "cards/display/preview/collection", card: card %> <%= render "cards/display/preview/tags", card: card %>
diff --git a/app/views/cards/display/common/_collection.html.erb b/app/views/cards/display/common/_collection.html.erb new file mode 100644 index 000000000..aacabb869 --- /dev/null +++ b/app/views/cards/display/common/_collection.html.erb @@ -0,0 +1,6 @@ +
+ <%= card.id %> + <%= link_to card.collection.name, cards_path(collection_ids: [ card.collection ]), + class: "card__collection-name overflow-ellipsis" %> + <%= yield %> +
\ No newline at end of file diff --git a/app/views/cards/display/perma/_collection.html.erb b/app/views/cards/display/perma/_collection.html.erb new file mode 100644 index 000000000..01da2c473 --- /dev/null +++ b/app/views/cards/display/perma/_collection.html.erb @@ -0,0 +1,38 @@ +<%= render "cards/display/common/collection", card: card do %> +
> + + + + <%= tag.div class: "max-width full-width", data: { + controller: "filter", + dialog_target: "dialog", + filter_active_class: "filter--active", + filter_selected_class: "selected"} do %> + Put this card in… + + <% if Current.user.collections.count > 20 %> + + <% end %> + + <%= form_with(model: card, url: collection_card_path(card.collection, card), method: :patch, class: "full-width", data: { controller: "form" }) do |form| %> + + <% end %> + <% end %> + +
+<% end %> \ No newline at end of file diff --git a/app/views/cards/display/preview/_collection.html.erb b/app/views/cards/display/preview/_collection.html.erb new file mode 100644 index 000000000..ffbb7c3f7 --- /dev/null +++ b/app/views/cards/display/preview/_collection.html.erb @@ -0,0 +1 @@ +<%= render "cards/display/common/collection", card: card %> \ No newline at end of file From fdc90eb5386e42e96f5723aaf123a0573d243b8a Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 29 May 2025 22:09:23 -0500 Subject: [PATCH 2/8] Grant access to assignees when changing collections --- app/models/card.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/models/card.rb b/app/models/card.rb index 69588ea88..744e8744c 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -12,6 +12,7 @@ class Card < ApplicationRecord has_rich_text :description before_save :set_default_title, if: :published? + after_save :grant_access_to_assignees, if: :saved_change_to_collection_id? scope :reverse_chronologically, -> { order created_at: :desc, id: :desc } scope :chronologically, -> { order created_at: :asc, id: :asc } @@ -39,4 +40,9 @@ class Card < ApplicationRecord def set_default_title self.title = "Untitled" if title.blank? end + + def grant_access_to_assignees + return if collection.all_access? + collection.accesses.grant_to(assignees) + end end From 922122538aa36178f1853c11d2db74654bb96ebf Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 29 May 2025 22:09:33 -0500 Subject: [PATCH 3/8] Test granting access --- test/fixtures/collections.yml | 6 ++++++ test/models/card_test.rb | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/test/fixtures/collections.yml b/test/fixtures/collections.yml index b7919cf36..2f00b7646 100644 --- a/test/fixtures/collections.yml +++ b/test/fixtures/collections.yml @@ -4,3 +4,9 @@ writebook: all_access: true auto_close_period: <%= 30.days.to_i %> workflow: qa + +private: + name: Private collection + creator: kevin + all_access: false + auto_close_period: <%= 30.days.to_i %> diff --git a/test/models/card_test.rb b/test/models/card_test.rb index 94fc9ab86..01405ef25 100644 --- a/test/models/card_test.rb +++ b/test/models/card_test.rb @@ -128,4 +128,16 @@ class CardTest < ActiveSupport::TestCase card.publish assert_equal "Untitled", card.reload.title end + + test "grants access to assignees when moved to a new collection" do + card = cards(:logo) + assignee = users(:david) + card.toggle_assignment(assignee) + + collection = collections(:private) + assert_not_includes collection.users, assignee + + card.update!(collection: collection) + assert_includes collection.users.reload, assignee + end end From c1cc1f8fcaff8e64c6b7f59ac63a0e0e374a9005 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 29 May 2025 22:54:28 -0500 Subject: [PATCH 4/8] Track events for changing collections --- app/helpers/events_helper.rb | 2 ++ app/models/card/eventable.rb | 12 ++++++++++++ app/models/card/eventable/system_commenter.rb | 2 ++ 3 files changed, 16 insertions(+) diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index f771b0160..10788615b 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -96,6 +96,8 @@ module EventsHelper "#{event_creator_name(event)} removed the date on #{ title }" when "card_title_changed" "#{event_creator_name(event)} renamed #{ title } (was: '#{event.particulars.dig('particulars', 'old_title')})'".html_safe + when "card_collection_changed" + "#{event_creator_name(event)} moved #{ title } to '#{event.particulars.dig('particulars', 'new_collection')}'".html_safe end end diff --git a/app/models/card/eventable.rb b/app/models/card/eventable.rb index b9815fd93..4ab8821d4 100644 --- a/app/models/card/eventable.rb +++ b/app/models/card/eventable.rb @@ -7,6 +7,7 @@ module Card::Eventable before_create { self.last_active_at = Time.current } after_save :track_title_change, if: :saved_change_to_title? + after_save :track_collection_change, if: :saved_change_to_collection_id? end def event_was_created(event) @@ -27,6 +28,17 @@ module Card::Eventable end end + def track_collection_change + old_collection = Collection.find_by(id: collection_id_before_last_save) + + if old_collection.present? + track_event "collection_changed", particulars: { + old_collection: old_collection.name, + new_collection: collection.name + } + end + end + def create_system_comment_for(event) SystemCommenter.new(self, event).comment end diff --git a/app/models/card/eventable/system_commenter.rb b/app/models/card/eventable/system_commenter.rb index 73247d2a3..bcc48ba85 100644 --- a/app/models/card/eventable/system_commenter.rb +++ b/app/models/card/eventable/system_commenter.rb @@ -24,6 +24,8 @@ class Card::Eventable::SystemCommenter "Closed as “#{ card.closure.reason }” by #{ event.creator.name }" when "card_title_changed" "#{event.creator.name} changed the title from '#{event.particulars.dig('particulars', 'old_title')}' to '#{event.particulars.dig('particulars', 'new_title')}'." + when "card_collection_changed" + "#{event.creator.name} moved this from '#{event.particulars.dig('particulars', 'old_collection')}' to '#{event.particulars.dig('particulars', 'new_collection')}'." end end end From ac53f9ee2197e99bcd047185348f410420589119 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 29 May 2025 23:25:29 -0500 Subject: [PATCH 5/8] Need to do this in one transaction --- app/models/card.rb | 16 ++++++++++++++-- app/models/card/eventable.rb | 12 ------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/models/card.rb b/app/models/card.rb index 744e8744c..74818320e 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -12,7 +12,7 @@ class Card < ApplicationRecord has_rich_text :description before_save :set_default_title, if: :published? - after_save :grant_access_to_assignees, if: :saved_change_to_collection_id? + after_save :handle_collection_change, if: :saved_change_to_collection_id? scope :reverse_chronologically, -> { order created_at: :desc, id: :desc } scope :chronologically, -> { order created_at: :asc, id: :asc } @@ -41,8 +41,20 @@ class Card < ApplicationRecord self.title = "Untitled" if title.blank? end + def handle_collection_change + transaction do + old_collection = Collection.find_by(id: collection_id_before_last_save) + if old_collection.present? + track_event "collection_changed", particulars: { + old_collection: old_collection.name, + new_collection: collection.name + } + end + grant_access_to_assignees unless collection.all_access? + end + end + def grant_access_to_assignees - return if collection.all_access? collection.accesses.grant_to(assignees) end end diff --git a/app/models/card/eventable.rb b/app/models/card/eventable.rb index 4ab8821d4..b9815fd93 100644 --- a/app/models/card/eventable.rb +++ b/app/models/card/eventable.rb @@ -7,7 +7,6 @@ module Card::Eventable before_create { self.last_active_at = Time.current } after_save :track_title_change, if: :saved_change_to_title? - after_save :track_collection_change, if: :saved_change_to_collection_id? end def event_was_created(event) @@ -28,17 +27,6 @@ module Card::Eventable end end - def track_collection_change - old_collection = Collection.find_by(id: collection_id_before_last_save) - - if old_collection.present? - track_event "collection_changed", particulars: { - old_collection: old_collection.name, - new_collection: collection.name - } - end - end - def create_system_comment_for(event) SystemCommenter.new(self, event).comment end From 5051e5d53d5e6c5b1c8fb8bdf502eb26ff4f35ec Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 29 May 2025 23:27:28 -0500 Subject: [PATCH 6/8] Linter: TrailingWhitespace --- app/models/card.rb | 2 +- test/models/card_test.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/card.rb b/app/models/card.rb index 74818320e..ba26a18d7 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -45,7 +45,7 @@ class Card < ApplicationRecord transaction do old_collection = Collection.find_by(id: collection_id_before_last_save) if old_collection.present? - track_event "collection_changed", particulars: { + track_event "collection_changed", particulars: { old_collection: old_collection.name, new_collection: collection.name } diff --git a/test/models/card_test.rb b/test/models/card_test.rb index 01405ef25..f99bdec70 100644 --- a/test/models/card_test.rb +++ b/test/models/card_test.rb @@ -133,10 +133,10 @@ class CardTest < ActiveSupport::TestCase card = cards(:logo) assignee = users(:david) card.toggle_assignment(assignee) - + collection = collections(:private) assert_not_includes collection.users, assignee - + card.update!(collection: collection) assert_includes collection.users.reload, assignee end From a2a914ee72897cbe88e0022e1bec13cfecc28b14 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 30 May 2025 08:04:13 -0500 Subject: [PATCH 7/8] Event icon for changing collection --- app/assets/images/move.svg | 1 + app/assets/stylesheets/icons.css | 1 + app/helpers/events_helper.rb | 2 ++ 3 files changed, 4 insertions(+) create mode 100644 app/assets/images/move.svg diff --git a/app/assets/images/move.svg b/app/assets/images/move.svg new file mode 100644 index 000000000..cbce644c3 --- /dev/null +++ b/app/assets/images/move.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/icons.css b/app/assets/stylesheets/icons.css index bc6f9e77f..be4f36e3d 100644 --- a/app/assets/stylesheets/icons.css +++ b/app/assets/stylesheets/icons.css @@ -44,6 +44,7 @@ .icon--menu { --svg: url("menu.svg "); } .icon--menu-dots-horizontal { --svg: url("menu-dots-horizontal.svg "); } .icon--minus { --svg: url("minus.svg "); } + .icon--move { --svg: url("move.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 "); } diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 10788615b..faa353779 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -113,6 +113,8 @@ module EventsHelper "comment" when "card_title_changed" "rename" + when "card_collection_changed" + "move" else "person" end From 3ab0cb742225fb676c4d16b9e93e7865448d997b Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Mon, 2 Jun 2025 10:02:27 -0500 Subject: [PATCH 8/8] Down arrow glyph --- app/views/cards/display/perma/_collection.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/cards/display/perma/_collection.html.erb b/app/views/cards/display/perma/_collection.html.erb index 01da2c473..bde20356e 100644 --- a/app/views/cards/display/perma/_collection.html.erb +++ b/app/views/cards/display/perma/_collection.html.erb @@ -1,7 +1,7 @@ <%= render "cards/display/common/collection", card: card do %>
>