Merge branch 'main' into filter-revamp

* main:
  `event.assignees` collection doesn't include `event.creator` when self-assigning
  Consistent verb forms
  Autolinking shouldn't include final punctuation.
  dep: update kamal to edge
  No need to delegate auto_closing? anymore
  Extract common method to query when entropy is cleaned
  Invalidate card caches when editing workflows

# Conflicts:
#	app/javascript/controllers/navigable_list_controller.js
This commit is contained in:
Jorge Manrubia
2025-06-03 06:12:34 +02:00
12 changed files with 92 additions and 33 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ gem "turbo-rails"
# Deployment and drivers
gem "active_record-tenanted", bc: "active_record-tenanted"
gem "bootsnap", require: false
gem "kamal", require: false
gem "kamal", bc: "kamal", ref: "344e2d79", require: false
gem "puma", ">= 5.0"
gem "solid_cable", ">= 3.0"
gem "solid_cache", "~> 1.0"
+18 -12
View File
@@ -15,6 +15,23 @@ GIT
railties (>= 8.1.alpha)
zeitwerk
GIT
remote: https://github.com/basecamp/kamal
revision: 344e2d7995e0134aa52f195a984d8d5e24e31d94
ref: 344e2d79
specs:
kamal (2.6.1)
activesupport (>= 7.0)
base64 (~> 0.2)
bcrypt_pbkdf (~> 1.0)
concurrent-ruby (~> 1.2)
dotenv (~> 3.1)
ed25519 (~> 1.4)
net-ssh (~> 7.3)
sshkit (>= 1.23.0, < 2.0)
thor (~> 1.3)
zeitwerk (>= 2.6.18, < 3.0)
GIT
remote: https://github.com/basecamp/rails-structured-logging
revision: 76960cb5c15fc2b6b5f7542e05d7dcc031cef9e6
@@ -246,17 +263,6 @@ GEM
activesupport (>= 5.0.0)
jmespath (1.6.2)
json (2.12.2)
kamal (2.6.1)
activesupport (>= 7.0)
base64 (~> 0.2)
bcrypt_pbkdf (~> 1.0)
concurrent-ruby (~> 1.2)
dotenv (~> 3.1)
ed25519 (~> 1.4)
net-ssh (~> 7.3)
sshkit (>= 1.23.0, < 2.0)
thor (~> 1.3)
zeitwerk (>= 2.6.18, < 3.0)
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
logger (1.7.0)
@@ -511,7 +517,7 @@ DEPENDENCIES
image_processing (~> 1.14)
importmap-rails
jbuilder
kamal
kamal!
mission_control-jobs
platform_agent
propshaft
+10 -1
View File
@@ -34,7 +34,16 @@ module HtmlHelper
def auto_link_urls(linked_content)
linked_content.gsub!(URL_REGEXP) do |match|
%(<a href="#{match}" rel="noreferrer">#{match}</a>)
url, trailing_punct = extract_url_and_punctuation(match)
%(<a href="#{url}" rel="noreferrer">#{url}</a>#{trailing_punct})
end
end
def extract_url_and_punctuation(url_match)
if url_match.end_with?(".", "?", ",", ":")
[ url_match[..-2], url_match[-1] ]
else
[ url_match, "" ]
end
end
+1 -1
View File
@@ -2,7 +2,7 @@ module NotificationsHelper
def event_notification_title(event)
case event_notification_action(event)
when "comment_created" then "RE: #{card_notification_title(event.eventable.card)}"
when "card_assigned" then "Assigned to #{event.assignees.pluck(:name).to_sentence}: #{card_notification_title(event.eventable)}"
when "card_assigned" then "Assigned to #{event.assignees.none? ? "self" : event.assignees.pluck(:name).to_sentence}: #{card_notification_title(event.eventable)}"
else card_notification_title(event.eventable)
end
end
+16 -4
View File
@@ -10,7 +10,7 @@ module Card::Entropy
scope :stagnated, -> { doing.where(last_active_at: ..AUTO_RECONSIDER_PERIOD.ago) }
scope :due_to_be_closed, -> { considering.in_auto_closing_collection.where("last_active_at <= DATETIME('now', '-' || auto_close_period || ' seconds')") }
delegate :auto_closing?, :auto_close_period, to: :collection
delegate :auto_close_period, to: :collection
end
class_methods do
@@ -26,11 +26,19 @@ module Card::Entropy
end
def subject_to_entropy?
doing? || (auto_closing? && considering?)
auto_reconsidering? || auto_closing?
end
def auto_reconsidering?
doing? && last_active_at
end
def auto_closing?
considering? && collection.auto_closing? && last_active_at
end
def auto_close_at
last_active_at + auto_close_period if auto_closing? && last_active_at
last_active_at + auto_close_period if auto_closing?
end
def days_until_close
@@ -38,10 +46,14 @@ module Card::Entropy
end
def auto_reconsider_at
last_active_at + AUTO_RECONSIDER_PERIOD if last_active_at
last_active_at + AUTO_RECONSIDER_PERIOD if auto_reconsidering?
end
def days_until_reconsider
(auto_reconsider_at.to_date - Date.current).to_i if auto_reconsider_at
end
def entropy_cleaned_at
auto_close_at || auto_reconsider_at
end
end
+1 -1
View File
@@ -1,5 +1,5 @@
class Workflow::Stage < ApplicationRecord
belongs_to :workflow
belongs_to :workflow, touch: true
before_validation :assign_random_color, on: :create
+1 -1
View File
@@ -1,4 +1,4 @@
<% cache card do %>
<% cache [ card, card.collection.workflow ] do %>
<%= card_article_tag card, class: "card" do %>
<div class="flex gap">
<div class="flex flex-column flex-item-grow">
@@ -1,7 +1,7 @@
<div hidden class="bubble bubble--<%= card.engagement_status %>"
data-controller="bubble" data-action="turbo:morph-element->bubble#update"
data-bubble-reminder-before-value="<%= Card::ENTROPY_REMINDER_BEFORE.in_days.to_i %>"
data-bubble-closes-at-value="<%= card.auto_close_at.iso8601 %>"
data-bubble-closes-at-value="<%= card.entropy_cleaned_at.iso8601 %>"
data-bubble-entropy-action-value="<%= card_entropy_action(card) %>">
<svg viewBox="0 0 200 100">
<path id="top-half" fill="transparent" d="M 20,100 A 80,80 0 0,1 180,100" />
@@ -8,7 +8,7 @@
<% end %>
<% if page.used? %>
<%= render partial: "cards/display/preview", collection: page.records, as: :card, cached: true %>
<%= render partial: "cards/display/preview", collection: page.records, as: :card, cached: ->(record) { [ record, record.collection.workflow ] } %>
<% unless page.last? %>
<%= cards_next_page_link "doing-cards", page: page, filter: filter %>
+26 -2
View File
@@ -1,10 +1,34 @@
require "test_helper"
class HtmlHelperTest < ActionView::TestCase
test "converts URLs into anchor tags" do
test "convert URLs into anchor tags" do
assert_equal_html \
%(<p>Check this: <a href="https://example.com" rel="noreferrer">https://example.com</a></p>),
format_html("<p>Check this: https://example.com</p>")
assert_equal_html \
%(<p>Check this: <a href="https://example.com/" rel="noreferrer">https://example.com/</a></p>),
format_html("<p>Check this: https://example.com/</p>")
end
test "don't' include punctuation in URL autolinking" do
assert_equal_html \
%(<p>Check this: <a href="https://example.com" rel="noreferrer">https://example.com</a>!</p>),
format_html("<p>Check this: https://example.com!</p>")
assert_equal_html \
%(<p>Check this: <a href="https://example.com" rel="noreferrer">https://example.com</a>.</p>),
format_html("<p>Check this: https://example.com.</p>")
assert_equal_html \
%(<p>Check this: <a href="https://example.com" rel="noreferrer">https://example.com</a>?</p>),
format_html("<p>Check this: https://example.com?</p>")
assert_equal_html \
%(<p>Check this: <a href="https://example.com" rel="noreferrer">https://example.com</a>,</p>),
format_html("<p>Check this: https://example.com,</p>")
assert_equal_html \
%(<p>Check this: <a href="https://example.com" rel="noreferrer">https://example.com</a>:</p>),
format_html("<p>Check this: https://example.com:</p>")
assert_equal_html \
%(<p>Check this: <a href="https://example.com" rel="noreferrer">https://example.com</a>;</p>),
format_html("<p>Check this: https://example.com;</p>")
end
test "respect existing links" do
@@ -13,7 +37,7 @@ class HtmlHelperTest < ActionView::TestCase
format_html("<p>Check this: <a href=\"https://example.com\">https://example.com</a></p>")
end
test "converts email addresses into mailto links" do
test "convert email addresses into mailto links" do
assert_equal_html \
%(<p>Contact us at <a href="mailto:support@example.com">support@example.com</a></p>),
format_html("<p>Contact us at support@example.com</p>")
-8
View File
@@ -18,12 +18,4 @@ class Card::CloseableTest < ActiveSupport::TestCase
assert cards(:logo).closed?
assert_equal users(:kevin), cards(:logo).closed_by
end
test "autoclose_at infers the period from the collection" do
freeze_time
collections(:writebook).update! auto_close_period: 123.days
cards(:logo).update! last_active_at: 2.day.ago
assert_equal (123-2).days.from_now, cards(:logo).auto_close_at
end
end
+16
View File
@@ -5,6 +5,14 @@ class Card::EntropyTest < ActiveSupport::TestCase
Current.session = sessions(:david)
end
test "auto_close_at infers the period from the collection" do
freeze_time
collections(:writebook).update! auto_close_period: 123.days
cards(:layout).update! last_active_at: 2.day.ago
assert_equal (123-2).days.from_now, cards(:layout).auto_close_at
end
test "auto close all due" do
cards(:logo, :shipping).each(&:reconsider)
@@ -47,4 +55,12 @@ class Card::EntropyTest < ActiveSupport::TestCase
assert cards(:logo).reload.considering?
assert_equal Time.current, cards(:logo).last_active_at
end
test "entropy_cleaned_at returns when the entropy will be cleaned" do
assert_equal cards(:layout).auto_close_at, cards(:layout).entropy_cleaned_at
assert_not_nil cards(:layout).entropy_cleaned_at
assert_equal cards(:logo).auto_reconsider_at, cards(:logo).entropy_cleaned_at
assert_not_nil cards(:logo).entropy_cleaned_at
end
end