Skip to content

Improve batch update UI/UX: site context, responsive layout, accessibility, and safer bulk actions #1775

Description

@cyfung1031

Summary

The batch update page in current main is a substantial improvement over the implementation at 741b0bd2ec2f75a7e84c62fbe02654ce6bc41543. The current version has dedicated desktop/mobile layouts, row-level progress, batch progress, skeleton/loading/error states, explicit retry paths, and much better async feedback.

However, the redesign also removed or weakened several pieces of context that were useful in the older flow, and a few parts of the new layout do not fully follow the repository's own responsive/accessibility design rules.

This issue proposes a focused follow-up pass. The goal is not to revert the new UI. The goal is to keep the stronger state model and visual system in main, while fixing the remaining workflow, responsive, accessibility, and bulk-action problems.

Comparison baseline

What should be preserved from current main

These are clear improvements and should remain:

Area Old behavior Current main Direction
Async feedback Mostly global busy state Per-row queued / updating / success / failure, retry, batch summary Keep current
Loading Little visible structure while records load Skeleton table/cards and top progress Keep current
Failure handling Some failures could look like no-op/success Dedicated load error, record-expired handling, retry paths Keep current
Mobile Same general content model as desktop Dedicated mobile shell and card layout Keep current
Batch control Group-wide actions only Explicit selection + selected count Keep current as the safe base
Update detail opening Limited feedback Loading state and duplicate-click protection Keep current
Auto close Page could close itself after a countdown Removed in #1720 after #1715 Do not restore auto-close

The old countdown should not come back. #1720 correctly removed it because users could lose the page before finishing their review.


1. Restore visible site context and make batch scope unambiguous

Background

The older page explicitly separated updates into:

  • updates related to the current site;
  • updates for other sites;
  • ignored updates.

That distinction was especially useful when the batch update page was opened because the user navigated to a site with relevant updates.

Current main still calculates this information:

  • UpdateItem.siteMatch exists;
  • categorize(records, site) sorts matching items to the top.

But the view never renders siteMatch. The result is that the user sees some rows at the top without any explanation of why they are first.

This is more than a visual detail. The page can be opened with ?site=<domain>, so there is real task context behind that ordering.

Current UX problem

A user entering from example.com may see:

  1. several rows related to example.com;
  2. then unrelated updates;
  3. one global "select all" control.

Nothing in the UI explains where the current-site group ends.

This also changes the meaning of "select all": in the old page, batch actions were scoped to a visible group; in current main, select-all selects every pending update, including unrelated sites.

Required improvement

Make the current-site context visible whenever a site parameter exists.

A good implementation could use either grouped sections or an equally clear scoped treatment:

  • For example.com — N updates
  • Other updates — M updates
  • Ignored updates — K updates

The exact visual treatment can follow the current design system; it does not need to copy the old Collapse component.

Batch-selection behavior

When site context exists, batch scope should be explicit.

Preferred behavior:

  • provide a "select all for this site" action or section-level checkbox;
  • keep an intentional way to select all pending updates globally;
  • never make a site-triggered page silently select unrelated updates.

If the team prefers one global table, add a non-color site marker and a scoped selection action so the boundary remains understandable.

Acceptance criteria

  • When ?site=example.com is present, the UI visibly identifies updates that match example.com.
  • The boundary between current-site and other updates is understandable without relying only on ordering.
  • A bulk-selection control makes its scope clear.
  • Keyboard and screen-reader users receive the same site/group context.
  • Without a site parameter, the page remains simple and does not show an empty/current-site section.

2. Make the desktop layout truly usable from the 768 px breakpoint upward

Background

The project has one mobile breakpoint: widths below 768 px use the mobile shell. At 768 px and above, batch update uses the desktop table.

In the current desktop row, fixed columns reserve approximately:

Column Width
Checkbox slot 36 px
Version 170 px
Change 230 px
Source 160 px
Action 180 px
Fixed subtotal 776 px

This subtotal is before the script-name column and before the row/container horizontal padding.

At a 768 px viewport, the desktop content area is already narrower than those fixed columns. The name area therefore has no realistic room, and the row can become cramped or overflow-prone.

This is the same general fixed-column problem that other ScriptCat list pages have already been moving away from.

Required improvement

Keep the single 768 px shell breakpoint, but make the desktop row itself adaptive.

Suggested direction:

  • keep a stable left anchor for selection + script identity;
  • keep the primary action area stable on the right;
  • move lower-priority metadata such as source/risk into a secondary line under the script name when horizontal space is tight;
  • allow metadata to wrap/truncate intentionally;
  • avoid a layout whose fixed columns already exceed the smallest supported desktop width.

Another acceptable design is a denser two-line desktop list row rather than a traditional six-column table.

Do not solve this by

  • adding a second JavaScript mobile breakpoint only for this page;
  • introducing horizontal scrolling as the normal behavior at ordinary tablet/narrow-desktop widths;
  • hiding security-relevant information without another discoverable path.

Acceptance criteria

  • At 768 px wide, the desktop shell does not horizontally overflow.
  • Script names retain useful readable space at narrow desktop widths.
  • Update risk and new-@connect information remains discoverable.
  • Actions remain aligned and reachable.
  • Test at 768, 800, 900, 1024, and 1100 px, in both light and dark themes.
  • Include at least one long-locale fixture, as required by the design guidelines.

3. Fix keyboard focus visibility for custom text actions

Background

The repository design guide explicitly notes that the global base layer removes native outlines. Custom buttons must therefore add a visible focus-visible ring, or reuse a shared primitive that already provides one.

The batch update page contains several custom <button> elements that use text/underline styling but do not visibly add the standard focus ring, for example:

  • clickable script names;
  • Update / Ignore / Restore text actions;
  • row Retry;
  • "View updated scripts";
  • record-expired "Recheck";
  • several mobile text actions.

This can leave keyboard users with no visible indication of where focus is.

Required improvement

Prefer a shared text-action/link-button primitive instead of repeating raw button classes.

At minimum, every custom interactive element must have:

  • keyboard reachability;
  • visible focus-visible styling;
  • adequate contrast;
  • an accessible name.

Acceptance criteria

  • Tabbing through every batch-update action always shows a visible focus indicator.
  • Focus indication works in both themes.
  • Row status changes do not unexpectedly drop keyboard focus to body.
  • No action relies on hover alone to reveal essential information.

4. Increase mobile hit areas for frequently used actions

Background

The project design guide targets roughly 44 px touch areas for primary mobile interactions.

Current mobile batch update uses several controls smaller than that:

  • top-bar refresh/close use size="icon-sm" (32 px in the shared Button primitive);
  • Update / Ignore / Restore are compact text buttons with little or no hit-area padding;
  • some inline recovery actions are similarly compact.

These controls are visually clean, but they are easy to miss on a phone.

Required improvement

Keep the visual density, but enlarge the interactive hit area.

Possible approaches:

  • use a larger Button size for top-bar controls;
  • keep text visually compact while adding vertical/horizontal padding;
  • use a pseudo-element/absolute hit target when the visible control must stay small;
  • preserve enough spacing that adjacent Update / Ignore actions are not easy to mis-tap.

Acceptance criteria

  • Primary mobile actions have approximately 44 px touch targets or equivalent expanded hit areas.
  • Update and Ignore cannot be easily mis-tapped as neighboring controls.
  • Enlarged hit areas do not cause the card layout to jump or become visually heavy.
  • Verify on the narrowest supported mobile width and with long translated labels.

5. Do not dim security-relevant update information when a script is disabled

Background

The current row/card applies opacity-55 to much of the content for a disabled script.

That visual treatment also reduces emphasis on:

  • version change;
  • code-change risk;
  • new @connect warning;
  • source.

A script being disabled is an execution state. It does not make an update's security/review information less important.

The UI already has an explicit Enabled/Disabled badge, so the additional broad opacity reduction is not necessary to communicate status.

Required improvement

De-emphasize only the script's execution status/identity if desired, but keep update-decision information at normal legibility.

In particular:

  • risk badges should keep their normal contrast;
  • new-@connect warnings should keep their normal contrast;
  • versions and source should remain readable;
  • the Disabled badge should be the main status cue.

Acceptance criteria

  • Security/risk metadata has the same legibility for enabled and disabled scripts.
  • Disabled state remains clear without relying on whole-row opacity.
  • Contrast continues to meet the project's WCAG AA target in both themes.

6. Add aggregate risk feedback before a large bulk update

Background

The current row design is much better than the old page at showing risk:

  • code-change severity;
  • new @connect domains;
  • source;
  • version transition.

However, once many scripts are selected, the batch action area only reports the selected count. It does not summarize whether the selection contains high-attention updates.

This matters most when the user uses "select all" and the risky rows are outside the current scroll position.

Required improvement

Before committing a risky batch, surface a compact aggregate risk summary.

For example:

12 selected · 2 major code changes · 1 adds new @connect domains

For ordinary low-risk selections, the current one-click flow can remain.

For a selection containing especially important review signals (at least new @connect; optionally major code changes), add a lightweight confirmation that names the affected scripts and the reason they need attention.

This should not turn every batch update into a modal-heavy flow.

Acceptance criteria

  • The batch toolbar/action bar summarizes important risk within the current selection.
  • New-@connect additions cannot be hidden only inside off-screen rows before a bulk update.
  • Any confirmation is conditional and focused on meaningful risk, not shown for every normal batch.
  • The user can cancel and return to the same selection without losing it.

Interaction/state considerations

Please preserve the current state model while implementing the UI changes:

  • row state remains visible for queued / working / success / failure;
  • failed rows remain retryable;
  • successful rows may exit after the current short confirmation period;
  • batch progress remains deterministic;
  • record-expired recovery remains explicit;
  • checking updates keeps the top progress signal;
  • initial loading keeps layout-preserving skeletons;
  • load failure must never render as "all scripts are up to date";
  • auto-close remains removed.

Suggested information hierarchy

Desktop

  1. Page title + last-check/checking state + Check updates + Close
  2. Optional current-site context summary
  3. Optional record-expired / batch-progress banner
  4. Scoped selection toolbar
  5. Adaptive update list
  6. Ignored updates section

Mobile

  1. Title + concise status + Refresh + Close
  2. Optional current-site context
  3. Optional record-expired / batch-progress banner
  4. Selection summary
  5. Update cards
  6. Ignored section
  7. Bottom batch action bar with selected count + risk summary

Testing / verification

Please add or update tests for the behavior rather than only snapshotting markup.

Suggested coverage:

  • site parameter renders visible current-site context.
  • Current-site and global selection scopes are correct.
  • No site parameter keeps the generic list behavior.
  • Desktop layout has no horizontal overflow at 768 px.
  • Keyboard focus is visible on every custom action.
  • Mobile controls expose adequate hit areas.
  • Disabled scripts do not dim risk/new-@connect metadata.
  • Bulk risk summary updates as selection changes.
  • Risk confirmation appears only when required.
  • Existing batch-progress, retry, skeleton, load-error, record-expired, and no-auto-close tests continue to pass.

Design intent

The main principle is:

Keep the new page's stronger state feedback, but make the user's scope and risk visible before they commit a batch action.

The old UI was clearer about "updates for the site I am on" versus "other updates." The new UI is much better at progress, errors, mobile presentation, and detailed per-row risk. Combining those strengths should make the batch-update flow easier to understand without adding unnecessary visual complexity.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions