Backup: wire the modernized dashboard to real REST + Gates#48859
Backup: wire the modernized dashboard to real REST + Gates#48859dhasilva wants to merge 8 commits into
Conversation
Adds the @tanstack/react-query infrastructure with no behavior change. DashboardLayout now wraps children in a QueryClientProvider so every screen in every route shares a module-scope singleton client — caches survive navigation between routes. Phase 2 setup commit. Capability gates and real REST hooks follow. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces the per-feature REST bridges pattern with a thin
Rest_Controller that registers routes only when the modernization
filter is on. Capabilities_Bridge proxies /sites/{id}/rewind to
expose hasBackupPlan + planSlug for the React layer.
Gates mounts inside DashboardLayout between the QueryClientProvider
and the body slot. Top-to-bottom: loading → not-connected →
secondary-admin → no-plan → children. All three routes inherit
gating for free.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces useMockActivityLog with useActivityLog backed by an
apiFetch -> bridge -> WPCOM /sites/{id}/activity/rewindable chain.
A small normalize/activity-log.ts maps WPCOM's rewindable-activity
shape (gridicon, content.text, object.backup_stats) onto the
ActivityItem discriminated union the UI already consumes.
Fixture activity-log.ts is deleted; findActivityById's three callers
swap to: getCachedActivityById (Overview, reads from React Query cache)
for the selected-row right-pane, and a direct rewindId -> Unix
timestamp derivation for Restore and Download (the only field they
used was the publishedAt timestamp anyway).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the File_Browser_Bridge (ls + path-info + file-content), each
proxying WPCOM /sites/{id}/rewind/backup/* via as_user. The file-content
endpoint resolves the signed stream URL server-side and caps the
returned body at 64 KB so previews can't balloon the REST response.
React side: useFileTree replaces useMockFileTree, useFileContents
replaces the static findContents() fixture lookup. The rewindId prop
on FileBrowser and FileInfoCard is now actually consumed and threaded
down to the bridge call.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
useDownload replaces useMockDownload, driving the same
idle → submitting → progress → success | error state machine off
a TanStack useMutation (initiate) + polled useQuery (status).
The bridge proxies WPCOM's /rewind/backups/{rewindId}/prepare-download
and /rewind/backups/{rewindId}/downloads/{id} endpoints.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
useRestore replaces useMockRestore, driving the same state machine off
a TanStack useMutation (initiate) + polled useQuery (status). The
bridge proxies WPCOM's v1 /activity-log/{site}/rewind/to/{rewindId}
and /rewind/{restoreId}/restore-status endpoints, with the verbatim
comment from `d3f8b8da7e` explaining why the rewind endpoint must
sign as_user (blog-token auth is rejected by WPCOM with
"That API call is not allowed for this account").
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the last mock-mode artifacts: useIsMockMode, the dev banner component, and the <DevModeBanner /> mount inside DashboardLayout. The modernized Backup dashboard now only renders real data via the jetpack/v4/* bridges, with <Gates> handling the not-connected and no-plan fallbacks. This completes Phase 2 of the Backup modernization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three follow-ups from the final code review: - Wrap the bare 'Download failed.' / 'Restore failed.' fallbacks in __() with the jetpack-backup-pkg textdomain (the strings flow into <Notice> user-facing copy). - Route fetchCapabilities through apiCall + apiPath so a 4xx from /jetpack/v4/site/capabilities throws an ApiError with `code`, matching every other fetcher in the data layer. - Update Restore/Download screen JSDoc — "mocked state machine" was true in Phase 1; Phase 2 made it real. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! Jetpack plugin: The Jetpack plugin has different release cadences depending on the platform:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Backup plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
398c7a4 to
5e780c0
Compare
Fixes # n/a
Proposed changes
projects/packages/backup/src/rest/(Capabilities,Activity_Log,File_Browser,Download,Restore) registered by a singleRest_Controlleronly when thersm_jetpack_ui_modernization_backupfilter is on. All proxy WPCOM viaClient::wpcom_json_api_request_as_user; Restore signs as_user against therest/v1activity-log endpoint and ports the blog-token-rejection block comment from the abandoned branch's commitd3f8b8da7eso the next developer doesn't repeat the experiment.<Gates>capability/connection gate inside<DashboardLayout>— decision tree is loading → not-connected → secondary-admin → no-plan → children, with three local fallback screens.useConnectionreads fromwindow.JP_CONNECTION_INITIAL_STATEdirectly (rendered inline byJetpack_Backup::render_connection_initial_stateonadmin_print_scriptspriority 1).queryClient+keystable;data/api/_helpers.tswithapiPath,toIntRewindId,ApiError,apiCall; one fetcher file per bridge; adata/normalize/activity-log.tsadapter mapping WPCOM's rewindable-activity shape onto the Phase 1ActivityItemdiscriminated union.useMock*hook with a real React Query hook, identical return shape, one-import-line swap per screen. The hooks are:useActivityLog,useFileTree,useFileContents,usePathInfo,useDownload,useRestore,useCapabilities,useConnection.?jpb-mock=1developer affordance — deleteuse-is-mock-mode.ts,dev-mode-banner/, all four mock hooks, and the three fixture files.toIntRewindId(3 cases) +normalize/activity-log.ts(6 cases); phpunit per bridge (capabilities ×2, activity-log ×2, file-browser ×4, download ×3, restore ×3 — 14 total new assertions). Run from the package:pnpm run build && pnpm run typecheck && pnpm exec eslint src/dashboard && pnpm exec jest src/dashboard/data && composer phpunit.Related product discussion/links
Pagechassis), and PR3 (Backup: modernized dashboard UI — Overview, Restore, Download (mocked) #48853, UI with mocked data — this PR's base).Does this pull request change what data or activity we track or use?
No.
Testing instructions
pnpm installfrom the repo root, thencomposer installinprojects/packages/backup/.wp-admin → Jetpack → VaultPress Backup./jetpack/v4/rewind/backup/lscall, clicking a text file loads the path-info and shows a monospace preview (≤ 64 KB).<Gates>renders the "no plan" fallback with a CTA tojetpack.com/upgrade/backup/.<Gates>renders the "Connect Jetpack" fallback..off, reload). Confirm the legacy Backup admin renders unchanged.🤖 Generated with Claude Code