Files
radicle-desktop/src/components/IssueStateButton.svelte
T
Rūdolfs Ošiņš 010cac0377 Redesign app with new UI kit
Redesign the entire app with a new UI kit. Typography, colors, icons,
avatars, and border radii have all been updated for a more polished,
consistent appearance that matches our other products like
radicle-explorer.

- Replace blockies-based avatars with a new DID-based avatar system
- Move Settings and Create Issue into fullscreen modals
- Change the default theme to follow the system theme
- Remove window decorations on macOS for a cleaner, more native feel
- Update the app icon
- Fix popovers and tooltips

Navigation:

- Rewrite app navigation and layouts
- Add a sidebar that gives you access to all your repos
- Change the startup screen to open directly to the notification inbox
- Add a getting started guide shown to new users on first launch

Settings:

- Add a setting to disable the notification badge
- Add a code font setting

Bug fixes:

- Fix reactions and edits incorrectly targeting the root comment
  instead of the intended reply
- Restrict issue/patch state, labels and assignees to delegates only
2026-03-20 17:48:38 -06:00

105 lines
3.4 KiB
Svelte

<script lang="ts">
import type { State } from "@bindings/cob/issue/State";
import capitalize from "lodash/capitalize";
import isEqual from "lodash/isEqual";
import { issueStatusBackgroundColor, issueStatusColor } from "@app/lib/utils";
import Button from "@app/components/Button.svelte";
import DropdownList from "@app/components/DropdownList.svelte";
import DropdownListItem from "@app/components/DropdownListItem.svelte";
import Icon from "@app/components/Icon.svelte";
import { closeFocused } from "@app/components/Popover.svelte";
import Popover from "@app/components/Popover.svelte";
interface Props {
selectedState: State;
onSelect: (selectedStatus: State) => void;
disabled?: boolean;
}
const { selectedState, onSelect, disabled = false }: Props = $props();
let popoverExpanded: boolean = $state(false);
</script>
<Popover
popoverPadding="0"
placement="bottom-start"
bind:expanded={popoverExpanded}>
{#snippet toggle(onclick)}
<Button
variant="outline"
{disabled}
{onclick}
active={popoverExpanded}
title={disabled
? "You must be a delegate to change the issue state"
: undefined}>
<span
class="global-chip"
style:padding="0"
style:margin-left="-0.25rem"
style:color={disabled
? undefined
: issueStatusColor[selectedState.status]}
style:background-color={disabled
? undefined
: issueStatusBackgroundColor[selectedState.status]}>
<Icon
name={selectedState.status === "open"
? "issue"
: `issue-${selectedState.status}`} />
</span>
<span style:color={disabled ? undefined : "var(--color-text-secondary)"}>
{capitalize(selectedState.status)}
{selectedState.status === "closed" ? `as ${selectedState.reason}` : ""}
</span>
<Icon name={popoverExpanded ? "chevron-up" : "chevron-down"} />
</Button>
{/snippet}
{#snippet popover()}
<div
style:border="1px solid var(--color-border-subtle)"
style:border-radius="var(--border-radius-sm)"
style:display="flex"
style:gap="0.5rem"
style:align-items="center"
style:background-color="var(--color-surface-canvas)">
<DropdownList
items={[
{ status: "open" },
{ status: "closed", reason: "solved" },
{ status: "closed", reason: "other" },
] as State[]}>
{#snippet item(state)}
<DropdownListItem
selected={isEqual(selectedState, state)}
styleGap="0.5rem"
onclick={() => {
onSelect(state);
closeFocused();
}}>
<span
class="global-chip"
style:padding="0"
style:margin-left="-0.5rem"
style:color={issueStatusColor[state.status]}
style:background-color={issueStatusBackgroundColor[state.status]}>
<Icon
name={state.status === "open"
? "issue"
: `issue-${state.status}`} />
</span>
<span style:color="var(--color-text-secondary)">
{capitalize(state.status)}
{state.status === "closed" ? `as ${state.reason}` : ""}
</span>
</DropdownListItem>
{/snippet}
</DropdownList>
</div>
{/snippet}
</Popover>