Skip to content

Keep library empty states centred below timed allowances - #253

Merged
sudoHG merged 2 commits into
mainfrom
sudoHG/251-empty-state-centred
Nov 3, 2026
Merged

sudoHG merged 2 commits into
mainfrom
sudoHG/251-empty-state-centred

Conversation

@sudoHG

@sudoHG sudoHG commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Closes #251

Summary

  • Keep library, empty-group and no-search-results empty states centred within the visible scroll area.
  • Give only the empty-list branch a viewport minimum height; active allowance rows remain above the empty state, which fills the remaining space.
  • Preserve the existing non-empty list layout, allowance actions and localized strings.
  • Keep the one-second allowance projection mounted while there are no grants, so newly approved grants appear without navigation or search changes.
  • Add hidden-window layout coverage and 12 original English / Simplified Chinese PNG renders.

Diff stat

git diff --stat origin/main: 2 files changed, 252 insertions, 11 deletions.

  • CredentialManagementView+List.swift: 39 lines changed.
  • CredentialEmptyLayoutTests.swift: 224 lines added.

Tests

  • swift build: PASS.
  • swift test --filter 'CredentialEmptyLayoutTests|CredentialLibraryPresentationTests|TimedAllowanceRevocationTests': 6 passed, 0 failed, 0 skipped on 017cb48bc213603550cbc907fe3aa5e737ec7552.
  • Compared with main: 3 new layout tests, with 12 bilingual empty-state combinations, 4 next-refresh grant transitions and 2 non-empty-list cases; the 3 existing library-presentation / UUID-revocation tests remain green. The local full suite and a separate full main run were NOT_RUN, as required by the executor workflow.
  • Layout assertions locate the actual rendered empty-state content block and the allowance card, then check the block's centre against the visible space below the card (or the viewport when no grant exists) with 1-point accuracy. The card reference excludes the ticking countdown; no hidden-window accessibility children are needed.
  • Regression checks: restoring the parent allowance condition makes the transition test fail because timed-allowance-list never appears (1 failed test, 2 assertions). Forcing the content to the top while retaining the full viewport height makes all 12 centre assertions fail, proving the test checks placement independently of document height. Both intentional mutations were removed.
  • Temporary hidden-render test: 1 passed, 0 failed, 0 skipped; the combined render / targeted run had 7 passed, 0 failed, 0 skipped. It used the real SettingsView, production management-window factory, hidden windows, isolated preferences and read-only synthetic fixtures. The temporary render test was removed before the final 6-test run. All 12 PNGs were regenerated after review round 1 and retain the same SHA-256 values as the original static renders.
  • Desktop E2E and visible-window testing: NOT_RUN locally; CI is the acceptance gate.

Checks

  • python3 scripts/check_hygiene.py: PASS, all violation counts 0.
  • python3 scripts/check_module_deps.py: PASS.
  • git diff --check: PASS.
  • Rebased onto origin/main (5cf9bc3038981cdc82baec3f6fcc3a64157f7119) before pushing; final head: 017cb48bc213603550cbc907fe3aa5e737ec7552.
  • Visual review: PASS for all 12 PNGs. Empty-library, empty-group and no-search-results content is centred in both languages, with the allowance row above it when present.
  • Secret-gist readback: PASS, all 12 PNGs anonymously downloaded and byte-for-byte identical to the rendered originals.
  • Final-head CI: PASS, all 3 jobs green, run 41558726099, head 017cb48bc213603550cbc907fe3aa5e737ec7552.
  • build-and-test: 1,618 executed; 1,615 passed, 0 failed, 3 skipped. All 3 new layout tests passed on CI. Hygiene, module dependencies, SDK markers, release binary and UI delivery-gate self-checks also passed.
  • The 3 skips are the opt-in installed Codex CLI contract, the isolated crash-subprocess entry and explicit synthetic fixture generation. No new skip or acceptance waiver was introduced.
  • basic-ui-flows: 15 passed, 0 failed, 0 skipped; optional screenshots and evidence upload also completed successfully.
  • release-sdk-window-check: PASS, Debug / Release SDK markers verified and the visible management-window lifecycle test passed with SDK 27.0 (1 passed, 0 failed, 0 skipped).
  • Cleanup: removed the task's .build, temporary render test, PNGs, previews, gist clone and local build/test logs (about 1.1 GiB from the final verification). Final data-volume free space: 231.2 GiB. No build/test or simulator process remains from this task; the pre-existing idle system testmanagerd was left untouched. The clean task branch/worktree is retained for review.
  • No production data, production Keychain service, login Keychain inspection, installed app or local desktop automation was used. No CHANGELOG, README or documentation files changed.

Original PNG SHA-256 values in the secret render gist:

PNG SHA-256
en-group-allowance.png 29bb4dcb7581b9b90743998b7fa758491fda199c3635056499ba4a2f0db57764
en-group-no-allowance.png 347e835c8b91d5667bc35acce7488d0339ef379ab94b8de89310628e3070fdb9
en-library-allowance.png 97c36e8e207f4decb2a43b96ee49d207dc626b9afe6e11cb580530f21285a009
en-library-no-allowance.png 59a17d7ca645e9d6299af7d2ce5b55bdfcc6c77886df2735fd829c2c91e92610
en-search-allowance.png 2ae58ae63ae1c11bc1b9767abff7a0464ccf2b9d8468c09d8dadce6eeda5f0f6
en-search-no-allowance.png 836f162794e4a36c3a19aca808db9d3a91996401b66a9c1da05cf0a45eb22f64
zh-Hans-group-allowance.png f6125e4a6ceaf22a5ad2038059a0f313fac71d248f295d02f990f2d641d6d50e
zh-Hans-group-no-allowance.png 1f336d2067c97af0dcbbcbe1016de613a79a3be4d7649be5cb9201fa1c4533ad
zh-Hans-library-allowance.png 78836f90f8336eb11544091fd5a621323e91e2f68f342be41e82a7a5a0fb9cc3
zh-Hans-library-no-allowance.png 3e48c638f4909e29ae6d873a47742851bceb8940d8594c09e04a7aa594e017a9
zh-Hans-search-allowance.png 80143cca1f1d7277e5705f5a6855ed4bf194b483a3bd3ecd994598147f4367e9
zh-Hans-search-no-allowance.png 881673001acc091c5e144e73e65424a43179e90c9906e5703bd2685667988c1a

Deviations and questions

None. Gist's CLI rejected binary uploads, so the original PNG files were uploaded through the gist's git remote as directed through Orca.

@luoji-bot luoji-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review round 1: request changes (small; independent Opus review of 5c89d32, verified)

Renders and non-empty lists look right. Two P2s:

  1. A new timed allowance does not appear while the list is empty. CredentialManagementView+List.swift ~177 checks !libraryPresentation.allowances.isEmpty in the parent body. activeTimedAllowances() is a Broker read, not observable state, so when an agent's request is approved with a timed allowance while the user views an empty group or a search with no matches, nothing redraws the view and the Timed allowances card and its Revoke button stay hidden. Before this PR the TimelineView was always mounted and showed it within about 1 s. Always mount timedAllowanceList in the empty branch (as the non-empty branch and the inspector do; FrozenTimedAllowanceList draws nothing when empty), and move its bottom padding inside so an empty list adds no height and does not push the empty state off centre.
  2. The test checks height, not centring or the card. CredentialEmptyLayoutTests.swift ~86-87 only asserts the document fills the viewport. Also assert that the empty state's title or icon is vertically centred in the space below the card (or the viewport when no allowance), that timed-allowance-list is present when an allowance exists, and add the transition case: empty list with no allowance, then an allowance is granted without any other view change, and the card appears within the next refresh.

Re-render the two "allowance" variants in English and Chinese after the change and update the gist with git as before.

@wangmiao-bot

wangmiao-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

Review round 1 addressed in 017cb48bc213603550cbc907fe3aa5e737ec7552:

  1. The empty branch always mounts the periodic allowance projection. The empty-card condition and its padding now live inside the timeline callback; non-empty lists retain their original spacing. The transition fixture changes only a non-observable allowance store and verifies that the card appears after the next refresh, for empty groups and no-result searches in both languages. Restoring the old parent condition makes this test fail with a missing timed-allowance-list.
  2. Layout tests now match the actual rendered empty-state block and allowance card, checking the block's vertical centre within 1 point below the card (or within the viewport without a grant). A mutation that keeps document height correct but top-aligns the content fails all 12 centre assertions. The match excludes the ticking countdown and hidden-window edges.

swift build, the final filtered run (6 passed, 0 failed, 0 skipped), hygiene, module dependencies and git diff --check pass. All 12 PNGs were regenerated after the change and verified visually; their original bytes are unchanged, and the secret gist records the updated source SHA. The temporary render test is removed and final-head CI is pending; its outcome will be added to the receipt before completion.

@sudoHG
sudoHG merged commit c789230 into main Nov 3, 2026
3 checks passed
@sudoHG
sudoHG deleted the sudoHG/251-empty-state-centred branch November 3, 2026 01:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Keep the library empty state centred above the timed-allowance list

1 participant