Load patch list in project router

Signed-off-by: Rūdolfs Ošiņš <rudolfs@osins.org>
This commit is contained in:
Rūdolfs Ošiņš
2023-07-25 11:32:28 +02:00
parent 1b6bed73a6
commit fbe133cd95
3 changed files with 61 additions and 47 deletions
+24 -32
View File
@@ -1,14 +1,9 @@
<script lang="ts" context="module">
import type { Patch, PatchState } from "@httpd-client";
export type PatchStatus = PatchState["status"];
</script>
<script lang="ts">
import type { BaseUrl } from "@httpd-client";
import type { BaseUrl, Patch, PatchState } from "@httpd-client";
import capitalize from "lodash/capitalize";
import { HttpdClient } from "@httpd-client";
import { PATCHES_PER_PAGE } from "./router";
import Button from "@app/components/Button.svelte";
import ErrorMessage from "@app/components/ErrorMessage.svelte";
@@ -18,9 +13,10 @@
import Placeholder from "@app/components/Placeholder.svelte";
import SquareButton from "@app/components/SquareButton.svelte";
export let search: string | undefined = undefined;
export let projectId: string;
export let baseUrl: BaseUrl;
export let patches: Patch[];
export let state: PatchState["status"];
export let patchCounters: {
draft: number;
open: number;
@@ -28,28 +24,28 @@
merged: number;
};
$: searchParams = new URLSearchParams(search || "");
$: state = (searchParams.get("state") as PatchStatus) || "open";
const perPage = 10;
let loading = false;
let page = 0;
let error: any;
let patches: Patch[] = [];
let allPatches: Patch[];
$: {
allPatches = patches;
page = 0;
}
const api = new HttpdClient(baseUrl);
async function loadPatches(state: PatchStatus): Promise<void> {
async function loadMore(state: PatchState["status"]): Promise<void> {
loading = true;
page += 1;
try {
const response = await api.project.getAllPatches(projectId, {
state,
page,
perPage,
perPage: PATCHES_PER_PAGE,
});
patches = [...patches, ...response];
page += 1;
allPatches = [...allPatches, ...response];
} catch (e) {
error = e;
} finally {
@@ -58,12 +54,17 @@
}
interface Tab {
value: PatchStatus;
value: PatchState["status"];
title: string;
disabled: boolean;
}
const stateOptions: PatchStatus[] = ["draft", "open", "archived", "merged"];
const stateOptions: PatchState["status"][] = [
"draft",
"open",
"archived",
"merged",
];
const options = stateOptions.map<Tab>(s => ({
value: s,
title: `${patchCounters[s]} ${s}`,
@@ -71,16 +72,7 @@
}));
$: showMoreButton =
!loading &&
!error &&
patchCounters[state] &&
patches.length < patchCounters[state];
$: {
page = 0;
patches = [];
void loadPatches(state);
}
!loading && !error && allPatches.length < patchCounters[state];
</script>
<style>
@@ -139,7 +131,7 @@
</div>
</div>
<div class="patches-list">
{#each patches as patch}
{#each allPatches as patch (patch.id)}
<div class="teaser">
<PatchTeaser {baseUrl} {projectId} {patch} />
</div>
@@ -164,7 +156,7 @@
{/if}
{#if showMoreButton}
<Button variant="foreground" on:click={() => loadPatches(state)}>
<Button variant="foreground" on:click={() => loadMore(state)}>
More
</Button>
{/if}
+2 -1
View File
@@ -107,7 +107,8 @@
{baseUrl}
projectId={id}
patchCounters={project.patches}
search={view.search} />
state={view.state}
patches={view.patches} />
{:else if view.resource === "patch"}
<Patch
patch={view.patch}
+35 -14
View File
@@ -7,6 +7,7 @@ import type {
Diff,
Issue,
Patch,
PatchState,
Project,
Remote,
Tree,
@@ -18,6 +19,7 @@ import { unreachable } from "@app/lib/utils";
import { seedPath } from "@app/views/seeds/router";
export const COMMITS_PER_PAGE = 30;
export const PATCHES_PER_PAGE = 10;
export type ProjectRoute =
| ProjectTreeRoute
@@ -125,7 +127,7 @@ export type ProjectLoadedView =
| { resource: "issue"; issue: Issue }
| { resource: "issues"; state: "open" | "closed" }
| { resource: "newIssue" }
| { resource: "patches"; search: string }
| { resource: "patches"; patches: Patch[]; state: PatchState["status"] }
| PatchView;
interface LoadedSourceBrowsingParams {
@@ -271,19 +273,7 @@ export async function loadProjectRoute(
},
};
} else if (route.resource === "project.patches") {
const project = await api.project.getById(route.project);
return {
resource: "projects",
params: {
id: route.project,
baseUrl: route.seed,
view: {
resource: "patches",
search: route.search || "",
},
project,
},
};
return loadPatchesView(route);
} else {
return unreachable(route);
}
@@ -299,6 +289,37 @@ export async function loadProjectRoute(
}
}
async function loadPatchesView(
route: ProjectPatchesRoute,
): Promise<ProjectLoadedRoute> {
const api = new HttpdClient(route.seed);
const searchParams = new URLSearchParams(route.search || "");
const state = (searchParams.get("state") as PatchState["status"]) || "open";
const [project, patches] = await Promise.all([
api.project.getById(route.project),
api.project.getAllPatches(route.project, {
state,
page: 0,
perPage: PATCHES_PER_PAGE,
}),
]);
return {
resource: "projects",
params: {
id: route.project,
baseUrl: route.seed,
view: {
resource: "patches",
patches,
state,
},
project,
},
};
}
async function loadTreeView(
route: ProjectTreeRoute,
): Promise<ProjectLoadedRoute> {