Skip to content

VideoPress: Modernization Phase 2 — Library tab (DataViews grid + table)#48586

Merged
dhasilva merged 24 commits intotrunkfrom
update/videopress-modernization-phase-2
May 8, 2026
Merged

VideoPress: Modernization Phase 2 — Library tab (DataViews grid + table)#48586
dhasilva merged 24 commits intotrunkfrom
update/videopress-modernization-phase-2

Conversation

@dhasilva
Copy link
Copy Markdown
Contributor

@dhasilva dhasilva commented May 6, 2026

Part of #48506

This PR is intended for visual changes only, for design review. All data is mocked.


This is Phase 2 of the VideoPress dashboard modernization tracking issue (#48506) — the Library tab. UI-only with mocked data, all behind the existing rsm_jetpack_ui_modernization_videopress filter (Phase 0). Subsequent phases each open their own PR.

Proposed changes

  • Library route is now a @wordpress/dataviews v14 grid (default) with a table alternate. Layout switcher in the toolbar; grid is the primary mode for visual browsing, table is dense info.
  • One hook owns the mock data layer. New useMockLibrary() (src/dashboard/hooks/use-mock-library.ts) returns 50 programmatically-generated fixtures (~80% VideoPress, ~20% Local) with a 1-second initial-loading window, a 10-second per-item upload simulation, and a deterministic every-5th-upload-fails-at-60% failure path with a Retry recovery action. The hook signature matches the TanStack Query hook Phase 6 will swap in — Phase 6 is a one-file change.
  • ThumbnailField (src/dashboard/components/Library/ThumbnailField.tsx) layers four states on the DataViews grid card: idle VideoPress (thumbnail + duration badge), idle Local (gray "Local video" placeholder + hover-revealed Upload to VideoPress button), uploading (light overlay + percentage + ProgressBar), failed (red overlay + Retry button).
  • Table view shows status as a pill in the Title cell (Local / Uploading 47% / Upload failed) instead of the larger card overlays — the table-cell thumbnail is too small to host the full chrome. Pills only render in the table view; in the grid the per-card overlays already convey the same info.
  • DataViews fields: thumbnail (media), title, filename, type (primary filter, Local / VideoPress), uploadDate (default sort, desc), duration, privacy (secondary filter), fileSize. Default visible columns differ between layouts: grid shows filename below the title; switching to table reveals filename, duration, fileSize, uploadDate, privacy.
  • DataViews actions: Per-row Edit details (primary, no-op until Phase 4 wires the details screen), three top-level Make public / Make private / Use site default actions (DataViews has no nested-submenu API in v14), Delete, Upload to VideoPress (Local only), Retry (failed only). Bulk: Trash only — isEligible filters out Local items, so mixed-selection bulk-Trash silently skips them while keeping them selectable (matches the Figma mock).
  • Page-header Upload video button wires into AdminPage's actions slot, opens a hidden <input type="file" accept="video/*">, and prepends an "uploading" card to the grid on file pick. Uses @wordpress/ui Button size="compact" to match Settings's Save button so there's no layout shift on tab change.
  • DashboardLayout gains a hideFooter prop. Library opts in (per the design directive: pages with a central DataViews component don't show the JetpackFooter). Overview and Settings keep the footer.
  • Cross-package: added @wordpress/dataviews@14.1.0 as a direct dep of @automattic/jetpack-videopress (and the library route's package.json) so wp-build's externals plugin can resolve it. SCSS pulls in DataViews's stylesheet via @include meta.load-css("@wordpress/dataviews/build-style/style.css") — same pattern Forms uses (projects/packages/forms/routes/shared.scss).

Related product discussion/links

Does this pull request change what data or activity we track or use?

No. UI-only changes; all data is mocked client-side, no API calls, no analytics events, no tracked data added or changed.

Testing instructions

  1. Enable the modernization filter — drop into a mu-plugin or run wp eval:
    add_filter( 'rsm_jetpack_ui_modernization_videopress', '__return_true' );
  2. Visit wp-admin/admin.php?page=jetpack-videopress → click the Library tab.
  3. Confirm the grid:
    • 1-second loading state, then a 4-column grid of cards (12 per page across 5 pages).
    • Each VideoPress card has thumbnail + duration badge bottom-right + title + filename.
    • Local cards have a gray "Local video" placeholder; on hover, an Upload to VideoPress button is revealed.
    • Three-dot menu shows the right actions per type: VideoPress → Edit details, Make public/Make private/Use site default, Delete. Local → Upload to VideoPress. Failed → Retry.
  4. Per-card upload (Local → VideoPress): hover a Local card → click Upload to VideoPress → ~10s ProgressBar climbs → card flips to a regular VideoPress card with a thumbnail.
  5. Failure path: trigger uploads in sequence (mix of header Upload video and per-card promotions). Every 5th upload session deterministically stalls at ~60% with a red Upload failed overlay; click Retry → restarts and succeeds.
  6. Header upload: click Upload video (top-right) → file picker → select any local video file → a new Local-typed card prepends to the grid in uploading state → progresses → resolves into a VideoPress card.
  7. Bulk Trash with mixed selection: select 2 VideoPress cards + 1 Local card → click Trash in the bulk-action bar → only the VideoPress cards are removed; the Local card remains selected (DataViews's isEligible silently skips ineligible items).
  8. Filters:
    • Primary Type chip is always visible — toggle to Local (only Local cards) or VideoPress (only VP cards).
    • Click the filter icon → secondary Privacy filter appears (Public / Private / Site default); intersects with the type filter.
  9. Search filters titles and filenames in real time.
  10. Sort: change sort field; grid re-orders.
  11. View switcher: toggle to table view → 6 sortable columns (Title, Filename, Duration, File size, Uploaded, Privacy); status pills appear next to the title for Local / Uploading XX% / Upload failed rows. Switch back to grid.
  12. Pagination prev / next / jump-to-page work; "12 of 50 Items · Page X of 5" displays.
  13. No JetpackFooter is rendered on the Library tab. Switch to Overview and Settings — footer reappears on those tabs.
  14. Open browser devtools and confirm no console errors or warnings.
  15. Remove the add_filter and confirm the legacy VideoPress dashboard still loads at the same URL.

Out of scope (parked for follow-up)

  • Pin DataViews pagination footer to the bottom of the visible page area. Earlier attempts propagated flex height through Tabs.Root + Tabs.Panel but the chain breaks above Tabs.Root because AdminPage's wrapper isn't itself a flex container. TODO note in DashboardLayout/style.scss flags it for Phase 2.5.
  • Table-view thumbnail white-band. wp-build's .boot-layout-container .boot-layout img { height: auto } reset is winning specificity even with the matching .boot-layout-container .boot-layout prefix on our rule. Needs DevTools to pin down the exact override path.
  • Real persistence / backend wiring — Phase 5 (REST surface) and Phase 6 (TanStack Query swap).
  • class-initial-state.php seeding — Phase 5 (originally scoped into Phase 1, deferred since neither Phase 1 nor 2 has a client-side consumer).
  • phpunit + jest scaffolding — tracked as a deferred follow-up in Modernize Jetpack VideoPress admin dashboard #48506.
Screenshot from 2026-05-06 19-27-54 Screenshot from 2026-05-06 19-28-06

@dhasilva dhasilva added the [Status] Needs Review This PR is ready for review. label May 6, 2026
@dhasilva dhasilva self-assigned this May 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

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:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@dhasilva dhasilva force-pushed the update/videopress-modernization-phase-2 branch from d149a48 to 8fca223 Compare May 6, 2026 22:19
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack or WordPress.com Site Helper), and enable the update/videopress-modernization-phase-2 branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack update/videopress-modernization-phase-2
bin/jetpack-downloader test jetpack-mu-wpcom-plugin update/videopress-modernization-phase-2

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@jp-launch-control
Copy link
Copy Markdown

jp-launch-control Bot commented May 6, 2026

Code Coverage Summary

8 files are newly checked for coverage. Only the first 5 are listed here.

File Coverage
projects/packages/videopress/src/dashboard/components/Library/ThumbnailField.tsx 0/5 (0.00%) 💔
projects/packages/videopress/src/dashboard/components/Library/actions.ts 0/28 (0.00%) 💔
projects/packages/videopress/src/dashboard/components/Library/fields.tsx 0/31 (0.00%) 💔
projects/packages/videopress/src/dashboard/components/Library/upload-actions-context.tsx 0/6 (0.00%) 💔
projects/packages/videopress/src/dashboard/fixtures/library.ts 0/22 (0.00%) 💔

Full summary · PHP report · JS report

Coverage check overridden by Coverage tests to be added later Use to ignore the Code coverage requirement check when tests will be added in a follow-up PR .

@dhasilva dhasilva added [Status] In Progress and removed [Status] Needs Review This PR is ready for review. labels May 6, 2026
@dhasilva dhasilva force-pushed the update/videopress-modernization-phase-2 branch from 95d623d to 2b21410 Compare May 7, 2026 03:14
@dhasilva dhasilva added [Status] Needs Review This PR is ready for review. and removed [Status] In Progress labels May 7, 2026
@dhasilva dhasilva requested review from a team, CGastrell, ilonagl and keoshi May 7, 2026 03:18
@dhasilva dhasilva added the Coverage tests to be added later Use to ignore the Code coverage requirement check when tests will be added in a follow-up PR label May 7, 2026
@simison simison requested a review from obenland May 7, 2026 06:41
@@ -0,0 +1,66 @@
import { Button, ProgressBar } from '@wordpress/components';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Recommend Button from @wordpress/ui instead.

Comment thread projects/packages/videopress/src/dashboard/fixtures/library.ts
Comment on lines +31 to +33
<span className="vp-library__thumbnail-duration-badge">
{ formatDuration( durationSeconds ) }
</span>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like Badge from @wordpress/ui could be suitable here, just not sure what to do with color.

callback: items => {
api.deleteItems( items.map( i => i.id ) );
},
},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

UX comment — this and others might benefit from feedback after action, so I'd add a Snackbar notice here.

@simison
Copy link
Copy Markdown
Member

simison commented May 7, 2026

Out of scope (parked for follow-up)

Would be good to get upstream Gutenberg issues for most of these, particularly to avoid styles in projects/packages/videopress/src/dashboard/components/DashboardLayout/style.scss.

label: __( 'Uploaded', 'jetpack-videopress-pkg' ),
type: 'datetime',
getValue: ( { item } ) => item.uploadDate,
render: ( { item } ) => dateI18n( dateSettings.formats.date, item.uploadDate ),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not sure, but format might also use date settings already so you wouldn't need render at all..

* @param bytes - Total bytes.
* @return Formatted size.
*/
export function formatBytes( bytes: number ): string {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not a biggie, but there might already be a helper around Jetpack for this.

Comment on lines +95 to +98
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You might be able to use Stack instead of these styles.

Comment on lines +103 to +104
font-size: 16px;
font-weight: 600;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Might need Text component instead.

align-items: center;
justify-content: center;
gap: 6px;
background: rgba(204, 24, 24, 0.85);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should probably pull style token for "error" background + foreground colors. Or use Notice component?

Comment on lines +116 to +120
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Might be able to use Stack for all these styles.

Comment on lines +128 to +130
font-size: 12px;
color: #757575;
line-height: 1.4;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like bit like Text would do this already.

dhasilva and others added 24 commits May 8, 2026 14:33
Two layout fixes for the Phase 2 Library tab:

* Replace `min-height: calc(100vh - 220px)` on `.vp-library__viewport` with
  `flex: 1; min-height: 0`, and propagate `display: flex` through Tabs.Root +
  Tabs.Panel (Base UI primitives default to `display: block`, breaking the
  flex chain). Pagination footer now flexes to the visible bottom regardless
  of the chrome above. Targeted via stable ARIA roles, not the obfuscated
  CSS-in-JS classnames.
* Lock `.vp-library__thumbnail` to 32x32 in table view. The DataViews cell
  wrapper applies `align-items: center`, so an img with non-square intrinsic
  ratio (e.g. 32x18 for 16:9) collapses the wrapper to its content height,
  leaving white space above and below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…selectors

Replace third-party-private classnames with selectors anchored to either
the public `view.type` API or our own class hierarchy:

* `.dataviews-wrapper` → `> *` (the viewport only ever wraps a single
  DataViews instance).
* `.dataviews-view-table` → `&__viewport--table`, mirrored from `view.type`
  via a new modifier class on the viewport in stage.tsx.
* `.dataviews-view-grid` → `&__viewport--grid` (same mechanism).
* `.boot-layout-container .boot-layout &__thumbnail-image` (specificity
  0,2,1) → `&__viewport &__thumbnail &__thumbnail-image` (specificity
  0,3,0). Beats wp-build's `img { height: auto }` reset by chaining our
  own classes instead of naming the wp-build classes.

Behavior is unchanged; verified live in both grid and table views (img
still 32x32 in table view, pagination still pinned to viewport bottom).
The Library route's SCSS no longer references any @wordpress/dataviews
or wp-build private classnames, so future renames in those packages
won't break this tab.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ref p1HpG7-wSr-p2

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… render

DataViews' built-in datetime field type formats values via field.format.datetime
+ dateI18n internally, so the custom render call is redundant. Drop it and pass
the desired format on the field instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aligns ThumbnailField with the design-system migration already underway across
modernized dashboards. variant="secondary" -> variant="outline"; the primary
"Retry" relies on the wp/ui Button defaults (solid + brand).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the custom .vp-library__status-pill SCSS (uploading / failed / local)
with wp/ui Badge driven by intent (informational / high / none) — colors and
dark-mode behaviour now ride the design tokens. The title cell becomes a Stack
with a stable className so the badge can still be hidden in grid view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the bespoke flex centering and font sizing on .vp-library__placeholder /
__hover-action / __progress / __failed onto wp/ui Stack wrappers, and render
the filename cell with Text body-sm. SCSS keeps positioning, background, and
truncation — typography and layout now ride the design tokens.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires @automattic/jetpack-components' GlobalNotices/useGlobalNotices into the
Library route so Delete and "Make public/private/use site default" emit a
success snackbar. Promote/Retry stay silent — the per-card progress overlay
already conveys the state. Adds a global-notices sub-path export to the
shared package so wp-build dashboards can pull it in alongside admin-page
without dragging in the rest of the bundle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the `variant="minimal"` on `<Tabs.List>` so we get the canonical 16px
per-tab inline padding and no tablist gap. `admin-page-layout` still bumps
`[role="tab"]` to 24px for header-edge alignment; the local override walks
that back to the lg token (16px) and offsets the tablist by the missing 8px,
so the first tab's text edge still sits under the page title (8px tablist +
16px tab = 24px). The hairline stays full-width on `.jp-admin-page-tabs`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops `isPrimary: true` from the `type` field so it joins `privacy` under the
filter icon instead of always showing as a pinned chip. With only one primary
filter, the dropdown looked empty and the filter icon read as disabled — now
both filters live behind the same affordance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the placeholder Save action from the Settings header. The toggle is
local-only state for Phase 1; persistence will land in Phase 6, at which point
we can settle on the right UX (likely save-on-change rather than a discrete
button).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dhasilva dhasilva force-pushed the update/videopress-modernization-phase-2 branch from d9e6c48 to 6bc08c3 Compare May 8, 2026 17:50
@dhasilva dhasilva merged commit ef23d9f into trunk May 8, 2026
143 of 148 checks passed
@dhasilva dhasilva deleted the update/videopress-modernization-phase-2 branch May 8, 2026 23:43
@github-actions github-actions Bot removed the [Status] Needs Review This PR is ready for review. label May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Coverage tests to be added later Use to ignore the Code coverage requirement check when tests will be added in a follow-up PR [JS Package] Components [Package] VideoPress RNA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants