Skip to content

fix: block submit while file upload is pending#701

Open
k08200 wants to merge 3 commits intogridaco:mainfrom
k08200:fix/137-file-upload-pending-validation
Open

fix: block submit while file upload is pending#701
k08200 wants to merge 3 commits intogridaco:mainfrom
k08200:fix/137-file-upload-pending-validation

Conversation

@k08200
Copy link
Copy Markdown
Contributor

@k08200 k08200 commented Apr 30, 2026

Summary

  • mark the uploaded-file value input invalid while a selected non-multipart file has not produced an uploaded path
  • keep multipart upload behavior unchanged
  • add focused validation helper coverage

Verification

  • pnpm --dir editor exec vitest run components/formfield/file-upload-field/tests/file-upload-validation.test.ts
  • pnpm exec oxfmt --check editor/components/formfield/file-upload-field/file-upload-field.tsx editor/components/formfield/file-upload-field/file-upload-validation.ts editor/components/formfield/file-upload-field/tests/file-upload-validation.test.ts
  • pnpm exec oxlint editor/components/formfield/file-upload-field/file-upload-field.tsx editor/components/formfield/file-upload-field/file-upload-validation.ts editor/components/formfield/file-upload-field/tests/file-upload-validation.test.ts

Note: pnpm --dir editor typecheck currently fails on unrelated missing static image modules under app/(www), app/(site), app/(workbench), and components/stripe.

Closes #137

Summary by CodeRabbit

  • Bug Fixes

    • Forms with file uploads are now reliably blocked from submission until all selected files finish uploading, preventing incomplete uploads.
    • Browser-level validation now enforces the upload-complete requirement.
  • Improvements

    • File upload field is explicitly non-editable and displays clearer validation state while uploads are in progress.
    • Required validation is applied conditionally based on upload state.
  • Tests

    • Added tests covering multiple file-upload states and validation outcomes.

@vercel vercel Bot temporarily deployed to Preview – backgrounds April 30, 2026 08:27 Inactive
@vercel vercel Bot temporarily deployed to Preview – viewer April 30, 2026 08:27 Inactive
@vercel vercel Bot temporarily deployed to Preview – blog April 30, 2026 08:27 Inactive
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

@k08200 is attempting to deploy a commit to the Grida Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
backgrounds Skipped Skipped Apr 30, 2026 3:59pm
blog Skipped Skipped Apr 30, 2026 3:59pm
viewer Skipped Skipped Apr 30, 2026 3:59pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

Walkthrough

Blocks form submission while non-multipart file uploads are in progress by adding shouldBlockSubmitForFileUpload, wiring upload state into the file-upload field to toggle required/validity, marking the uploaded-file input readOnly, and adding unit tests for validation scenarios.

Changes

Cohort / File(s) Summary
Validation helper & integration
editor/components/formfield/file-upload-field/file-upload-validation.ts, editor/components/formfield/file-upload-field/file-upload-field.tsx
Added exported shouldBlockSubmitForFileUpload; component now reads isUploading, selectedFilesCount, uploadedFilesCount, and isMultipartFile to decide blocking, sets custom validity, and toggles required accordingly.
Tests
editor/components/formfield/file-upload-field/__tests__/file-upload-validation.test.ts
New Vitest tests covering untouched optional, in-progress uploads, completed uploads, and multipart-file behavior for submit blocking logic.
UploadedFileValue input attribute
editor/components/extension/file-upload.tsx
Set the UploadedFileValue input to readOnly to prevent user edits.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant FormComp as FileUploadField
    participant Uploader as useFileUploader
    participant Browser as Browser/FormValidation

    User->>FormComp: Select files / Submit form
    FormComp->>Uploader: request selectedFilesCount, uploadedFilesCount, isUploading, isMultipartFile
    Uploader-->>FormComp: return upload state
    FormComp->>FormComp: shouldBlock = shouldBlockSubmitForFileUpload(...)
    alt shouldBlock == true
        FormComp->>Browser: set custom validity on UploadedFileValue (prevent submit)
        Browser-->>User: block submission / show validation
    else shouldBlock == false
        Browser-->>User: allow submission
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective of the PR: preventing form submission when a file upload is pending.
Linked Issues check ✅ Passed The code changes fully implement the requirement from issue #137: blocking form submission when file uploads are pending for non-required fields.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing file upload validation and blocking submission during pending uploads; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@editor/components/formfield/file-upload-field/__tests__/file-upload-validation.test.ts`:
- Around line 4-45: Add a new test in the
describe("shouldBlockSubmitForFileUpload") block that exercises the branch where
uploadedFilesCount < selectedFilesCount while isUploading is false: call
shouldBlockSubmitForFileUpload with selectedFilesCount: 2, uploadedFilesCount:
1, isUploading: false (and isMultipartFile omitted or false) and assert it
returns true so the helper blocks submit when uploads stopped but counts
mismatch; place it alongside the other tests for clarity.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 479215b4-4a22-449a-95e6-bb3517ca46b3

📥 Commits

Reviewing files that changed from the base of the PR and between 5e63162 and e16a37d.

📒 Files selected for processing (3)
  • editor/components/formfield/file-upload-field/__tests__/file-upload-validation.test.ts
  • editor/components/formfield/file-upload-field/file-upload-field.tsx
  • editor/components/formfield/file-upload-field/file-upload-validation.ts

Comment on lines +4 to +45
describe("shouldBlockSubmitForFileUpload", () => {
test("does not block an untouched optional upload field", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 0,
uploadedFilesCount: 0,
isUploading: false,
})
).toBe(false);
});

test("blocks when a selected file has not produced an uploaded path yet", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 1,
uploadedFilesCount: 0,
isUploading: true,
})
).toBe(true);
});

test("allows submit after each selected file has an uploaded path", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 2,
uploadedFilesCount: 2,
isUploading: false,
})
).toBe(false);
});

test("does not block multipart file uploads", () => {
expect(
shouldBlockSubmitForFileUpload({
isMultipartFile: true,
selectedFilesCount: 1,
uploadedFilesCount: 0,
isUploading: true,
})
).toBe(false);
});
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a test for count mismatch when isUploading is false.

There’s no assertion for the uploadedFilesCount < selectedFilesCount branch when upload activity has stopped, which is part of the helper contract.

Proposed test addition
 describe("shouldBlockSubmitForFileUpload", () => {
+  test("blocks when selected files still lack uploaded paths even if not actively uploading", () => {
+    expect(
+      shouldBlockSubmitForFileUpload({
+        selectedFilesCount: 2,
+        uploadedFilesCount: 1,
+        isUploading: false,
+      })
+    ).toBe(true);
+  });
+
   test("does not block an untouched optional upload field", () => {
     expect(
       shouldBlockSubmitForFileUpload({
         selectedFilesCount: 0,
         uploadedFilesCount: 0,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
describe("shouldBlockSubmitForFileUpload", () => {
test("does not block an untouched optional upload field", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 0,
uploadedFilesCount: 0,
isUploading: false,
})
).toBe(false);
});
test("blocks when a selected file has not produced an uploaded path yet", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 1,
uploadedFilesCount: 0,
isUploading: true,
})
).toBe(true);
});
test("allows submit after each selected file has an uploaded path", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 2,
uploadedFilesCount: 2,
isUploading: false,
})
).toBe(false);
});
test("does not block multipart file uploads", () => {
expect(
shouldBlockSubmitForFileUpload({
isMultipartFile: true,
selectedFilesCount: 1,
uploadedFilesCount: 0,
isUploading: true,
})
).toBe(false);
});
});
describe("shouldBlockSubmitForFileUpload", () => {
test("blocks when selected files still lack uploaded paths even if not actively uploading", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 2,
uploadedFilesCount: 1,
isUploading: false,
})
).toBe(true);
});
test("does not block an untouched optional upload field", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 0,
uploadedFilesCount: 0,
isUploading: false,
})
).toBe(false);
});
test("blocks when a selected file has not produced an uploaded path yet", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 1,
uploadedFilesCount: 0,
isUploading: true,
})
).toBe(true);
});
test("allows submit after each selected file has an uploaded path", () => {
expect(
shouldBlockSubmitForFileUpload({
selectedFilesCount: 2,
uploadedFilesCount: 2,
isUploading: false,
})
).toBe(false);
});
test("does not block multipart file uploads", () => {
expect(
shouldBlockSubmitForFileUpload({
isMultipartFile: true,
selectedFilesCount: 1,
uploadedFilesCount: 0,
isUploading: true,
})
).toBe(false);
});
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@editor/components/formfield/file-upload-field/__tests__/file-upload-validation.test.ts`
around lines 4 - 45, Add a new test in the
describe("shouldBlockSubmitForFileUpload") block that exercises the branch where
uploadedFilesCount < selectedFilesCount while isUploading is false: call
shouldBlockSubmitForFileUpload with selectedFilesCount: 2, uploadedFilesCount:
1, isUploading: false (and isMultipartFile omitted or false) and assert it
returns true so the helper blocks submit when uploads stopped but counts
mismatch; place it alongside the other tests for clarity.

Copy link
Copy Markdown
Contributor Author

k08200 commented Apr 30, 2026

Behavior verification update: I ran a temporary Next dev route with Playwright in Chromium. For a non-multipart FileUploadField, selecting a file kept native form validity false while upload was pending; after the uploader resolved with a path, the hidden value became valid and submit succeeded.

Copy link
Copy Markdown
Contributor Author

k08200 commented Apr 30, 2026

Follow-up: added readOnly to the hidden uploaded-file value input so React does not warn about a controlled input without onChange during manual/browser verification. Focused validation test, oxfmt, and oxlint still pass.

@vercel vercel Bot temporarily deployed to Preview – backgrounds April 30, 2026 14:06 Inactive
@vercel vercel Bot temporarily deployed to Preview – viewer April 30, 2026 14:06 Inactive
@vercel vercel Bot temporarily deployed to Preview – blog April 30, 2026 14:06 Inactive
@vercel vercel Bot temporarily deployed to Preview – backgrounds April 30, 2026 15:59 Inactive
@vercel vercel Bot temporarily deployed to Preview – viewer April 30, 2026 15:59 Inactive
@vercel vercel Bot temporarily deployed to Preview – blog April 30, 2026 15:59 Inactive
@k08200
Copy link
Copy Markdown
Contributor Author

k08200 commented Apr 30, 2026

2026-05-01.1.01.31.mov

Is it right??

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@editor/components/formfield/file-upload-field/file-upload-field.tsx`:
- Around line 109-111: The validation text currently uses shouldBlockSubmit
only, causing the message to always read "Please wait…" even when uploads
failed; update the logic that sets validationMessage (in file-upload-field
component where validationMessage, shouldBlockSubmit and isUploading are
defined) to branch on isUploading: when shouldBlockSubmit && isUploading keep
the existing "Please wait for the selected file upload to finish." otherwise
when shouldBlockSubmit && !isUploading show a clear recovery message (e.g.,
"File upload incomplete or failed. Please retry or remove the file.") so users
aren’t misled; ensure you reference and use the existing isUploading flag and
preserve existing empty-string behavior when shouldBlockSubmit is false.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0e90062e-6d39-40fc-ab43-b8b21b2c4fef

📥 Commits

Reviewing files that changed from the base of the PR and between e1d062f and 283fc0d.

📒 Files selected for processing (1)
  • editor/components/formfield/file-upload-field/file-upload-field.tsx

Comment on lines +109 to +111
const validationMessage = shouldBlockSubmit
? "Please wait for the selected file upload to finish."
: "";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validation message is inaccurate when upload is not in progress

shouldBlockSubmit is also true when uploads are incomplete due to non-uploading states (e.g., failed upload), but the message always says “Please wait…”. This can mislead users about recovery steps. Consider branching the message by isUploading vs mismatch-only states.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@editor/components/formfield/file-upload-field/file-upload-field.tsx` around
lines 109 - 111, The validation text currently uses shouldBlockSubmit only,
causing the message to always read "Please wait…" even when uploads failed;
update the logic that sets validationMessage (in file-upload-field component
where validationMessage, shouldBlockSubmit and isUploading are defined) to
branch on isUploading: when shouldBlockSubmit && isUploading keep the existing
"Please wait for the selected file upload to finish." otherwise when
shouldBlockSubmit && !isUploading show a clear recovery message (e.g., "File
upload incomplete or failed. Please retry or remove the file.") so users aren’t
misled; ensure you reference and use the existing isUploading flag and preserve
existing empty-string behavior when shouldBlockSubmit is false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Grida Forms] Validate form when file is being uploaded for non required fields

1 participant