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

  1. cyfung1031 commented on Sep 27, 2026

    @cyfung1031
    CollaboratorAuthor

    主要是1 問題 "Restore visible site context and make batch scope unambiguous"
    新UI完全沒考慮實際使用的操作
    這個問題必須改善

  2. CodFrm commented on Oct 9, 2026

    @CodFrm
    Member

    第一轮改动在 #1788,各点的处理情况如下:

    1. 站点上下文(本次主要处理的点):已完成。带 ?site= 打开且有命中的脚本时,列表分成「{site} 相关」和「其他更新」两段,每段的组头复选框只切换本段;顶部复选框显式标为「全选」,部分选中时显示半选。没有 site 参数或没有命中时不分段,页面和以前一样。桌面端和移动端都做了。

    2. 768px 起的桌面布局:已完成。没有加新的断点,而是改成两行行布局:表格只保留「脚本 / 变更 / 操作」三列,版本和来源放到脚本名下面一行,长版本截断后悬停可以看全文。768px 下不再重叠,脚本名有可读宽度。移动端触屏没有悬停,版本单独占一行,折行显示完整内容。

    3. 键盘焦点不可见:这一点不成立。src/index.css 的全局规则已经给所有 button:focus-visible / [role="button"]:focus-visible 加了 ring-2 ring-ring/50,用 Tab 切换时这些自定义按钮都有可见的焦点环,所以不改。

    4. 移动端点击区域:已完成。顶栏的刷新 / 关闭从 32px 改为 44px;卡片里的「更新 / 忽略」和所有复选框的点击区域扩到约 44px,用负外边距和伪元素实现,外观和卡片高度不变,相邻两个按钮的点击区域也不重叠。顺带修了一处不一致:移动端批量进行中卡片复选框没有禁用,现在和桌面端一致了。

    5. 禁用脚本不要调暗风险信息:维护者决定保持现状,这次不改。

    6. 批量更新前汇总风险:这次先不做,留作后续。

    另外,风险标签配色也按讨论调整了:重大改动从危险红改为警示橙,显著改动从主色蓝改为中性灰,轻微改动保持绿色。

    这个 issue 先保持打开,第 6 点等后续再处理。

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