fix: show same-path re-uploads without a manual refresh#409
Merged
Conversation
Re-uploading a file to an existing path stayed hidden until you navigated/refreshed: the object listing is fetched server-side once and passed as a static prop, and mergeUploadsWithFiles keys rows by filename, so a re-upload just overlays upload progress on the existing row without updating its size/date. Edge-trigger router.refresh() when a product scope's uploads drain to re-run the server component and re-list S3. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
Claude finished @alukach's task in 2m 31s —— View job Reviewing PR #409
✅ No blocking issues — safe to merge. Traced both fixes end-to-end against
Two non-blocking observations, already effectively acknowledged by the PR's scoping:
|
The refresh-on-drain effect was in DirectoryList, which the page renders only for directory views — when the path resolves to a single file, page.tsx returns the ObjectSummary/ObjectPreview branch and never mounts DirectoryList. So re-uploading while viewing that exact file never triggered a refresh. Move the effect into Dropzone, which lives in the product layout and is mounted for both directory and file views. router.refresh() now re-runs the server render (listing, file metadata, and server-fetched internal previews) after either kind of re-upload. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
DirectoryList optimistically hides deleted paths in client state (deletedPaths). That state survives router.refresh(), so re-uploading to a just-deleted path stayed hidden until you navigated away (which resets the set) — the exact case the prior ponytail comment flagged as unhandled. Reconcile: when a scoped upload targets a hidden path, drop it from deletedPaths so the re-created object shows again. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
deletedPaths never holds "", so "".split("\n") -> [""] already no-ops
through the .some() guard. Remove the ternary.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
alukach
pushed a commit
that referenced
this pull request
Jul 2, 2026
🤖 I have created a release *beep* *boop* --- ## [1.4.0](v1.3.0...v1.4.0) (2026-07-01) ### ⚠ BREAKING CHANGES * require auth for restricted products ([#284](#284)) ### Features * add INI-style credentials format tab ([2bcc3f1](2bcc3f1)), closes [#388](#388) * add INI-style credentials format tab ([#389](#389)) ([ebd4a1e](ebd4a1e)) * add X-Robots-Tag header for non-production deployments ([72249b9](72249b9)), closes [#302](#302) * add X-Robots-Tag header for non-production deployments ([#323](#323)) ([4fa9f9d](4fa9f9d)) * **admin-ui:** trust-policy sub-pattern preview on the federated connection edit page ([#377](#377)) ([ba82dc4](ba82dc4)) * **admin:** admin email-to-profile lookup view ([#350](#350)) ([a056a28](a056a28)) * **admin:** data connection management (CRUD, S3/Azure/GCP/R2, product mirrors) ([#364](#364)) ([9ca1f53](9ca1f53)) * **authz:** let product owners view their own deactivated products ([#399](#399)) ([09fd4d0](09fd4d0)) * **data-connection:** expose secret-less federated config; never return stored secrets ([#376](#376)) ([395b6c2](395b6c2)) * **data-connection:** federated backend authentication (AWS web identity + GCP/Azure scaffold) ([#332](#332)) ([999a076](999a076)) * **data-connections:** account-owned data connections ([#383](#383)) ([b04755b](b04755b)) * **data-connections:** expose secret-less federated config by connection visibility ([#327](#327)) ([#339](#339)) ([43f1f63](43f1f63)) * **data-connections:** link product-owned connections to admin form ([#392](#392)) ([c6e8f10](c6e8f10)) * **data-connections:** require unsigned connections to be read-only ([#394](#394)) ([c2af48b](c2af48b)) * delete product feature with confirmation modal ([#361](#361)) ([0f68e47](0f68e47)) * **globe:** render live activity per datacenter ([#395](#395)) ([d119935](d119935)) * **globe:** tidy live-activity popup, per-product count on hover ([#397](#397)) ([1d92b1f](1d92b1f)) * **object-browser:** delete files and prefixes in edit mode ([#403](#403)) ([2b1426b](2b1426b)) * OIDC auth ([#283](#283)) ([c40ec89](c40ec89)) * **products:** choose a data connection and enforce its allowed visibilities ([#338](#338)) ([c40818f](c40818f)) * **products:** deactivate products — form toggle, admin-only viewing, API 404s others ([#372](#372)) ([77dc24b](77dc24b)) * **products:** mark deactivated products in account product list ([#385](#385)) ([b8e6806](b8e6806)) * **profile:** link to Ory settings from read-only email field ([#349](#349)) ([34a2244](34a2244)) * **scripts:** bulk-apply web-identity auth to opendata S3 connections ([#398](#398)) ([45e4133](45e4133)) * **scripts:** migrate restricted open-data products to unlisted ([#343](#343)) ([#371](#371)) ([2977ee4](2977ee4)) * **uploads:** route in-browser uploads through the data proxy ([#391](#391)) ([92f61ed](92f61ed)) * **viewer:** Add PDF viewer, PNG bindings ([#315](#315)) ([7927431](7927431)) * **viewer:** support ndjson/jsonl ([3790a24](3790a24)), closes [#390](#390) ### Bug Fixes * **api:** return 200 on successful member invite ([#381](#381)) ([3be8e49](3be8e49)) * **auth:** log out sessions stuck at AAL1 when whoami requires AAL2 ([#396](#396)) ([b9af694](b9af694)) * **data-connection:** enforce provider↔auth pairing, tighten ARN + GCP SA validation ([#368](#368)) ([4780089](4780089)) * **data-connections:** admin form-reset, redirect, and prefix-template handling ([#379](#379)) ([963e7c8](963e7c8)) * **data-connections:** correct trust-policy aud to sts.amazonaws.com ([#382](#382)) ([d53b894](d53b894)) * **email-verification:** reconcile Ory verification on every page load ([#347](#347)) ([e0a85c3](e0a85c3)) * **forms:** opt out of React's auto form-reset so controlled fields don't flash ([#373](#373)) ([0eb033f](0eb033f)) * **globe:** fall back to static image when WebGL is disabled ([#387](#387)) ([eb5c9a6](eb5c9a6)) * make full menu item area clickable ([#295](#295)) ([e27a3c2](e27a3c2)) * **product:** hide edit buttons when data connection is read-only ([#353](#353)) ([b57cfab](b57cfab)) * **products:** degrade gracefully when a data-proxy read fails ([#400](#400)) ([3b5adb5](3b5adb5)) * re-render auth UI after form-submission redirects ([#344](#344)) ([a378ebc](a378ebc)) * require auth for restricted products ([#284](#284)) ([112265a](112265a)) * return user to current view after login ([#346](#346)) ([9dd6d5f](9dd6d5f)) * show same-path re-uploads without a manual refresh ([#409](#409)) ([b878b68](b878b68)) * **uploads:** refresh STS credentials mid-upload ([#401](#401)) ([#402](#402)) ([8da202d](8da202d)) * use [source-coop] as INI profile name ([c06a5ac](c06a5ac)) * validate product DOI format ([#319](#319)) ([4727dec](4727dec)) ### Performance Improvements * **db:** request-scoped memoization of DynamoDB reads ([#320](#320)) ([1f295cf](1f295cf)) ### Miscellaneous Chores * release 1.4.0 ([810ff3c](810ff3c)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: source-release-bot[bot] <265100246+source-release-bot[bot]@users.noreply.github.com>
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
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.
Problem
Re-uploading a file to the exact same path in the object browser, without navigating away, stayed hidden until you navigated or refreshed the page.
Root cause
DirectoryListas a staticobjectsprop — nothing re-fetches it after an upload.mergeUploadsWithFileskeys rows by filename. A re-upload to an existing path finds the existing server row and just spreadsuploadProgressonto it, leaving the oldsize/updated_at/objectin place. When it flips tocompletedthe row looks identical to before — no new row, no changed metadata — so the re-upload is invisible.revalidatePath), product uploads go client→S3 directly, so nothing invalidates the listing.Fix
Edge-trigger
router.refresh()inDirectoryListwhen this product scope's uploads drain (lastuploading/queued→ none). That re-runs the server component and re-lists S3 — the programmatic equivalent of the manual navigate/refresh that already worked. A same-path re-upload now updates its size/date/etag in place.router.refresh()rather thanrevalidatePathbecause product uploads have no server action to hang revalidation on.Not covered (separate layer)
File content URLs (
fileSourceUrl, the external image-viewer iframe) are keyed by path only, so a re-uploaded image's bytes can still render from browser/CDN cache even after the listing updates. Fixing that means adding a?v={etag|updated_at}cache-buster across file URLs + previews — left out of this PR.Testing
tsc --noEmitpasses clean.🤖 Generated with Claude Code