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>
The tiptap-markdown extension was registered with default config, where
`transformPastedText` defaults to false. As a result, pasting markdown
text into card descriptions resulted in literal characters (e.g. '# heading'
shown as a paragraph of text) rather than rendered formatting.
Typing markdown shortcuts in the editor already worked because that goes
through a different path. Programmatic writes via the API also work
because they bypass the editor entirely. Only paste was affected.
Enabling `transformPastedText: true` makes pasted markdown behave as
users intuitively expect, matching the typed-markdown UX.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>