PullRequestCard: 'View details' button

Add a button to the PR card that shows a Modal with the PR details
This commit is contained in:
estib 2024-09-25 17:19:04 +02:00
parent 4137b31a5c
commit 108533777e
4 changed files with 114 additions and 1 deletions

View File

@ -10,6 +10,7 @@ export function parseGitHubDetailedPullRequest(
id: data.id, id: data.id,
number: data.number, number: data.number,
title: data.title, title: data.title,
body: data.body ?? undefined,
sourceBranch: data.base?.ref, sourceBranch: data.base?.ref,
draft: data.draft, draft: data.draft,
htmlUrl: data.html_url, htmlUrl: data.html_url,

View File

@ -30,6 +30,7 @@ export interface PullRequest {
export interface DetailedPullRequest { export interface DetailedPullRequest {
id: number; id: number;
title: string; title: string;
body: string | undefined;
number: number; number: number;
sourceBranch: string; sourceBranch: string;
draft?: boolean; draft?: boolean;

View File

@ -0,0 +1,75 @@
<script lang="ts">
import Markdown from '$lib/components/Markdown.svelte';
import ScrollableContainer from '$lib/scroll/ScrollableContainer.svelte';
import Button from '@gitbutler/ui/Button.svelte';
import Modal from '@gitbutler/ui/Modal.svelte';
import type { DetailedPullRequest } from '$lib/gitHost/interface/types';
interface Props {
pr: DetailedPullRequest;
}
let { pr }: Props = $props();
let modal = $state<Modal>();
export function show() {
modal?.show();
}
export const imports = {
get open() {
return modal?.imports.open;
}
};
</script>
<Modal bind:this={modal} width="large" noPadding>
{#snippet children(_, close)}
<ScrollableContainer maxHeight="70vh">
<div class="pr-modal__content">
<div class="card">
<div class="card__header text-14 text-body text-semibold pr-modal__header">
{pr.title}
</div>
{#if pr.body}
<div class="card__content text-13 text-body">
<Markdown content={pr.body} />
</div>
{:else}
<div class="card__content text-13 text-body text-clr2">No PR description.</div>
{/if}
</div>
</div>
</ScrollableContainer>
<div class="pr-modal__footer">
<Button style="ghost" outline onclick={close}>Done</Button>
</div>
{/snippet}
</Modal>
<style>
.pr-modal__content {
padding: 16px;
}
.pr-modal__header {
position: sticky;
top: 0;
background: var(--clr-bg-1);
border-top-left-radius: var(--radius-m);
border-top-right-radius: var(--radius-m);
}
.pr-modal__footer {
display: flex;
width: 100%;
justify-content: flex-end;
gap: 8px;
padding: 16px;
border-top: 1px solid var(--clr-border-2);
background-color: var(--clr-bg-1);
border-bottom-left-radius: var(--radius-l);
border-bottom-right-radius: var(--radius-l);
}
</style>

View File

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import MergeButton from './MergeButton.svelte'; import MergeButton from './MergeButton.svelte';
import PrDetailsModal from './PrDetailsModal.svelte';
import ViewPrButton from './ViewPrButton.svelte'; import ViewPrButton from './ViewPrButton.svelte';
import InfoMessage from '../shared/InfoMessage.svelte'; import InfoMessage from '../shared/InfoMessage.svelte';
import { Project } from '$lib/backend/projects'; import { Project } from '$lib/backend/projects';
@ -34,6 +35,8 @@
const baseBranchService = getContext(BaseBranchService); const baseBranchService = getContext(BaseBranchService);
const project = getContext(Project); const project = getContext(Project);
let prDetailsModal = $state<PrDetailsModal>();
const gitHostListingService = getGitHostListingService(); const gitHostListingService = getGitHostListingService();
const prStore = $derived($gitHostListingService?.prs); const prStore = $derived($gitHostListingService?.prs);
const prs = $derived(prStore ? $prStore : undefined); const prs = $derived(prStore ? $prStore : undefined);
@ -192,6 +195,17 @@
<span style="color: var(--clr-scale-ntrl-50)">PR #{$pr?.number}:</span> <span style="color: var(--clr-scale-ntrl-50)">PR #{$pr?.number}:</span>
{$pr.title} {$pr.title}
</div> </div>
<div class="pr-options">
<Button
size="tag"
style="ghost"
outline
icon="eye-shown"
onclick={() => {
prDetailsModal?.show();
}}>View details</Button
>
</div>
<div class="pr-tags"> <div class="pr-tags">
<Button <Button
size="tag" size="tag"
@ -269,6 +283,10 @@
</div> </div>
{/if} {/if}
{#if $pr}
<PrDetailsModal bind:this={prDetailsModal} pr={$pr} />
{/if}
<style lang="postcss"> <style lang="postcss">
.pr-card { .pr-card {
position: relative; position: relative;
@ -284,7 +302,25 @@
cursor: text; cursor: text;
} }
.pr-tags { <<<<<<< ours|||||||ancestor .stacked-pr-title {
color: var(--clr-scale-ntrl-0);
padding: 14px 14px 12px 14px;
user-select: text;
cursor: text;
}
======= .stacked-pr-title {
color: var(--clr-scale-ntrl-0);
padding: 14px 14px 12px 14px;
user-select: text;
cursor: text;
}
.pr-options {
margin-bottom: 12px;
}
>>>>>>>theirs .pr-tags {
display: flex; display: flex;
gap: 4px; gap: 4px;
} }