Implement issue and patch filters in second column

This commit is contained in:
Rūdolfs Ošiņš
2025-01-20 15:30:24 -06:00
parent 4571d466db
commit c2f38bb0cb
8 changed files with 279 additions and 69 deletions
+103 -16
View File
@@ -3,11 +3,18 @@
import type { RepoInfo } from "@bindings/repo/RepoInfo";
import type { IssueStatus } from "@app/views/repo/router";
import * as router from "@app/lib/router";
import capitalize from "lodash/capitalize";
import IssueTeaser from "@app/components/IssueTeaser.svelte";
import * as router from "@app/lib/router";
import { issueStatusColor } from "@app/lib/utils";
import Border from "./Border.svelte";
import DropdownList from "./DropdownList.svelte";
import DropdownListItem from "./DropdownListItem.svelte";
import Icon from "./Icon.svelte";
import IssueTeaser from "@app/components/IssueTeaser.svelte";
import OutlineButton from "./OutlineButton.svelte";
import Popover, { closeFocused } from "./Popover.svelte";
const activeRouteStore = router.activeRouteStore;
@@ -17,11 +24,15 @@
issues: Issue[];
status: IssueStatus;
title: string;
changeFilter: (status: IssueStatus) => void;
}
/* eslint-disable prefer-const */
let { repo, selectedIssueId, issues, status, title }: Props = $props();
let { repo, selectedIssueId, issues, status, title, changeFilter }: Props =
$props();
/* eslint-enable prefer-const */
const project = $derived(repo.payloads["xyz.radicle.project"]!);
</script>
<style>
@@ -40,25 +51,79 @@
}
</style>
{#snippet icons(status: IssueStatus)}
<div
class="icon"
style:color={status === "all" ? undefined : issueStatusColor[status]}>
<Icon name={status === "closed" ? "issue-closed" : "issue"} />
</div>
{/snippet}
{#snippet counters(status: IssueStatus)}
<div style:margin-left="auto" style:padding-left="0.25rem">
{#if status === "all"}
{project.meta.issues.open + project.meta.issues.closed}
{:else}
{project.meta.issues[status]}
{/if}
</div>
{/snippet}
<div class="container">
<div class="txt-regular txt-semibold global-flex" style:gap="4px">
<div
class="txt-regular txt-semibold global-flex"
style:gap="4px"
style:white-space="nowrap">
{title}
<Icon name="chevron-right" />
Issues
</div>
<OutlineButton
variant="ghost"
disabled={$activeRouteStore.resource === "repo.createIssue"}
onclick={() => {
void router.push({
resource: "repo.createIssue",
rid: repo.rid,
status,
});
}}>
<Icon name="plus" />New
</OutlineButton>
<div class="global-flex" style:margin-left="1rem">
<Popover popoverPositionRight="0" popoverPositionTop="2.5rem">
{#snippet toggle(onclick)}
<OutlineButton variant="ghost" {onclick}>
{@render icons(status)}
{capitalize(status)}
{@render counters(status)}
<Icon name="chevron-down" />
</OutlineButton>
{/snippet}
{#snippet popover()}
<Border variant="ghost">
<DropdownList items={["all", "open", "closed"] as IssueStatus[]}>
{#snippet item(state)}
<DropdownListItem
style="gap: 0.5rem"
selected={status === state}
onclick={() => {
changeFilter(state);
closeFocused();
}}>
{@render icons(state)}
{capitalize(state)}
{@render counters(state)}
</DropdownListItem>
{/snippet}
</DropdownList>
</Border>
{/snippet}
</Popover>
<OutlineButton
variant="ghost"
disabled={$activeRouteStore.resource === "repo.createIssue"}
onclick={() => {
void router.push({
resource: "repo.createIssue",
rid: repo.rid,
status,
});
}}>
<Icon name="plus" />New
</OutlineButton>
</div>
</div>
<div class="issue-list">
{#each issues as issue}
@@ -69,4 +134,26 @@
rid={repo.rid}
selected={issue.id === selectedIssueId} />
{/each}
{#if issues.length === 0}
<Border
styleMinWidth="25rem"
variant="ghost"
styleAlignItems="center"
styleJustifyContent="center">
<div
class="global-flex"
style:height="74px"
style:justify-content="center">
<div class="txt-missing txt-small global-flex" style:gap="0.25rem">
<Icon name="none" />
{#if status === "all"}
No issues.
{:else}
No {status} issues.
{/if}
</div>
</div>
</Border>
{/if}
</div>
+3 -3
View File
@@ -1,6 +1,5 @@
<script lang="ts">
import type { IssueStatus } from "@app/views/repo/router";
import type { ProjectPayload } from "@bindings/repo/ProjectPayload";
import type { RepoInfo } from "@bindings/repo/RepoInfo";
import Border from "./Border.svelte";
@@ -10,12 +9,13 @@
import Settings from "./Settings.svelte";
interface Props {
project: ProjectPayload;
status: IssueStatus;
repo: RepoInfo;
}
const { project, status, repo }: Props = $props();
const { status, repo }: Props = $props();
const project = $derived(repo.payloads["xyz.radicle.project"]!);
</script>
<style>
+2 -22
View File
@@ -2,8 +2,6 @@
import type { IssueStatus, PatchStatus } from "@app/views/repo/router";
import * as router from "@app/lib/router";
import { patchStatusColor } from "@app/lib/utils";
import { issueStatusColor } from "@app/lib/utils";
import { storeLayout, getLayout } from "@app/views/repo/Layout.svelte";
@@ -61,16 +59,7 @@
styleWidth="40px"
styleHeight="40px"
styleJustifyContent="center">
<div
style:color={activeTab.status === "all"
? undefined
: issueStatusColor[activeTab.status]}>
{#if activeTab.status === "open"}
<Icon name="issue" />
{:else}
<Icon name="issue-closed" />
{/if}
</div>
<Icon name="issue" />
</Border>
{:else}
<button
@@ -100,16 +89,7 @@
styleWidth="40px"
styleHeight="40px"
styleJustifyContent="center">
<div
style:color={activeTab.status
? patchStatusColor[activeTab.status]
: undefined}>
{#if activeTab.status === "open" || activeTab.status === undefined}
<Icon name="patch" />
{:else}
<Icon name={`patch-${activeTab.status}`} />
{/if}
</div>
<Icon name="patch" />
</Border>
{:else}
<button