Skip to content

Commit c8587b6

Browse files
Merge pull request #6175 from gitbutlerapp/Branch-statuses
Branch-statuses
2 parents 23a5961 + 54733ea commit c8587b6

File tree

5 files changed

+67
-50
lines changed

5 files changed

+67
-50
lines changed

apps/web/src/lib/components/branches/BranchIndexCard.svelte

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import CommitsGraph from '../review/CommitsGraph.svelte';
44
import { BranchService } from '@gitbutler/shared/branches/branchService';
55
import { getBranchReview } from '@gitbutler/shared/branches/branchesPreview.svelte';
6-
import { BranchStatus, getContributorsWithAvatars } from '@gitbutler/shared/branches/types';
6+
import { getContributorsWithAvatars } from '@gitbutler/shared/branches/types';
77
import { getContext } from '@gitbutler/shared/context';
88
import Loading from '@gitbutler/shared/network/Loading.svelte';
99
import { isFound } from '@gitbutler/shared/network/loadable';
@@ -12,7 +12,6 @@
1212
WebRoutesService,
1313
type ProjectParameters
1414
} from '@gitbutler/shared/routing/webRoutes.svelte';
15-
import Badge from '@gitbutler/ui/Badge.svelte';
1615
import AvatarGroup from '@gitbutler/ui/avatar/AvatarGroup.svelte';
1716
import dayjs from 'dayjs';
1817
import relativeTime from 'dayjs/plugin/relativeTime';
@@ -39,18 +38,6 @@
3938
);
4039
</script>
4140

42-
{#snippet status(status: BranchStatus)}
43-
{#if status === BranchStatus.Active}
44-
<Badge>Active</Badge>
45-
{:else if status === BranchStatus.Inactive}
46-
<Badge>Inactive</Badge>
47-
{:else if status === BranchStatus.Closed}
48-
<Badge>Closed</Badge>
49-
{:else if status === BranchStatus.Loading}
50-
<Badge>Processing</Badge>
51-
{/if}
52-
{/snippet}
53-
5441
<Loading loadable={branch.current}>
5542
{#snippet children(branch)}
5643
<tr class:rounded-top={roundedTop} class:rounded-bottom={roundedBottom} class="row">
@@ -64,11 +51,6 @@
6451
</td>
6552
<td><div class="uuid">{branch.branchId.slice(0, 7)}</div></td>
6653
<td><div><CommitsGraph {branch} /></div></td>
67-
<td>
68-
<div>
69-
{@render status(branch.status || BranchStatus.Active)}
70-
</div>
71-
</td>
7254
<td><div class="norm">{dayjs(branch.updatedAt).fromNow()}</div></td>
7355
<td>
7456
<div>
Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
<script lang="ts">
2+
import { BranchStatus, type Branch, type Patch } from '@gitbutler/shared/branches/types';
23
import CommitStatusBadge from '@gitbutler/ui/CommitStatusBadge.svelte';
3-
import type { Branch, Patch } from '@gitbutler/shared/branches/types';
44
55
type Props = {
66
branch: Branch;
77
};
88
99
const { branch }: Props = $props();
1010
11-
const patches = branch.patches;
11+
const patches = $derived(branch.patches);
1212
13-
let anyRejected = patches.some((patch: Patch) => patch.reviewAll.rejected.length > 0);
14-
let someApproved = patches.some((patch: Patch) => patch.reviewAll.signedOff.length > 0);
15-
let allApproved = !patches.some((patch: Patch) => patch.reviewAll.signedOff.length === 0);
13+
const anyRejected = $derived(patches.some((patch: Patch) => patch.reviewAll.rejected.length > 0));
14+
const someApproved = $derived(
15+
patches.some((patch: Patch) => patch.reviewAll.signedOff.length > 0)
16+
);
17+
const allApproved = $derived(
18+
!patches.some((patch: Patch) => patch.reviewAll.signedOff.length === 0)
19+
);
1620
17-
function getStatus() {
18-
if (anyRejected) {
21+
const status = $derived.by(() => {
22+
if (branch.status === BranchStatus.Closed) {
23+
return 'closed';
24+
} else if (branch.status === BranchStatus.Loading) {
25+
return 'loading';
26+
} else if (anyRejected) {
1927
return 'changes-requested';
2028
} else if (allApproved) {
2129
return 'approved';
@@ -24,7 +32,7 @@
2432
} else {
2533
return 'unreviewed';
2634
}
27-
}
35+
});
2836
</script>
2937

30-
<CommitStatusBadge status={getStatus()} />
38+
<CommitStatusBadge {status} />

apps/web/src/routes/[ownerSlug]/[projectSlug]/reviews/+page.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
<th><div>Name</div></th>
4141
<th><div>UUID</div></th>
4242
<th><div>Branch commits</div></th>
43-
<th><div>Status</div></th>
4443
<th><div>Last update</div></th>
4544
<th><div>Authors</div></th>
4645
<th><div>Version</div></th>

apps/web/src/routes/[ownerSlug]/[projectSlug]/reviews/[branchId]/+page.svelte

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
import { getBranchReview } from '@gitbutler/shared/branches/branchesPreview.svelte';
88
import { lookupLatestBranchUuid } from '@gitbutler/shared/branches/latestBranchLookup.svelte';
99
import { LatestBranchLookupService } from '@gitbutler/shared/branches/latestBranchLookupService';
10-
import { getContributorsWithAvatars, type Branch } from '@gitbutler/shared/branches/types';
10+
import {
11+
BranchStatus,
12+
getContributorsWithAvatars,
13+
type Branch
14+
} from '@gitbutler/shared/branches/types';
1115
import { copyToClipboard } from '@gitbutler/shared/clipboard';
1216
import { getContext } from '@gitbutler/shared/context';
1317
import Loading from '@gitbutler/shared/network/Loading.svelte';
@@ -17,6 +21,7 @@
1721
WebRoutesService,
1822
type ProjectReviewParameters
1923
} from '@gitbutler/shared/routing/webRoutes.svelte';
24+
import AsyncButton from '@gitbutler/ui/AsyncButton.svelte';
2025
import Button from '@gitbutler/ui/Button.svelte';
2126
import Textarea from '@gitbutler/ui/Textarea.svelte';
2227
import AvatarGroup from '@gitbutler/ui/avatar/AvatarGroup.svelte';
@@ -85,24 +90,28 @@
8590
editingSummary = false;
8691
}
8792
88-
let savingSummary = $state<'inert' | 'loading' | 'complete'>('inert');
89-
9093
async function saveSummary() {
9194
if (!isFound(branch?.current)) return;
9295
93-
savingSummary = 'loading';
94-
9596
try {
9697
await branchService.updateBranch(branch.current.value.uuid, {
9798
description: summary
9899
});
99-
toasts.success('Saved review summary');
100+
toasts.success('Updated review status');
100101
} finally {
101102
editingSummary = false;
102-
savingSummary = 'complete';
103103
}
104104
}
105105
106+
async function updateStatus(status: BranchStatus.Active | BranchStatus.Closed) {
107+
if (!isFound(branch?.current)) return;
108+
109+
await branchService.updateBranch(branch.current.value.uuid, {
110+
status
111+
});
112+
toasts.success('Saved review summary');
113+
}
114+
106115
function copyLocation() {
107116
copyToClipboard(location.href);
108117
}
@@ -128,11 +137,19 @@
128137
<div class="heading">
129138
<p class="text-15 text-bold">{branch.title}</p>
130139
<div class="actions">
131-
<!-- {#if !branch.description}
132-
<Button icon="plus-small" kind="outline" onclick={editSummary}>Add summary</Button>
133-
{/if} -->
134140
<Button icon="text-link" kind="outline" onclick={copyLocation}>Branch link</Button>
135141
{@render startReview(branch)}
142+
{#if branch.status === BranchStatus.Closed}
143+
<AsyncButton action={async () => updateStatus(BranchStatus.Active)} kind="outline"
144+
>Re-open review</AsyncButton
145+
>
146+
{:else}
147+
<AsyncButton
148+
style="error"
149+
kind="outline"
150+
action={async () => updateStatus(BranchStatus.Closed)}>Close review</AsyncButton
151+
>
152+
{/if}
136153
</div>
137154
</div>
138155
<div class="stats">
@@ -156,14 +173,8 @@
156173
{#if editingSummary}
157174
<Textarea minRows={6} bind:value={summary}></Textarea>
158175
<div class="summary-actions">
159-
<Button
160-
kind="outline"
161-
onclick={abortEditingSummary}
162-
loading={savingSummary === 'loading'}>Cancel</Button
163-
>
164-
<Button style="pop" onclick={saveSummary} loading={savingSummary === 'loading'}
165-
>Save</Button
166-
>
176+
<Button kind="outline" onclick={abortEditingSummary}>Cancel</Button>
177+
<AsyncButton style="pop" action={saveSummary}>Save</AsyncButton>
167178
</div>
168179
{:else if branch.description}
169180
<Markdown content={branch.description} />

packages/ui/src/lib/CommitStatusBadge.svelte

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
import Icon from '$lib/Icon.svelte';
33
44
type Props = {
5-
status: 'unreviewed' | 'in-discussion' | 'approved' | 'changes-requested';
5+
status:
6+
| 'unreviewed'
7+
| 'in-discussion'
8+
| 'approved'
9+
| 'changes-requested'
10+
| 'closed'
11+
| 'loading';
612
kind?: 'icon' | 'text';
713
};
814
@@ -25,6 +31,8 @@
2531
class="status-badge"
2632
class:status-badge_icon={kind === 'icon'}
2733
class:status-badge_approved={status === 'approved'}
34+
class:status-badge_closed={status === 'closed'}
35+
class:status-badge_loading={status === 'loading'}
2836
class:status-badge_changes-requested={status === 'changes-requested'}
2937
class:status-badge_in-discussion={status === 'in-discussion'}
3038
class:status-badge_unreviewed={status === 'unreviewed'}
@@ -33,7 +41,11 @@
3341
<Icon name={getIconName()} />
3442
{:else}
3543
<span class="text-10 text-bold status-badge__text">
36-
{#if status === 'changes-requested'}
44+
{#if status === 'closed'}
45+
Closed
46+
{:else if status === 'loading'}
47+
Processing
48+
{:else if status === 'changes-requested'}
3749
Changes requested
3850
{:else if status === 'approved'}
3951
Approved
@@ -57,6 +69,10 @@
5769
text-wrap: nowrap;
5870
padding: 0 4px;
5971
}
72+
.status-badge_closed {
73+
background-color: var(--clr-theme-purp-element);
74+
color: var(--clr-core-ntrl-100);
75+
}
6076
6177
.status-badge_approved {
6278
background-color: var(--clr-br-commit-approved-bg);
@@ -73,7 +89,8 @@
7389
color: var(--clr-br-commit-in-discussion-text);
7490
}
7591
76-
.status-badge_unreviewed {
92+
.status-badge_unreviewed,
93+
.status-badge_loading {
7794
background-color: var(--clr-br-commit-unreviewed-bg);
7895
color: var(--clr-br-commit-unreviewed-text);
7996
}

0 commit comments

Comments
 (0)