feat: make log recalculation task cancellable - #5800
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughRecalculation jobs can now be cancelled from the logs workspace. The UI handles cancellation requests, cancelled terminal states, cancellation-specific toasts, polling stop, and post-completion refreshes. ChangesRecalculation Cancellation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant ActionsMenu
participant logsHeaderView
participant LogsAPI
ActionsMenu->>logsHeaderView: Request cancellation
logsHeaderView->>LogsAPI: Cancel recalculation job
LogsAPI-->>logsHeaderView: Return cancellation status
logsHeaderView->>ActionsMenu: Update toast and action state
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
a2fa02c to
ce013ad
Compare
8682338 to
ffe386f
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
ui/app/workspace/logs/views/logsHeaderView.tsx (1)
237-246: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider
data-testidon the new cancellation controls.Neither the toast's
Cancelaction (Line 237-245) nor the actions-menuCommandItemthat now doubles as a cancel control (Line 350-362) has adata-testid. Theaction: { label, onClick }shorthand does not accept adata-testidprop, but sonner supports passing JSX as theactionvalue instead, which would allow adding one. Adding stable test ids to these new interactive elements would let E2E tests target the cancellation flow directly.As per path instructions, "Preserve existing UI conventions and data-testid attributes used by Playwright tests," and as per coding guidelines, "Add `data-testid` attributes to new interactive elements and preserve existing values because E2E tests depend on them."♻️ Example for the toast action (JSX form)
- action: { - label: "Cancel", - // preventDefault keeps the toast mounted so it can report the cancellation; - // sonner otherwise dismisses a toast as soon as its action fires. - onClick: (event) => { - event.preventDefault(); - void handleCancelRecalculate(); - }, - }, + action: ( + <button + data-testid="logs-recalc-cancel-btn" + onClick={(event) => { + event.preventDefault(); + void handleCancelRecalculate(); + }} + > + Cancel + </button> + ),Also applies to: 350-362
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ui/app/workspace/logs/views/logsHeaderView.tsx` around lines 237 - 246, Add stable data-testid attributes to both new cancellation controls: the Sonner action in the toast configuration and the actions-menu CommandItem cancel control. Convert the toast action from the label/onClick shorthand to JSX so its rendered element can receive a test id, while preserving the existing cancellation behavior and UI labels.Sources: Coding guidelines, Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ui/app/workspace/logs/views/logsHeaderView.tsx`:
- Around line 170-180: Guard the recalculation status/progress effect that
consumes recalcJobStatus so it returns immediately when recalcJobStatusError is
present, preventing stale non-terminal data from replacing the error toast.
Include recalcJobStatusError in that effect’s dependency list, while preserving
normal progress and terminal-status handling when the latest poll succeeds.
- Around line 151-168: Update the catch block in handleCancelRecalculate to use
RECALC_TOAST_ID for the cancellation failure toast instead of the separate
hardcoded ID, so it replaces the existing “Cancelling…” toast rather than
creating a second toast.
In `@ui/lib/store/apis/logsApi.ts`:
- Around line 434-443: The backend routing for cost recalculation must expose
POST /api/logs/recalculate-cost/cancel to match cancelRecalculateCostJob.
Register a cancel handler alongside the existing recalculation start and status
routes, reading the optional id from the query string and forwarding it to the
cancellation logic; alternatively, update both backend and
cancelRecalculateCostJob to use a request body consistently.
---
Nitpick comments:
In `@ui/app/workspace/logs/views/logsHeaderView.tsx`:
- Around line 237-246: Add stable data-testid attributes to both new
cancellation controls: the Sonner action in the toast configuration and the
actions-menu CommandItem cancel control. Convert the toast action from the
label/onClick shorthand to JSX so its rendered element can receive a test id,
while preserving the existing cancellation behavior and UI labels.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 90b7f5b2-1db7-431a-836d-c4d617399241
📒 Files selected for processing (3)
ui/app/workspace/logs/views/logsHeaderView.tsxui/lib/store/apis/logsApi.tsui/lib/types/logs.ts
ce013ad to
8c14bfc
Compare
ffe386f to
143f6db
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ui/lib/store/apis/logsApi.ts`:
- Around line 434-443: Update the cancelRecalculateCostJob mutation definition
to add invalidatesTags: ["Logs"], ensuring all Logs-tagged queries refresh after
cancellation while preserving its existing request configuration.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 19d6c5f0-4a52-4efd-abaf-8e015cce5576
📒 Files selected for processing (3)
ui/app/workspace/logs/views/logsHeaderView.tsxui/lib/store/apis/logsApi.tsui/lib/types/logs.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- ui/lib/types/logs.ts
- ui/app/workspace/logs/views/logsHeaderView.tsx
143f6db to
f9fad16
Compare
8c14bfc to
f873ca9
Compare
f9fad16 to
5fe32e9
Compare
5fe32e9 to
ac36c68
Compare
f873ca9 to
0ec20b4
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
766ae59 to
bb0a87f
Compare
ba27848 to
bc50835
Compare
bb0a87f to
717a66d
Compare
Merge activity
|
bc50835 to
d7b75a6
Compare
717a66d to
ad74fed
Compare
ad74fed to
d30dfd4
Compare
d7b75a6 to
c1ffea5
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
d30dfd4 to
cf49fc5
Compare
c1ffea5 to
e27c8a7
Compare
The base branch was changed.
## Summary Adds the ability to cancel a running cost recalculation job from the logs header. Previously, once a recalculation was started it could not be stopped from the UI. This PR wires up a new `POST /logs/recalculate-cost/cancel` API endpoint, adds a `cancelled` terminal status to the job lifecycle, and updates the progress toast and "More actions" menu to expose a cancel control. ## Changes - Added `cancelRecalculateCostJob` mutation to `logsApi` targeting `POST /logs/recalculate-cost/cancel`, which resolves with the job's post-cancel status. - Added `"cancelled"` as a terminal `RecalcJobStatus` status alongside `completed` and `failed`, with counters reflecting work committed before stopping. - Introduced `isTerminalRecalcStatus` helper and a shared `RECALC_TOAST_ID` constant to consolidate all recalculation lifecycle toast updates onto a single toast. - Added `recalcCancelRequested` state to track the window between the cancel request being sent and the job settling, preventing duplicate cancel clicks and avoiding progress toast overwrites during that window. - The in-progress toast now includes a **Cancel** action button; `event.preventDefault()` keeps the toast mounted so it can report the cancellation result rather than dismissing immediately. - The "More actions" menu item transforms into a **Cancel recalculation** control while a job is running, providing a fallback cancel path if the toast was dismissed. It is disabled (not hidden) while cancellation is in flight. - On a `cancelled` terminal status, an informational (non-error) toast reports the partial result, and logs/stats are refreshed since the job may have committed partial cost updates. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test 1. Navigate to the Logs view and open **More actions**. 2. Click **Recalculate costs** to start a recalculation over a large log window. 3. While the progress toast is visible, click the **Cancel** button on the toast. Verify: - The toast switches to "Cancelling cost recalculation…" with a description about finishing the current batch. - The "More actions" menu item shows "Cancelling…" and is disabled. - Once the job settles, an info toast appears reporting the partial result (rows updated/skipped before stopping). - The logs and stats views refresh. 4. Repeat and cancel via the **More actions** menu item instead of the toast button. 5. Dismiss the progress toast mid-run, then open **More actions** and verify **Cancel recalculation** is still available and functional. 6. Verify that a completed or failed job still reports correctly and is unaffected by this change. ```sh cd ui pnpm i || npm i pnpm build || npm run build ``` ## Breaking changes - [ ] Yes - [x] No ## Security considerations No new auth surfaces. The cancel endpoint follows the same authentication pattern as the existing recalculate-cost endpoints. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
## Summary Adds the ability to cancel a running cost recalculation job from the logs header. Previously, once a recalculation was started it could not be stopped from the UI. This PR wires up a new `POST /logs/recalculate-cost/cancel` API endpoint, adds a `cancelled` terminal status to the job lifecycle, and updates the progress toast and "More actions" menu to expose a cancel control. ## Changes - Added `cancelRecalculateCostJob` mutation to `logsApi` targeting `POST /logs/recalculate-cost/cancel`, which resolves with the job's post-cancel status. - Added `"cancelled"` as a terminal `RecalcJobStatus` status alongside `completed` and `failed`, with counters reflecting work committed before stopping. - Introduced `isTerminalRecalcStatus` helper and a shared `RECALC_TOAST_ID` constant to consolidate all recalculation lifecycle toast updates onto a single toast. - Added `recalcCancelRequested` state to track the window between the cancel request being sent and the job settling, preventing duplicate cancel clicks and avoiding progress toast overwrites during that window. - The in-progress toast now includes a **Cancel** action button; `event.preventDefault()` keeps the toast mounted so it can report the cancellation result rather than dismissing immediately. - The "More actions" menu item transforms into a **Cancel recalculation** control while a job is running, providing a fallback cancel path if the toast was dismissed. It is disabled (not hidden) while cancellation is in flight. - On a `cancelled` terminal status, an informational (non-error) toast reports the partial result, and logs/stats are refreshed since the job may have committed partial cost updates. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test 1. Navigate to the Logs view and open **More actions**. 2. Click **Recalculate costs** to start a recalculation over a large log window. 3. While the progress toast is visible, click the **Cancel** button on the toast. Verify: - The toast switches to "Cancelling cost recalculation…" with a description about finishing the current batch. - The "More actions" menu item shows "Cancelling…" and is disabled. - Once the job settles, an info toast appears reporting the partial result (rows updated/skipped before stopping). - The logs and stats views refresh. 4. Repeat and cancel via the **More actions** menu item instead of the toast button. 5. Dismiss the progress toast mid-run, then open **More actions** and verify **Cancel recalculation** is still available and functional. 6. Verify that a completed or failed job still reports correctly and is unaffected by this change. ```sh cd ui pnpm i || npm i pnpm build || npm run build ``` ## Breaking changes - [ ] Yes - [x] No ## Security considerations No new auth surfaces. The cancel endpoint follows the same authentication pattern as the existing recalculate-cost endpoints. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
## Summary Adds the ability to cancel a running cost recalculation job from the logs header. Previously, once a recalculation was started it could not be stopped from the UI. This PR wires up a new `POST /logs/recalculate-cost/cancel` API endpoint, adds a `cancelled` terminal status to the job lifecycle, and updates the progress toast and "More actions" menu to expose a cancel control. ## Changes - Added `cancelRecalculateCostJob` mutation to `logsApi` targeting `POST /logs/recalculate-cost/cancel`, which resolves with the job's post-cancel status. - Added `"cancelled"` as a terminal `RecalcJobStatus` status alongside `completed` and `failed`, with counters reflecting work committed before stopping. - Introduced `isTerminalRecalcStatus` helper and a shared `RECALC_TOAST_ID` constant to consolidate all recalculation lifecycle toast updates onto a single toast. - Added `recalcCancelRequested` state to track the window between the cancel request being sent and the job settling, preventing duplicate cancel clicks and avoiding progress toast overwrites during that window. - The in-progress toast now includes a **Cancel** action button; `event.preventDefault()` keeps the toast mounted so it can report the cancellation result rather than dismissing immediately. - The "More actions" menu item transforms into a **Cancel recalculation** control while a job is running, providing a fallback cancel path if the toast was dismissed. It is disabled (not hidden) while cancellation is in flight. - On a `cancelled` terminal status, an informational (non-error) toast reports the partial result, and logs/stats are refreshed since the job may have committed partial cost updates. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test 1. Navigate to the Logs view and open **More actions**. 2. Click **Recalculate costs** to start a recalculation over a large log window. 3. While the progress toast is visible, click the **Cancel** button on the toast. Verify: - The toast switches to "Cancelling cost recalculation…" with a description about finishing the current batch. - The "More actions" menu item shows "Cancelling…" and is disabled. - Once the job settles, an info toast appears reporting the partial result (rows updated/skipped before stopping). - The logs and stats views refresh. 4. Repeat and cancel via the **More actions** menu item instead of the toast button. 5. Dismiss the progress toast mid-run, then open **More actions** and verify **Cancel recalculation** is still available and functional. 6. Verify that a completed or failed job still reports correctly and is unaffected by this change. ```sh cd ui pnpm i || npm i pnpm build || npm run build ``` ## Breaking changes - [ ] Yes - [x] No ## Security considerations No new auth surfaces. The cancel endpoint follows the same authentication pattern as the existing recalculate-cost endpoints. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
## Summary Adds the ability to cancel a running cost recalculation job from the logs header. Previously, once a recalculation was started it could not be stopped from the UI. This PR wires up a new `POST /logs/recalculate-cost/cancel` API endpoint, adds a `cancelled` terminal status to the job lifecycle, and updates the progress toast and "More actions" menu to expose a cancel control. ## Changes - Added `cancelRecalculateCostJob` mutation to `logsApi` targeting `POST /logs/recalculate-cost/cancel`, which resolves with the job's post-cancel status. - Added `"cancelled"` as a terminal `RecalcJobStatus` status alongside `completed` and `failed`, with counters reflecting work committed before stopping. - Introduced `isTerminalRecalcStatus` helper and a shared `RECALC_TOAST_ID` constant to consolidate all recalculation lifecycle toast updates onto a single toast. - Added `recalcCancelRequested` state to track the window between the cancel request being sent and the job settling, preventing duplicate cancel clicks and avoiding progress toast overwrites during that window. - The in-progress toast now includes a **Cancel** action button; `event.preventDefault()` keeps the toast mounted so it can report the cancellation result rather than dismissing immediately. - The "More actions" menu item transforms into a **Cancel recalculation** control while a job is running, providing a fallback cancel path if the toast was dismissed. It is disabled (not hidden) while cancellation is in flight. - On a `cancelled` terminal status, an informational (non-error) toast reports the partial result, and logs/stats are refreshed since the job may have committed partial cost updates. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test 1. Navigate to the Logs view and open **More actions**. 2. Click **Recalculate costs** to start a recalculation over a large log window. 3. While the progress toast is visible, click the **Cancel** button on the toast. Verify: - The toast switches to "Cancelling cost recalculation…" with a description about finishing the current batch. - The "More actions" menu item shows "Cancelling…" and is disabled. - Once the job settles, an info toast appears reporting the partial result (rows updated/skipped before stopping). - The logs and stats views refresh. 4. Repeat and cancel via the **More actions** menu item instead of the toast button. 5. Dismiss the progress toast mid-run, then open **More actions** and verify **Cancel recalculation** is still available and functional. 6. Verify that a completed or failed job still reports correctly and is unaffected by this change. ```sh cd ui pnpm i || npm i pnpm build || npm run build ``` ## Breaking changes - [ ] Yes - [x] No ## Security considerations No new auth surfaces. The cancel endpoint follows the same authentication pattern as the existing recalculate-cost endpoints. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable

Summary
Adds the ability to cancel a running cost recalculation job from the logs header. Previously, once a recalculation was started it could not be stopped from the UI. This PR wires up a new
POST /logs/recalculate-cost/cancelAPI endpoint, adds acancelledterminal status to the job lifecycle, and updates the progress toast and "More actions" menu to expose a cancel control.Changes
cancelRecalculateCostJobmutation tologsApitargetingPOST /logs/recalculate-cost/cancel, which resolves with the job's post-cancel status."cancelled"as a terminalRecalcJobStatusstatus alongsidecompletedandfailed, with counters reflecting work committed before stopping.isTerminalRecalcStatushelper and a sharedRECALC_TOAST_IDconstant to consolidate all recalculation lifecycle toast updates onto a single toast.recalcCancelRequestedstate to track the window between the cancel request being sent and the job settling, preventing duplicate cancel clicks and avoiding progress toast overwrites during that window.event.preventDefault()keeps the toast mounted so it can report the cancellation result rather than dismissing immediately.cancelledterminal status, an informational (non-error) toast reports the partial result, and logs/stats are refreshed since the job may have committed partial cost updates.Type of change
Affected areas
How to test
Breaking changes
Security considerations
No new auth surfaces. The cancel endpoint follows the same authentication pattern as the existing recalculate-cost endpoints.
Checklist
docs/contributing/README.mdand followed the guidelines