From c2f38bb0cbb117a3c602c4ea14ae7546fb840cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C5=ABdolfs=20O=C5=A1i=C5=86=C5=A1?= Date: Mon, 20 Jan 2025 15:30:24 -0600 Subject: [PATCH] Implement issue and patch filters in second column --- src/components/IssueSecondColumn.svelte | 119 ++++++++++++++++--- src/components/IssuesSecondColumn.svelte | 6 +- src/components/Sidebar.svelte | 24 +--- src/views/repo/CreateIssue.svelte | 30 ++++- src/views/repo/Issue.svelte | 23 +++- src/views/repo/Issues.svelte | 6 +- src/views/repo/Layout.svelte | 2 +- src/views/repo/Patch.svelte | 138 ++++++++++++++++++++--- 8 files changed, 279 insertions(+), 69 deletions(-) diff --git a/src/components/IssueSecondColumn.svelte b/src/components/IssueSecondColumn.svelte index 3d18ae163..9be10863b 100644 --- a/src/components/IssueSecondColumn.svelte +++ b/src/components/IssueSecondColumn.svelte @@ -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"]!); +{#snippet icons(status: IssueStatus)} +
+ +
+{/snippet} + +{#snippet counters(status: IssueStatus)} +
+ {#if status === "all"} + {project.meta.issues.open + project.meta.issues.closed} + {:else} + {project.meta.issues[status]} + {/if} +
+{/snippet} +
-
+
{title} Issues
- { - void router.push({ - resource: "repo.createIssue", - rid: repo.rid, - status, - }); - }}> - New - +
+ + {#snippet toggle(onclick)} + + {@render icons(status)} + {capitalize(status)} + {@render counters(status)} + + + {/snippet} + + {#snippet popover()} + + + {#snippet item(state)} + { + changeFilter(state); + closeFocused(); + }}> + {@render icons(state)} + {capitalize(state)} + {@render counters(state)} + + {/snippet} + + + {/snippet} + + + { + void router.push({ + resource: "repo.createIssue", + rid: repo.rid, + status, + }); + }}> + New + +
{#each issues as issue} @@ -69,4 +134,26 @@ rid={repo.rid} selected={issue.id === selectedIssueId} /> {/each} + + {#if issues.length === 0} + +
+
+ + {#if status === "all"} + No issues. + {:else} + No {status} issues. + {/if} +
+
+
+ {/if}
diff --git a/src/components/IssuesSecondColumn.svelte b/src/components/IssuesSecondColumn.svelte index b316d85fe..5b9072aaa 100644 --- a/src/components/IssuesSecondColumn.svelte +++ b/src/components/IssuesSecondColumn.svelte @@ -1,6 +1,5 @@ - +{#snippet icons(status: PatchStatus | undefined)} +
+ +
+{/snippet} + +{#snippet counters(status: PatchStatus | undefined)} +
+ {#if status} + {project.meta.patches[status]} + {:else} + {project.meta.patches.draft + + project.meta.patches.open + + project.meta.patches.archived + + project.meta.patches.merged} + {/if} +
+{/snippet} + + {#snippet headerCenter()} {/snippet} @@ -303,22 +345,84 @@ {#snippet secondColumn()}
- {project.data.name} - - Patches + style:min-height="40px" + style:justify-content="space-between"> +
+ {project.data.name} + + Patches +
+ + + {#snippet toggle(onclick)} + + {@render icons(status)} + {status ? capitalize(status) : "All"} + {@render counters(status)} + + + {/snippet} + + {#snippet popover()} + + + {#snippet item(state)} + { + await loadPatches(state); + closeFocused(); + }}> + {@render icons(state)} + {state ? capitalize(state) : "All"} + {@render counters(state)} + + {/snippet} + + + {/snippet} +
- {#each items as p} + {#each patchTeasers as teaser} + selected={patch && teaser.id === patch.id} /> {/each} + + {#if patches.content.length === 0} + +
+
+ + {#if status === undefined} + No patches. + {:else} + No {status} patches. + {/if} +
+
+
+ {/if}
{/snippet}