authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-14 23:55:46-08:00
committergravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-14 23:55:46-08:00
log170c3a7162525df90164e118023e3bc8bb97dda0
treece3a05b1211933b24b9158d1bc3f2653d705f265
parent1fe3cf53a7ea192bc1b440dfeb5c6a3b3a75b12d

Fix push-only progress stages in Git action toasts

- Move `buildGitActionProgressStages` into shared logic for reuse and tests - Add `forcePushOnly` path so push actions show only `Pushing...` - Cover push-only and commit+push stage behavior with new logic tests

3 files changed, 62 insertions(+), 23 deletions(-)

apps/web/src/components/GitActionsControl.logic.test.ts+22
......@@ -1,6 +1,7 @@
11import type { GitStatusResult } from "@t3tools/contracts";
22import { assert, describe, it } from "vitest";
33import {
4 buildGitActionProgressStages,
45 buildMenuItems,
56 requiresDefaultBranchConfirmation,
67 resolveQuickAction,
......@@ -596,6 +597,27 @@ describe("requiresDefaultBranchConfirmation", () => {
596597 });
597598});
598599
600describe("buildGitActionProgressStages", () => {
601 it("shows only push progress when push-only is forced", () => {
602 const stages = buildGitActionProgressStages({
603 action: "commit_push",
604 hasCustomCommitMessage: false,
605 hasWorkingTreeChanges: true,
606 forcePushOnly: true,
607 });
608 assert.deepEqual(stages, ["Pushing..."]);
609 });
610
611 it("includes commit stages for commit+push when working tree is dirty", () => {
612 const stages = buildGitActionProgressStages({
613 action: "commit_push",
614 hasCustomCommitMessage: false,
615 hasWorkingTreeChanges: true,
616 });
617 assert.deepEqual(stages, ["Generating commit message...", "Committing...", "Pushing..."]);
618 });
619});
620
599621describe("summarizeGitResult", () => {
600622 it("returns commit-focused toast for commit action", () => {
601623 const result = summarizeGitResult({
apps/web/src/components/GitActionsControl.logic.ts+22
......@@ -43,6 +43,28 @@ function truncateText(
4343 return `${value.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
4444}
4545
46export function buildGitActionProgressStages(input: {
47 action: GitStackedAction;
48 hasCustomCommitMessage: boolean;
49 hasWorkingTreeChanges: boolean;
50 forcePushOnly?: boolean;
51}): string[] {
52 const shouldIncludeCommitStages =
53 !input.forcePushOnly && (input.action === "commit" || input.hasWorkingTreeChanges);
54 const commitStages = !shouldIncludeCommitStages
55 ? []
56 : input.hasCustomCommitMessage
57 ? ["Committing..."]
58 : ["Generating commit message...", "Committing..."];
59 if (input.action === "commit") {
60 return commitStages;
61 }
62 if (input.action === "commit_push") {
63 return [...commitStages, "Pushing..."];
64 }
65 return [...commitStages, "Pushing...", "Creating PR..."];
66}
67
4668export function summarizeGitResult(result: GitRunStackedActionResult): {
4769 title: string;
4870 description?: string;
apps/web/src/components/GitActionsControl.tsx+18-23
......@@ -4,6 +4,7 @@ import { useCallback, useMemo, useState } from "react";
44import { ChevronDownIcon, CloudUploadIcon, GitCommitIcon, InfoIcon } from "lucide-react";
55import { GitHubIcon } from "./Icons";
66import {
7 buildGitActionProgressStages,
78 buildMenuItems,
89 type GitActionIconName,
910 type GitActionMenuItem,
......@@ -134,26 +135,6 @@ function GitQuickActionIcon({ quickAction }: { quickAction: GitQuickAction }) {
134135 return <InfoIcon className={iconClassName} />;
135136}
136137
137function buildGitActionProgressStages(input: {
138 action: GitStackedAction;
139 hasCustomCommitMessage: boolean;
140 hasWorkingTreeChanges: boolean;
141}): string[] {
142 const shouldIncludeCommitStages = input.action === "commit" || input.hasWorkingTreeChanges;
143 const commitStages = !shouldIncludeCommitStages
144 ? []
145 : input.hasCustomCommitMessage
146 ? ["Committing..."]
147 : ["Generating commit message...", "Committing..."];
148 if (input.action === "commit") {
149 return commitStages;
150 }
151 if (input.action === "commit_push") {
152 return [...commitStages, "Pushing..."];
153 }
154 return [...commitStages, "Pushing...", "Creating PR..."];
155}
156
157138export default function GitActionsControl({ api, gitCwd }: GitActionsControlProps) {
158139 const queryClient = useQueryClient();
159140 const [activeDialogAction, setActiveDialogAction] = useState<GitDialogAction | null>(null);
......@@ -230,7 +211,15 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
230211 }, [api, gitStatus?.openPr?.url]);
231212
232213 const runGitActionWithToast = useCallback(
233 async ({ action, commitMessage }: { action: GitStackedAction; commitMessage?: string }) => {
214 async ({
215 action,
216 commitMessage,
217 forcePushOnlyProgress = false,
218 }: {
219 action: GitStackedAction;
220 commitMessage?: string;
221 forcePushOnlyProgress?: boolean;
222 }) => {
234223 const confirmed = await maybeConfirmPushToDefaultBranch(action);
235224 if (!confirmed) return;
236225
......@@ -238,6 +227,7 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
238227 action,
239228 hasCustomCommitMessage: !!commitMessage?.trim(),
240229 hasWorkingTreeChanges: !!gitStatus?.hasWorkingTreeChanges,
230 forcePushOnly: forcePushOnlyProgress,
241231 });
242232 const progressToastId = toastManager.add({
243233 type: "loading",
......@@ -290,7 +280,10 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
290280 children: "Push",
291281 onClick: () => {
292282 closeResultToast();
293 void runGitActionWithToast({ action: "commit_push" });
283 void runGitActionWithToast({
284 action: "commit_push",
285 forcePushOnlyProgress: true,
286 });
294287 },
295288 },
296289 }
......@@ -381,7 +374,7 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
381374 return;
382375 }
383376 if (item.dialogAction === "push") {
384 void runGitActionWithToast({ action: "commit_push" });
377 void runGitActionWithToast({ action: "commit_push", forcePushOnlyProgress: true });
385378 return;
386379 }
387380 if (item.dialogAction) {
......@@ -400,10 +393,12 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
400393 ? "commit_push"
401394 : "commit_push_pr";
402395 const commitMessage = activeDialogAction === "commit" ? dialogCommitMessage.trim() : "";
396 const forcePushOnlyProgress = activeDialogAction === "push";
403397 setActiveDialogAction(null);
404398 void runGitActionWithToast({
405399 action,
406400 ...(commitMessage ? { commitMessage } : {}),
401 ...(forcePushOnlyProgress ? { forcePushOnlyProgress } : {}),
407402 });
408403 }, [activeDialogAction, dialogCommitMessage, runGitActionWithToast]);
409404