Replace git action disables with unavailability toasts

This commit is contained in:
Mohamed Boudra
2026-04-10 20:57:51 +07:00
parent 70985088f6
commit 7a1e12f0c0
4 changed files with 90 additions and 41 deletions
@@ -18,7 +18,7 @@ export interface GitAction {
successLabel: string;
disabled: boolean;
status: ActionStatus;
description?: string;
unavailableMessage?: string;
icon?: ReactElement;
handler: () => void;
}
@@ -82,9 +82,9 @@ export function buildGitActions(input: BuildGitActionsInput): GitActions {
label: "Pull",
pendingLabel: "Pulling...",
successLabel: "Pulled",
disabled: input.runtime.pull.disabled || !canPull(input),
disabled: input.runtime.pull.disabled,
status: input.runtime.pull.status,
description: getPullDescription(input),
unavailableMessage: input.runtime.pull.disabled ? undefined : getPullUnavailableMessage(input),
icon: input.runtime.pull.icon,
handler: input.runtime.pull.handler,
});
@@ -94,9 +94,9 @@ export function buildGitActions(input: BuildGitActionsInput): GitActions {
label: "Push",
pendingLabel: "Pushing...",
successLabel: "Pushed",
disabled: input.runtime.push.disabled || !canPush(input),
disabled: input.runtime.push.disabled,
status: input.runtime.push.status,
description: getPushDescription(input),
unavailableMessage: input.runtime.push.disabled ? undefined : getPushUnavailableMessage(input),
icon: input.runtime.push.icon,
handler: input.runtime.push.handler,
});
@@ -108,9 +108,10 @@ export function buildGitActions(input: BuildGitActionsInput): GitActions {
label: `Merge into ${input.baseRefLabel}`,
pendingLabel: "Merging...",
successLabel: "Merged",
disabled: input.runtime["merge-branch"].disabled || !canMergeBranch(input),
disabled: input.runtime["merge-branch"].disabled,
status: input.runtime["merge-branch"].status,
description: getMergeBranchDescription(input),
unavailableMessage:
input.runtime["merge-branch"].disabled ? undefined : getMergeBranchUnavailableMessage(input),
icon: input.runtime["merge-branch"].icon,
handler: input.runtime["merge-branch"].handler,
});
@@ -120,9 +121,12 @@ export function buildGitActions(input: BuildGitActionsInput): GitActions {
label: `Update from ${input.baseRefLabel}`,
pendingLabel: "Updating...",
successLabel: "Updated",
disabled: input.runtime["merge-from-base"].disabled || !canMergeFromBase(input),
disabled: input.runtime["merge-from-base"].disabled,
status: input.runtime["merge-from-base"].status,
description: getMergeFromBaseDescription(input),
unavailableMessage:
input.runtime["merge-from-base"].disabled
? undefined
: getMergeFromBaseUnavailableMessage(input),
icon: input.runtime["merge-from-base"].icon,
handler: input.runtime["merge-from-base"].handler,
});
@@ -132,9 +136,12 @@ export function buildGitActions(input: BuildGitActionsInput): GitActions {
label: "Archive worktree",
pendingLabel: "Archiving...",
successLabel: "Archived",
disabled: input.runtime["archive-worktree"].disabled || !input.isPaseoOwnedWorktree,
disabled: input.runtime["archive-worktree"].disabled,
status: input.runtime["archive-worktree"].status,
description: input.isPaseoOwnedWorktree ? undefined : "Only for worktrees",
unavailableMessage:
input.runtime["archive-worktree"].disabled || input.isPaseoOwnedWorktree
? undefined
: "Archive isn't available here because this workspace was not created as a Paseo worktree",
icon: input.runtime["archive-worktree"].icon,
handler: input.runtime["archive-worktree"].handler,
});
@@ -189,9 +196,12 @@ function buildPrAction(input: BuildGitActionsInput): GitAction {
label: "View PR",
pendingLabel: "View PR",
successLabel: "View PR",
disabled: input.runtime.pr.disabled || !input.githubFeaturesEnabled,
disabled: input.runtime.pr.disabled,
status: input.runtime.pr.status,
description: input.githubFeaturesEnabled ? undefined : "GitHub unavailable",
unavailableMessage:
input.runtime.pr.disabled || input.githubFeaturesEnabled
? undefined
: "View PR isn't available right now because GitHub isn't connected",
icon: input.runtime.pr.icon,
handler: input.runtime.pr.handler,
};
@@ -202,9 +212,10 @@ function buildPrAction(input: BuildGitActionsInput): GitAction {
label: "Create PR",
pendingLabel: "Creating PR...",
successLabel: "PR Created",
disabled: input.runtime.pr.disabled || !input.githubFeaturesEnabled || input.aheadCount === 0,
disabled: input.runtime.pr.disabled,
status: input.runtime.pr.status,
description: getCreatePrDescription(input),
unavailableMessage:
input.runtime.pr.disabled ? undefined : getCreatePrUnavailableMessage(input),
icon: input.runtime.pr.icon,
handler: input.runtime.pr.handler,
};
@@ -240,64 +251,64 @@ function canMergeFromBase(input: BuildGitActionsInput): boolean {
);
}
function getPullDescription(input: BuildGitActionsInput): string | undefined {
function getPullUnavailableMessage(input: BuildGitActionsInput): string | undefined {
if (!input.hasRemote) {
return "No remote";
return "Pull isn't available here because this branch is not connected to a remote yet";
}
if (input.hasUncommittedChanges) {
return "Clean tree";
return "Pull isn't available while you have local changes so commit or stash them first";
}
if (input.behindOfOrigin === 0) {
return "Nothing to pull";
return "Pull isn't available because this branch is already up to date";
}
return undefined;
}
function getPushDescription(input: BuildGitActionsInput): string | undefined {
function getPushUnavailableMessage(input: BuildGitActionsInput): string | undefined {
if (!input.hasRemote) {
return "No remote";
return "Push isn't available here because this branch is not connected to a remote yet";
}
if (input.behindOfOrigin > 0) {
return "Pull first";
return "Push isn't available yet because there are newer changes to bring in first";
}
if (input.aheadOfOrigin === 0) {
return "Nothing to push";
return "Push isn't available because there is nothing new to send";
}
return undefined;
}
function getCreatePrDescription(input: BuildGitActionsInput): string | undefined {
function getCreatePrUnavailableMessage(input: BuildGitActionsInput): string | undefined {
if (!input.githubFeaturesEnabled) {
return "GitHub unavailable";
return "Create PR isn't available right now because GitHub isn't connected";
}
if (input.aheadCount === 0) {
return "No new commits";
return "Create PR isn't available because this branch doesn't have any new commits yet";
}
return undefined;
}
function getMergeBranchDescription(input: BuildGitActionsInput): string | undefined {
function getMergeBranchUnavailableMessage(input: BuildGitActionsInput): string | undefined {
if (!input.baseRefAvailable) {
return "No base";
return "Merge isn't available because we couldn't determine the base branch";
}
if (input.hasUncommittedChanges) {
return "Clean tree";
return "Merge isn't available while you have local changes so commit or stash them first";
}
if (input.aheadCount === 0) {
return "No new commits";
return "Merge isn't available because this branch doesn't have anything new to merge yet";
}
return undefined;
}
function getMergeFromBaseDescription(input: BuildGitActionsInput): string | undefined {
function getMergeFromBaseUnavailableMessage(input: BuildGitActionsInput): string | undefined {
if (!input.baseRefAvailable) {
return "No base";
return "Update isn't available because we couldn't determine the base branch";
}
if (input.hasUncommittedChanges) {
return "Clean tree";
return "Update isn't available while you have local changes so commit or stash them first";
}
if (input.behindBaseCount === 0) {
return "Up to date";
return `Update isn't available because this branch is already up to date with ${input.baseRefLabel}`;
}
return undefined;
}