From 2348dbb0d9599deef9f33dc53a8f6463f59e7338 Mon Sep 17 00:00:00 2001 From: Yuri Sidorov <403994+newstler@users.noreply.github.com> Date: Thu, 15 Jan 2026 17:06:35 +0100 Subject: [PATCH 1/3] Add column card counts to board menu items Display colored badge-style counts showing active cards per column in the jump menu. Shows "Maybe?" (triage) count first, followed by each column's count with its respective color. - Add board_column_counts_tag helper to render count badges - Eager load columns and cards in menus controller - Add CSS for .board-menu-counts and .board-menu-count - Add helper tests for the new functionality Co-Authored-By: Claude Sonnet 4.5 --- app/assets/stylesheets/popup.css | 24 ++++++++++++ app/controllers/my/menus_controller.rb | 2 +- app/helpers/my/menu_helper.rb | 26 ++++++++++++- test/helpers/my/menu_helper_test.rb | 52 ++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 test/helpers/my/menu_helper_test.rb diff --git a/app/assets/stylesheets/popup.css b/app/assets/stylesheets/popup.css index 02ae8969e5..2f34436448 100644 --- a/app/assets/stylesheets/popup.css +++ b/app/assets/stylesheets/popup.css @@ -219,4 +219,28 @@ } } } + + /* Board menu column counts + /* -------------------------------------------------------------------------- */ + + .board-menu-counts { + display: inline-flex; + gap: 0.25ch; + margin-inline-start: auto; + padding-inline-start: 1ch; + flex-shrink: 0; + } + + .board-menu-count { + --card-color: var(--color-ink-light); + + background-color: color-mix(in srgb, var(--card-color) 20%, transparent); + border-radius: 0.3em; + color: color-mix(in srgb, var(--card-color) 90%, var(--color-ink)); + font-size: var(--text-xx-small); + font-weight: 600; + min-inline-size: 1.8em; + padding: 0.1em 0.4em; + text-align: center; + } } diff --git a/app/controllers/my/menus_controller.rb b/app/controllers/my/menus_controller.rb index 24fa2b085a..c970ec0c4e 100644 --- a/app/controllers/my/menus_controller.rb +++ b/app/controllers/my/menus_controller.rb @@ -1,7 +1,7 @@ class My::MenusController < ApplicationController def show @filters = Current.user.filters.all - @boards = Current.user.boards.ordered_by_recently_accessed + @boards = Current.user.boards.ordered_by_recently_accessed.includes(columns: :cards) @tags = Current.account.tags.all.alphabetically @users = Current.account.users.active.alphabetically @accounts = Current.identity.accounts.active diff --git a/app/helpers/my/menu_helper.rb b/app/helpers/my/menu_helper.rb index 753bad6a2c..699d1cec72 100644 --- a/app/helpers/my/menu_helper.rb +++ b/app/helpers/my/menu_helper.rb @@ -19,7 +19,10 @@ def jump_field_tag def my_menu_board_item(board) my_menu_item("board", board) do - link_to(tag.span(board.name, class: "overflow-ellipsis"), board, class: "popup__btn btn") + link_to(board, class: "popup__btn btn") do + tag.span(board.name, class: "overflow-ellipsis") + + board_column_counts_tag(board) + end end end @@ -53,4 +56,25 @@ def my_menu_item(item, record) icon_tag(item, class: "popup__icon") + yield end end + + private + def board_column_counts_tag(board) + columns = board.columns.sorted + maybe_count = board.cards.awaiting_triage.size + + return tag.span if columns.empty? && maybe_count.zero? + + tag.span(class: "board-menu-counts") do + counts = [] + counts << board_count_tag(maybe_count) if maybe_count > 0 || columns.any? + counts += columns.map { |column| board_count_tag(column.cards.active.size, color: column.color) } + safe_join(counts) + end + end + + def board_count_tag(count, color: nil) + formatted_count = count > 99 ? "99+" : count.to_s + style = "--card-color: #{color};" if color + tag.span(formatted_count, class: "board-menu-count", style: style) + end end diff --git a/test/helpers/my/menu_helper_test.rb b/test/helpers/my/menu_helper_test.rb new file mode 100644 index 0000000000..890d419ca4 --- /dev/null +++ b/test/helpers/my/menu_helper_test.rb @@ -0,0 +1,52 @@ +require "test_helper" + +class My::MenuHelperTest < ActionView::TestCase + setup do + @board = boards(:writebook) + end + + test "board_column_counts_tag shows awaiting triage count first" do + html = send(:board_column_counts_tag, @board) + + # First count should be awaiting triage (no color style) + first_count = html.match(/(\d+)<\/span>/) + assert first_count, "Should have a count without color for awaiting triage" + assert_equal @board.cards.awaiting_triage.count.to_s, first_count[1] + end + + test "board_column_counts_tag shows column counts with colors" do + html = send(:board_column_counts_tag, @board) + + @board.columns.sorted.each do |column| + assert_match "--card-color: #{column.color};", html + end + end + + test "board_column_counts_tag returns empty span when no columns and no cards" do + board = Board.new + board.define_singleton_method(:columns) { Column.none } + board.define_singleton_method(:cards) { Card.none } + + html = send(:board_column_counts_tag, board) + + assert_equal "", html + end + + test "board_count_tag formats count over 99 as 99+" do + html = send(:board_count_tag, 150) + + assert_match "99+", html + end + + test "board_count_tag includes color style when provided" do + html = send(:board_count_tag, 5, color: "var(--color-card-3)") + + assert_match "--card-color: var(--color-card-3);", html + end + + test "board_count_tag omits style when no color provided" do + html = send(:board_count_tag, 5) + + assert_no_match(/style=/, html) + end +end From 4eac338df14b35f9dd3112ad9261a7badc1ec34a Mon Sep 17 00:00:00 2001 From: Yuri Sidorov <403994+newstler@users.noreply.github.com> Date: Thu, 15 Jan 2026 17:58:22 +0100 Subject: [PATCH 2/3] Hide zero-count columns in board menu item counts Only display column badges for columns that have active cards. Previously all columns were shown including those with zero cards. Co-Authored-By: Claude Opus 4.5 --- app/helpers/my/menu_helper.rb | 7 +++++-- test/helpers/my/menu_helper_test.rb | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/app/helpers/my/menu_helper.rb b/app/helpers/my/menu_helper.rb index 699d1cec72..9e623a8b0f 100644 --- a/app/helpers/my/menu_helper.rb +++ b/app/helpers/my/menu_helper.rb @@ -66,8 +66,11 @@ def board_column_counts_tag(board) tag.span(class: "board-menu-counts") do counts = [] - counts << board_count_tag(maybe_count) if maybe_count > 0 || columns.any? - counts += columns.map { |column| board_count_tag(column.cards.active.size, color: column.color) } + counts << board_count_tag(maybe_count) if maybe_count > 0 + counts += columns.filter_map do |column| + count = column.cards.active.size + board_count_tag(count, color: column.color) if count > 0 + end safe_join(counts) end end diff --git a/test/helpers/my/menu_helper_test.rb b/test/helpers/my/menu_helper_test.rb index 890d419ca4..6f54728ec4 100644 --- a/test/helpers/my/menu_helper_test.rb +++ b/test/helpers/my/menu_helper_test.rb @@ -17,9 +17,20 @@ class My::MenuHelperTest < ActionView::TestCase test "board_column_counts_tag shows column counts with colors" do html = send(:board_column_counts_tag, @board) - @board.columns.sorted.each do |column| - assert_match "--card-color: #{column.color};", html - end + # Verify that at least one column with cards shows its color + assert_match /--card-color:/, html + end + + test "board_column_counts_tag excludes columns with zero cards" do + html = send(:board_column_counts_tag, @board) + + # Count the number of colored badges in the output + colored_badges = html.scan(/--card-color:/).count + + # Count columns that have active cards + columns_with_cards = @board.columns.sorted.count { |c| c.cards.active.size > 0 } + + assert_equal columns_with_cards, colored_badges end test "board_column_counts_tag returns empty span when no columns and no cards" do From 5647ed9b4ce57a44b0a5920be9f8dc5d49fcde27 Mon Sep 17 00:00:00 2001 From: Yuri Sidorov <403994+newstler@users.noreply.github.com> Date: Thu, 15 Jan 2026 18:25:40 +0100 Subject: [PATCH 3/3] Add native tooltips to board menu column counts Shows column name on hover using the title attribute for a lightweight, accessible tooltip experience. Co-Authored-By: Claude Sonnet 4.5 --- app/helpers/my/menu_helper.rb | 8 ++++---- test/helpers/my/menu_helper_test.rb | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/helpers/my/menu_helper.rb b/app/helpers/my/menu_helper.rb index 9e623a8b0f..25544355ca 100644 --- a/app/helpers/my/menu_helper.rb +++ b/app/helpers/my/menu_helper.rb @@ -66,18 +66,18 @@ def board_column_counts_tag(board) tag.span(class: "board-menu-counts") do counts = [] - counts << board_count_tag(maybe_count) if maybe_count > 0 + counts << board_count_tag(maybe_count, title: "Maybe?") if maybe_count > 0 counts += columns.filter_map do |column| count = column.cards.active.size - board_count_tag(count, color: column.color) if count > 0 + board_count_tag(count, color: column.color, title: column.name) if count > 0 end safe_join(counts) end end - def board_count_tag(count, color: nil) + def board_count_tag(count, color: nil, title: nil) formatted_count = count > 99 ? "99+" : count.to_s style = "--card-color: #{color};" if color - tag.span(formatted_count, class: "board-menu-count", style: style) + tag.span(formatted_count, class: "board-menu-count", style: style, title: title) end end diff --git a/test/helpers/my/menu_helper_test.rb b/test/helpers/my/menu_helper_test.rb index 6f54728ec4..5694884eff 100644 --- a/test/helpers/my/menu_helper_test.rb +++ b/test/helpers/my/menu_helper_test.rb @@ -8,8 +8,8 @@ class My::MenuHelperTest < ActionView::TestCase test "board_column_counts_tag shows awaiting triage count first" do html = send(:board_column_counts_tag, @board) - # First count should be awaiting triage (no color style) - first_count = html.match(/(\d+)<\/span>/) + # First count should be awaiting triage (no color style, has "Maybe?" title) + first_count = html.match(/(\d+)<\/span>/) assert first_count, "Should have a count without color for awaiting triage" assert_equal @board.cards.awaiting_triage.count.to_s, first_count[1] end