fix(file-editor): preserve drafts and harden editing behavior - #7478
fix(file-editor): preserve drafts and harden editing behavior#7478waleedlatif1 wants to merge 3 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Greptile SummaryThe PR hardens file editing by preserving local drafts, adding version-aware saves and conflict recovery, and improving rich Markdown editing behavior.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/use-editable-file-content.ts | Coordinates draft ownership, streamed content, save versions, conflict state, reloads, and storage-key recovery. |
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor-state.ts | Adds reducer-level synchronization and stale-version protections for accepted baselines, drafts, and conflicts. |
| apps/sim/hooks/use-autosave.ts | Strengthens queued draft persistence, discard correction, and recovery behavior. |
| apps/sim/hooks/queries/workspace-files.ts | Adds version-aware content mutations, bounded stale-storage-key recovery, and related cache reconciliation. |
| apps/sim/app/api/workspaces/[id]/files/[fileId]/content/route.ts | Passes validated content-version preconditions into the authorized file-update use case. |
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/extensions.ts | Expands Markdown schema and serialization behavior for lists, tables, hard breaks, and structural empty paragraphs. |
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/image-upload.ts | Introduces transaction-mapped placeholders for cancellable asynchronous image insertion. |
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/list-input-rules.ts | Joins newly typed compatible lists while preserving undo and collaborative-list boundaries. |
Sequence Diagram
sequenceDiagram
participant User
participant Editor
participant Draft as Local Draft
participant API as File Content API
participant Store as Workspace Storage
User->>Editor: Edit file
Editor->>Draft: Preserve and autosave draft
Editor->>API: Save(content, expectedUpdatedAt)
API->>Store: Compare version and update
alt Version matches
Store-->>API: Updated content and version
API-->>Editor: Save acknowledged
Editor->>Draft: Mark draft saved
else Version changed elsewhere
Store-->>API: Conflict
API-->>Editor: 409 conflict
Editor-->>User: Preserve draft and pause saving
User->>Editor: Download draft or reload latest
end
Reviews (3): Last reviewed commit: "fix(file-editor): retain conflicts with ..." | Re-trigger Greptile
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
1 issue found across 69 files
Confidence score: 4/5
- In
apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/image-upload.test.ts, theunrelatedparametrized case insertsPEERwell after the anchor range in another paragraph, so it may not validate the plugin’s handling of the intended edit interaction and could leave a regression undetected — align the peer insertion with the scenario the test is meant to cover.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/image-upload.test.ts">
<violation number="1" location="apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/image-upload.test.ts:52">
P2: In the `unrelated` branch of this parametrized test, the peer inserts `'PEER '` at `content.size - 1` (position 21), which is well after the anchor range 8–14 in a separate paragraph. Per the plugin's apply() logic, an insert entirely after the range maps `from`/`to` unchanged and keeps `doc.slice(from,to).eq(replacement)` true, so the anchor survives and `finishImageUpload` should return true — yet the test asserts `findImageUploadRange(...)` is null and `finishImageUpload(...)` is false for both `unrelated` values. This directly contradicts the sibling test 'maps a replacement through edits before it', which shows unrelated interrupts preserve the anchor. Either the implementation is silently cancelling a local pending upload when a collaborator edits an unrelated paragraph (a user-facing bug: the image upload is dropped), or this assertion is wrong and the case is not actually covering what its name claims. Resolve the discrepancy and make the two cases assert distinct, correct outcomes.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
Type of Change
Testing
Checklist