mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-15 11:20:36 +08:00
Load issue list in project router
Signed-off-by: Rūdolfs Ošiņš <rudolfs@osins.org>
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user