Load issue 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:33:52 +02:00
parent fbe133cd95
commit 251d97cdde
3 changed files with 62 additions and 50 deletions
+18 -29
View File
@@ -1,17 +1,11 @@
<script lang="ts" context="module">
import type { IssueState } from "@httpd-client";
export type IssueStatus = IssueState["status"];
</script>
<script lang="ts">
import type { Issue } from "@httpd-client";
import type { BaseUrl } from "@httpd-client";
import type { BaseUrl, Issue, IssueState } from "@httpd-client";
import * as utils from "@app/lib/utils";
import capitalize from "lodash/capitalize";
import { HttpdClient } from "@httpd-client";
import { httpdStore } from "@app/lib/httpd";
import { ISSUES_PER_PAGE } from "./router";
import Button from "@app/components/Button.svelte";
import ErrorMessage from "@app/components/ErrorMessage.svelte";
@@ -23,28 +17,32 @@
export let projectId: string;
export let baseUrl: BaseUrl;
export let issues: Issue[];
export let state: IssueState["status"];
export let issueCounters: { open: number; closed: number };
export let state: "open" | "closed";
const perPage = 10;
let loading = false;
let page = 0;
let error: any;
let issues: Issue[] = [];
let allIssues: Issue[];
$: {
allIssues = issues;
page = 0;
}
const api = new HttpdClient(baseUrl);
async function loadIssues(state: IssueStatus): Promise<void> {
async function loadIssues(state: IssueState["status"]): Promise<void> {
loading = true;
page += 1;
try {
const response = await api.project.getAllIssues(projectId, {
state,
page,
perPage,
perPage: ISSUES_PER_PAGE,
});
issues = [...issues, ...response];
page += 1;
allIssues = [...allIssues, ...response];
} catch (e) {
error = e;
} finally {
@@ -53,12 +51,12 @@
}
interface Tab {
value: IssueStatus;
value: IssueState["status"];
title: string;
disabled: boolean;
}
const stateOptions: IssueStatus[] = ["open", "closed"];
const stateOptions: IssueState["status"][] = ["open", "closed"];
const options = stateOptions.map<Tab>(s => ({
value: s,
title: `${issueCounters[s]} ${s}`,
@@ -66,16 +64,7 @@
}));
$: showMoreButton =
!loading &&
!error &&
issueCounters[state] &&
issues.length < issueCounters[state];
$: {
page = 0;
issues = [];
void loadIssues(state);
}
!loading && !error && allIssues.length < issueCounters[state];
</script>
<style>
@@ -152,7 +141,7 @@
{/if}
</div>
<div class="issues-list">
{#each issues as issue}
{#each allIssues as issue (issue.id)}
<div class="teaser">
<IssueTeaser {projectId} {baseUrl} {issue} />
</div>
+2 -1
View File
@@ -93,7 +93,8 @@
{baseUrl}
projectId={id}
issueCounters={project.issues}
state={view.state} />
state={view.state}
issues={view.issues} />
{:else if view.resource === "newIssue"}
<NewIssue projectId={id} projectHead={project.head} {baseUrl} />
{:else if view.resource === "issue"}
+42 -20
View File
@@ -6,6 +6,7 @@ import type {
CommitHeader,
Diff,
Issue,
IssueState,
Patch,
PatchState,
Project,
@@ -20,6 +21,7 @@ import { seedPath } from "@app/views/seeds/router";
export const COMMITS_PER_PAGE = 30;
export const PATCHES_PER_PAGE = 10;
export const ISSUES_PER_PAGE = 10;
export type ProjectRoute =
| ProjectTreeRoute
@@ -30,12 +32,7 @@ export type ProjectRoute =
project: string;
commit: string;
}
| {
resource: "project.issues";
seed: BaseUrl;
project: string;
state?: "open" | "closed";
}
| ProjectIssuesRoute
| { resource: "project.newIssue"; seed: BaseUrl; project: string }
| {
resource: "project.issue";
@@ -46,6 +43,13 @@ export type ProjectRoute =
| ProjectPatchesRoute
| ProjectPatchRoute;
interface ProjectIssuesRoute {
resource: "project.issues";
seed: BaseUrl;
project: string;
state?: "open" | "closed";
}
interface ProjectTreeRoute {
resource: "project.tree";
seed: BaseUrl;
@@ -125,7 +129,7 @@ export type ProjectLoadedView =
commit: Commit;
}
| { resource: "issue"; issue: Issue }
| { resource: "issues"; state: "open" | "closed" }
| { resource: "issues"; issues: Issue[]; state: IssueState["status"] }
| { resource: "newIssue" }
| { resource: "patches"; patches: Patch[]; state: PatchState["status"] }
| PatchView;
@@ -246,19 +250,7 @@ export async function loadProjectRoute(
} else if (route.resource === "project.patch") {
return loadPatchView(route);
} else if (route.resource === "project.issues") {
const project = await api.project.getById(route.project);
return {
resource: "projects",
params: {
id: route.project,
baseUrl: route.seed,
view: {
resource: "issues",
state: route.state || "open",
},
project,
},
};
return loadIssuesView(route);
} else if (route.resource === "project.newIssue") {
const project = await api.project.getById(route.project);
return {
@@ -320,6 +312,36 @@ async function loadPatchesView(
};
}
async function loadIssuesView(
route: ProjectIssuesRoute,
): Promise<ProjectLoadedRoute> {
const api = new HttpdClient(route.seed);
const state = route.state || "open";
const [project, issues] = await Promise.all([
api.project.getById(route.project),
api.project.getAllIssues(route.project, {
state,
page: 0,
perPage: ISSUES_PER_PAGE,
}),
]);
return {
resource: "projects",
params: {
id: route.project,
baseUrl: route.seed,
view: {
resource: "issues",
issues,
state,
},
project,
},
};
}
async function loadTreeView(
route: ProjectTreeRoute,
): Promise<ProjectLoadedRoute> {