🚀 feat: add state management for PR service and update createPullRequest method

This commit is contained in:
Mattias Granlund 2023-11-29 22:07:00 +01:00
parent 915426ea4e
commit 46909a3a25
2 changed files with 62 additions and 30 deletions

View File

@ -9,9 +9,14 @@ import {
} from '$lib/github/types';
import { newClient } from '$lib/github/client';
export type PrAction = 'creating_pr';
export type PrServiceState = { busy: boolean; branchId: string; action?: PrAction };
export class PrService {
prs$: Observable<PullRequest[]>;
error$ = new BehaviorSubject<string | undefined>(undefined);
private stateMap = new Map<string, BehaviorSubject<PrServiceState>>();
private reload$ = new BehaviorSubject<{ skipCache: boolean } | undefined>(undefined);
private fresh$ = new Subject<void>();
@ -27,6 +32,7 @@ export class PrService {
}),
shareReplay(1),
catchError((err) => {
console.log(err);
this.error$.next(err);
return of([]);
})
@ -42,6 +48,53 @@ export class PrService {
if (!branch) return;
return this.prs$.pipe(map((prs) => prs.find((pr) => pr.targetBranch == branch)));
}
/* TODO: Figure out a way to cleanup old behavior subjects */
getState(branchId: string) {
let state$ = this.stateMap.get(branchId);
if (!state$) {
state$ = new BehaviorSubject<PrServiceState>({ busy: false, branchId });
this.stateMap.set(branchId, state$);
}
return state$;
}
private setBusy(action: PrAction, branchId: string) {
const state$ = this.getState(branchId);
state$.next({ busy: true, action, branchId });
}
private setIdle(branchId: string) {
const state$ = this.getState(branchId);
state$.next({ busy: false, branchId });
}
async createPullRequest(
ctx: GitHubIntegrationContext,
head: string,
base: string,
title: string,
body: string,
branchId: string
): Promise<PullRequest | undefined> {
const octokit = newClient(ctx);
this.setBusy('creating_pr', branchId);
try {
const rsp = await octokit.rest.pulls.create({
owner: ctx.owner,
repo: ctx.repo,
head,
base,
title,
body
});
return ghResponseToInstance(rsp.data);
} catch (e) {
console.log(e);
} finally {
this.setIdle(branchId);
}
}
}
function loadPrs(ctx: GitHubIntegrationContext, skipCache: boolean): Observable<PullRequest[]> {
@ -90,26 +143,3 @@ export async function getPullRequestByBranch(
console.log(e);
}
}
export async function createPullRequest(
ctx: GitHubIntegrationContext,
head: string,
base: string,
title: string,
body: string
): Promise<PullRequest | undefined> {
const octokit = newClient(ctx);
try {
const rsp = await octokit.rest.pulls.create({
owner: ctx.owner,
repo: ctx.repo,
head,
base,
title,
body
});
return ghResponseToInstance(rsp.data);
} catch (e) {
console.log(e);
}
}

View File

@ -16,7 +16,7 @@
import { open } from '@tauri-apps/api/shell';
import toast from 'svelte-french-toast';
import { sleep } from '$lib/utils/sleep';
import { createPullRequest, type PrService } from '$lib/github/pullrequest';
import type { PrService } from '$lib/github/pullrequest';
export let branch: Branch;
export let githubContext: GitHubIntegrationContext | undefined;
@ -48,6 +48,7 @@
}
});
$: pr$ = prService.get(branchName);
$: prServiceState$ = prService.getState(branch.id);
async function push(opts?: { createPr: boolean }) {
isPushing = true;
@ -69,17 +70,20 @@
async function createPr(): Promise<void> {
if (githubContext && base?.branchName && branchName) {
const pr = await createPullRequest(
const pr = await prService.createPullRequest(
githubContext,
branchName,
base.branchName.split('/').slice(-1)[0],
branch.name,
branch.notes
branch.notes,
branch.id
);
if (pr) {
await prService.reload();
}
return;
} else {
console.log('Unable to create pull request');
}
}
@ -152,7 +156,7 @@
{#if githubContext && !$pr$ && type == 'local'}
<PushButton
wide
isLoading={isPushing}
isLoading={isPushing || $prServiceState$?.busy}
{projectId}
{githubContext}
on:trigger={async (e) => {
@ -168,8 +172,7 @@
wide
kind="outlined"
color="primary"
id="push-commits"
loading={isPushing}
loading={isPushing || $prServiceState$?.busy}
on:click={async () => {
try {
await push({ createPr: true });
@ -184,7 +187,6 @@
<Button
kind="outlined"
color="primary"
id="push-commits"
loading={isPushing}
on:click={async () => {
try {