Skip to content

Commit

Permalink
feat: add mergeAll btn
Browse files Browse the repository at this point in the history
  • Loading branch information
ndom91 committed Nov 20, 2024
1 parent 7a90cfa commit 1ecb46b
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 17 deletions.
42 changes: 29 additions & 13 deletions apps/desktop/src/lib/pr/MergeButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,37 @@
import { MergeMethod } from '$lib/forge/interface/types';
import DropDownButton from '$lib/shared/DropDownButton.svelte';
import { persisted, type Persisted } from '@gitbutler/shared/persisted';
import { createEventDispatcher } from 'svelte';
import type { Props as ButtonProps } from '@gitbutler/ui/Button.svelte';
export let projectId: string;
export let loading = false;
export let disabled = false;
export let wide = false;
export let tooltip = '';
interface Props {
projectId: string;
onclick: (method: MergeMethod) => void;
loading?: boolean;
disabled?: boolean;
wide?: boolean;
tooltip?: string;
style?: ButtonProps['style'];
kind?: ButtonProps['kind'];
outline?: boolean;
}
const {
projectId,
onclick,
loading = false,
disabled = false,
wide = false,
tooltip = '',
style = 'ghost',
kind = 'soft',
outline = true
}: Props = $props();
function persistedAction(projectId: string): Persisted<MergeMethod> {
const key = 'projectMergeMethod';
return persisted<MergeMethod>(MergeMethod.Merge, key + projectId);
}
const dispatch = createEventDispatcher<{ click: { method: MergeMethod } }>();
const action = persistedAction(projectId);
let dropDown: ReturnType<typeof DropDownButton> | undefined;
Expand All @@ -30,16 +47,15 @@
</script>

<DropDownButton
style="ghost"
outline
{loading}
bind:this={dropDown}
onclick={() => onclick($action)}
{outline}
{style}
{kind}
{loading}
{wide}
{tooltip}
{disabled}
onclick={() => {
dispatch('click', { method: $action });
}}
>
{labels[$action]}
{#snippet contextMenuSlot()}
Expand Down
3 changes: 1 addition & 2 deletions apps/desktop/src/lib/pr/PullRequestCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,9 @@
disabled={mergability.disabled}
tooltip={mergability.tooltip}
loading={isMerging}
on:click={async (e) => {
onclick={async (method) => {
if (!pr) return;
isMerging = true;
const method = e.detail.method;
try {
await $prService?.merge(method, pr.number);
await baseBranchService.fetchFromRemotes();
Expand Down
61 changes: 59 additions & 2 deletions apps/desktop/src/lib/stack/Stack.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@
import laneNewSvg from '$lib/assets/empty-state/lane-new.svg?raw';
import noChangesSvg from '$lib/assets/empty-state/lane-no-changes.svg?raw';
import { Project } from '$lib/backend/projects';
import { BaseBranchService } from '$lib/baseBranch/baseBranchService';
import Dropzones from '$lib/branch/Dropzones.svelte';
import { getForgeListingService } from '$lib/forge/interface/forgeListingService';
import { getForgePrService } from '$lib/forge/interface/forgePrService';
import { type MergeMethod } from '$lib/forge/interface/types';
import { showError } from '$lib/notifications/toasts';
import MergeButton from '$lib/pr/MergeButton.svelte';
import ScrollableContainer from '$lib/scroll/ScrollableContainer.svelte';
import { SETTINGS, type Settings } from '$lib/settings/userSettings';
import Resizer from '$lib/shared/Resizer.svelte';
import CollapsedLane from '$lib/stack/CollapsedLane.svelte';
import { intersectionObserver } from '$lib/utils/intersectionObserver';
import * as toasts from '$lib/utils/toasts';
import { BranchController } from '$lib/vbranches/branchController';
import { FileIdSelection } from '$lib/vbranches/fileIdSelection';
import { DetailedCommit, VirtualBranch } from '$lib/vbranches/types';
import { VirtualBranchService } from '$lib/vbranches/virtualBranch';
import { getContext, getContextStore, getContextStoreBySymbol } from '@gitbutler/shared/context';
import { persisted } from '@gitbutler/shared/persisted';
import Button from '@gitbutler/ui/Button.svelte';
Expand All @@ -29,20 +36,29 @@
commitBoxOpen
}: { isLaneCollapsed: Writable<boolean>; commitBoxOpen: Writable<boolean> } = $props();
const vbranchService = getContext(VirtualBranchService);
const branchController = getContext(BranchController);
const fileIdSelection = getContext(FileIdSelection);
const branchStore = getContextStore(VirtualBranch);
const baseBranchService = getContext(BaseBranchService);
const project = getContext(Project);
const prService = getForgePrService();
const branch = $derived($branchStore);
const userSettings = getContextStoreBySymbol<Settings>(SETTINGS);
const defaultBranchWidthRem = persisted<number>(24, 'defaulBranchWidth' + project.id);
const laneWidthKey = 'laneWidth_';
let lastPush = $state<Date | undefined>();
let canMergeAll = $derived.by(() => {
console.log('canMergeAll.validSeries', branch.validSeries);
const validSeries = branch.validSeries.filter((s) => !s.archived).length;
const validSeriesWithPrs = branch.validSeries.filter((s) => s.prNumber && !s.archived).length;
return validSeries === validSeriesWithPrs;
});
const laneWidthKey = 'laneWidth_';
let laneWidth: number | undefined = $state();
let rsViewport = $state<HTMLElement>();
const branchHasFiles = $derived(branch.files !== undefined && branch.files.length > 0);
const branchHasNoCommits = $derived(branch.commits !== undefined && branch.commits.length === 0);
Expand All @@ -58,6 +74,7 @@
let scrollEndVisible = $state(true);
let isPushingCommits = $state(false);
let isMergingSeries = $state(false);
const { upstreamPatches, branchPatches, hasConflicts } = $derived.by(() => {
let hasConflicts = false;
Expand Down Expand Up @@ -96,6 +113,30 @@
isPushingCommits = false;
}
}
async function mergeAll(method: MergeMethod) {
isMergingSeries = true;
try {
for (const validBranch of branch.validSeries.reverse()) {
console.log('validBranch', validBranch);
if (validBranch.prNumber && $prService) {
await $prService.merge(method, validBranch.prNumber);
toasts.success(`Merged PR ${validBranch.prNumber}`);
await Promise.all([
$prService?.prMonitor(validBranch.prNumber).refresh(),
$listingService?.refresh(),
vbranchService.refresh(),
baseBranchService.refresh()
]);
}
}
} catch (e) {
console.error(e);
showError('Failed to merge PR', e);
} finally {
isMergingSeries = false;
}
}
</script>

{#if $isLaneCollapsed}
Expand Down Expand Up @@ -161,6 +202,7 @@
<div
class="lane-branches__action"
class:scroll-end-visible={scrollEndVisible}
class:can-merge-all={canMergeAll}
use:intersectionObserver={{
callback: (entry) => {
if (entry?.isIntersecting) {
Expand Down Expand Up @@ -193,6 +235,17 @@
? 'Push All'
: 'Push'}
</Button>
{#if canMergeAll}
<MergeButton
style="neutral"
kind="solid"
wide
projectId={project.id}
tooltip="Merge all possible branches"
loading={isMergingSeries}
onclick={mergeAll}
/>
{/if}
</div>
{/if}
</ScrollableContainer>
Expand Down Expand Up @@ -245,6 +298,10 @@
bottom: 0;
transition: background-color var(--transition-fast);
&:global(.can-merge-all > button:not(:last-child)) {
margin-bottom: 8px;
}
&:after {
content: '';
display: block;
Expand Down

0 comments on commit 1ecb46b

Please sign in to comment.