History

Revert git action button logic toward main behavior

Julius Marminge committed 8 months ago

Commit ebe44d01 parent dcd2d503 files · +46 −69Browse files

Unified · Split

3 files
  1. apps/web/src/components/GitActionsControl.logic.test.ts +7 −24
  2. apps/web/src/components/GitActionsControl.logic.ts +3 −14
  3. apps/web/src/components/GitActionsControl.tsx +36 −31
apps/web/src/components/GitActionsControl.logic.test.ts+7−24
@@ -250,20 +250,15 @@ describe("when: branch is clean, ahead, and has no open PR", () => { · 249 unmodified lines
250250 });
251251
252252 describe("when: branch is clean, up to date, and has no open PR", () => {
253− it("resolveQuickAction offers create PR", () => {
253+ it("resolveQuickAction returns disabled no-action state", () => {
254254 const quick = resolveQuickAction(
255255 status({ aheadCount: 0, behindCount: 0, hasWorkingTreeChanges: false, pr: null }),
256256 false,
257257 );
258− assert.deepInclude(quick, {
259− kind: "run_action",
260− action: "commit_push_pr",
261− label: "Create PR",
262− disabled: false,
263− });
258+ assert.deepInclude(quick, { kind: "show_hint", label: "Commit", disabled: true });
264259 });
265260
266− it("buildMenuItems enables create PR and keeps commit/push disabled", () => {
261+ it("buildMenuItems disables commit, push, and create PR", () => {
267262 const items = buildMenuItems(status({ aheadCount: 0, behindCount: 0, pr: null }), false);
268263 assert.deepEqual(items, [
269264 {
@@ -285,25 +280,13 @@ describe("when: branch is clean, up to date, and has no open PR", () => { · 15 unmodified lines
285280 {
286281 id: "pr",
287282 label: "Create PR",
288− disabled: false,
283+ disabled: true,
289284 icon: "pr",
290285 kind: "open_dialog",
291286 dialogAction: "create_pr",
292287 },
293288 ]);
294289 });
295−
296− it("buildMenuItems keeps create PR disabled on default branch", () => {
297− const items = buildMenuItems(status({ branch: "main", aheadCount: 0, behindCount: 0 }), false, true);
298− assert.deepEqual(items[2], {
299− id: "pr",
300− label: "Create PR",
301− disabled: true,
302− icon: "pr",
303− kind: "open_dialog",
304− dialogAction: "create_pr",
305− });
306− });
307290 });
308291
309292 describe("when: branch is behind upstream", () => {
@@ -365,7 +348,7 @@ describe("when: working tree has local changes", () => { · 55 unmodified lines
365348 });
366349 });
367350
368− it("resolveQuickAction keeps full commit/push/pr flow on non-default branches even when PR exists", () => {
351+ it("resolveQuickAction returns commit and push when open PR exists", () => {
369352 const quick = resolveQuickAction(
370353 status({
371354 hasWorkingTreeChanges: true,
@@ -382,8 +365,8 @@ describe("when: working tree has local changes", () => { · 10 unmodified lines
382365 );
383366 assert.deepInclude(quick, {
384367 kind: "run_action",
385− action: "commit_push_pr",
386− label: "Commit, push & create PR",
368+ action: "commit_push",
369+ label: "Commit & push",
387370 });
388371 });
389372
apps/web/src/components/GitActionsControl.logic.ts+3−14
@@ -113,7 +113,6 @@ export function summarizeGitResult(result: GitRunStackedActionResult): { · 112 unmodified lines
113113 export function buildMenuItems(
114114 gitStatus: GitStatusResult | null,
115115 isBusy: boolean,
116− isDefaultBranch = false,
117116 ): GitActionMenuItem[] {
118117 if (!gitStatus) return [];
119118
@@ -128,9 +127,8 @@ export function buildMenuItems( · 8 unmodified lines
128127 hasBranch &&
129128 !hasChanges &&
130129 !hasOpenPr &&
131− !isBehind &&
132− !isDefaultBranch &&
133− (gitStatus.aheadCount > 0 || gitStatus.hasUpstream);
130+ gitStatus.aheadCount > 0 &&
131+ !isBehind;
134132 const canOpenPr = !isBusy && hasOpenPr;
135133
136134 return [
@@ -204,7 +202,7 @@ export function resolveQuickAction( · 67 unmodified lines
204202 }
205203
206204 if (hasChanges) {
207− if (isDefaultBranch) {
205+ if (hasOpenPr || isDefaultBranch) {
208206 return { label: "Commit & push", disabled: false, kind: "run_action", action: "commit_push" };
209207 }
210208 return {
@@ -267,15 +265,6 @@ export function resolveQuickAction( · 56 unmodified lines
267265 };
268266 }
269267
270− if (!hasOpenPr && !isDefaultBranch && gitStatus.hasUpstream) {
271− return {
272− label: "Create PR",
273− disabled: false,
274− kind: "run_action",
275− action: "commit_push_pr",
276− };
277− }
278−
279268 if (hasOpenPr && gitStatus.hasUpstream) {
280269 return { label: "Open PR", disabled: false, kind: "open_pr" };
281270 }
apps/web/src/components/GitActionsControl.tsx+36−31
@@ -57,6 +57,8 @@ interface PendingDefaultBranchAction { · 56 unmodified lines
5757 onConfirmed?: () => void;
5858 }
5959
60+type GitActionToastId = ReturnType<typeof toastManager.add>;
61+
6062 function getMenuActionDisabledReason(
6163 item: GitActionMenuItem,
6264 gitStatus: GitStatusResult | null,
@@ -180,19 +182,10 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 117 unmodified lines
180182 const current = branchList?.branches.find((branch) => branch.name === branchName);
181183 return current?.isDefault ?? (branchName === "main" || branchName === "master");
182184 }, [branchList?.branches, gitStatusForActions?.branch]);
183− const isDefaultBranchName = useCallback(
184− (branchName: string | null | undefined) => {
185− if (!branchName) return false;
186− const defaultBranchName = branchList?.branches.find((branch) => branch.isDefault)?.name;
187− if (defaultBranchName) return branchName === defaultBranchName;
188− return branchName === "main" || branchName === "master";
189− },
190− [branchList?.branches],
191− );
192185
193186 const gitActionMenuItems = useMemo(
194− () => buildMenuItems(gitStatusForActions, isGitActionRunning, isDefaultBranch),
195− [gitStatusForActions, isGitActionRunning, isDefaultBranch],
187+ () => buildMenuItems(gitStatusForActions, isGitActionRunning),
188+ [gitStatusForActions, isGitActionRunning],
196189 );
197190 const quickAction = useMemo(
198191 () => resolveQuickAction(gitStatusForActions, isGitActionRunning, isDefaultBranch),
@@ -245,26 +238,28 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 46 unmodified lines
245238 forcePushOnlyProgress = false,
246239 onConfirmed,
247240 skipDefaultBranchPrompt = false,
241+ statusOverride,
248242 featureBranch = false,
249243 isDefaultBranchOverride,
244+ progressToastId,
250245 }: {
251246 action: GitStackedAction;
252247 commitMessage?: string;
253248 forcePushOnlyProgress?: boolean;
254249 onConfirmed?: () => void;
255250 skipDefaultBranchPrompt?: boolean;
251+ statusOverride?: GitStatusResult | null;
256252 featureBranch?: boolean;
257253 isDefaultBranchOverride?: boolean;
254+ progressToastId?: GitActionToastId;
258255 }) => {
259− const actionStatus = gitStatusForActions;
256+ const actionStatus = statusOverride ?? gitStatusForActions;
260257 const actionBranch = actionStatus?.branch ?? null;
261− const actionIsDefaultBranch =
262− isDefaultBranchOverride ?? (featureBranch ? false : isDefaultBranchName(actionBranch));
258+ const actionIsDefaultBranch = isDefaultBranchOverride ?? (featureBranch ? false : isDefaultBranch);
263259 const includesCommit =
264260 !forcePushOnlyProgress && (action === "commit" || !!actionStatus?.hasWorkingTreeChanges);
265261 if (
266262 !skipDefaultBranchPrompt &&
267− !featureBranch &&
268263 requiresDefaultBranchConfirmation(action, actionIsDefaultBranch) &&
269264 actionBranch
270265 ) {
@@ -292,17 +287,28 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 21 unmodified lines
292287 featureBranch,
293288 ...(pushTarget ? { pushTarget } : {}),
294289 });
295− const progressToastId = toastManager.add({
296− type: "loading",
297− title: progressStages[0] ?? "Running git action...",
298− timeout: 0,
299− data: threadToastData,
300− });
290+ const resolvedProgressToastId =
291+ progressToastId ??
292+ toastManager.add({
293+ type: "loading",
294+ title: progressStages[0] ?? "Running git action...",
295+ timeout: 0,
296+ data: threadToastData,
297+ });
298+
299+ if (progressToastId) {
300+ toastManager.update(progressToastId, {
301+ type: "loading",
302+ title: progressStages[0] ?? "Running git action...",
303+ timeout: 0,
304+ data: threadToastData,
305+ });
306+ }
301307
302308 let stageIndex = 0;
303309 const stageInterval = setInterval(() => {
304310 stageIndex = Math.min(stageIndex + 1, progressStages.length - 1);
305− toastManager.update(progressToastId, {
311+ toastManager.update(resolvedProgressToastId, {
306312 title: progressStages[stageIndex] ?? "Running git action...",
307313 type: "loading",
308314 timeout: 0,
@@ -338,10 +344,10 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 29 unmodified lines
338344 result.push.status === "pushed" &&
339345 !actionIsDefaultBranch;
340346 const closeResultToast = () => {
341− toastManager.close(progressToastId);
347+ toastManager.close(resolvedProgressToastId);
342348 };
343349
344− toastManager.update(progressToastId, {
350+ toastManager.update(resolvedProgressToastId, {
345351 type: "success",
346352 title: resultToast.title,
347353 description: resultToast.description,
@@ -359,8 +365,8 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 11 unmodified lines
359365 action: "commit_push",
360366 forcePushOnlyProgress: true,
361367 onConfirmed: closeResultToast,
362− ...(featureBranch ? { skipDefaultBranchPrompt: true } : {}),
363− ...(featureBranch ? { isDefaultBranchOverride: false } : {}),
368+ statusOverride: actionStatus,
369+ isDefaultBranchOverride: actionIsDefaultBranch,
364370 });
365371 },
366372 },
@@ -386,8 +392,8 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 19 unmodified lines
386392 void runGitActionWithToast({
387393 action: "commit_push_pr",
388394 forcePushOnlyProgress: true,
389− ...(featureBranch ? { skipDefaultBranchPrompt: true } : {}),
390− ...(featureBranch ? { isDefaultBranchOverride: false } : {}),
395+ statusOverride: actionStatus,
396+ isDefaultBranchOverride: actionIsDefaultBranch,
391397 });
392398 },
393399 },
@@ -396,7 +402,7 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 2 unmodified lines
396402 });
397403 } catch (err) {
398404 stopProgressUpdates();
399− toastManager.update(progressToastId, {
405+ toastManager.update(resolvedProgressToastId, {
400406 type: "error",
401407 title: "Action failed",
402408 description: err instanceof Error ? err.message : "An error occurred.",
@@ -406,7 +412,7 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 3 unmodified lines
406412 },
407413
408414 [
409− isDefaultBranchName,
415+ isDefaultBranch,
410416 runImmediateGitActionMutation,
411417 setPendingDefaultBranchAction,
412418 threadToastData,
@@ -424,7 +430,6 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions · 11 unmodified lines
424430 forcePushOnlyProgress,
425431 ...(onConfirmed ? { onConfirmed } : {}),
426432 skipDefaultBranchPrompt: true,
427− isDefaultBranchOverride: true,
428433 });
429434 }, [pendingDefaultBranchAction, runGitActionWithToast]);
430435