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/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 bb74bc503..92e540165 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -81,7 +81,12 @@ 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); + color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); + padding: 0 0 0 var(--inline-space); + } } .card__id { @@ -100,6 +105,12 @@ 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)); + color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); + } } .card__tags { 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/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/helpers/events_helper.rb b/app/helpers/events_helper.rb index 54c0c4678..a6a25c5b5 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 @@ -113,6 +115,8 @@ module EventsHelper "comment" when "card_title_changed" "rename" + when "card_collection_changed" + "move" else "person" end diff --git a/app/models/card.rb b/app/models/card.rb index bbb5e5843..656a51b12 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 :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 } @@ -39,4 +40,21 @@ class Card < ApplicationRecord def set_default_title 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 + collection.accesses.grant_to(assignees) + end 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 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 @@