443 Commits

Author SHA1 Message Date
994bf5c7e0 fix: correct webhook translation
Some checks failed
Translate / translate (push) Has been cancelled
2026-08-23 15:25:02 +08:00
61123f708d fix: complete Chinese frontend localization 2026-08-23 15:05:45 +08:00
5a8a478386 feat: add Chinese translations 2026-08-23 11:58:02 +08:00
hjball
02b367fcaa chore: update translations 2026-08-12 20:12:18 +00:00
Henry
f9aaebc4b5 fix: prevent maximum update depth exceeded error (#549) 2026-08-12 21:11:05 +01:00
hjball
56af094c50 chore: update translations 2026-08-08 12:38:59 +00:00
Henry
e9ebd06eaa feat(cloud): replace novu for all notification triggers 2026-08-08 13:37:51 +01:00
Henry
b4e9dd3811 feat(cloud): sync subscriber preferences on unsubscribe 2026-08-03 11:53:29 +01:00
Henry
d6aa82e070 feat(cloud): create subscribers 2026-07-31 16:25:25 +01:00
hjball
5c72968d44 chore: update translations 2026-07-29 11:50:09 +00:00
Henry
5b586f4871 fix(cloud): default to active workspace on upgrade path 2026-07-29 12:49:00 +01:00
hjball
03a043784a chore: update translations 2026-07-27 20:16:05 +00:00
Anatoly Rubinshteyn
395dbfae04 fix(editor): guard tippy instance in suggestion handlers (#543)
The popup variable stays undefined when onStart bails out early because
props.clientRect is missing, so popup[0] throws instead of no-oping.
Use optional chaining on the array itself.
2026-07-27 21:14:51 +01:00
hjball
9ec4bedd9a chore: compile translations 2026-07-08 09:55:44 +00:00
hjball
ca694595c7 chore: update translations 2026-07-08 09:55:40 +00:00
Henry
0500d5171d feat: allow submitting comments via keyboard shortcut (#533) 2026-07-08 10:54:16 +01:00
hjball
a15e193f66 chore: update translations 2026-06-30 11:00:57 +00:00
Henry
019ecbc364 fix: correct template creation condition in BoardDropdown (#529) 2026-06-30 11:59:43 +01:00
hjball
82b2b4a8e1 chore: compile translations 2026-06-30 10:21:13 +00:00
hjball
c1adb2d4dd chore: update translations 2026-06-30 10:21:09 +00:00
Nick Meinhold
25ed4e39b3 feat: move boards between workspaces (#458)
* feat: add ability to move boards between workspaces

Implements the "Move to workspace" feature (#344) allowing users to
relocate a board and all its contents (lists, cards, labels, checklists,
comments, activity) to a different workspace.

Key design decisions:
- Card member assignments are cleared on move (they reference
  workspace-scoped members that may not exist in the target workspace)
- Comments and activity history are preserved (they reference global
  user IDs, not workspace members)
- Slug conflicts in the target workspace are auto-resolved by
  appending a UID suffix
- Permission model: requires board:edit in source workspace and
  board:create in target workspace
- Templates and archived boards cannot be moved

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

* refactor: consolidate board queries in move mutation

Address review feedback:
- Consolidate 3 separate board queries into a single findFirst()
  that fetches all needed fields (id, name, slug, type, isArchived,
  workspaceId, createdBy)
- Fix slug fallback to use board.name instead of publicId for
  human-readable URLs

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

* fix: filter guest workspaces from move board destination list

Guests typically lack board:create permission in the target workspace,
so showing them as destinations leads to a confusing server rejection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: extract getBoardForMove repo function

Moves the inline board query from the move mutation into the repo
layer, consistent with how every other board mutation fetches data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add unit tests for board.move mutation

10 test cases covering auth, validation, permissions, slug conflict
resolution, and the happy path. Follows webhook.test.ts patterns.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: mark locale files as linguist-generated

GitHub will now auto-collapse compiled translation files (messages.json,
messages.ts, messages.po) in PR diffs and exclude them from language
stats. This makes PRs that touch i18n strings much easier to review.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: remove locale file changes from PR

Reverts locale file diffs and .gitattributes to match main, per review
feedback. The locale changes were unrelated translation updates that
inflated the PR diff.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: remove locale file changes from PR

Per @hjball's review: locale compilation/translations are handled
automatically on merge to main, so this PR shouldn't carry them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: align locale files with upstream/main

Previous removal commit used local main, which had drifted from
upstream. Re-syncing to upstream/main so the PR carries no locale diff.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(board-move): tighten deletedAt handling per review

Three changes addressing @hjball's review comments, all about the
schema treating deletedAt as optional metadata while the move-board
flow needs it as a load-bearing invariant.

1. getBoardForMove now filters isNull(deletedAt). Moving a tombstoned
   board has no defensible semantics. Replaces the implicit
   "the board exists in the table" check with an explicit
   "the board is not soft-deleted" check.

2. Move-flow's clearing of cardToWorkspaceMembers now spans every
   card under every list ever associated with this board, including
   soft-deleted ones. If we leave member assignments on a deleted
   card and that card is later restored, the assignments would
   resurrect rogue references to workspace members from the OLD
   workspace. Removed the isNull filters on both lists and cards in
   that loop.

3. Move-flow now refuses to move into a soft-deleted target
   workspace. workspaceRepo.getByPublicId did not previously project
   deletedAt; extended its column selection so the call-site guard
   in board.move can check it. (A wider fix to make the repo treat
   deleted-as-not-found across all 14+ callers is left for a
   separate PR — narrow scope here.)

Plus one regression test: throws NOT_FOUND when target workspace is
soft-deleted. All 11 board-move tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-30 11:19:39 +01:00
Henry
6e1d821b35 fix: list dnd when board exceeds viewport width (#526) 2026-06-25 17:00:07 +01:00
Henry
120504ab58 feat: tweak mobile list snapping 2026-06-25 16:38:13 +01:00
Max K.
ebb19584a2 feat: add mobile list snap scrolling (#510) 2026-06-25 16:05:27 +01:00
hjball
410f4c481e chore: update translations 2026-06-25 15:01:34 +00:00
JayDataEngineer
9d7a82d381 fix: sync Editor editable state with readOnly prop (#523)
The rich-text Editor (used for card descriptions) creates its Tiptap
instance once via useEditor with an empty dependency array. This means
the initial value of `editable: !readOnly` is captured at mount time
and never updated, and the onChange/onBlur callbacks are frozen as the
first-render closures.

In CardPage, the description Editor mounts as soon as the card query
resolves but before the permissions query resolves, so `readOnly` is
`true` and onChange/onBlur are `undefined` at that moment. When
permissions resolve a moment later and `canEdit` flips to `true`,
the Editor never becomes editable — leaving the description stuck
read-only even for workspace admins.

Fix mirrors the existing pattern in PlainTextEditor.tsx:
- Use refs for onChange/onBlur so the editor reads the latest values
- Add a useEffect that calls editor.setEditable(!readOnly) when the
  readOnly prop changes

Co-authored-by: Jay <CodeEngineering@pm.me>
2026-06-25 16:00:13 +01:00
hjball
f369ebeaa8 chore: compile translations 2026-06-11 15:45:43 +00:00
hajorappe
0fbe198fa2 fix: improve German translations in /de/messages.json (#514)
Improved German translations for better readability.
2026-06-11 16:44:09 +01:00
Henry
1347cc562c fix: encode attachment filename header to support non-ASCII characters (#519) 2026-06-09 12:16:51 +01:00
Henry
89654c20b0 fix(partner): scope auto-claim to owned workspaces and guard against active subs 2026-05-30 12:51:21 +01:00
hjball
4442e67832 chore: update translations 2026-05-29 22:53:24 +00:00
Henry
03e1e19464 fix: ensure upgrade/downgrade paths for migrate requests 2026-05-29 23:48:01 +01:00
hjball
a3353acf44 chore: compile translations 2026-05-29 22:29:11 +00:00
hjball
a4a807ed1d chore: update translations 2026-05-29 22:29:06 +00:00
Henry
6b8ada8d90 feat: duplicate card via dropdown 2026-05-29 23:27:21 +01:00
hjball
22899cd14c chore: update translations 2026-05-29 21:59:33 +00:00
Henry
833c69a73e cloud: enable workspace slots for partners 2026-05-29 22:58:09 +01:00
hjball
d9cf363302 chore: update translations 2026-05-25 21:01:17 +00:00
Henry
9212b1ca2e fix: adjust layout of card prefix on public modal 2026-05-25 21:59:57 +01:00
hjball
ede2475796 chore: update translations 2026-05-25 20:49:46 +00:00
Henry
e32ad1cd32 fix(cloud): hide empty notice box for pro subscriptions 2026-05-25 21:48:27 +01:00
hjball
bac22021ad chore: update translations 2026-05-21 21:53:34 +00:00
Henry
8d8cfa3bae feat(cloud): pause members when subscription is cancelled 2026-05-21 22:52:17 +01:00
hjball
971348a397 chore: compile translations 2026-05-21 20:39:43 +00:00
hjball
d3920cd246 chore: update translations 2026-05-21 20:39:39 +00:00
Henry
5af375825b fix: reliably select workspace on login (#507) 2026-05-21 21:38:09 +01:00
Henry
861416a18e feat(cloud): set seat limit checks for partner member invitations (#506) 2026-05-21 21:36:57 +01:00
Henry
a7e78ad580 fix: respect redirect param on login and signup pages (#504) 2026-05-21 21:36:02 +01:00
Henry
f288047a6a fix: run web container as non-root user (UID 1000) (#501) 2026-05-21 21:35:47 +01:00
hjball
edb88525c0 chore: compile translations 2026-05-18 22:21:55 +00:00