fix: StackingPullRequestCard reactivity

This commit is contained in:
ndom91 2024-10-28 16:57:54 +01:00 committed by Nico Domino
parent d8328de56b
commit 50ed7667b7
2 changed files with 34 additions and 31 deletions

View File

@ -210,7 +210,12 @@
<div class="branch-action__line" style:--bg-color={lineColor}></div> <div class="branch-action__line" style:--bg-color={lineColor}></div>
<div class="branch-action__body"> <div class="branch-action__body">
{#if $pr} {#if $pr}
<StackingPullRequestCard upstreamName={currentSeries.name} reloadPR={handleReloadPR} /> <StackingPullRequestCard
upstreamName={currentSeries.name}
reloadPR={handleReloadPR}
pr={$pr}
{checksMonitor}
/>
{:else} {:else}
<Button <Button
style="ghost" style="ghost"

View File

@ -5,7 +5,7 @@
import ContextMenu from '$lib/components/contextmenu/ContextMenu.svelte'; import ContextMenu from '$lib/components/contextmenu/ContextMenu.svelte';
import ContextMenuItem from '$lib/components/contextmenu/ContextMenuItem.svelte'; import ContextMenuItem from '$lib/components/contextmenu/ContextMenuItem.svelte';
import ContextMenuSection from '$lib/components/contextmenu/ContextMenuSection.svelte'; import ContextMenuSection from '$lib/components/contextmenu/ContextMenuSection.svelte';
import { getGitHostChecksMonitor } from '$lib/gitHost/interface/gitHostChecksMonitor'; import { type GitHostChecksMonitor } from '$lib/gitHost/interface/gitHostChecksMonitor';
import { getGitHostListingService } from '$lib/gitHost/interface/gitHostListingService'; import { getGitHostListingService } from '$lib/gitHost/interface/gitHostListingService';
import { getGitHostPrService } from '$lib/gitHost/interface/gitHostPrService'; import { getGitHostPrService } from '$lib/gitHost/interface/gitHostPrService';
import { copyToClipboard } from '$lib/utils/clipboard'; import { copyToClipboard } from '$lib/utils/clipboard';
@ -15,15 +15,18 @@
import { getContext } from '@gitbutler/shared/context'; import { getContext } from '@gitbutler/shared/context';
import Button from '@gitbutler/ui/Button.svelte'; import Button from '@gitbutler/ui/Button.svelte';
import { type ComponentColor } from '@gitbutler/ui/utils/colorTypes'; import { type ComponentColor } from '@gitbutler/ui/utils/colorTypes';
import type { DetailedPullRequest } from '$lib/gitHost/interface/types';
import type { MessageStyle } from '$lib/shared/InfoMessage.svelte'; import type { MessageStyle } from '$lib/shared/InfoMessage.svelte';
import type iconsJson from '@gitbutler/ui/data/icons.json'; import type iconsJson from '@gitbutler/ui/data/icons.json';
interface Props { interface Props {
upstreamName: string; upstreamName: string;
pr: DetailedPullRequest;
checksMonitor?: GitHostChecksMonitor;
reloadPR?: () => void; reloadPR?: () => void;
} }
const { upstreamName, reloadPR }: Props = $props(); const { upstreamName, reloadPR, pr, checksMonitor }: Props = $props();
type StatusInfo = { type StatusInfo = {
text: string; text: string;
@ -49,12 +52,7 @@
const prService = getGitHostPrService(); const prService = getGitHostPrService();
const prMonitor = $derived(prNumber ? $prService?.prMonitor(prNumber) : undefined); const prMonitor = $derived(prNumber ? $prService?.prMonitor(prNumber) : undefined);
// This PR has been loaded on demand, and contains more details than the version const checks = $derived(checksMonitor?.status);
// obtained when listing them.
const pr = $derived(prMonitor?.pr);
const checksMonitor = getGitHostChecksMonitor();
const checks = $derived($checksMonitor?.status);
// While the pr monitor is set to fetch updates by interval, we want // While the pr monitor is set to fetch updates by interval, we want
// frequent updates while checks are running. // frequent updates while checks are running.
@ -67,9 +65,9 @@
let isMerging = $state(false); let isMerging = $state(false);
const mrLoading = $derived(prMonitor?.loading); const mrLoading = $derived(prMonitor?.loading);
const checksLoading = $derived($checksMonitor?.loading); const checksLoading = $derived(checksMonitor?.loading);
const checksError = $derived($checksMonitor?.error); const checksError = $derived(checksMonitor?.error);
const detailsError = $derived(prMonitor?.error); const detailsError = $derived(prMonitor?.error);
const checksTagInfo: StatusInfo = $derived.by(() => { const checksTagInfo: StatusInfo = $derived.by(() => {
@ -100,19 +98,19 @@
}); });
const prStatusInfo: StatusInfo = $derived.by(() => { const prStatusInfo: StatusInfo = $derived.by(() => {
if (!$pr) { if (!pr) {
return { text: 'Status', icon: 'spinner', style: 'neutral' }; return { text: 'Status', icon: 'spinner', style: 'neutral' };
} }
if ($pr?.mergedAt) { if (pr?.mergedAt) {
return { text: 'Merged', icon: 'merged-pr-small', style: 'purple' }; return { text: 'Merged', icon: 'merged-pr-small', style: 'purple' };
} }
if ($pr?.closedAt) { if (pr?.closedAt) {
return { text: 'Closed', icon: 'closed-pr-small', style: 'error' }; return { text: 'Closed', icon: 'closed-pr-small', style: 'error' };
} }
if ($pr?.draft) { if (pr?.draft) {
return { text: 'Draft', icon: 'draft-pr-small', style: 'neutral' }; return { text: 'Draft', icon: 'draft-pr-small', style: 'neutral' };
} }
@ -120,20 +118,20 @@
}); });
</script> </script>
{#if $pr} {#if pr}
<ContextMenu bind:this={contextMenuEl} target={contextMenuTarget} openByMouse> <ContextMenu bind:this={contextMenuEl} target={contextMenuTarget} openByMouse>
<ContextMenuSection> <ContextMenuSection>
<ContextMenuItem <ContextMenuItem
label="Open PR in browser" label="Open PR in browser"
onclick={() => { onclick={() => {
openExternalUrl($pr.htmlUrl); openExternalUrl(pr.htmlUrl);
contextMenuEl?.close(); contextMenuEl?.close();
}} }}
/> />
<ContextMenuItem <ContextMenuItem
label="Copy PR link" label="Copy PR link"
onclick={() => { onclick={() => {
copyToClipboard($pr.htmlUrl); copyToClipboard(pr.htmlUrl);
contextMenuEl?.close(); contextMenuEl?.close();
}} }}
/> />
@ -151,14 +149,14 @@
<ContextMenuItem <ContextMenuItem
label="Open checks" label="Open checks"
onclick={() => { onclick={() => {
openExternalUrl(`${$pr.htmlUrl}/checks`); openExternalUrl(`${pr.htmlUrl}/checks`);
contextMenuEl?.close(); contextMenuEl?.close();
}} }}
/> />
<ContextMenuItem <ContextMenuItem
label="Copy checks" label="Copy checks"
onclick={() => { onclick={() => {
copyToClipboard(`${$pr.htmlUrl}/checks`); copyToClipboard(`${pr.htmlUrl}/checks`);
contextMenuEl?.close(); contextMenuEl?.close();
}} }}
/> />
@ -177,8 +175,8 @@
}} }}
> >
<div class="text-13 text-semibold pr-header-title"> <div class="text-13 text-semibold pr-header-title">
<span style="color: var(--clr-scale-ntrl-50)">PR #{$pr?.number}:</span> <span style="color: var(--clr-scale-ntrl-50)">PR #{pr?.number}:</span>
<span>{$pr?.title}</span> <span>{pr?.title}</span>
</div> </div>
<div class="pr-header-tags"> <div class="pr-header-tags">
<Button <Button
@ -192,7 +190,7 @@
> >
{prStatusInfo.text} {prStatusInfo.text}
</Button> </Button>
{#if !$pr?.closedAt && checksTagInfo} {#if !pr?.closedAt && checksTagInfo}
<Button <Button
size="tag" size="tag"
clickable={false} clickable={false}
@ -203,7 +201,7 @@
{checksTagInfo.text} {checksTagInfo.text}
</Button> </Button>
{/if} {/if}
{#if $pr?.htmlUrl} {#if pr?.htmlUrl}
<Button <Button
icon="open-link" icon="open-link"
size="tag" size="tag"
@ -211,7 +209,7 @@
outline outline
tooltip="Open in browser" tooltip="Open in browser"
onclick={() => { onclick={() => {
openExternalUrl($pr.htmlUrl); openExternalUrl(pr.htmlUrl);
}} }}
> >
View PR View PR
@ -227,23 +225,23 @@
determining "no checks will run for this PR" such that we can show the merge button determining "no checks will run for this PR" such that we can show the merge button
immediately. immediately.
--> -->
{#if $pr} {#if pr}
<div class="pr-header-actions"> <div class="pr-header-actions">
<MergeButton <MergeButton
wide wide
projectId={project.id} projectId={project.id}
disabled={$mrLoading || disabled={$mrLoading ||
$checksLoading || $checksLoading ||
$pr?.draft || pr?.draft ||
!$pr?.mergeable || !pr?.mergeable ||
['dirty', 'unknown', 'blocked', 'behind'].includes($pr?.mergeableState)} ['dirty', 'unknown', 'blocked', 'behind'].includes(pr?.mergeableState)}
loading={isMerging} loading={isMerging}
on:click={async (e) => { on:click={async (e) => {
if (!$pr) return; if (!pr) return;
isMerging = true; isMerging = true;
const method = e.detail.method; const method = e.detail.method;
try { try {
await $prService?.merge(method, $pr.number); await $prService?.merge(method, pr.number);
await baseBranchService.fetchFromRemotes(); await baseBranchService.fetchFromRemotes();
await Promise.all([ await Promise.all([
prMonitor?.refresh(), prMonitor?.refresh(),