Baseline replacing collection with board across code

This commit is contained in:
Jorge Manrubia
2025-11-05 13:31:54 +01:00
parent 8caaad0105
commit 03a345609e
269 changed files with 990 additions and 990 deletions
+1 -1
View File
@@ -45,7 +45,7 @@
.bubble__number { .bubble__number {
display: grid; display: grid;
font-size: clamp(10px, 50cqi, var(--bubble-number-max)); /* FF bug: https://app.fizzy.do/5986089/collections/2/cards/1373 */ font-size: clamp(10px, 50cqi, var(--bubble-number-max)); /* FF bug: https://app.fizzy.do/5986089/boards/2/cards/1373 */
font-weight: 900; font-weight: 900;
inset: 0; inset: 0;
place-content: center; place-content: center;
+5 -5
View File
@@ -492,7 +492,7 @@
} }
} }
.card__collection { .card__board {
background-color: transparent; background-color: transparent;
color: var(--card-content-color); color: var(--card-content-color);
} }
@@ -519,10 +519,10 @@
} }
} }
/* Collection tools /* Board tools
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
.collection-tools.card { .board-tools.card {
--border-color: var(--color-selected-dark); --border-color: var(--color-selected-dark);
--border-size: 1px; --border-size: 1px;
--card-padding-block: var(--block-space); --card-padding-block: var(--block-space);
@@ -560,7 +560,7 @@
} }
} }
.collection-tools__watching { .board-tools__watching {
--btn-size: 32px; --btn-size: 32px;
--gap: 0.5ch; --gap: 0.5ch;
@@ -572,7 +572,7 @@
position: relative; position: relative;
} }
.collection-tools__watching-dialog { .board-tools__watching-dialog {
--panel-padding: 2ch; --panel-padding: 2ch;
--panel-size: 100%; --panel-size: 100%;
+1 -1
View File
@@ -85,7 +85,7 @@
} }
} }
.collection-picker__button { .board-picker__button {
--btn-border-size: 0; --btn-border-size: 0;
font-size: 0.5em; font-size: 0.5em;
+5 -5
View File
@@ -55,7 +55,7 @@
} }
} }
.card__collection { .card__board {
background-color: var(--card-color); background-color: var(--card-color);
border-radius: var(--border-radius) 0 var(--border-radius) 0; border-radius: var(--border-radius) 0 var(--border-radius) 0;
color: var(--color-ink-inverted); color: var(--color-ink-inverted);
@@ -66,7 +66,7 @@
padding-block: 0.25lh; padding-block: 0.25lh;
padding-inline: var(--card-padding-inline) 1ch; padding-inline: var(--card-padding-inline) 1ch;
&:has(.collection-picker__button) { &:has(.board-picker__button) {
cursor: pointer; cursor: pointer;
transition: background-color 100ms ease-out; transition: background-color 100ms ease-out;
@@ -92,7 +92,7 @@
} }
} }
.card__collection-name { .card__board-name {
border-inline-start: 1px solid color-mix(in hsl, transparent 75%, currentColor); border-inline-start: 1px solid color-mix(in hsl, transparent 75%, currentColor);
color: currentColor; color: currentColor;
display: flex; display: flex;
@@ -404,7 +404,7 @@
padding-block-end: 0; padding-block-end: 0;
} }
.card__collection { .card__board {
font-size: var(--text-xx-small); font-size: var(--text-xx-small);
padding-block: 0.5ch; padding-block: 0.5ch;
padding-inline-start: var(--inline-space-double); padding-inline-start: var(--inline-space-double);
@@ -487,7 +487,7 @@
} }
} }
.card__collection-public-description { .card__board-public-description {
max-inline-size: 66ch; max-inline-size: 66ch;
> *:first-child { margin-block-start: 0; } > *:first-child { margin-block-start: 0; }
+2 -2
View File
@@ -270,7 +270,7 @@
z-index: 0; z-index: 0;
} }
.card__collection { .card__board {
background-color: transparent; background-color: transparent;
color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
font-size: 0.7em; font-size: 0.7em;
@@ -278,7 +278,7 @@
translate: 0 -0.3em; translate: 0 -0.3em;
} }
.card__collection-name { .card__board-name {
border-inline-start: 1px solid color-mix(in srgb, var(--color-ink) 33%, var(--color-canvas)); 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)); color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
margin: 0 0 0 calc(var(--inline-space) * 0.75); margin: 0 0 0 calc(var(--inline-space) * 0.75);
+2 -2
View File
@@ -42,8 +42,8 @@
.icon--clipboard { --svg: url("clipboard.svg "); } .icon--clipboard { --svg: url("clipboard.svg "); }
.icon--close { --svg: url("close.svg "); } .icon--close { --svg: url("close.svg "); }
.icon--close-circle { --svg: url("close-circle.svg "); } .icon--close-circle { --svg: url("close-circle.svg "); }
.icon--collection { --svg: url("collection.svg "); } .icon--board { --svg: url("board.svg "); }
.icon--collection-add { --svg: url("collection-add.svg "); } .icon--board-add { --svg: url("board-add.svg "); }
.icon--column-left { --svg: url("column-left.svg "); } .icon--column-left { --svg: url("column-left.svg "); }
.icon--column-right { --svg: url("column-right.svg "); } .icon--column-right { --svg: url("column-right.svg "); }
.icon--comment { --svg: url("comment.svg "); } .icon--comment { --svg: url("comment.svg "); }
+3 -3
View File
@@ -63,7 +63,7 @@
} }
.card { .card {
.card__collection { .card__board {
background: var(--color-canvas); background: var(--color-canvas);
border-block-end: var(--border-light); border-block-end: var(--border-light);
border-inline-end: var(--border-light); border-inline-end: var(--border-light);
@@ -118,7 +118,7 @@
} }
} }
/* Collections /* Boards
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
.filters, .filters,
@@ -181,7 +181,7 @@
.card__meta-avatars--assignees > div > div:last-child, .card__meta-avatars--assignees > div > div:last-child,
.steps > .step:last-child, .steps > .step:last-child,
div:has(> .tag-picker__button), div:has(> .tag-picker__button),
div:has(> .collection-picker__button), div:has(> .board-picker__button),
.delete-card, .delete-card,
.header--card .header__title { .header--card .header__title {
display: none; display: none;
+1 -1
View File
@@ -314,7 +314,7 @@
padding-block-end: 0; padding-block-end: 0;
} }
.card__collection { .card__board {
padding-block: 0.25ch; padding-block: 0.25ch;
} }
@@ -2,11 +2,11 @@ class Cards::AssignmentsController < ApplicationController
include CardScoped include CardScoped
def new def new
@users = @collection.users.active.alphabetically @users = @board.users.active.alphabetically
fresh_when @users fresh_when @users
end end
def create def create
@card.toggle_assignment @collection.users.active.find(params[:assignee_id]) @card.toggle_assignment @board.users.active.find(params[:assignee_id])
end end
end end
@@ -1,16 +1,16 @@
class Cards::CollectionsController < ApplicationController class Cards::BoardsController < ApplicationController
include CollectionScoped include BoardScoped
skip_before_action :set_collection, only: %i[ edit ] skip_before_action :set_board, only: %i[ edit ]
before_action :set_card before_action :set_card
def edit def edit
@collections = Current.user.collections.ordered_by_recently_accessed @boards = Current.user.boards.ordered_by_recently_accessed
fresh_when @collections fresh_when @boards
end end
def update def update
@card.move_to(@collection) @card.move_to(@board)
redirect_to @card redirect_to @card
end end
+1 -1
View File
@@ -1,7 +1,7 @@
class Cards::ColumnsController < ApplicationController class Cards::ColumnsController < ApplicationController
def edit def edit
@card = Current.user.accessible_cards.find(params[:card_id]) @card = Current.user.accessible_cards.find(params[:card_id])
@columns = @card.collection.columns @columns = @card.board.columns
fresh_when etag: [ @card, @columns ] fresh_when etag: [ @card, @columns ]
end end
@@ -5,9 +5,9 @@ class Cards::PublishesController < ApplicationController
@card.publish @card.publish
if add_another_param? if add_another_param?
redirect_to @collection.cards.create!, notice: "Card added" redirect_to @board.cards.create!, notice: "Card added"
else else
redirect_to @card.collection redirect_to @card.board
end end
end end
+3 -3
View File
@@ -5,11 +5,11 @@ class Cards::ReadingsController < ApplicationController
def create def create
@notifications = @card.read_by(Current.user) @notifications = @card.read_by(Current.user)
record_collection_access record_board_access
end end
private private
def record_collection_access def record_board_access
@card.collection.accessed_by(Current.user) @card.board.accessed_by(Current.user)
end end
end end
+1 -1
View File
@@ -2,7 +2,7 @@ class Cards::TriagesController < ApplicationController
include CardScoped include CardScoped
def create def create
column = @card.collection.columns.find(params[:column_id]) column = @card.board.columns.find(params[:column_id])
@card.triage_into(column) @card.triage_into(column)
redirect_to @card redirect_to @card
+6 -6
View File
@@ -1,7 +1,7 @@
class CardsController < ApplicationController class CardsController < ApplicationController
include FilterScoped include FilterScoped
before_action :set_collection, only: %i[ create ] before_action :set_board, only: %i[ create ]
before_action :set_card, only: %i[ show edit update destroy ] before_action :set_card, only: %i[ show edit update destroy ]
def index def index
@@ -9,7 +9,7 @@ class CardsController < ApplicationController
end end
def create def create
card = @collection.cards.find_or_create_by!(creator: Current.user, status: "drafted") card = @board.cards.find_or_create_by!(creator: Current.user, status: "drafted")
redirect_to card redirect_to card
end end
@@ -30,12 +30,12 @@ class CardsController < ApplicationController
def destroy def destroy
@card.destroy! @card.destroy!
redirect_to @card.collection, notice: "Card deleted" redirect_to @card.board, notice: "Card deleted"
end end
private private
def set_collection def set_board
@collection = Current.user.collections.find params[:collection_id] @board = Current.user.boards.find params[:board_id]
end end
def set_card def set_card
@@ -46,7 +46,7 @@ class CardsController < ApplicationController
if card.published? if card.published?
yield yield
else else
Collection.suppressing_turbo_broadcasts(&block) Board.suppressing_turbo_broadcasts(&block)
end end
end end
@@ -1,8 +1,8 @@
class Collections::Columns::ClosedsController < ApplicationController class Boards::Columns::ClosedsController < ApplicationController
include CollectionScoped include BoardScoped
def show def show
set_page_and_extract_portion_from @collection.cards.closed.recently_closed_first set_page_and_extract_portion_from @board.cards.closed.recently_closed_first
fresh_when etag: @page.records fresh_when etag: @page.records
end end
end end
@@ -1,8 +1,8 @@
class Collections::Columns::NotNowsController < ApplicationController class Boards::Columns::NotNowsController < ApplicationController
include CollectionScoped include BoardScoped
def show def show
set_page_and_extract_portion_from @collection.cards.postponed.reverse_chronologically.with_golden_first set_page_and_extract_portion_from @board.cards.postponed.reverse_chronologically.with_golden_first
fresh_when etag: @page.records fresh_when etag: @page.records
end end
end end
@@ -1,8 +1,8 @@
class Collections::Columns::StreamsController < ApplicationController class Boards::Columns::StreamsController < ApplicationController
include CollectionScoped include BoardScoped
def show def show
set_page_and_extract_portion_from @collection.cards.awaiting_triage.latest.with_golden_first set_page_and_extract_portion_from @board.cards.awaiting_triage.latest.with_golden_first
fresh_when etag: @page.records fresh_when etag: @page.records
end end
end end
@@ -1,5 +1,5 @@
class Collections::ColumnsController < ApplicationController class Boards::ColumnsController < ApplicationController
include CollectionScoped include BoardScoped
before_action :set_column, only: %i[ show update destroy ] before_action :set_column, only: %i[ show update destroy ]
@@ -9,7 +9,7 @@ class Collections::ColumnsController < ApplicationController
end end
def create def create
@column = @collection.columns.create!(column_params) @column = @board.columns.create!(column_params)
end end
def update def update
@@ -22,7 +22,7 @@ class Collections::ColumnsController < ApplicationController
private private
def set_column def set_column
@column = @collection.columns.find(params[:id]) @column = @board.columns.find(params[:id])
end end
def column_params def column_params
@@ -1,12 +1,12 @@
class Collections::EntropiesController < ApplicationController class Boards::EntropiesController < ApplicationController
include CollectionScoped include BoardScoped
def update def update
@collection.entropy.update!(entropy_params) @board.entropy.update!(entropy_params)
end end
private private
def entropy_params def entropy_params
params.expect(collection: [ :auto_postpone_period ]) params.expect(board: [ :auto_postpone_period ])
end end
end end
@@ -1,7 +1,7 @@
class Collections::InvolvementsController < ApplicationController class Boards::InvolvementsController < ApplicationController
include CollectionScoped include BoardScoped
def update def update
@collection.access_for(Current.user).update!(involvement: params[:involvement]) @board.access_for(Current.user).update!(involvement: params[:involvement])
end end
end end
@@ -1,12 +1,12 @@
class Collections::PublicationsController < ApplicationController class Boards::PublicationsController < ApplicationController
include CollectionScoped include BoardScoped
def create def create
@collection.publish @board.publish
end end
def destroy def destroy
@collection.unpublish @board.unpublish
@collection.reload @board.reload
end end
end end
+21 -21
View File
@@ -1,10 +1,10 @@
class CollectionsController < ApplicationController class BoardsController < ApplicationController
include FilterScoped include FilterScoped
before_action :set_collection, except: %i[ new create ] before_action :set_board, except: %i[ new create ]
def show def show
if @filter.used?(ignore_collections: true) if @filter.used?(ignore_boards: true)
show_filtered_cards show_filtered_cards
else else
show_columns show_columns
@@ -12,53 +12,53 @@ class CollectionsController < ApplicationController
end end
def new def new
@collection = Collection.new @board = Board.new
end end
def create def create
@collection = Collection.create! collection_params.with_defaults(all_access: true) @board = Board.create! board_params.with_defaults(all_access: true)
redirect_to collection_path(@collection) redirect_to board_path(@board)
end end
def edit def edit
selected_user_ids = @collection.users.pluck :id selected_user_ids = @board.users.pluck :id
@selected_users, @unselected_users = \ @selected_users, @unselected_users = \
User.active.alphabetically.partition { |user| selected_user_ids.include? user.id } User.active.alphabetically.partition { |user| selected_user_ids.include? user.id }
end end
def update def update
@collection.update! collection_params @board.update! board_params
@collection.accesses.revise granted: grantees, revoked: revokees if grantees_changed? @board.accesses.revise granted: grantees, revoked: revokees if grantees_changed?
if @collection.accessible_to?(Current.user) if @board.accessible_to?(Current.user)
redirect_to edit_collection_path(@collection), notice: "Saved" redirect_to edit_board_path(@board), notice: "Saved"
else else
redirect_to root_path, notice: "Saved (you were removed from the collection)" redirect_to root_path, notice: "Saved (you were removed from the board)"
end end
end end
def destroy def destroy
@collection.destroy @board.destroy
redirect_to root_path redirect_to root_path
end end
private private
def set_collection def set_board
@collection = Current.user.collections.find params[:id] @board = Current.user.boards.find params[:id]
end end
def show_filtered_cards def show_filtered_cards
@filter.collection_ids = [ @collection.id ] @filter.board_ids = [ @board.id ]
set_page_and_extract_portion_from @filter.cards set_page_and_extract_portion_from @filter.cards
end end
def show_columns def show_columns
set_page_and_extract_portion_from @collection.cards.awaiting_triage.latest.with_golden_first set_page_and_extract_portion_from @board.cards.awaiting_triage.latest.with_golden_first
fresh_when etag: [ @collection, @page.records, @user_filtering ] fresh_when etag: [ @board, @page.records, @user_filtering ]
end end
def collection_params def board_params
params.expect(collection: [ :name, :all_access, :auto_postpone_period, :public_description ]) params.expect(board: [ :name, :all_access, :auto_postpone_period, :public_description ])
end end
def grantees def grantees
@@ -66,7 +66,7 @@ class CollectionsController < ApplicationController
end end
def revokees def revokees
@collection.users.where.not id: grantee_ids @board.users.where.not id: grantee_ids
end end
def grantee_ids def grantee_ids
@@ -2,7 +2,7 @@ class Columns::Cards::Drops::ColumnsController < ApplicationController
include CardScoped include CardScoped
def create def create
@column = @card.collection.columns.find(params[:column_id]) @column = @card.board.columns.find(params[:column_id])
@card.triage_into(@column) @card.triage_into(@column)
end end
end end
@@ -3,6 +3,6 @@ class Columns::Cards::Drops::StreamsController < ApplicationController
def create def create
@card.send_back_to_triage @card.send_back_to_triage
set_page_and_extract_portion_from @collection.cards.awaiting_triage.latest.with_golden_first set_page_and_extract_portion_from @board.cards.awaiting_triage.latest.with_golden_first
end end
end end
+3 -3
View File
@@ -2,7 +2,7 @@ module CardScoped
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
before_action :set_card, :set_collection before_action :set_card, :set_board
end end
private private
@@ -10,8 +10,8 @@ module CardScoped
@card = Current.user.accessible_cards.find(params[:card_id]) @card = Current.user.accessible_cards.find(params[:card_id])
end end
def set_collection def set_board
@collection = @card.collection @board = @card.board
end end
def render_card_replacement def render_card_replacement
@@ -1,12 +1,12 @@
module CollectionScoped module BoardScoped
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
before_action :set_collection before_action :set_board
end end
private private
def set_collection def set_board
@collection = Current.user.collections.find(params[:collection_id]) @board = Current.user.boards.find(params[:board_id])
end end
end end
+2 -2
View File
@@ -1,7 +1,7 @@
class LandingsController < ApplicationController class LandingsController < ApplicationController
def show def show
if Current.user.collections.one? if Current.user.boards.one?
redirect_to collection_path(Current.user.collections.first) redirect_to board_path(Current.user.boards.first)
else else
redirect_to events_path redirect_to events_path
end end
@@ -2,7 +2,7 @@ class Notifications::SettingsController < ApplicationController
before_action :set_settings before_action :set_settings
def show def show
@collections = Current.user.collections.alphabetically @boards = Current.user.boards.alphabetically
end end
def update def update
@@ -1,8 +1,8 @@
class Prompts::Collections::UsersController < ApplicationController class Prompts::Boards::UsersController < ApplicationController
include CollectionScoped include BoardScoped
def index def index
@users = @collection.users.alphabetically @users = @board.users.alphabetically
if stale? etag: @users if stale? etag: @users
render layout: false render layout: false
+4 -4
View File
@@ -1,17 +1,17 @@
class Public::BaseController < ApplicationController class Public::BaseController < ApplicationController
allow_unauthenticated_access allow_unauthenticated_access
before_action :set_collection, :set_card, :set_public_cache_expiration before_action :set_board, :set_card, :set_public_cache_expiration
layout "public" layout "public"
private private
def set_collection def set_board
@collection = Collection.find_by_published_key(params[:collection_id] || params[:id]) @board = Board.find_by_published_key(params[:board_id] || params[:id])
end end
def set_card def set_card
@card = @collection.cards.find(params[:id]) if params[:collection_id] && params[:id] @card = @board.cards.find(params[:id]) if params[:board_id] && params[:id]
end end
def set_public_cache_expiration def set_public_cache_expiration
@@ -1,5 +1,5 @@
class Public::Collections::Columns::ClosedsController < Public::BaseController class Public::Boards::Columns::ClosedsController < Public::BaseController
def show def show
set_page_and_extract_portion_from @collection.cards.closed.recently_closed_first set_page_and_extract_portion_from @board.cards.closed.recently_closed_first
end end
end end
@@ -1,5 +1,5 @@
class Public::Collections::Columns::NotNowsController < Public::BaseController class Public::Boards::Columns::NotNowsController < Public::BaseController
def show def show
set_page_and_extract_portion_from @collection.cards.postponed.reverse_chronologically.with_golden_first set_page_and_extract_portion_from @board.cards.postponed.reverse_chronologically.with_golden_first
end end
end end
@@ -1,5 +1,5 @@
class Public::Collections::Columns::StreamsController < Public::BaseController class Public::Boards::Columns::StreamsController < Public::BaseController
def show def show
set_page_and_extract_portion_from @collection.cards.awaiting_triage.latest.with_golden_first set_page_and_extract_portion_from @board.cards.awaiting_triage.latest.with_golden_first
end end
end end
@@ -1,4 +1,4 @@
class Public::Collections::ColumnsController < Public::BaseController class Public::Boards::ColumnsController < Public::BaseController
before_action :set_column before_action :set_column
def show def show
@@ -11,6 +11,6 @@ class Public::Collections::ColumnsController < Public::BaseController
end end
def set_column def set_column
@column = @collection.columns.find(params[:id]) @column = @board.columns.find(params[:id])
end end
end end
@@ -1,5 +1,5 @@
class Public::CollectionsController < Public::BaseController class Public::BoardsController < Public::BaseController
def show def show
set_page_and_extract_portion_from @collection.cards.awaiting_triage.latest.with_golden_first set_page_and_extract_portion_from @board.cards.awaiting_triage.latest.with_golden_first
end end
end end
+7 -7
View File
@@ -1,22 +1,22 @@
class WebhooksController < ApplicationController class WebhooksController < ApplicationController
include CollectionScoped include BoardScoped
before_action :ensure_admin before_action :ensure_admin
before_action :set_webhook, except: %i[ index new create ] before_action :set_webhook, except: %i[ index new create ]
def index def index
set_page_and_extract_portion_from @collection.webhooks.ordered set_page_and_extract_portion_from @board.webhooks.ordered
end end
def show def show
end end
def new def new
@webhook = @collection.webhooks.new @webhook = @board.webhooks.new
end end
def create def create
webhook = @collection.webhooks.create!(webhook_params) webhook = @board.webhooks.create!(webhook_params)
redirect_to webhook redirect_to webhook
end end
@@ -30,17 +30,17 @@ class WebhooksController < ApplicationController
def destroy def destroy
@webhook.destroy! @webhook.destroy!
redirect_to collection_webhooks_path redirect_to board_webhooks_path
end end
private private
def set_webhook def set_webhook
@webhook = @collection.webhooks.find(params[:id]) @webhook = @board.webhooks.find(params[:id])
end end
def webhook_params def webhook_params
params params
.expect(webhook: [ :name, :url, subscribed_actions: [] ]) .expect(webhook: [ :name, :url, subscribed_actions: [] ])
.merge(collection_id: @collection.id) .merge(board_id: @board.id)
end end
end end
+16 -16
View File
@@ -1,8 +1,8 @@
module AccessesHelper module AccessesHelper
MAX_DISPLAYED_WATCHERS = 8 MAX_DISPLAYED_WATCHERS = 8
def access_menu_tag(collection, **options, &) def access_menu_tag(board, **options, &)
tag.menu class: [ options[:class], { "toggler--toggled": collection.all_access? } ], data: { tag.menu class: [ options[:class], { "toggler--toggled": board.all_access? } ], data: {
controller: "filter toggle-class navigable-list", controller: "filter toggle-class navigable-list",
action: "keydown->navigable-list#navigate filter:changed->navigable-list#reset", action: "keydown->navigable-list#navigate filter:changed->navigable-list#reset",
navigable_list_focus_on_selection_value: true, navigable_list_focus_on_selection_value: true,
@@ -11,35 +11,35 @@ module AccessesHelper
end end
def access_toggles_for(users, selected:) def access_toggles_for(users, selected:)
render partial: "collections/access_toggle", render partial: "boards/access_toggle",
collection: users, as: :user, board: users, as: :user,
locals: { selected: selected }, locals: { selected: selected },
cached: ->(user) { [ user, selected ] } cached: ->(user) { [ user, selected ] }
end end
def access_involvement_advance_button(collection, user, show_watchers: true, icon_only: false) def access_involvement_advance_button(board, user, show_watchers: true, icon_only: false)
access = collection.access_for(user) access = board.access_for(user)
turbo_frame_tag dom_id(collection, :involvement_button) do turbo_frame_tag dom_id(board, :involvement_button) do
concat collection_watchers_list(collection) if show_watchers concat board_watchers_list(board) if show_watchers
concat involvement_button(collection, access, show_watchers, icon_only) concat involvement_button(board, access, show_watchers, icon_only)
end end
end end
def collection_watchers_list(collection) def board_watchers_list(board)
watchers = collection.watchers watchers = board.watchers
displayed_watchers = watchers.limit(MAX_DISPLAYED_WATCHERS) displayed_watchers = watchers.limit(MAX_DISPLAYED_WATCHERS)
overflow_count = watchers.count - MAX_DISPLAYED_WATCHERS overflow_count = watchers.count - MAX_DISPLAYED_WATCHERS
safe_join([ safe_join([
tag.strong(displayed_watchers.any? ? "Watching for new cards" : "No one is watching for new cards", class: "txt-uppercase"), tag.strong(displayed_watchers.any? ? "Watching for new cards" : "No one is watching for new cards", class: "txt-uppercase"),
tag.div(class: "collection-tools__watching") do tag.div(class: "board-tools__watching") do
safe_join([ safe_join([
safe_join(displayed_watchers.map { |watcher| avatar_tag(watcher) }), safe_join(displayed_watchers.map { |watcher| avatar_tag(watcher) }),
(tag.div(data: { controller: "dialog", action: "keydown.esc->dialog#close click@document->dialog#closeOnClickOutside" }) do (tag.div(data: { controller: "dialog", action: "keydown.esc->dialog#close click@document->dialog#closeOnClickOutside" }) do
concat tag.button("+#{overflow_count}", class: "overflow-count btn btn--circle borderless", data: { action: "dialog#open" }, aria: { label: "Show #{overflow_count} more watchers" }) concat tag.button("+#{overflow_count}", class: "overflow-count btn btn--circle borderless", data: { action: "dialog#open" }, aria: { label: "Show #{overflow_count} more watchers" })
concat(tag.dialog(class: "collection-tools__watching-dialog dialog panel", data: { dialog_target: "dialog" }, aria: { hidden: "true" }) do concat(tag.dialog(class: "board-tools__watching-dialog dialog panel", data: { dialog_target: "dialog" }, aria: { hidden: "true" }) do
safe_join(watchers.map { |watcher| avatar_tag(watcher) }) safe_join(watchers.map { |watcher| avatar_tag(watcher) })
end) end)
end if overflow_count > 0) end if overflow_count > 0)
@@ -48,11 +48,11 @@ module AccessesHelper
]) ])
end end
def involvement_button(collection, access, show_watchers, icon_only) def involvement_button(board, access, show_watchers, icon_only)
involvement_label_id = dom_id(collection, :involvement_label) involvement_label_id = dom_id(board, :involvement_label)
button_to( button_to(
collection_involvement_path(collection), board_involvement_path(board),
method: :put, method: :put,
aria: { labelledby: involvement_label_id }, aria: { labelledby: involvement_label_id },
class: class_names("btn", { "btn--reversed": access.watching? && icon_only }), class: class_names("btn", { "btn--reversed": access.watching? && icon_only }),
+2 -2
View File
@@ -27,14 +27,14 @@ module CardsHelper
title = [ title = [
card.title, card.title,
"added by #{card.creator.name}", "added by #{card.creator.name}",
"in #{card.collection.name}" "in #{card.board.name}"
] ]
title << "assigned to #{card.assignees.map(&:name).to_sentence}" if card.assignees.any? title << "assigned to #{card.assignees.map(&:name).to_sentence}" if card.assignees.any?
title.join(" ") title.join(" ")
end end
def card_social_tags(card) def card_social_tags(card)
tag.meta(property: "og:title", content: "#{card.title} | #{card.collection.name}") + tag.meta(property: "og:title", content: "#{card.title} | #{card.board.name}") +
tag.meta(property: "og:description", content: format_excerpt(@card&.description, length: 200)) + tag.meta(property: "og:description", content: format_excerpt(@card&.description, length: 200)) +
tag.meta(property: "og:image", content: @card.image.attached? ? "#{request.base_url}#{url_for(@card.image)}" : "#{request.base_url}/app-icon.png") + tag.meta(property: "og:image", content: @card.image.attached? ? "#{request.base_url}#{url_for(@card.image)}" : "#{request.base_url}/app-icon.png") +
tag.meta(property: "og:url", content: card_url(@card)) tag.meta(property: "og:url", content: card_url(@card))
+7 -7
View File
@@ -1,14 +1,14 @@
module CollectionsHelper module BoardsHelper
def link_back_to_collection(collection) def link_back_to_board(board)
link_to collection, class: "btn borderless txt-medium", link_to board, class: "btn borderless txt-medium",
data: { controller: "hotkey", action: "keydown.esc@document->hotkey#click click->turbo-navigation#backIfSamePath" } do data: { controller: "hotkey", action: "keydown.esc@document->hotkey#click click->turbo-navigation#backIfSamePath" } do
tag.span ("&larr;" + tag.strong(collection.name, class: "overflow-ellipsis")).html_safe tag.span ("&larr;" + tag.strong(board.name, class: "overflow-ellipsis")).html_safe
end end
end end
def link_to_edit_collection(collection) def link_to_edit_board(board)
link_to edit_collection_path(collection), class: "btn", data: { controller: "tooltip" } do link_to edit_board_path(board), class: "btn", data: { controller: "tooltip" } do
icon_tag("settings") + tag.span("Settings for #{collection.name}", class: "for-screen-reader") icon_tag("settings") + tag.span("Settings for #{board.name}", class: "for-screen-reader")
end end
end end
end end
+3 -3
View File
@@ -102,8 +102,8 @@ module EventsHelper
"#{event_creator_name(event)} resumed #{event_card_title(card)}" "#{event_creator_name(event)} resumed #{event_card_title(card)}"
when "card_title_changed" when "card_title_changed"
"#{event_creator_name(event)} renamed #{event_card_title(card)} (was: “#{h event.particulars.dig('particulars', 'old_title')}”)" "#{event_creator_name(event)} renamed #{event_card_title(card)} (was: “#{h event.particulars.dig('particulars', 'old_title')}”)"
when "card_collection_changed" when "card_board_changed"
"#{event_creator_name(event)} moved #{event_card_title(card)} to “#{h event.particulars.dig('particulars', 'new_collection')}" "#{event_creator_name(event)} moved #{event_card_title(card)} to “#{h event.particulars.dig('particulars', 'new_board')}"
when "card_triaged" when "card_triaged"
"#{event_creator_name(event)} moved #{event_card_title(card)} to “#{h event.particulars.dig('particulars', 'column')}" "#{event_creator_name(event)} moved #{event_card_title(card)} to “#{h event.particulars.dig('particulars', 'column')}"
when "card_sent_back_to_triage" when "card_sent_back_to_triage"
@@ -129,7 +129,7 @@ module EventsHelper
"comment" "comment"
when "card_title_changed" when "card_title_changed"
"rename" "rename"
when "card_collection_changed" when "card_board_changed"
"move" "move"
else else
"person" "person"
+2 -2
View File
@@ -11,8 +11,8 @@ module FiltersHelper
hidden_field_tag name, value, id: nil hidden_field_tag name, value, id: nil
end end
def filter_selected_collections_title(user_filtering) def filter_selected_boards_title(user_filtering)
user_filtering.selected_collection_titles.collect { tag.strong it }.to_sentence.html_safe user_filtering.selected_board_titles.collect { tag.strong it }.to_sentence.html_safe
end end
def filter_place_menu_item(path, label, icon, new_window: false, current: false) def filter_place_menu_item(path, label, icon, new_window: false, current: false)
+1 -1
View File
@@ -3,7 +3,7 @@ module My::MenuHelper
text_field_tag :search, nil, text_field_tag :search, nil,
type: "search", type: "search",
role: "combobox", role: "combobox",
placeholder: "Type to jump to a collection, person, place, or tag…", placeholder: "Type to jump to a board, person, place, or tag…",
class: "input input--transparent txt-small", class: "input input--transparent txt-small",
autofocus: true, autofocus: true,
autocorrect: "off", autocorrect: "off",
+4 -4
View File
@@ -1,6 +1,6 @@
module RichTextHelper module RichTextHelper
def mentions_prompt(collection) def mentions_prompt(board)
content_tag "lexxy-prompt", "", trigger: "@", src: prompts_collection_users_path(collection), name: "mention" content_tag "lexxy-prompt", "", trigger: "@", src: prompts_board_users_path(board), name: "mention"
end end
def global_mentions_prompt def global_mentions_prompt
@@ -19,7 +19,7 @@ module RichTextHelper
content_tag "lexxy-code-language-picker" content_tag "lexxy-code-language-picker"
end end
def general_prompts(collection) def general_prompts(board)
safe_join([ mentions_prompt(collection), cards_prompt, code_language_picker ]) safe_join([ mentions_prompt(board), cards_prompt, code_language_picker ])
end end
end end
+4 -4
View File
@@ -2,7 +2,7 @@ module WebhooksHelper
ACTION_LABELS = { ACTION_LABELS = {
card_published: "Card added", card_published: "Card added",
card_title_changed: "Card title changed", card_title_changed: "Card title changed",
card_collection_changed: "Card collection changed", card_board_changed: "Card board changed",
comment_created: "Comment added", comment_created: "Comment added",
card_assigned: "Card assigned", card_assigned: "Card assigned",
card_unassigned: "Card unassigned", card_unassigned: "Card unassigned",
@@ -22,9 +22,9 @@ module WebhooksHelper
ACTION_LABELS[action] || action.to_s.humanize ACTION_LABELS[action] || action.to_s.humanize
end end
def link_to_webhooks(collection, &) def link_to_webhooks(board, &)
link_to collection_webhooks_path(collection_id: collection), link_to board_webhooks_path(board_id: board),
class: [ "btn", { "btn--reversed": collection.webhooks.any? } ], class: [ "btn", { "btn--reversed": board.webhooks.any? } ],
data: { controller: "tooltip" } do data: { controller: "tooltip" } do
icon_tag("world") + tag.span("Webhooks", class: "for-screen-reader") icon_tag("world") + tag.span("Webhooks", class: "for-screen-reader")
end end
@@ -5,7 +5,7 @@ export default class extends Controller {
static classes = [ "collapsed", "noTransitions" ] static classes = [ "collapsed", "noTransitions" ]
static targets = [ "column", "button" ] static targets = [ "column", "button" ]
static values = { static values = {
collection: String board: String
} }
initialize() { initialize() {
@@ -104,6 +104,6 @@ export default class extends Controller {
} }
#localStorageKeyFor(column) { #localStorageKeyFor(column) {
return `expand-${this.collectionValue}-${column.getAttribute("id")}` return `expand-${this.boardValue}-${column.getAttribute("id")}`
} }
} }
@@ -24,7 +24,7 @@ export default class extends Controller {
checkNone() { checkNone() {
this.checkboxTargets.forEach(checkbox => { this.checkboxTargets.forEach(checkbox => {
if (checkbox.dataset.collectionsFormTarget === "meCheckbox") return if (checkbox.dataset.boardsFormTarget === "meCheckbox") return
checkbox.checked = false checkbox.checked = false
}) })
} }
@@ -1,5 +1,5 @@
class Collection::CleanInaccessibleDataJob < ApplicationJob class Board::CleanInaccessibleDataJob < ApplicationJob
def perform(user, collection) def perform(user, board)
collection.clean_inaccessible_data_for(user) board.clean_inaccessible_data_for(user)
end end
end end
+2 -2
View File
@@ -1,5 +1,5 @@
class Access < ApplicationRecord class Access < ApplicationRecord
belongs_to :collection, touch: true belongs_to :board, touch: true
belongs_to :user, touch: true belongs_to :user, touch: true
enum :involvement, %i[ access_only watching ].index_by(&:itself), default: :access_only enum :involvement, %i[ access_only watching ].index_by(&:itself), default: :access_only
@@ -18,6 +18,6 @@ class Access < ApplicationRecord
end end
def clean_inaccessible_data_later def clean_inaccessible_data_later
Collection::CleanInaccessibleDataJob.perform_later(user, collection) Board::CleanInaccessibleDataJob.perform_later(user, board)
end end
end end
+3 -3
View File
@@ -26,9 +26,9 @@ class Account::Seeder
def populate def populate
# --------------- # ---------------
# Playground Collection # Playground Board
# --------------- # ---------------
playground = Collection.create! name: "Playground", creator: creator, all_access: true playground = Board.create! name: "Playground", creator: creator, all_access: true
# Cards # Cards
playground.cards.create! creator: creator, title: "Watch this: Fizzy orientation video", status: "published", description: <<~HTML playground.cards.create! creator: creator, title: "Watch this: Fizzy orientation video", status: "published", description: <<~HTML
@@ -105,7 +105,7 @@ class Account::Seeder
def delete_everything def delete_everything
Current.set session: session do Current.set session: session do
Collection.destroy_all Board.destroy_all
end end
end end
end end
+13 -13
View File
@@ -3,7 +3,7 @@ class Card < ApplicationRecord
Eventable, Golden, Mentions, Multistep, Pinnable, Postponable, Promptable, Eventable, Golden, Mentions, Multistep, Pinnable, Postponable, Promptable,
Readable, Searchable, Stallable, Statuses, Taggable, Triageable, Watchable Readable, Searchable, Stallable, Statuses, Taggable, Triageable, Watchable
belongs_to :collection, touch: true belongs_to :board, touch: true
belongs_to :creator, class_name: "User", default: -> { Current.user } belongs_to :creator, class_name: "User", default: -> { Current.user }
has_many :comments, dependent: :destroy has_many :comments, dependent: :destroy
@@ -12,7 +12,7 @@ class Card < ApplicationRecord
has_rich_text :description has_rich_text :description
before_save :set_default_title, if: :published? before_save :set_default_title, if: :published?
after_update :handle_collection_change, if: :saved_change_to_collection_id? after_update :handle_board_change, if: :saved_change_to_board_id?
scope :reverse_chronologically, -> { order created_at: :desc, id: :desc } scope :reverse_chronologically, -> { order created_at: :desc, id: :desc }
scope :chronologically, -> { order created_at: :asc, id: :asc } scope :chronologically, -> { order created_at: :asc, id: :asc }
@@ -39,16 +39,16 @@ class Card < ApplicationRecord
end end
end end
delegate :accessible_to?, to: :collection delegate :accessible_to?, to: :board
def card def card
self self
end end
def move_to(new_collection) def move_to(new_board)
transaction do transaction do
card.update!(collection: new_collection) card.update!(board: new_board)
card.events.update_all(collection_id: new_collection.id) card.events.update_all(board_id: new_board.id)
end end
end end
@@ -61,23 +61,23 @@ class Card < ApplicationRecord
self.title = "Untitled" if title.blank? self.title = "Untitled" if title.blank?
end end
def handle_collection_change def handle_board_change
old_collection = Collection.find_by(id: collection_id_before_last_save) old_board = Board.find_by(id: board_id_before_last_save)
transaction do transaction do
update! column: nil update! column: nil
track_collection_change_event(old_collection.name) track_board_change_event(old_board.name)
grant_access_to_assignees unless collection.all_access? grant_access_to_assignees unless board.all_access?
end end
remove_inaccessible_notifications_later remove_inaccessible_notifications_later
end end
def track_collection_change_event(old_collection_name) def track_board_change_event(old_board_name)
track_event "collection_changed", particulars: { old_collection: old_collection_name, new_collection: collection.name } track_event "board_changed", particulars: { old_board: old_board_name, new_board: board.name }
end end
def grant_access_to_assignees def grant_access_to_assignees
collection.accesses.grant_to(assignees) board.accesses.grant_to(assignees)
end end
end end
+3 -3
View File
@@ -4,19 +4,19 @@ module Card::Entropic
included do included do
scope :due_to_be_postponed, -> do scope :due_to_be_postponed, -> do
active active
.left_outer_joins(collection: :entropy) .left_outer_joins(board: :entropy)
.where("last_active_at <= DATETIME('now', '-' || COALESCE(entropies.auto_postpone_period, ?) || ' seconds')", .where("last_active_at <= DATETIME('now', '-' || COALESCE(entropies.auto_postpone_period, ?) || ' seconds')",
Account.sole.entropy.auto_postpone_period) Account.sole.entropy.auto_postpone_period)
end end
scope :postponing_soon, -> do scope :postponing_soon, -> do
active active
.left_outer_joins(collection: :entropy) .left_outer_joins(board: :entropy)
.where("last_active_at > DATETIME('now', '-' || COALESCE(entropies.auto_postpone_period, ?) || ' seconds')", Account.sole.entropy.auto_postpone_period) .where("last_active_at > DATETIME('now', '-' || COALESCE(entropies.auto_postpone_period, ?) || ' seconds')", Account.sole.entropy.auto_postpone_period)
.where("last_active_at <= DATETIME('now', '-' || CAST(COALESCE(entropies.auto_postpone_period, ?) * 0.75 AS INTEGER) || ' seconds')", Account.sole.entropy.auto_postpone_period) .where("last_active_at <= DATETIME('now', '-' || CAST(COALESCE(entropies.auto_postpone_period, ?) * 0.75 AS INTEGER) || ' seconds')", Account.sole.entropy.auto_postpone_period)
end end
delegate :auto_postpone_period, to: :collection delegate :auto_postpone_period, to: :board
end end
class_methods do class_methods do
@@ -28,8 +28,8 @@ class Card::Eventable::SystemCommenter
"<strong>Closed</strong> as “Not Now” due to inactivity" "<strong>Closed</strong> as “Not Now” due to inactivity"
when "card_title_changed" when "card_title_changed"
"#{event.creator.name} <strong>changed the title</strong> from “#{event.particulars.dig('particulars', 'old_title')}” to “#{event.particulars.dig('particulars', 'new_title')}”." "#{event.creator.name} <strong>changed the title</strong> from “#{event.particulars.dig('particulars', 'old_title')}” to “#{event.particulars.dig('particulars', 'new_title')}”."
when "card_collection_changed" when "card_board_changed"
"#{event.creator.name} <strong>moved</strong> this from “#{event.particulars.dig('particulars', 'old_collection')}” to “#{event.particulars.dig('particulars', 'new_collection')}”." "#{event.creator.name} <strong>moved</strong> this from “#{event.particulars.dig('particulars', 'old_board')}” to “#{event.particulars.dig('particulars', 'new_board')}”."
when "card_triaged" when "card_triaged"
"#{event.creator.name} <strong>moved</strong> this to “#{event.particulars.dig('particulars', 'column')}" "#{event.creator.name} <strong>moved</strong> this to “#{event.particulars.dig('particulars', 'column')}"
when "card_sent_back_to_triage" when "card_sent_back_to_triage"
+2 -2
View File
@@ -21,8 +21,8 @@ module Card::Promptable
* Assigned to: #{assignees.map(&:name).join(", ")} * Assigned to: #{assignees.map(&:name).join(", ")}
* Column: #{column_prompt_label} * Column: #{column_prompt_label}
* Created at: #{created_at}} * Created at: #{created_at}}
* Collection id: #{collection_id} * Board id: #{board_id}
* Collection name: #{collection.name} * Board name: #{board.name}
* Number of comments: #{comments.count} * Number of comments: #{comments.count}
* Path: #{card_path(self, script_name: Account.sole.slug)} * Path: #{card_path(self, script_name: Account.sole.slug)}
+1 -1
View File
@@ -17,7 +17,7 @@ module Card::Triageable
end end
def triage_into(column) def triage_into(column)
raise "The column must belong to the card collection" unless collection == column.collection raise "The column must belong to the card board" unless board == column.board
transaction do transaction do
resume resume
+1 -1
View File
@@ -1,4 +1,4 @@
class Collection < ApplicationRecord class Board < ApplicationRecord
include AutoClosing, Accessible, Broadcastable, Cards, Entropic, Filterable, Publishable, Triageable include AutoClosing, Accessible, Broadcastable, Cards, Entropic, Filterable, Publishable, Triageable
belongs_to :creator, class_name: "User", default: -> { Current.user } belongs_to :creator, class_name: "User", default: -> { Current.user }
+5 -5
View File
@@ -1,4 +1,4 @@
module Collection::Accessible module Board::Accessible
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
@@ -11,7 +11,7 @@ module Collection::Accessible
end end
def grant_to(users) def grant_to(users)
Access.insert_all Array(users).collect { |user| { collection_id: proxy_association.owner.id, user_id: user.id } } Access.insert_all Array(users).collect { |user| { board_id: proxy_association.owner.id, user_id: user.id } }
end end
def revoke_from(users) def revoke_from(users)
@@ -69,7 +69,7 @@ module Collection::Accessible
.joins("LEFT JOIN cards ON mentions.source_id = cards.id AND mentions.source_type = 'Card'") .joins("LEFT JOIN cards ON mentions.source_id = cards.id AND mentions.source_type = 'Card'")
.joins("LEFT JOIN comments ON mentions.source_id = comments.id AND mentions.source_type = 'Comment'") .joins("LEFT JOIN comments ON mentions.source_id = comments.id AND mentions.source_type = 'Comment'")
.joins("LEFT JOIN cards AS comment_cards ON comments.card_id = comment_cards.id") .joins("LEFT JOIN cards AS comment_cards ON comments.card_id = comment_cards.id")
.where("(mentions.source_type = 'Card' AND cards.collection_id = ?) OR (mentions.source_type = 'Comment' AND comment_cards.collection_id = ?)", id, id) .where("(mentions.source_type = 'Card' AND cards.board_id = ?) OR (mentions.source_type = 'Comment' AND comment_cards.board_id = ?)", id, id)
end end
def notifications_for_user(user) def notifications_for_user(user)
@@ -85,8 +85,8 @@ module Collection::Accessible
.joins("LEFT JOIN cards AS event_cards ON events.eventable_id = event_cards.id AND events.eventable_type = 'Card'") .joins("LEFT JOIN cards AS event_cards ON events.eventable_id = event_cards.id AND events.eventable_type = 'Card'")
.joins("LEFT JOIN comments AS event_comments ON events.eventable_id = event_comments.id AND events.eventable_type = 'Comment'") .joins("LEFT JOIN comments AS event_comments ON events.eventable_id = event_comments.id AND events.eventable_type = 'Comment'")
.joins("LEFT JOIN cards AS event_comment_cards ON event_comments.card_id = event_comment_cards.id") .joins("LEFT JOIN cards AS event_comment_cards ON event_comments.card_id = event_comment_cards.id")
.where("(notifications.source_type = 'Event' AND events.eventable_type = 'Card' AND event_cards.collection_id = ?) OR .where("(notifications.source_type = 'Event' AND events.eventable_type = 'Card' AND event_cards.board_id = ?) OR
(notifications.source_type = 'Event' AND events.eventable_type = 'Comment' AND event_comment_cards.collection_id = ?)", (notifications.source_type = 'Event' AND events.eventable_type = 'Comment' AND event_comment_cards.board_id = ?)",
id, id) id, id)
end end
end end
+1 -1
View File
@@ -1,4 +1,4 @@
module Collection::AutoClosing module Board::AutoClosing
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
+2 -2
View File
@@ -1,8 +1,8 @@
module Collection::Broadcastable module Board::Broadcastable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
broadcasts_refreshes broadcasts_refreshes
broadcasts_refreshes_to ->(_) { :all_collections } broadcasts_refreshes_to ->(_) { :all_boards }
end end
end end
+1 -1
View File
@@ -1,4 +1,4 @@
module Collection::Cards module Board::Cards
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
+1 -1
View File
@@ -1,4 +1,4 @@
module Collection::Entropic module Board::Entropic
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
+2 -2
View File
@@ -1,5 +1,5 @@
class Collection::Publication < ApplicationRecord class Board::Publication < ApplicationRecord
belongs_to :collection belongs_to :board
has_secure_token :key has_secure_token :key
end end
+3 -3
View File
@@ -1,14 +1,14 @@
module Collection::Publishable module Board::Publishable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
has_one :publication, class_name: "Collection::Publication", dependent: :destroy has_one :publication, class_name: "Board::Publication", dependent: :destroy
scope :published, -> { joins(:publication) } scope :published, -> { joins(:publication) }
end end
class_methods do class_methods do
def find_by_published_key(key) def find_by_published_key(key)
Collection::Publication.find_by!(key: key).collection Board::Publication.find_by!(key: key).board
end end
end end
+1 -1
View File
@@ -1,4 +1,4 @@
module Collection::Triageable module Board::Triageable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
+2 -2
View File
@@ -1,10 +1,10 @@
class Column < ApplicationRecord class Column < ApplicationRecord
include Positioned include Positioned
belongs_to :collection, touch: true belongs_to :board, touch: true
has_many :cards, dependent: :nullify has_many :cards, dependent: :nullify
before_validation -> { self.color ||= Card::DEFAULT_COLOR } before_validation -> { self.color ||= Card::DEFAULT_COLOR }
after_save_commit -> { cards.touch_all }, if: -> { saved_change_to_name? || saved_change_to_color? } after_save_commit -> { cards.touch_all }, if: -> { saved_change_to_name? || saved_change_to_color? }
after_destroy_commit -> { collection.cards.touch_all } after_destroy_commit -> { board.cards.touch_all }
end end
+3 -3
View File
@@ -16,11 +16,11 @@ module Column::Positioned
end end
def left_column def left_column
collection.columns.where("position < ?", position).sorted.last board.columns.where("position < ?", position).sorted.last
end end
def right_column def right_column
collection.columns.where("position > ?", position).sorted.first board.columns.where("position > ?", position).sorted.first
end end
def leftmost? def leftmost?
@@ -33,7 +33,7 @@ module Column::Positioned
private private
def set_position def set_position
max_position = collection.columns.maximum(:position) || 0 max_position = board.columns.maximum(:position) || 0
self.position = max_position + 1 self.position = max_position + 1
end end
+1 -1
View File
@@ -14,7 +14,7 @@ class Comment < ApplicationRecord
after_create_commit :watch_card_by_creator after_create_commit :watch_card_by_creator
delegate :collection, :watch_by, to: :card delegate :board, :watch_by, to: :card
def to_partial_path def to_partial_path
"cards/#{super}" "cards/#{super}"
+1 -1
View File
@@ -17,6 +17,6 @@ module Comment::Eventable
end end
def track_creation def track_creation
track_event("created", collection: card.collection, creator: creator) track_event("created", board: card.board, creator: creator)
end end
end end
+1 -1
View File
@@ -41,7 +41,7 @@ module Mentions
end end
def mentionable_users def mentionable_users
collection.users board.users
end end
def rich_text_associations def rich_text_associations
+1 -1
View File
@@ -1,7 +1,7 @@
class Event < ApplicationRecord class Event < ApplicationRecord
include Notifiable, Particulars, Promptable include Notifiable, Particulars, Promptable
belongs_to :collection belongs_to :board
belongs_to :creator, class_name: "User" belongs_to :creator, class_name: "User"
belongs_to :eventable, polymorphic: true belongs_to :eventable, polymorphic: true
+2 -2
View File
@@ -5,9 +5,9 @@ module Eventable
has_many :events, as: :eventable, dependent: :destroy has_many :events, as: :eventable, dependent: :destroy
end end
def track_event(action, creator: Current.user, collection: self.collection, **particulars) def track_event(action, creator: Current.user, board: self.board, **particulars)
if should_track_event? if should_track_event?
collection.events.create!(action: "#{eventable_prefix}_#{action}", creator:, collection:, eventable: self, particulars:) board.events.create!(action: "#{eventable_prefix}_#{action}", creator:, board:, eventable: self, particulars:)
end end
end end
+5 -5
View File
@@ -27,7 +27,7 @@ class Filter < ApplicationRecord
result = result.unassigned if assignment_status.unassigned? result = result.unassigned if assignment_status.unassigned?
result = result.assigned_to(assignees.ids) if assignees.present? result = result.assigned_to(assignees.ids) if assignees.present?
result = result.where(creator_id: creators.ids) if creators.present? result = result.where(creator_id: creators.ids) if creators.present?
result = result.where(collection: collections.ids) if collections.present? result = result.where(board: boards.ids) if boards.present?
result = result.tagged_with(tags.ids) if tags.present? result = result.tagged_with(tags.ids) if tags.present?
result = result.where("cards.created_at": creation_window) if creation_window result = result.where("cards.created_at": creation_window) if creation_window
result = result.closed_at_window(closure_window) if closure_window result = result.closed_at_window(closure_window) if closure_window
@@ -44,16 +44,16 @@ class Filter < ApplicationRecord
self.class.normalize_params(as_params).blank? self.class.normalize_params(as_params).blank?
end end
def single_collection def single_board
collections.first if collections.one? boards.first if boards.one?
end end
def single_workflow def single_workflow
collections.first.workflow if collections.pluck(:workflow_id).uniq.one? boards.first.workflow if boards.pluck(:workflow_id).uniq.one?
end end
def cacheable? def cacheable?
collections.exists? boards.exists?
end end
def cache_key def cache_key
+4 -4
View File
@@ -11,7 +11,7 @@ module Filter::Params
assignee_ids: [], assignee_ids: [],
creator_ids: [], creator_ids: [],
closer_ids: [], closer_ids: [],
collection_ids: [], board_ids: [],
tag_ids: [], tag_ids: [],
terms: [] terms: []
] ]
@@ -40,9 +40,9 @@ module Filter::Params
before_save { self.params_digest = self.class.digest_params(as_params) } before_save { self.params_digest = self.class.digest_params(as_params) }
end end
def used?(ignore_collections: false) def used?(ignore_boards: false)
tags.any? || assignees.any? || creators.any? || closers.any? || tags.any? || assignees.any? || creators.any? || closers.any? ||
terms.any? || card_ids&.any? || (!ignore_collections && collections.present?) || terms.any? || card_ids&.any? || (!ignore_boards && boards.present?) ||
assignment_status.unassigned? || !indexed_by.all? || !sorted_by.latest? assignment_status.unassigned? || !indexed_by.all? || !sorted_by.latest?
end end
@@ -57,7 +57,7 @@ module Filter::Params
params[:assignment_status] = assignment_status params[:assignment_status] = assignment_status
params[:terms] = terms params[:terms] = terms
params[:tag_ids] = tags.ids params[:tag_ids] = tags.ids
params[:collection_ids] = collections.ids params[:board_ids] = boards.ids
params[:card_ids] = card_ids params[:card_ids] = card_ids
params[:assignee_ids] = assignees.ids params[:assignee_ids] = assignees.ids
params[:creator_ids] = creators.ids params[:creator_ids] = creators.ids
+9 -9
View File
@@ -3,7 +3,7 @@ module Filter::Resources
included do included do
has_and_belongs_to_many :tags has_and_belongs_to_many :tags
has_and_belongs_to_many :collections has_and_belongs_to_many :boards
has_and_belongs_to_many :assignees, class_name: "User", join_table: "assignees_filters", association_foreign_key: "assignee_id" has_and_belongs_to_many :assignees, class_name: "User", join_table: "assignees_filters", association_foreign_key: "assignee_id"
has_and_belongs_to_many :creators, class_name: "User", join_table: "creators_filters", association_foreign_key: "creator_id" has_and_belongs_to_many :creators, class_name: "User", join_table: "creators_filters", association_foreign_key: "creator_id"
has_and_belongs_to_many :closers, class_name: "User", join_table: "closers_filters", association_foreign_key: "closer_id" has_and_belongs_to_many :closers, class_name: "User", join_table: "closers_filters", association_foreign_key: "closer_id"
@@ -17,19 +17,19 @@ module Filter::Resources
destroy! destroy!
end end
def collections def boards
creator.collections.where id: super.ids creator.boards.where id: super.ids
end end
def collection_titles def board_titles
if collections.none? if boards.none?
Collection.one? ? [ Collection.first.name ] : [ "all boards" ] Board.one? ? [ Board.first.name ] : [ "all boards" ]
else else
collections.map(&:name) boards.map(&:name)
end end
end end
def collections_label def boards_label
collection_titles.to_sentence board_titles.to_sentence
end end
end end
+3 -3
View File
@@ -1,6 +1,6 @@
class Notifier::CardEventNotifier < Notifier class Notifier::CardEventNotifier < Notifier
delegate :creator, to: :source delegate :creator, to: :source
delegate :collection, to: :card delegate :board, to: :card
private private
def recipients def recipients
@@ -8,11 +8,11 @@ class Notifier::CardEventNotifier < Notifier
when "card_assigned" when "card_assigned"
source.assignees.excluding(creator) source.assignees.excluding(creator)
when "card_published" when "card_published"
collection.watchers.without(creator, *card.mentionees) board.watchers.without(creator, *card.mentionees)
when "comment_created" when "comment_created"
card.watchers.without(creator, *source.eventable.mentionees) card.watchers.without(creator, *source.eventable.mentionees)
else else
collection.watchers.without(creator) board.watchers.without(creator)
end end
end end
+2 -2
View File
@@ -21,7 +21,7 @@ class Search
"highlight(cards_search_index, 0, '#{HIGHLIGHT_OPENING_MARK}', '#{HIGHLIGHT_CLOSING_MARK}') AS card_title", "highlight(cards_search_index, 0, '#{HIGHLIGHT_OPENING_MARK}', '#{HIGHLIGHT_CLOSING_MARK}') AS card_title",
"snippet(cards_search_index, 1, '#{HIGHLIGHT_OPENING_MARK}', '#{HIGHLIGHT_CLOSING_MARK}', '...', 20) AS card_description", "snippet(cards_search_index, 1, '#{HIGHLIGHT_OPENING_MARK}', '#{HIGHLIGHT_CLOSING_MARK}', '...', 20) AS card_description",
"null as comment_body", "null as comment_body",
"collections.name as collection_name", "boards.name as board_name",
"cards.creator_id", "cards.creator_id",
"cards.created_at", "cards.created_at",
"bm25(cards_search_index, 10.0, 2.0) AS score" "bm25(cards_search_index, 10.0, 2.0) AS score"
@@ -34,7 +34,7 @@ class Search
"cards.title AS card_title", "cards.title AS card_title",
"null AS card_description", "null AS card_description",
"snippet(comments_search_index, 0, '#{HIGHLIGHT_OPENING_MARK}', '#{HIGHLIGHT_CLOSING_MARK}', '...', 20) AS comment_body", "snippet(comments_search_index, 0, '#{HIGHLIGHT_OPENING_MARK}', '#{HIGHLIGHT_CLOSING_MARK}', '...', 20) AS comment_body",
"collections.name as collection_name", "boards.name as board_name",
"comments.creator_id", "comments.creator_id",
"comments.created_at", "comments.created_at",
"bm25(comments_search_index, 1.0) AS score" "bm25(comments_search_index, 1.0) AS score"
+5 -5
View File
@@ -3,15 +3,15 @@ module User::Accessor
included do included do
has_many :accesses, dependent: :destroy has_many :accesses, dependent: :destroy
has_many :collections, through: :accesses has_many :boards, through: :accesses
has_many :accessible_cards, through: :collections, source: :cards has_many :accessible_cards, through: :boards, source: :cards
has_many :accessible_comments, through: :accessible_cards, source: :comments has_many :accessible_comments, through: :accessible_cards, source: :comments
after_create_commit :grant_access_to_collections, unless: :system? after_create_commit :grant_access_to_boards, unless: :system?
end end
private private
def grant_access_to_collections def grant_access_to_boards
Access.insert_all Collection.all_access.pluck(:id).collect { |collection_id| { collection_id: collection_id, user_id: id } } Access.insert_all Board.all_access.pluck(:id).collect { |board_id| { board_id: board_id, user_id: id } }
end end
end end
+4 -4
View File
@@ -40,7 +40,7 @@ class User::DayTimeline
card_published card_published
card_closed card_closed
card_reopened card_reopened
card_collection_changed card_board_changed
card_postponed card_postponed
card_triaged card_triaged
card_sent_back_to_triage card_sent_back_to_triage
@@ -57,12 +57,12 @@ class User::DayTimeline
def timelineable_events def timelineable_events
Event Event
.where(collection: collections) .where(board: boards)
.where(action: TIMELINEABLE_ACTIONS) .where(action: TIMELINEABLE_ACTIONS)
end end
def collections def boards
filter.collections.presence || user.collections filter.boards.presence || user.boards
end end
def latest_event_before def latest_event_before
+13 -13
View File
@@ -1,23 +1,23 @@
class User::Filtering class User::Filtering
attr_reader :user, :filter, :expanded attr_reader :user, :filter, :expanded
delegate :as_params, :single_collection, to: :filter delegate :as_params, :single_board, to: :filter
delegate :only_closed?, to: :filter delegate :only_closed?, to: :filter
def initialize(user, filter, expanded: false) def initialize(user, filter, expanded: false)
@user, @filter, @expanded = user, filter, expanded @user, @filter, @expanded = user, filter, expanded
end end
def collections def boards
@collections ||= user.collections.ordered_by_recently_accessed @boards ||= user.boards.ordered_by_recently_accessed
end end
def selected_collection_titles def selected_board_titles
filter.collection_titles filter.board_titles
end end
def selected_collections_label def selected_boards_label
filter.collections_label filter.boards_label
end end
def tags def tags
@@ -37,7 +37,7 @@ class User::Filtering
end end
def any? def any?
filter.used?(ignore_collections: true) filter.used?(ignore_boards: true)
end end
def show_indexed_by? def show_indexed_by?
@@ -65,16 +65,16 @@ class User::Filtering
filter.closers.any? filter.closers.any?
end end
def show_collections? def show_boards?
filter.collections.any? filter.boards.any?
end end
def single_collection_or_first def single_board_or_first
# Default to the first selected or, when no selection, to the first one # Default to the first selected or, when no selection, to the first one
filter.collections.first || collections.first filter.boards.first || boards.first
end end
def cache_key def cache_key
ActiveSupport::Cache.expand_cache_key([ user, filter, expanded?, collections, tags, users, filters ], "user-filtering") ActiveSupport::Cache.expand_cache_key([ user, filter, expanded?, boards, tags, users, filters ], "user-filtering")
end end
end end
+1 -1
View File
@@ -2,7 +2,7 @@ module User::Timelined
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
has_many :accessible_events, through: :collections, source: :events has_many :accessible_events, through: :boards, source: :events
end end
def timeline_for(day, filter:) def timeline_for(day, filter:)
+2 -2
View File
@@ -11,7 +11,7 @@ class Webhook < ApplicationRecord
card_closed card_closed
card_postponed card_postponed
card_auto_postponed card_auto_postponed
card_collection_changed card_board_changed
card_published card_published
card_reopened card_reopened
card_sent_back_to_triage card_sent_back_to_triage
@@ -25,7 +25,7 @@ class Webhook < ApplicationRecord
has_many :deliveries, dependent: :delete_all has_many :deliveries, dependent: :delete_all
has_one :delinquency_tracker, dependent: :delete has_one :delinquency_tracker, dependent: :delete
belongs_to :collection belongs_to :board
serialize :subscribed_actions, type: Array, coder: JSON serialize :subscribed_actions, type: Array, coder: JSON
+1 -1
View File
@@ -2,7 +2,7 @@ module Webhook::Triggerable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
scope :triggered_by, ->(event) { where(collection: event.collection).triggered_by_action(event.action) } scope :triggered_by, ->(event) { where(board: event.board).triggered_by_action(event.action) }
scope :triggered_by_action, ->(action) { where("subscribed_actions LIKE ?", "%\"#{action}\"%") } scope :triggered_by_action, ->(action) { where("subscribed_actions LIKE ?", "%\"#{action}\"%") }
end end
+1 -1
View File
@@ -13,7 +13,7 @@
<input placeholder="Filter…" class="input input--transparent full-width txt-small" type="search" autocorrect="off" autocomplete="off" data-1p-ignore="true" data-filter-target="input" data-action="input->filter#filter"> <input placeholder="Filter…" class="input input--transparent full-width txt-small" type="search" autocorrect="off" autocomplete="off" data-1p-ignore="true" data-filter-target="input" data-action="input->filter#filter">
<ul class="settings__user-list margin-block-half" data-filter-target="list"> <ul class="settings__user-list margin-block-half" data-filter-target="list">
<%= render partial: "account/settings/user", collection: users %> <%= render partial: "account/settings/user", board: users %>
</ul> </ul>
</div> </div>
+4 -4
View File
@@ -1,7 +1,7 @@
<% if filter.collections.any? %> <% if filter.boards.any? %>
<% filter.collections.each do |collection| %> <% filter.boards.each do |board| %>
<%= turbo_stream_from collection %> <%= turbo_stream_from board %>
<% end %> <% end %>
<% else %> <% else %>
<%= turbo_stream_from :all_collections %> <%= turbo_stream_from :all_boards %>
<% end %> <% end %>
+2 -2
View File
@@ -8,8 +8,8 @@ json.cache! [ card, card.column&.color ] do
json.url card_url(card) json.url card_url(card)
json.collection do json.board do
json.partial! "collections/collection", locals: { collection: card.collection } json.partial! "boards/board", locals: { board: card.board }
end end
json.column do json.column do
+1 -1
View File
@@ -8,7 +8,7 @@
<div class="card-perma__bg"> <div class="card-perma__bg">
<%= card_article_tag card, class: "card" do %> <%= card_article_tag card, class: "card" do %>
<header class="card__header"> <header class="card__header">
<%= render "cards/display/perma/collection", card: card %> <%= render "cards/display/perma/board", card: card %>
<%= render "cards/display/perma/tags", card: card %> <%= render "cards/display/perma/tags", card: card %>
</header> </header>
+1 -1
View File
@@ -1,6 +1,6 @@
<%= messages_tag(card) do %> <%= messages_tag(card) do %>
<% if card.published? %> <% if card.published? %>
<%= render partial: "cards/comments/comment", collection: card.comments.chronologically, cached: true %> <%= render partial: "cards/comments/comment", board: card.comments.chronologically, cached: true %>
<%= render "cards/comments/new", card: card %> <%= render "cards/comments/new", card: card %>
<%= render "cards/comments/watchers", card: card %> <%= render "cards/comments/watchers", card: card %>
+5 -5
View File
@@ -1,4 +1,4 @@
<%= turbo_frame_tag "collection_picker" do %> <%= turbo_frame_tag "board_picker" do %>
<%= tag.div class: "max-width full-width", data: { <%= tag.div class: "max-width full-width", data: {
action: "turbo:before-cache@document->dialog#close dialog:show@document->navigable-list#reset keydown->navigable-list#navigate filter:changed->navigable-list#reset", action: "turbo:before-cache@document->dialog#close dialog:show@document->navigable-list#reset keydown->navigable-list#navigate filter:changed->navigable-list#reset",
controller: "filter navigable-list", controller: "filter navigable-list",
@@ -11,12 +11,12 @@
type: "search", autocorrect: "off", autocomplete: "off", data: { "1p-ignore": "true", filter_target: "input", action: "input->filter#filter" } %> type: "search", autocorrect: "off", autocomplete: "off", data: { "1p-ignore": "true", filter_target: "input", action: "input->filter#filter" } %>
<ul class="popup__list margin-block-start-half margin-none-block-end" data-filter-target="list"> <ul class="popup__list margin-block-start-half margin-none-block-end" data-filter-target="list">
<% @collections.each do |collection| %> <% @boards.each do |board| %>
<li class="popup__item" data-filter-target="item" data-navigable-list-target="item" aria-checked="<%= @card.collection == collection %>"> <li class="popup__item" data-filter-target="item" data-navigable-list-target="item" aria-checked="<%= @card.board == board %>">
<%= button_to card_collection_path(@card, params: { collection_id: collection.id }), method: :patch, <%= button_to card_board_path(@card, params: { board_id: board.id }), method: :patch,
class: "popup__btn btn", class: "popup__btn btn",
form_class: "max-width flex-item-grow" do %> form_class: "max-width flex-item-grow" do %>
<span class="overflow-ellipsis flex-item-grow"><%= collection.name %></span> <span class="overflow-ellipsis flex-item-grow"><%= board.name %></span>
<%= icon_tag "check", size: 18, class: "checked flex-item-no-shrink flex-item-justify-end", style: "--icon-size: 1em" %> <%= icon_tag "check", size: 18, class: "checked flex-item-no-shrink flex-item-justify-end", style: "--icon-size: 1em" %>
<% end %> <% end %>
</li> </li>
+1 -1
View File
@@ -11,7 +11,7 @@
action: "turbo:submit-end->local-save#submit keydown.ctrl+enter->form#debouncedSubmit:prevent keydown.meta+enter->form#debouncedSubmit:prevent keydown.esc->form#cancel:stop" } do |form| %> action: "turbo:submit-end->local-save#submit keydown.ctrl+enter->form#debouncedSubmit:prevent keydown.meta+enter->form#debouncedSubmit:prevent keydown.esc->form#cancel:stop" } do |form| %>
<%= form.rich_textarea :body, required: true, placeholder: new_comment_placeholder(card), <%= form.rich_textarea :body, required: true, placeholder: new_comment_placeholder(card),
data: { local_save_target: "input", action: "lexxy:change->form#disableSubmitWhenInvalid lexxy:change->local-save#save turbo:morph-element->local-save#restoreContent" } do %> data: { local_save_target: "input", action: "lexxy:change->form#disableSubmitWhenInvalid lexxy:change->local-save#save turbo:morph-element->local-save#restoreContent" } do %>
<%= general_prompts(@card.collection) %> <%= general_prompts(@card.board) %>
<% end %> <% end %>
<%= form.button class: "comment__submit btn btn--reversed flex-item-justify-start", data: { form_target: "submit" }, disabled: true do %> <%= form.button class: "comment__submit btn btn--reversed flex-item-justify-start", data: { form_target: "submit" }, disabled: true do %>
<span>Post this comment</span> <span>Post this comment</span>
+1 -1
View File
@@ -9,7 +9,7 @@
<%= form_with model: [ @card, @comment ], class: "flex flex-column gap full-width", <%= form_with model: [ @card, @comment ], class: "flex flex-column gap full-width",
data: { controller: "form", action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop" } do |form| %> data: { controller: "form", action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop" } do |form| %>
<%= form.rich_textarea :body, required: true, autofocus: true, placeholder: new_comment_placeholder(@card) do %> <%= form.rich_textarea :body, required: true, autofocus: true, placeholder: new_comment_placeholder(@card) do %>
<%= general_prompts(@card.collection) %> <%= general_prompts(@card.board) %>
<% end %> <% end %>
<div class="flex gap-half justify-start"> <div class="flex gap-half justify-start">
<%= form.button class: "btn btn--reversed", type: :submit do %> <%= form.button class: "btn btn--reversed", type: :submit do %>
@@ -1,7 +1,7 @@
<%= turbo_frame_tag comment, :reacting do %> <%= turbo_frame_tag comment, :reacting do %>
<div class="reactions"> <div class="reactions">
<div id="<%= dom_id(comment, :reactions) %>" class="reactions__list"> <div id="<%= dom_id(comment, :reactions) %>" class="reactions__list">
<%= render partial: "cards/comments/reactions/reaction", collection: comment.reactions.includes(:reacter).ordered %> <%= render partial: "cards/comments/reactions/reaction", board: comment.reactions.includes(:reacter).ordered %>
</div> </div>
<%= turbo_frame_tag comment, :new_reaction do %> <%= turbo_frame_tag comment, :new_reaction do %>
+1 -1
View File
@@ -22,7 +22,7 @@
<%= form.rich_textarea :description, class: "card-field__description rich-text-content", <%= form.rich_textarea :description, class: "card-field__description rich-text-content",
placeholder: "Add some notes, context, pictures, or video about this…", placeholder: "Add some notes, context, pictures, or video about this…",
data: { action: "lexxy:change->auto-save#change focusout->auto-save#submit" } do %> data: { action: "lexxy:change->auto-save#change focusout->auto-save#submit" } do %>
<%= general_prompts(card.collection) %> <%= general_prompts(card.board) %>
<% end %> <% end %>
<% end %> <% end %>
<% end %> <% end %>
+1 -1
View File
@@ -3,7 +3,7 @@
<%= card_article_tag card, class: "card", draggable: draggable, data: { id: card.id, drag_and_drop_target: "item" } do %> <%= card_article_tag card, class: "card", draggable: draggable, data: { id: card.id, drag_and_drop_target: "item" } do %>
<div class="flex flex-column flex-item-grow max-inline-size"> <div class="flex flex-column flex-item-grow max-inline-size">
<header class="card__header"> <header class="card__header">
<%= render "cards/display/preview/collection", card: card %> <%= render "cards/display/preview/board", card: card %>
<%= render "cards/display/preview/tags", card: card %> <%= render "cards/display/preview/tags", card: card %>
<%= render "cards/display/preview/steps", card: card %> <%= render "cards/display/preview/steps", card: card %>
<%= icon_tag "attachment", class: "card__attachments-indicator translucent" if card.has_attachments? %> <%= icon_tag "attachment", class: "card__attachments-indicator translucent" if card.has_attachments? %>
+1 -1
View File
@@ -1 +1 @@
<%= render partial: "cards/display/preview", collection: cards, as: :card, locals: { draggable: local_assigns.fetch(:draggable, false) }, cached: true %> <%= render partial: "cards/display/preview", board: cards, as: :card, locals: { draggable: local_assigns.fetch(:draggable, false) }, cached: true %>
@@ -1,13 +1,13 @@
<%= card_article_tag card, class: "card" do %> <%= card_article_tag card, class: "card" do %>
<div class="flex flex-column flex-item-grow max-inline-size"> <div class="flex flex-column flex-item-grow max-inline-size">
<header class="card__header"> <header class="card__header">
<div class="card__collection flex align-start"> <div class="card__board flex align-start">
<span class="card__id"> <span class="card__id">
<span class="for-screen-reader">Card number</span> <span class="for-screen-reader">Card number</span>
<%= card.id %> <%= card.id %>
</span> </span>
<span class="card__collection-name"> <span class="card__board-name">
<span class="overflow-ellipsis"><%= card.collection.name %></span> <span class="overflow-ellipsis"><%= card.board.name %></span>
</span> </span>
</div> </div>
@@ -37,6 +37,6 @@
<% if card.entropic? %> <% if card.entropic? %>
<%= render "cards/display/preview/bubble", card: card %> <%= render "cards/display/preview/bubble", card: card %>
<span class="card__collection-name"> <span class="card__board-name">
<% end %> <% end %>
<% end %> <% end %>
@@ -1 +1 @@
<%= render partial: "cards/display/public_preview", collection: cards, as: :card, cached: true %> <%= render partial: "cards/display/public_preview", board: cards, as: :card, cached: true %>
@@ -1,10 +1,10 @@
<label class="card__collection"> <label class="card__board">
<span class="card__id"> <span class="card__id">
<span class="for-screen-reader">Card number</span> <span class="for-screen-reader">Card number</span>
<%= card.id %> <%= card.id %>
</span> </span>
<span class="card__collection-name"> <span class="card__board-name">
<span class="overflow-ellipsis"><%= card.collection.name %></span> <span class="overflow-ellipsis"><%= card.board.name %></span>
</span> </span>
<%= yield %> <%= yield %>
</label> </label>
@@ -1,12 +1,12 @@
<%= render "cards/display/common/collection", card: card do %> <%= render "cards/display/common/board", card: card do %>
<div class="align-self-center position-relative txt-small" data-controller="dialog" data-action="keydown.esc->dialog#close:stop click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>> <div class="align-self-center position-relative txt-small" data-controller="dialog" data-action="keydown.esc->dialog#close:stop click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>>
<button class="collection-picker__button btn btn--reversed card__hide-on-index fill-transparent" data-action="click->dialog#open:stop"> <button class="board-picker__button btn btn--reversed card__hide-on-index fill-transparent" data-action="click->dialog#open:stop">
<%= icon_tag "caret-down" %> <%= icon_tag "caret-down" %>
<span class="for-screen-reader">Choose a collection for this card</span> <span class="for-screen-reader">Choose a board for this card</span>
</button> </button>
<dialog class="popup panel flex-column align-start gap-half fill-white shadow margin-block-double" data-dialog-target="dialog" data-action="turbo:before-morph-attribute->dialog#preventCloseOnMorphing turbo:submit-end->dialog#close"> <dialog class="popup panel flex-column align-start gap-half fill-white shadow margin-block-double" data-dialog-target="dialog" data-action="turbo:before-morph-attribute->dialog#preventCloseOnMorphing turbo:submit-end->dialog#close">
<%= turbo_frame_tag "collection_picker", src: edit_card_collection_path(card), target: "_top", refresh: "morph" %> <%= turbo_frame_tag "board_picker", src: edit_card_board_path(card), target: "_top", refresh: "morph" %>
</dialog> </dialog>
</div> </div>
<% end %> <% end %>
@@ -1,5 +1,5 @@
<ol class="steps txt-small margin-block-start-auto"> <ol class="steps txt-small margin-block-start-auto">
<%= render partial: "cards/steps/step", collection: card.steps, as: :step %> <%= render partial: "cards/steps/step", board: card.steps, as: :step %>
<li id="<%= dom_id(card, :new_step) %>" class="step"> <li id="<%= dom_id(card, :new_step) %>" class="step">
<input type="checkbox" class="step__checkbox" disabled> <input type="checkbox" class="step__checkbox" disabled>
+1 -1
View File
@@ -13,7 +13,7 @@
<% if card.tags.any? %> <% if card.tags.any? %>
<div class="min-width overflow-ellipsis"> <div class="min-width overflow-ellipsis">
<% card.tags.each_with_index do |tag, index| %> <% card.tags.each_with_index do |tag, index| %>
<%= link_to cards_path(collection_ids: [ card.collection ], tag_ids: [ tag.id ]), <%= link_to cards_path(board_ids: [ card.board ], tag_ids: [ tag.id ]),
class: "card__tag btn btn--plain min-width txt-uppercase fill-transparent" do %> class: "card__tag btn btn--plain min-width txt-uppercase fill-transparent" do %>
<%= tag.title %> <%= tag.title %>
<% end %><%= "," unless index == card.tags.size - 1 %> <% end %><%= "," unless index == card.tags.size - 1 %>

Some files were not shown because too many files have changed in this diff Show More