Commit Graph

6264 Commits

Author SHA1 Message Date
Andy Smith d55aa25f9a Polish the session menu page 2026-02-02 12:36:48 +01:00
Andy Smith 60787a00ef Touch up export modals 2026-02-02 12:36:48 +01:00
Stanko K.R. 122a228ed4 Use convention to create boilerplate record sets 2026-02-02 12:36:48 +01:00
Stanko K.R. f457273937 Convert double negatives into a positive question 2026-02-02 12:36:48 +01:00
Stanko K.R. 00c5f7feab Break import and export objects into record sets 2026-02-02 12:36:48 +01:00
Andy Smith 4f2cb01143 Polish up notification settings to match 2026-02-02 12:36:48 +01:00
Andy Smith e892b74cf2 Simplify settings layout and correct h2 levels 2026-02-02 12:36:48 +01:00
Stanko K.R. 19ae555c2e Convert Account::SingleUserExport to User::DataExport 2026-02-02 12:36:48 +01:00
Stanko K.R. 161efb0b8e Implement basic imports 2026-02-02 12:36:48 +01:00
Stanko K.R. 8953920652 Implement full account exports 2026-02-02 12:36:48 +01:00
Stanko K.R. 6f17e3867d Split Export model into user and whole-account export 2026-02-02 12:36:31 +01:00
Rosa Gutierrez 63d9f29b1e Return internal account ID after signup completion
This matches what we return from `/my/identity` endpoint for each
account.
2026-01-30 13:41:37 +01:00
Rosa Gutierrez 614527e9c2 Add JSON format support to signup flow for native API clients
The magic link verification endpoint now returns `requires_signup_completion`
to indicate whether the client needs to collect a name and complete signup.
The signup completion endpoint now supports JSON responses with the account ID.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:41:37 +01:00
Mike Dalessio 017e1434f1 Reapply "Fix lightbox blocking clicks on page elements"
This reverts commit c70c4b4107.
2026-01-28 17:53:53 -05:00
Mike Dalessio c70c4b4107 Revert "Fix lightbox blocking clicks on page elements"
This reverts commit 17b7af9b92.
2026-01-28 17:53:21 -05:00
Mike Dalessio 17b7af9b92 Fix lightbox blocking clicks on page elements
The CSS change in 39575a0 added `display: flex` to the lightbox dialog
unconditionally, which overrode the browser's default `display: none`
for closed dialogs. This made the invisible lightbox overlay intercept
all clicks on the page.

Move flexbox properties to the `&[open]` selector so they only apply
when the dialog is actually open.

Also fix typo: `innerHtml` → `innerHTML` (capital H).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 17:51:32 -05:00
Adrien Maston 70fba5e48b Merge pull request #2309 from basecamp/mobile/prepare-webviews-2
Mobile/prepare webviews 2
2026-01-28 16:03:54 +01:00
Rosa Gutierrez c059e0b216 Add JSON format support to session destroy for native API clients
This is so that native API clients can get the session record deleted
server-side. They still need to take care of clearing any cookies
they've set in web views.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:59:30 +01:00
Adrien Maston fefb28848b Merge branch 'main' into mobile/prepare-webviews-2
* main: (26 commits)
  Add a new Pins section to docs/API.md covering pin/unpin and the pinned cards list response.
  Align board name start so it doesn't get too big
  Clean up card/events header layout
  Sync email to Stripe when user changes email address (#2432)
  Fix IDOR in webhook activation endpoint (#2431)
  Add card reactions to API docs and reactions_url to card JSON (#2427)
  Remove unnecessary claude plan
  Allow boosts on cards (#2411)
  Revert "Fix notification click URL by using correct data property"
  Add migration to remove draft cards from search index
  Guard search indexing with searchable? check
  Forbid comments on draft cards
  prefactor: update search to use published cards
  Fix notification click URL by using correct data property
  Wait for service worker to be active before subscribing
  Fix stuck state when permission granted but no subscription
  Extract Card::Commentable
  Include arm64 build in Docker workflow
  Remove unnecessary `await` in push handler
  Correctly initialise WebPush connection (#2417)
  ...
2026-01-27 17:17:21 +01:00
Denis Švara a75d56d243 Merge branch 'main' into pins-api
* main: (127 commits)
  Align board name start so it doesn't get too big
  Clean up card/events header layout
  Sync email to Stripe when user changes email address (#2432)
  Fix IDOR in webhook activation endpoint (#2431)
  Add card reactions to API docs and reactions_url to card JSON (#2427)
  Remove unnecessary claude plan
  Allow boosts on cards (#2411)
  Revert "Fix notification click URL by using correct data property"
  Add migration to remove draft cards from search index
  Guard search indexing with searchable? check
  Forbid comments on draft cards
  prefactor: update search to use published cards
  Fix notification click URL by using correct data property
  Wait for service worker to be active before subscribing
  Fix stuck state when permission granted but no subscription
  Extract Card::Commentable
  Include arm64 build in Docker workflow
  Remove unnecessary `await` in push handler
  Correctly initialise WebPush connection (#2417)
  Update models, views, and fixtures for polymorphic reactions
  ...
2026-01-27 15:37:47 +01:00
Adrien Maston 70fc2a807c Clean iOS text size CSS 2026-01-27 11:38:04 +01:00
Adrien Maston e5bef41c54 Refactor orientation helper to express intent more clearly 2026-01-27 11:21:15 +01:00
Andy Smith 8cfcc6fca5 Align board name start so it doesn't get too big 2026-01-26 12:57:26 -06:00
Andy Smith 5beb413c41 Clean up card/events header layout 2026-01-26 12:53:01 -06:00
Jeremy Daer 4efa4da809 Fix IDOR in webhook activation endpoint (#2431)
The webhook activation controller was using account-scoped lookup
instead of board-scoped lookup, allowing users to reactivate webhooks
on boards they don't have access to.

This was an oversight when board-scoping was added to the main webhooks
controller - the activations controller was missed in that update.

The fix adds the BoardScoped concern to properly restrict webhook
activation to boards the user has explicit access to.
2026-01-24 17:06:12 -08:00
Mike Dalessio 16745e89d1 Add card reactions to API docs and reactions_url to card JSON (#2427)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 16:55:50 -05:00
Mike Dalessio cb61b36715 Allow boosts on cards (#2411)
* Add reactions association to Card model

Adds `has_many :reactions` to Card, matching the implementation in Comment.
This allows cards to be reacted to directly with emoji reactions.

The association:
- Orders reactions chronologically
- Uses polymorphic `:reactable` interface
- Deletes reactions when card is destroyed

Includes test coverage for the new association.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add reactions UI to card detail view

- Create Cards::ReactionsController with turbo stream responses
- Add card reactions views (reactions list, new form, menu partial)
- Position reaction button flush-right when no reactions exist
- Show reactions on bottom-left when present, with button inline
- Handle narrow viewports by flowing button below meta section
- Add controller tests for card reactions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add boost count to card preview

Display reaction count alongside comment count on card tiles in board
columns. Introduces a .card__counts wrapper to group both counts with
proper positioning on all viewport sizes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Consolidate reaction views for cards and comments

Extract shared views to app/views/reactions/ using polymorphic routing.
Both card and comment reactions now render the same partials, with a
helper to compute the correct path prefix for nested routes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix emoji picker width in card reactions

Override .card .popup { inline-size: 260px } for the reaction popup
so the emoji grid displays without horizontal scrollbar.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Hide boost count where comment count is hidden

Add .card__boosts alongside .card__comments in:
- Tray view (display: none)
- Cards with background images (opacity toggle on hover)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix reactions button overlap with zoom button in card footer

When a card has a background image, the footer contains both a reactions
button and a zoom button. Previously they would overlap because the
reactions button was absolutely positioned to the bottom-right.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Tighten up previews

* Move card reactions from meta partial to container

Fixes two issues:

1. Reactions were duplicated each time a card was assigned because the
   turbo stream replaced the meta div with the full perma/meta partial,
   which included reactions outside the replaced element.

2. Draft cards incorrectly showed the boost button because the meta
   partial was shared between published and draft containers.

Moving reactions to _container.html.erb (published cards only) fixes
both issues and keeps the meta partial focused on meta content.

Fixes https://app.fizzy.do/5986089/cards/3837
Fixes https://app.fizzy.do/5986089/cards/3835

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* WIP adjust perma page

* Position and style the footer

* Render the stamp in the card body instead of the footer

* Fix undefined local variable in public cards view

Changed `card` to `@card` when rendering the stamp partial.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Preload card reactions to avoid N+1 queries

Include reactions and their reacters in the preloaded scope, matching
what we already do for comments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add model tests for card and comment reaction cleanup

Test that:
- Creating a card reaction touches the card's last_active_at
- Reactions are deleted when their parent comment is destroyed
- Reactions are deleted when their parent card is destroyed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Minor improvements to reactions code

- Use size instead of count in boosts partial to avoid extra SQL query
  on already-loaded collection
- Add else clause to reaction_path_prefix_for to raise ArgumentError
  for unknown reactable types instead of silently returning nil

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Bump specificity of reaction popup in the card perma

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andy Smith <andy@37signals.com>
2026-01-23 13:25:55 -05:00
Rosa Gutierrez ffb2a0b82a Revert "Fix notification click URL by using correct data property"
This reverts commit 4f2308d380.

This was from another branch, shoudln't have been included here.
2026-01-23 19:25:23 +01:00
Mike Dalessio 0d138df952 Guard search indexing with searchable? check
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>
2026-01-23 12:13:08 -05:00
Adrien Maston 39575a0cb6 Fix lightbox layout and focus 2026-01-23 17:41:33 +01:00
Mike Dalessio f6211dbacc Merge pull request #2423 from basecamp/forbid-comments-on-draft-cards
Forbid comments on draft cards
2026-01-23 11:40:46 -05:00
Mike Dalessio 9aa15e9fb2 Forbid comments on draft cards
- 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>
2026-01-23 11:28:26 -05:00
Rosa Gutierrez 4f2308d380 Fix notification click URL by using correct data property
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>
2026-01-23 16:38:45 +01:00
Rosa Gutierrez 26d5701217 Wait for service worker to be active before subscribing
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>
2026-01-23 16:38:45 +01:00
Rosa Gutierrez c650cba179 Fix stuck state when permission granted but no subscription
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.
2026-01-23 16:38:45 +01:00
Mike Dalessio 1aea6850f0 Extract Card::Commentable 2026-01-23 10:30:12 -05:00
Adrien Maston 764eb8987a Tweak orientation helper to prevent popups from going off screen 2026-01-23 14:06:17 +01:00
Kevin McConnell d7c9c4f3b0 Remove unnecessary await in push handler
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 :)
2026-01-23 12:12:22 +00:00
Adrien Maston 65b2db0ec8 Add vertically compact layout for touch keyboard devices 2026-01-23 12:58:42 +01:00
Adrien Maston 97a1c29b0c Use bottom inset
... fixes content being stuck behind the tab bar in apps
2026-01-23 12:15:31 +01:00
Mike Dalessio ffab4cad6f Update models, views, and fixtures for polymorphic reactions
- 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>
2026-01-22 12:29:54 -05:00
Denis Švara 5384116f11 Rename the helper to user_pins and extract a pins_limit method. 2026-01-22 16:44:30 +01:00
Adrien Maston ff9e617f34 Merge branch 'main' into mobile/prepare-webviews-2
* main:
  Return to Board page when clearing filters
  Bump card perma z-index when dialog is open
  Only submit on blur if the input has a value
  Make the CLAUDE.md stub less obtrusive
  Only index up to 32KB of search content
  Use inline spacing variable
  Actually make it affect larger screens too
  Use CSS variable for panel size in delete dialogs
  Add viewport padding to dialogs on mobile
  Prevent page scrolling when modal dialog is open
2026-01-22 11:01:38 +01:00
Andy Smith f9f638a9a7 Return to Board page when clearing filters 2026-01-21 15:05:47 -06:00
Andy Smith 6c8d333bc9 Bump card perma z-index when dialog is open 2026-01-21 14:35:30 -06:00
Andy Smith eccef3b19c Only submit on blur if the input has a value 2026-01-21 14:33:19 -06:00
Andy Smith 9b1dd0bcd9 Merge pull request #2401 from nqst/modal-scroll-block
Prevent page scrolling when modal dialog is open
2026-01-21 14:02:20 -06:00
Andy Smith 72123dc251 Merge pull request #2404 from nqst/dialog-viewport-spacing
Prevent modal dialogs from touching viewport edges
2026-01-21 11:23:01 -06:00
Kevin McConnell 468fe5f16b Only index up to 32KB of search content
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.
2026-01-21 09:52:23 +00:00
Alexander Zaytsev 73cf1dede4 Use inline spacing variable 2026-01-20 20:51:01 +01:00