Add command to tag cards

This commit is contained in:
Jorge Manrubia
2025-05-07 16:48:33 +02:00
parent 31d0271952
commit b7f086d361
6 changed files with 111 additions and 17 deletions
+4 -9
View File
@@ -1,18 +1,13 @@
class Command::FilterByTag < Command
store_accessor :data, :tag_id, :params
include Command::Tags
validates_presence_of :tag_id
store_accessor :data, :params
def title
"Filter by tag ##{tag&.title || tag_id} "
"Filter by tag ##{tag_title}"
end
def execute
redirect_to cards_path(**params.merge(tag_ids: [ tag_id ]))
redirect_to cards_path(**params.merge(tag_ids: [ tag.id ]))
end
private
def tag
Tag.find_by_id(tag_id)
end
end
+8 -7
View File
@@ -19,14 +19,16 @@ class Command::Parser
command_name, *command_arguments = string.strip.split(" ")
case command_name
when /^#/
Command::FilterByTag.new(tag_title: tag_title_from(string), params: filter.as_params)
when /^@/
Command::GoToUser.new(user_id: assignee_from(command_name)&.id)
when "/assign", "/assignto"
Command::Assign.new(assignee_ids: assignees_from(command_arguments).collect(&:id), card_ids: cards.ids)
when "/close"
Command::Close.new(card_ids: cards.ids, reason: command_arguments.join(" "))
when /^#/
Command::FilterByTag.new(tag_id: tag_from(string).id, params: filter.as_params)
when /^@/
Command::GoToUser.new(user_id: assignee_from(command_name)&.id)
when "/tag"
Command::Tag.new(tag_title: tag_title_from(command_arguments.join(" ")), card_ids: cards.ids)
else
parse_free_string(string)
end
@@ -46,9 +48,8 @@ class Command::Parser
User.all.find { |user| user.mentionable_handles.include?(string_without_at) }
end
def tag_from(string)
title = string.gsub(/^#/, "")
Tag.find_or_create_by!(title: title)
def tag_title_from(string)
string.gsub(/^#/, "")
end
def parse_free_string(string)
+37
View File
@@ -0,0 +1,37 @@
class Command::Tag < Command
include Command::Cards, Command::Tags
store_accessor :data, :tagged_card_ids
def title
"Tag #{cards_description} with ##{tag_title}"
end
def execute
tagged_card_ids = []
transaction do
cards.find_each do |card|
unless card.tagged_with?(tag)
tagged_card_ids << card.id
card.toggle_tag_with(tag_title)
end
end
update! tagged_card_ids: tagged_card_ids
end
end
def undo
transaction do
tagged_cards.find_each do |card|
card.toggle_tag_with(tag_title) if card.tagged_with?(tag)
end
end
end
private
def tagged_cards
user.accessible_cards.where(id: tagged_card_ids)
end
end
+14
View File
@@ -0,0 +1,14 @@
module Command::Tags
extend ActiveSupport::Concern
included do
store_accessor :data, :tag_title
validates_presence_of :tag_title
end
private
def tag
Tag.find_or_create_by!(title: tag_title)
end
end
+1 -1
View File
@@ -7,7 +7,7 @@ class Command::FilterByCardTest < ActionDispatch::IntegrationTest
@tag = tags(:web)
end
test "redirects to the cards index filtering by cards" do
test "redirect to the cards index filtering by cards" do
result = execute_command "##{@tag.title}"
assert_equal cards_path(indexed_by: "newest", tag_ids: [ @tag.id ]), result.url
+47
View File
@@ -0,0 +1,47 @@
require "test_helper"
class Command::TagTest < ActionDispatch::IntegrationTest
include CommandTestHelper
setup do
Current.session = sessions(:david)
@card = cards(:text)
@tag = tags(:web)
end
test "tag card on perma with existing tag" do
assert_changes -> { @card.tagged_with?(@tag) }, from: false, to: true do
execute_command "/tag #{@tag.title}", context_url: collection_card_url(@card.collection, @card)
end
end
test "tag card on perma with new card" do
assert_difference -> { @card.tags.count }, +1 do
execute_command "/tag some-new-tag", context_url: collection_card_url(@card.collection, @card)
end
assert_equal "some-new-tag", @card.tags.last.title
end
test "tag several cards on cards' index page" do
cards = cards(:logo, :text, :layout)
cards.each { it.taggings.destroy_all }
execute_command "/tag #{@tag.title}", context_url: collection_cards_url(@card.collection)
cards.each { assert it.reload.tagged_with?(@tag) }
end
test "undo tagged cards" do
cards = cards(:logo, :text, :layout)
cards.each { it.taggings.destroy_all }
command = parse_command "/tag #{@tag.title}", context_url: collection_cards_url(@card.collection)
command.execute
cards.each { assert it.reload.tagged_with?(@tag) }
command.undo
cards.each { assert_not it.reload.tagged_with?(@tag) }
end
end