One-time script to clean up any search records that were indexed
before the searchable? guard was added.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Only index cards and comments if their card is `published?`, using a
new method `searchable?` that is implemented on both Card and Comment.
This prevents draft cards and their comments from being indexed.
When drafts are published, the existing `update_in_search_index`
callback creates the record via `upsert!`, or else ensures unpublished
records are removed from the index.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Card#commentable? method that returns true only for published cards.
- CardsController#create ensures that the card is commentable.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
We're about to make a change to assert that draft cards are not added
to the search index, and so let's make the intention behind these
tests clear first.
The web push payload sends the URL in data.url but the service
worker was looking for data.path, resulting in undefined URLs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The push subscription requires an active service worker. When
registering a new service worker, we now wait for it to become
active using navigator.serviceWorker.ready before attempting
to subscribe to push notifications.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When you had already granted notification permission but hadn't
completed the subscription flow (no service worker or no push
subscription), the UI showed neither the subscribe button nor the
enabled state, leaving you stuck with no way to subscribe, and wrong
instructions to fix it.
Instead, let's just show the button to allow you to subscribe.
We were `await`ing a synchronous method here, which will have the effect
of deferring its execution, and thus also the `event.waitUntil` call. We
want the latter to happen before control returns from the event.
Removing the unnecessary `await` solves this.
This seems unlikely to be a problem in practice, but all the same, it's
not right :)
The `ipaddr` arg here is being interpreted as a positional arg (since
the keyword arg doesn't exist), which results in an invalid connection
object. This was causing push notifications to silently fail.
We should initialise the property on the object instead.
- Reaction: belongs_to :reactable (polymorphic) instead of :comment
- Comment: has_many :reactions with as: :reactable
- Views: use reaction.reactable instead of reaction.comment
- Fixtures: use polymorphic syntax for reactable association
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add migration to replace comment_id with polymorphic reactable
association (reactable_type, reactable_id), enabling reactions on both
comments and cards.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
To prevent overflowing the columns in the search index tables (and also
just to avoid creating massive indexes), let's limit the searchable
content to the first 32KB.
turbo-rails 2.0.21 changed `capture_turbo_stream_broadcasts` to only
return broadcasts produced within the block, matching its documented
behavior (see hotwired/turbo-rails#736).
Since `broadcast_unread` uses `broadcast_prepend_later_to` (async via
job), we need to wrap the call in `perform_enqueued_jobs` so the
broadcast actually happens within the assertion block.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* main:
Create popup initial alignment classes
Fix class typo
Hide the board selector button if card is closed
Align board and tag picker dialogs without using math
Add dialog manager to card perma
Fix "M" hotkey using stale user from fragment cache
Add Enable all/Disable all buttons to webhook event selection
Remove whitespace
Remove hover styles from disabled menu items
# Conflicts:
# app/views/cards/_container.html.erb