mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-16 03:40:37 +08:00
Implement issue and patch list fuzzy finder
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
} from "@app/lib/utils";
|
||||
import { push } from "@app/lib/router";
|
||||
|
||||
import Border from "./Border.svelte";
|
||||
import Icon from "./Icon.svelte";
|
||||
import Id from "./Id.svelte";
|
||||
import InlineTitle from "./InlineTitle.svelte";
|
||||
@@ -17,19 +18,21 @@
|
||||
import NodeId from "./NodeId.svelte";
|
||||
|
||||
interface Props {
|
||||
compact?: boolean;
|
||||
focussed?: boolean;
|
||||
issue: Issue;
|
||||
rid: string;
|
||||
status: IssueStatus;
|
||||
selected?: boolean;
|
||||
compact?: boolean;
|
||||
status: IssueStatus;
|
||||
}
|
||||
|
||||
const {
|
||||
compact = false,
|
||||
focussed,
|
||||
issue,
|
||||
rid,
|
||||
status,
|
||||
selected = false,
|
||||
compact = false,
|
||||
status,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
@@ -37,7 +40,6 @@
|
||||
.issue-teaser {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.25rem;
|
||||
min-height: 5rem;
|
||||
background-color: var(--color-background-float);
|
||||
@@ -67,16 +69,7 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
class="issue-teaser"
|
||||
class:selected
|
||||
style:align-items="flex-start"
|
||||
onclick={() => {
|
||||
void push({ resource: "repo.issue", rid, issue: issue.id, status });
|
||||
}}>
|
||||
{#snippet issueSnippet()}
|
||||
<div class="global-flex" style:align-items="flex-start">
|
||||
<div
|
||||
class="global-counter status"
|
||||
@@ -102,7 +95,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="global-flex">
|
||||
<div class="global-flex" style:margin-left="auto">
|
||||
{#if !compact}
|
||||
{#each issue.labels as label}
|
||||
<Label {label} />
|
||||
@@ -116,4 +109,29 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
{#if focussed}
|
||||
<Border
|
||||
styleBackgroundColor="var(--color-background-float)"
|
||||
styleDisplay="flex"
|
||||
styleAlignItems="flex-start"
|
||||
styleMinHeight="5rem"
|
||||
stylePadding="1rem"
|
||||
variant="secondary">
|
||||
{@render issueSnippet()}
|
||||
</Border>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
class="issue-teaser"
|
||||
class:selected
|
||||
style:align-items="flex-start"
|
||||
onclick={() => {
|
||||
void push({ resource: "repo.issue", rid, issue: issue.id, status });
|
||||
}}>
|
||||
{@render issueSnippet()}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
import InlineTitle from "@app/components/InlineTitle.svelte";
|
||||
import Label from "@app/components/Label.svelte";
|
||||
import NodeId from "@app/components/NodeId.svelte";
|
||||
import Border from "./Border.svelte";
|
||||
|
||||
interface Props {
|
||||
compact?: boolean;
|
||||
focussed?: boolean;
|
||||
loadPatch?: (patchId: string) => Promise<void>;
|
||||
patch: Patch;
|
||||
rid: string;
|
||||
@@ -30,6 +32,7 @@
|
||||
|
||||
const {
|
||||
compact = false,
|
||||
focussed,
|
||||
loadPatch,
|
||||
patch,
|
||||
rid,
|
||||
@@ -72,26 +75,7 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
class:selected
|
||||
class="patch-teaser"
|
||||
style:align-items="flex-start"
|
||||
onclick={async () => {
|
||||
if (loadPatch) {
|
||||
await loadPatch(patch.id);
|
||||
} else {
|
||||
void push({
|
||||
resource: "repo.patch",
|
||||
rid,
|
||||
patch: patch.id,
|
||||
status,
|
||||
reviewId: undefined,
|
||||
});
|
||||
}
|
||||
}}>
|
||||
{#snippet patchSnippet()}
|
||||
<div class="global-flex" style:align-items="flex-start">
|
||||
<div
|
||||
class="global-counter status"
|
||||
@@ -116,7 +100,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="global-flex">
|
||||
<div class="global-flex" style:margin-left="auto">
|
||||
{#if !compact}
|
||||
{#await invoke<Stats>( "diff_stats", { rid, base: patch.base, head: patch.head }, ) then stats}
|
||||
<DiffStatBadge {stats} />
|
||||
@@ -134,4 +118,39 @@
|
||||
{patch.revisionCount}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
{#if focussed}
|
||||
<Border
|
||||
styleBackgroundColor="var(--color-background-float)"
|
||||
styleDisplay="flex"
|
||||
styleAlignItems="flex-start"
|
||||
styleMinHeight="5rem"
|
||||
stylePadding="1rem"
|
||||
variant="secondary">
|
||||
{@render patchSnippet()}
|
||||
</Border>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
class:selected
|
||||
class="patch-teaser"
|
||||
style:align-items="flex-start"
|
||||
onclick={async () => {
|
||||
if (loadPatch) {
|
||||
await loadPatch(patch.id);
|
||||
} else {
|
||||
void push({
|
||||
resource: "repo.patch",
|
||||
rid,
|
||||
patch: patch.id,
|
||||
status,
|
||||
reviewId: undefined,
|
||||
});
|
||||
}
|
||||
}}>
|
||||
{@render patchSnippet()}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -7,36 +7,38 @@
|
||||
import Border from "./Border.svelte";
|
||||
|
||||
interface Props {
|
||||
name?: string;
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
type?: string;
|
||||
autofocus?: boolean;
|
||||
autoselect?: boolean;
|
||||
disabled?: boolean;
|
||||
onSubmit?: () => void;
|
||||
onDismiss?: () => void;
|
||||
valid?: boolean;
|
||||
oninput?: FormEventHandler<HTMLInputElement>;
|
||||
keyShortcuts?: string;
|
||||
left?: Snippet;
|
||||
name?: string;
|
||||
onDismiss?: () => void;
|
||||
onFocus?: () => void;
|
||||
onSubmit?: () => void;
|
||||
oninput?: FormEventHandler<HTMLInputElement>;
|
||||
placeholder?: string;
|
||||
type?: string;
|
||||
valid?: boolean;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
/* eslint-disable prefer-const */
|
||||
let {
|
||||
name,
|
||||
placeholder,
|
||||
value = $bindable(undefined),
|
||||
type = "text",
|
||||
autofocus = false,
|
||||
autoselect = false,
|
||||
disabled = false,
|
||||
onSubmit,
|
||||
onDismiss,
|
||||
valid = true,
|
||||
oninput,
|
||||
keyShortcuts,
|
||||
left,
|
||||
name,
|
||||
onDismiss,
|
||||
onFocus,
|
||||
onSubmit,
|
||||
oninput,
|
||||
placeholder,
|
||||
type = "text",
|
||||
valid = true,
|
||||
value = $bindable(undefined),
|
||||
}: Props = $props();
|
||||
/* eslint-enable prefer-const */
|
||||
|
||||
@@ -102,6 +104,9 @@
|
||||
style:padding={left ? "0.25rem 0.75rem 0.25rem 0" : "0.25rem 0.75rem"}
|
||||
aria-keyshortcuts={keyShortcuts}
|
||||
onfocus={() => {
|
||||
if (onFocus) {
|
||||
onFocus();
|
||||
}
|
||||
focussed = true;
|
||||
}}
|
||||
onblur={() => {
|
||||
|
||||
Reference in New Issue
Block a user