-
Notifications
You must be signed in to change notification settings - Fork 615
WYSIWYG editor #1397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
stunningpixels
wants to merge
64
commits into
main
Choose a base branch
from
louis/markdown
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
WYSIWYG editor #1397
+4,531
−4,755
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
frontend/src/components/tasks/TaskFollowUpSection.tsx frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/ui/wysiwyg/image-chip-markdown.ts frontend/src/components/ui/wysiwyg/image-chip-node.tsx
LexicalTypeaheadMenuPlugin frontend/src/components/ui/wysiwyg.tsx frontend/src/components/ui/file-search-textarea.tsx (old)
Instead of saving markdown, we should save JSON eg `editorState.toJSON();`. This will enable us to properly serialize custom Elements in the future. frontend/src/components/ui/wysiwyg.tsx frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx
When searching for tags/files. Sometimes the dialog is cut off the bottom of the screen. frontend/src/components/ui/wysiwyg.tsx
Currently used for follow ups, we should also use for task frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx frontend/src/components/dialogs/tasks/TaskFormDialog.tsx frontend/src/components/ui/wysiwyg.tsx
We used to have a callback for: - CMD+Enter - Shift+CMD+Enter In create task dialog: - CMD+Enter = create and start - Shift+CMD+Enter = create without start In follow up: - CMD+Enter = Follow up - Shift+CMD+Enter = nothing frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx frontend/src/components/ui/wysiwyg.tsx frontend/src/components/dialogs/tasks/TaskFormDialog.tsx Ideally we can use the relevant Lexical plugin and callbacks, cleaning up the old `@/keyboard` hooks which no longer work.
LexicalTypeaheadMenuPlugin frontend/src/components/ui/wysiwyg.tsx frontend/src/components/ui/file-search-textarea.tsx (old)
Currently used for follow ups, we should also use for task frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx frontend/src/components/dialogs/tasks/TaskFormDialog.tsx frontend/src/components/ui/wysiwyg.tsx
{
ID,
message_json: Value,
message_md: String
}
We'll also need some endpoints to CRUD them.
crates/db
crates/server
crates/server/src/routes/scratch.rs It should be possible to listen for updates made to a single scratch
To consolidate the API stuff into frontend/src/lib/api.ts
Primary key should come from: ID and scratch type combination The frontend will provide both. Scratch IDs should not be generated on the backend.
Use of hooks that reside in frontend/src/hooks/follow-up/* should be removed, except for frontend/src/hooks/follow-up/useFollowUpSend.ts From: frontend/src/components/tasks/TaskFollowUpSection.tsx
The current task attempt ID should be used to save the content of the follow up box as scratch. frontend/src/components/tasks/TaskFollowUpSection.tsx
frontend/src/hooks/useScratch.ts crates/server/src/routes/scratch.rs crates/db/src/models/scratch.rs We are currently storing JSON + MD, however we should now store just MD and import/export the markdown into lexical.
Currently we have an old implementation of markdown rendering in frontend/src/components/ui/markdown-renderer.tsx But we have recently introduced the new WYSIWYG editor frontend/src/components/ui/wysiwyg.tsx wysiwyg takes JSON as input, not raw markdown. Ideally we could just use a single component and have a read only mode, removing Markdown Renderer and its dependencies and custom styling.
Create a Lexical plugin for images, with markdown import/export support. Visually, images should be displayed as a small thumbnail with the path truncated. Export/import should support standard markdown image format.
Task attempt endpoint to get info, given the relative URL of an image. We will also need an image that acts as a proxy to the file. Info to return: - Whether file exists - Size of image - Format - File name - Path - URL to get image (the proxy URL) The images are stored in the `.vibe-images` folder, relative to the task attempt container. crates/server/src/routes/task_attempts.rs
Currently when we upload an image, it adds markdown with the full relative path of the image, eg: /var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban-dev/worktrees/2702-testing-images/.vibe-images/b01e6b02-dbd0-464c-aa9f-a42a89f6d67b.png However, we should change this to be the path relative to the worktree eg .vibe-images/b01e6b02-dbd0-464c-aa9f-a42a89f6d67b.png
frontend/src/components/ui/wysiwyg/nodes/image-node.tsx Check if the image comes from `./vibe-images/...`, if so: Use the API endpoints to get and display metadata. Use the image proxy to display the thumbnail image. Do not render non `.vibe-images` images, instead just show the path and show a question icon as a thumbnail.
frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/ui/wysiwyg/nodes/image-node.tsx
frontend/src/components/ui/wysiwyg.tsx
Currently when I type triple backticks it doesn't create a multi-line code block frontend/src/components/ui/wysiwyg.tsx
I am only referring to the image upload for sending a follow up message. Currently we: - upload an image - when a follow up is made, send file IDs - copy the image into container based on those file IDs We should tweak this so that: - upload an image - immediately the image is copied into container - the image file location is added to the markdown of the follow up message (on the frontend) - when user makes follow up, the image is already in the container crates/server/src/routes/images.rs crates/server/src/routes/task_attempts/images.rs
frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/tasks/TaskFollowUpSection.tsx
crates/services/src/services/drafts.rs crates/db/src/models/draft.rs
Remove: - frontend/src/pages/TestScratch.tsx - frontend/src/components/ScratchEditor.tsx
frontend/src/components/ui/wysiwyg.tsx The placeholder can overlap the attachment icon
- New service (crates/services/src/services/...) that holds an in memory store - When the final executor_action finishes, if another follow up prompt (scratch ID) is queued then we can automatically begin executing it (crates/local-deployment/src/container.rs after finalize) - New endpoint required to modify the queue for a task attempt. - Scratch should be wiped after the execution process is created - Scratch can't be edited while queued - Add button to TaskFollowUpSection to make current scratch queued, or cancel queued item
…c21) - Type follow up - Press send - Expect follow up to be reset, but it is not frontend/src/components/tasks/TaskFollowUpSection.tsx
i18next::translator: missingKey en-GB tasks followUp.queue Queue
frontend/src/components/ui/wysiwyg.tsx frontend/src/components/tasks/TaskFollowUpSection.tsx
It takes 0.5-1s for the send button to go from no opacity to full opacity after I start typing frontend/src/components/tasks/TaskFollowUpSection.tsx
frontend/src/components/tasks/TaskFollowUpSection.tsx Dropdown should have settings-2
Say I have two messages to send: - I send first - I queue the second - I now see "message queued" and the follow up editable text contains the second - First finishes, second starts, no tasks are queued - I still see "message queued" box but the follow up editable text gets wiped frontend/src/components/tasks/TaskFollowUpSection.tsx
Attach button should be to the left of of the send button frontend/src/components/ui/wysiwyg.tsx frontend/src/components/tasks/TaskFollowUpSection.tsx
Props, and upstream logic: - make placeholder optional: - remove defaultValue: this seems redundant as value is always controlled, there may also be related cleanups for uncontrolled mode - remove onFocusChange: toggling states is unnecessary here - remove enableCopyButton: this is always enabled when the editor is disabled frontend/src/components/ui/wysiwyg.tsx
If a task is stopped or fails, the next queued task runs, however this is not the desired behaviour. Instead the queued task should be removed from the queue
…428) frontend/src/components/tasks/TaskFollowUpSection.tsx
frontend/src/components/ui/wysiwyg.tsx
I think we could change this so that it accepts a default variant and then returns what variant is currently selected, based on the user's preferences and if they select one from the dropdown
It seems to retry functionality was removed fromfrontend/src/components/NormalizedConversation/UserMessage.tsx
…b8e) frontend/src/components/tasks/TaskFollowUpSection.tsx If you write out a follow up and then hit send, if you then navigate away from the page quickly the scratch will still be present when you visit the page, when the expected behaviour is that the previous text would be cleared
Currently works for multi-line, can we get it working for multi-line frontend/src/components/ui/wysiwyg.tsx
Replace with frontend/src/components/ui/wysiwyg.tsx not frontend/src/components/ui/file-search-textarea.tsx
frontend/src/components/dialogs/tasks/TaskFormDialog.tsx - Placeholder for WYSIWYG too small, just use default - Make title same size as WYSIWYG H1
frontend/src/hooks/useVariant.ts frontend/src/components/NormalizedConversation/RetryEditorInline.tsx frontend/src/contexts/RetryUiContext.tsx Removing all existing logic related to variant picking
Refactor the WYSIWYG implementation in thefrontend/src/components/NormalizedConversation/PendingApprovalEntry.tsx so the styles align with usage infrontend/src/components/tasks/TaskFollowUpSection.tsx
When I start typing, it's a really small font for some reason frontend/src/components/tasks/TaskFollowUpSection.tsx
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a new WYSIWYG (What You See Is What You Get) editor powered by Lexical, replacing the previous plain text inputs for task creation, follow-ups, and inline editing throughout the app. It also implements a new "scratch" storage system for auto-saving draft content and adds support for queuing follow-up messages.
Key Changes
New WYSIWYG Editor (
frontend/src/components/ui/wysiwyg.tsx)@lexical/code@mentions (similar to previous FileSearchTextArea)Scratch Storage System (replaces Drafts)
scratchtable and API for persisting editor content in real-time/api/scratch/:type/:id/stream)Queued Follow-Up Messages
Image Handling Improvements
.vibe-images/folder.vibe-images/...) stored in markdown instead of absolute paths/api/task-attempts/:id/images/:path/info) and proxy (/api/task-attempts/:id/images/:path)Cleanup & Refactoring
FileSearchTextAreacomponent and related codeMarkdownRendererin favor of WYSIWYG read-only modedraftssystem (table, service, routes)useDefaultVarianthook for cleaner variant selectionFiles Changed
Database Migrations
20251120000001_refactor_to_scratch.sql- Creates new scratch table20251129155145_drop_drafts_table.sql- Removes deprecated drafts tableTest Plan
🤖 Generated with Claude Code