Repository navigation
fix(frontend): fix stale copy, pause toasts and name History confirms - #1369
Conversation
The header said "Logout" (a noun) where it means "Log out". The Purchasing policies tab opened on a panel headed "Purchasing Settings", and the service overrides dialog pointed at "Settings → Purchasing", a path that no longer exists. The add-override dialog said "Only AWS services are supported today" although Azure and GCP overrides are supported, and the Azure Workload Identity Federation option claimed it uses an RSA certificate assertion, contradicting the secret-free OIDC federated credential the form actually configures. Refs LeanerCloud#728 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…de Undo Toasts kept counting down while the pointer was over them or focus was on their buttons, so a long message or an Undo action could vanish mid-read (WCAG 2.2.1 Timing Adjustable). The countdown now pauses on hover and on focus inside the toast, and resumes with the time that was left (at least one second) when both leave. The override-delete Undo toast goes from 5 s to 10 s so there is time to reach Undo. The 30 s default timeout is unchanged: it was set as an explicit owner choice, so shortening success toasts or making errors sticky is left for the owner to decide. Refs LeanerCloud#728 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Cancel this pending purchase?" and "Retry this failed purchase?" did not say which row they applied to, so in a long table it was easy to confirm the wrong one. The confirm now opens with a summary of the row (provider, service, resource and count, region, account, term, upfront cost and date) above the existing explanation, built by a small helper module so history.ts does not grow further. Adds a Playwright spec for the named confirm and for a toast staying while hovered. Refs LeanerCloud#728 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ig save The planned-purchases timeline captured the configs and the global kill-switch state when it was mounted, so after enabling laddering or saving an account config it kept saying "Ladder planning is disabled" or "No ladder configuration" until a page reload. ladder.ts now calls refreshLadderTimeline() after both, which updates the mounted timeline's inputs and reloads it while keeping the selected provider, account and filters. Refs LeanerCloud#728 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 19 billable files and costs up to $4.75. Or wait 59 minutes for your next included review. View limit details
Comment |
Conflicts: - frontend/src/ladder-timeline.ts: both sides changed the disposeTimeline closure. Combined them: it now clears chart (main, LeanerCloud#1357, so a disposed chart is not reused) and updateTimeline (this branch, LeanerCloud#728, so refreshLadderTimeline is a no-op once the timeline is torn down). Main's disposeLadderTimeline export and hidden-section early return are kept; refreshLadderTimeline simply does nothing when the hidden-section path skipped mounting. - frontend/src/__tests__/ladder-timeline.test.ts: import line now brings in both refreshLadderTimeline and disposeLadderTimeline; kept this branch's refresh test and main's chart-teardown describe block side by side. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e2e Main's LeanerCloud#1331 made the Approval queue the only place to approve or cancel a pending purchase; the History table now shows a 'Review in queue' link instead. The confirm-summary and toast-hover spec still clicked Cancel in #history-list, so it timed out after the merge. It now clicks the queue's Cancel button. findHistoryRow already falls back to the queue's rows, so the confirm still names the purchase. Refs LeanerCloud#728 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): APPROVE Blocking:
|
Main's crosstab-storage-clear.spec.ts (LeanerCloud#317) waited for a button named "Logout", which this branch renames to "Log out". Update it, the jest fixtures in auth.test.ts and mobile-nav.test.ts, and the control names in mobile-header-drawer.spec.ts so no test refers to the old label. Refs LeanerCloud#728 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: - frontend/src/history.ts: utils import. Main (LeanerCloud#1376) added NO_VALUE to the utils import; this branch added the historyConfirmBody import. Kept both. - frontend/src/__tests__/ladder-timeline.test.ts: both sides appended a test at the same spot. Kept this branch's refreshLadderTimeline test (LeanerCloud#728) and main's planned-purchases layout and UTC date filter describe block (LeanerCloud#1387, issue LeanerCloud#753) one after the other. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): REQUEST_CHANGES Blocking:
|
…Retry confirms Main's LeanerCloud#181 guards (LeanerCloud#1329) stopped the Approval queue and History rows from printing the placeholder values of an execution with no recommendations: count 0, "0 commitment(s)", "multiple" provider/service/ region and $0 costs. The Cancel and Retry confirm summary added for LeanerCloud#728 still printed them, so a row reading "No recommendations attached" opened a confirm reading "multiple 0 commitment(s) in multiple ... Upfront: $0". The summary now uses NO_RECOMMENDATIONS_LABEL for such a row and leaves out upfront, service and region, drops a "multiple" region the same way as a "multiple" provider, and only shows a term isRealTerm accepts. Tests: Cancel and Retry on the EMPTY_PENDING fixture shape, plus a real row checked with the real currency formatter ("Upfront: $4,200"). The Cancel describe is renamed to the Approval queue, where Cancel now lives. Refs LeanerCloud#728 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in LeanerCloud#1365, LeanerCloud#1381, LeanerCloud#1378 and LeanerCloud#1389. No conflicts; index.html auto-merged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
On the blocking re-review finding above: fixed in
|
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): APPROVE Blocking:
|
Conflicts resolved: - frontend/src/toast.ts: kept this branch's hover/focus pause (startTimer/pauseTimer/resumeTimer and listeners) and main's LeanerCloud#742 stack layout. After the toast is appended, call layoutToastStack() and startWatching() from main, then startTimer() from this branch; dropped the duplicate appendChild. - frontend/src/__tests__/ladder.test.ts: kept both imports (refreshLadderTimeline from this branch, confirmDialog from main). - frontend/tests-e2e/mobile-header-drawer.spec.ts: combined main's 'navigation' role for Main navigation (LeanerCloud#1371) with this branch's "Log out" button name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): APPROVE Blocking:
|
|
Local verification at
|
|
Marked ready and merged by IAmJSD's agent, at IAmJSD's request (IAmJSD reviewed the before/after screenshots; cristim is traveling), after the independent review and local verification above, all at |
This tracker lists seven small UI problems; this PR fixes five of them. The header said "Logout", the Purchasing policies tab was headed "Purchasing Settings", help text cited a "Settings → Purchasing" path that no longer exists, claimed overrides were AWS-only and described Azure WIF as an RSA certificate login; toasts kept counting down while being read, the Approval-queue Cancel and History Retry confirms didn't name the purchase, and the ladder timeline stayed stale after a kill-switch toggle or config save until reload.
Refs #728
Partial: the full sentence-case sweep, shorter success toasts with sticky errors, and UX-30 (approval links ignoring purchase status) are left out; UX-37 did not reproduce on
a14dc8f2.What changed
One commit per item, so each can be taken or dropped on its own (2dcbcb5, aacd3ae, 674a94e, aa37ff0). Also on the branch: 5 merges of main (1c8489c, ed4b1e6, 4710317, 56a2219, a006d14) and 3 follow-ups (8b68eec clicks Cancel in the Approval queue in the e2e; c85b919 uses "Log out" in tests merged from main; 150979e applies #181's no-commitments guards to the confirm summary):
frontend/src/index.htmlandfrontend/src/settings.ts: "Log out", panel heading "Purchasing policies", overrides help path "Admin → Purchasing policies" (auth.test.ts,mobile-nav.test.ts,tests-e2e/mobile-header-drawer.spec.tsandtests-e2e/crosstab-storage-clear.spec.tsare updated). The add-override help no longer says AWS-only, and the Azure WIF tooltip now describes the OIDC federated credential with no secret or certificate stored.frontend/src/toast.ts: the countdown pauses on hover and on focus inside the toast, and resumes with the time left (at least 1 s) when both leave. Insettings.tsthe override Undo toast goes from 5 s to 10 s.frontend/src/history-confirm-body.ts: builds a summary of the row (provider, service, resource × count, region; account, term, upfront, created date) thathistory.tsputs above the existing text in the Approval-queue Cancel and History Retry confirms. The row is looked up from the already loaded History / Approval-queue data. It follows fix(frontend): impossible/placeholder values surfaced for scheduled and pending purchases #181's row guards (lib/purchase-row-guards.ts): a row with no commitments reads "No recommendations attached" with no upfront, service or region; a "multiple" provider or region is left out; and a term is shown only if it is a real one.frontend/src/ladder-timeline.ts: exportsrefreshLadderTimeline(configs, enabled?), which updates the mounted timeline's inputs and reloads it while keeping provider, account and filters.ladder.tscalls it after a successful kill-switch toggle and after a config save.Why this approach
The 30 s default toast timeout for all kinds was an explicit owner choice in the original toast commit, so only the uncontroversial WCAG 2.2.1 pause on hover/focus is added here, not shorter success toasts or sticky errors. The Cancel and Retry confirms reuse data already on screen instead of fetching details, so Cancel and Retry stay instant and still work when the details fetch is forbidden. The ladder refresh updates the mounted timeline instead of re-mounting it, so selections survive.
Screenshots
Screenshots were taken before this branch was merged with main; before = main at a14dc8f. After is this branch. Both are headless Chromium at 1440x900 against the repo's mocked e2e API.
The named Cancel and Retry confirms, the toast pause (behavior over time) and the ladder refresh (behind the laddering flag) have no screenshots here. The earlier Cancel confirm shot is not shown because it put Cancel in the History list, and main now shows Cancel only in the Approval queue. All three are covered by the e2e and jest tests below.
Verification
Run on this branch's head
a006d14d, on top of mainda896f42, fromfrontend/:ladder-timeline.tsand__tests__/ladder-timeline.test.tsin 1c8489c, and thehistory.tsutils import and__tests__/ladder-timeline.test.tsin 56a2219. The last merge (a006d14) was clean.--randomizeover the toast, ladder, ladder-timeline, history-cancel/retry and settings-accounts tests: 176/176.toast.test.ts(4: hover pause/resume, focus pause across buttons, 1 s minimum on resume, sticky stays sticky); named confirms inhistory-cancel-button.test.tsandhistory-retry-button.test.ts;purchases-placeholders-181.test.ts(4: Cancel and Retry confirms on a no-commitments row show "No recommendations attached" and no placeholders, a real row's confirm shows "Upfront: $4,200" with the real formatter, a "multiple" region is left out);ladder-timeline.test.ts(refresh after config save, then kill switch);ladder.test.tsasserts the refresh on toggle and save; thesettings-accountsUndo TTL assertion is now 10 s.tests-e2e/history-confirm-and-toast.spec.ts(2: named Cancel confirm in the Approval queue; a toast survives 20 s of hover underpage.clockand expires after the pointer leaves). Full suite: 247 passed.Notes for review
a14dc8f2a direct load of/admin/general(and/admin) sets the titleCUDly — Admin · General, checked live against the before build with Playwright.switchSettingsSubTabsets the title infrontend/src/navigation.ts:334before its self-switch return. Since the reviewedb50ca383, the onlydocument.titlechange is fix(frontend): show an error state when init() fails, not a silent Home #1338, which sets an error title wheninit()fails; that is a separate path. The reviewer may have hit a different path (for example a permission-gated admin load); worth a second look.index.html: a large diff over lines many other UI branches edit, and it needs a decision on the style rule.details.statusand show the requester. The issue marks it unverified end to end, so it is better done on its own with a live check.Overlaps
Textual conflicts with the open branches for #742 (
__tests__/ladder.test.ts; it also changessaveLadderConfiginladder.tsnext to the refresh call here) and #730 (the line next to this one intests-e2e/mobile-header-drawer.spec.ts).ladder.tsis 503 lines on this branch (main alone is 501), so it is already past 500 before #742 lands. #753, #739 and #731 are merged; their conflicts are resolved in the merges of main. Other open branches editindex.html(#749, #751),history.ts(#737, #751) andsettings.ts(#751) without touching the same lines. #181 is merged, and the confirm summary here applies its no-commitments guards.Note for the UI owner
This changes UI code that @cristim owns. IAmJSD reviewed the before/after screenshots and asked for it to be merged; any design point you disagree with can be a follow-up.
🤖 Generated with Claude Code