Skip to content

fix(home): run quick actions inline with optimistic task insert#2601

Open
k11kirky wants to merge 2 commits into
mainfrom
posthog-code/home-quick-action-inline
Open

fix(home): run quick actions inline with optimistic task insert#2601
k11kirky wants to merge 2 commits into
mainfrom
posthog-code/home-quick-action-inline

Conversation

@k11kirky

@k11kirky k11kirky commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Problem

On the Home tab, clicking a quick action ("Fix CI", "Address comments", "Create PR", "Review with agent") navigated away — to the pending route and then the task-detail view — and gave no in-flight feedback on the button. The desired behaviour is to kick off the cloud task in place, show it immediately in the workstream's task list, and disable the button while it starts.

Changes

  • Stay on Home. useRunWorkstreamAction no longer navigates to the pending or task-detail routes. It starts the cloud task, optimistically splices the new run into the workstream's task list (insertOptimisticTask), disables the trigger with a spinner while in flight (isPending threaded through useWorkstreamPresentation to the row / card / detail-panel buttons and overflow items), and fires a server snapshot refresh so the next poll reconciles. The offline / signed-out fallback still routes to the new-task screen.
  • Quick-action tags. The action label flows end-to-end (TaskCreationInput.homeQuickActionLabel → saga → api-client home_quick_action body) so the server records which quick action started a run. The snapshot's HomeWorkstreamTask gains quickAction, rendered as a per-task chip in the detail panel and a glanceable "✨ Fix CI, …" indicator on the workstream row. The optimistic row is tagged immediately too.

Server half (grouping + home_quick_action persistence + quickAction in the snapshot) is in PostHog/posthog.

How did you test this?

  • vitest run src/features/home — 36 passing, including new optimisticTask coverage (splice into the right workstream, no cross-workstream bleed, no duplicates, quick-action tagging).
  • tsc --noEmit clean across @posthog/ui, @posthog/core, @posthog/shared, @posthog/api-client.
  • biome check clean on all touched files.

I did test the app manually.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 68799a0.

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
packages/ui/src/features/home/hooks/useRunWorkstreamAction.ts:75-107
**Per-instance `inFlightRef` doesn't guard across simultaneous row + detail panel mounts**

`HomeWorkstreamRow` (via `useWorkstreamPresentation`) and `HomeWorkstreamDetailPanel` both mount their own `useRunWorkstreamAction()` instance, each with an independent `inFlightRef` and `isPending` state. When the detail panel is open alongside the row, clicking the quick action in the row sets only the row's `inFlightRef.current = true` and `isPending = true`; the detail panel's guard is still `false`. A user can then immediately click the panel's action button and start a second task for the same workstream.

Before this PR, navigation away unmounted both surfaces, so races were impossible. The new stay-on-Home design keeps both mounted, making this a real double-submit path. Sharing state through a context or lifting `inFlightRef` to a workstream-keyed store (e.g. a `Map<workstreamId, boolean>` ref at a common ancestor) would close the gap.

### Issue 2 of 3
packages/ui/src/features/home/hooks/useRunWorkstreamAction.ts:197-199
`refreshHome` is the entire `useMutation` result object, which gets a new reference whenever mutation state transitions (idle → pending → settled). Including it in the `useCallback` dep array means `run` is recreated on every transition, which defeats memoisation and propagates new references through every `useWorkstreamPresentation` caller. `mutateAsync` is a stable reference in react-query v5 and is the correct dep here.

```suggestion
      queryClient,
      refreshHome.mutateAsync,
      getUserIntegrationIdForRepo,
```

### Issue 3 of 3
packages/ui/src/features/home/utils/optimisticTask.test.ts:40-71
**Prefer parameterised tests for `workstreamTaskFromTask`**

The four `workstreamTaskFromTask` cases are each a distinct input-to-output mapping and are a natural fit for `it.each`. Per the project's convention, parameterised tests are preferred; this block could be expressed as a single `it.each` table covering id, title, status, and quickAction across the four variants.

Reviews (1): Last reviewed commit: "fix(home): run quick actions inline with..." | Re-trigger Greptile

Comment thread packages/ui/src/features/home/hooks/useRunWorkstreamAction.ts Outdated
Comment thread packages/ui/src/features/home/hooks/useRunWorkstreamAction.ts
Comment thread packages/ui/src/features/home/utils/optimisticTask.test.ts
k11kirky added a commit that referenced this pull request Jun 11, 2026
Addresses Greptile review on PR #2601.

- Move the quick-action in-flight guard from a per-hook ref/state into a shared,
  workstream-keyed Zustand store. The list/board row and the open detail panel
  mount independent useRunWorkstreamAction hooks, so the previous per-instance
  guard let both start a task for the same workstream. The store keys by
  workstream id, so the same workstream can't double-submit while distinct
  workstreams still run concurrently.
- Depend on refreshHome.mutateAsync (stable in react-query v5) instead of the
  whole mutation object, so run isn't recreated on every mutation transition.
- Parameterise the workstreamTaskFromTask tests with it.each per repo convention.

Generated-By: PostHog Code
Task-Id: 8dc7acb2-b80c-402c-be8c-5a82ea04a68f
k11kirky added a commit that referenced this pull request Jun 18, 2026
Addresses Greptile review on PR #2601.

- Move the quick-action in-flight guard from a per-hook ref/state into a shared,
  workstream-keyed Zustand store. The list/board row and the open detail panel
  mount independent useRunWorkstreamAction hooks, so the previous per-instance
  guard let both start a task for the same workstream. The store keys by
  workstream id, so the same workstream can't double-submit while distinct
  workstreams still run concurrently.
- Depend on refreshHome.mutateAsync (stable in react-query v5) instead of the
  whole mutation object, so run isn't recreated on every mutation transition.
- Parameterise the workstreamTaskFromTask tests with it.each per repo convention.

Generated-By: PostHog Code
Task-Id: 8dc7acb2-b80c-402c-be8c-5a82ea04a68f
@k11kirky k11kirky force-pushed the posthog-code/home-quick-action-inline branch from f51118a to 7489bab Compare June 18, 2026 13:42
k11kirky added 2 commits June 20, 2026 06:50
Quick actions on a workstream row/card/detail panel no longer navigate away.
The action starts the cloud task in place, optimistically splices the new run
into the workstream's task list (tagged with the action label), disables the
trigger with a spinner while in flight, and nudges a server snapshot refresh
so the next poll reconciles.

Threads the quick-action label end-to-end (TaskCreationInput -> saga ->
api-client body -> home_quick_action) and renders it: a per-task chip in the
detail panel and a glanceable indicator on the row showing which quick
actions have run against the workstream.

Generated-By: PostHog Code
Task-Id: 8dc7acb2-b80c-402c-be8c-5a82ea04a68f
Addresses Greptile review on PR #2601.

- Move the quick-action in-flight guard from a per-hook ref/state into a shared,
  workstream-keyed Zustand store. The list/board row and the open detail panel
  mount independent useRunWorkstreamAction hooks, so the previous per-instance
  guard let both start a task for the same workstream. The store keys by
  workstream id, so the same workstream can't double-submit while distinct
  workstreams still run concurrently.
- Depend on refreshHome.mutateAsync (stable in react-query v5) instead of the
  whole mutation object, so run isn't recreated on every mutation transition.
- Parameterise the workstreamTaskFromTask tests with it.each per repo convention.

Generated-By: PostHog Code
Task-Id: 8dc7acb2-b80c-402c-be8c-5a82ea04a68f
@k11kirky k11kirky force-pushed the posthog-code/home-quick-action-inline branch from 7489bab to 68799a0 Compare June 20, 2026 05:50
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.

1 participant