Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
Fine-tune repo layout
Open rudolfs opened 1 year ago
18 files changed +231 -237 6b336b0f 05ded704
modified public/index.css
@@ -62,6 +62,7 @@ body {
  padding: 0 0.5rem;
  min-width: 1.5rem;
  font-weight: var(--font-weight-regular);
+
  flex-shrink: 0;
}

:root {
modified src/components/Button.svelte
@@ -38,6 +38,7 @@
    -webkit-user-select: none;
    user-select: none;

+
    height: 2rem;
    column-gap: 0;
    row-gap: 0;
    display: grid;
@@ -301,7 +302,7 @@
  .p3-3 {
    grid-area: p3-3;
    background-color: var(--button-color-1);
-
    padding: 2px 8px;
+
    padding: 0 8px;
    display: flex;
    align-items: center;
    gap: 0.5rem;
modified src/components/DropdownListItem.svelte
@@ -26,8 +26,8 @@
    display: flex;
    align-items: center;
    flex-direction: row;
-
    gap: 0.375rem;
-
    padding: 0.5rem 0.375rem;
+
    min-height: 2rem;
+
    padding: 0 0.5rem;
    white-space: nowrap;
    font-size: var(--font-size-small);
    font-weight: var(--font-weight-regular);
modified src/components/Icon.svelte
@@ -32,6 +32,7 @@
      | "markdown"
      | "moon"
      | "more-vertical"
+
      | "none"
      | "offline"
      | "online"
      | "patch"
@@ -442,6 +443,38 @@
    <path d="M9 2V4L7 4L7 2L9 2Z" />
    <path d="M9 7L9 9H7L7 7H9Z" />
    <path d="M9 12L9 14H7L7 12H9Z" />
+
  {:else if name === "none"}
+
    <path d="M6 13H8V14H6V13Z" />
+
    <path d="M10 13H7V14H10V13Z" />
+
    <path d="M3 5.00003L3 8.00003H2L2 5.00003L3 5.00003Z" />
+
    <path d="M13 6.00003V8.00003H14V6.00003H13Z" />
+
    <path d="M4 12H6V13H4V12Z" />
+
    <path d="M12 12H10V13H12V12Z" />
+
    <path d="M4 4.00003V6.00003H3L3 4.00003H4Z" />
+
    <path d="M12 4.00003V6.00003L13 6.00003V4.00003L12 4.00003Z" />
+
    <path d="M4 10L4 12H3L3 10H4Z" />
+
    <path d="M12 10V12H13V10H12Z" />
+
    <path d="M6 4.00003L4 4.00003L4 3.00003L6 3.00003V4.00003Z" />
+
    <path d="M10 4.00003L12 4.00003V3.00003L10 3.00003V4.00003Z" />
+
    <path d="M3 8.00003L3 10H2L2 8.00003H3Z" />
+
    <path d="M13 7.00003V10H14V7.00003H13Z" />
+
    <path d="M9 3.00003L6 3.00003V2.00003L9 2.00003V3.00003Z" />
+
    <path d="M8 3.00003L10 3.00003L10 2.00003L8 2.00003L8 3.00003Z" />
+
    <path d="M11 4.00003H12V5.00003H11V4.00003Z" />
+
    <path d="M10 5.00003H11V6.00003H10V5.00003Z" />
+
    <path d="M11 5.00003H12V6.00003L11 6.00003V5.00003Z" />
+
    <path d="M10 6.00003H11V7.00003H10V6.00003Z" />
+
    <path d="M9 7.00003L10 7.00003V8.00003H9V7.00003Z" />
+
    <path d="M8 8.00003H9V9.00003H8V8.00003Z" />
+
    <path d="M7 9.00003L8 9.00003L8 10H7V9.00003Z" />
+
    <path d="M6 10H7V11H6V10Z" />
+
    <path d="M5 11H6L6 12H5V11Z" />
+
    <path d="M9 6.00003H10V7.00003L9 7.00003V6.00003Z" />
+
    <path d="M8 7.00003H9V8.00003H8V7.00003Z" />
+
    <path d="M7 8.00003L8 8.00003V9.00003L7 9.00003V8.00003Z" />
+
    <path d="M6 9.00003H7V10H6V9.00003Z" />
+
    <path d="M5 10H6V11H5L5 10Z" />
+
    <path d="M4 11H5V12H4V11Z" />
  {:else if name === "offline"}
    <path d="M3 6L3 8H2L2 6H3Z" />
    <path d="M13 10V8H14V10H13Z" />
modified src/components/IssueSecondColumn.svelte
@@ -16,14 +16,21 @@
    selectedIssueId?: string;
    issues: Issue[];
    status: IssueStatus;
+
    title: string;
  }

  /* eslint-disable prefer-const */
-
  let { repo, selectedIssueId, issues, status }: Props = $props();
+
  let { repo, selectedIssueId, issues, status, title }: Props = $props();
  /* eslint-enable prefer-const */
</script>

<style>
+
  .container {
+
    display: flex;
+
    justify-content: space-between;
+
    align-items: center;
+
    min-height: 40px;
+
  }
  .issue-list {
    margin-top: 0.5rem;
    display: flex;
@@ -33,8 +40,10 @@
  }
</style>

-
<div class="global-flex" style:justify-content="space-between">
-
  <div class="txt-medium" style:font-weight="var(--font-weight-medium)">
+
<div class="container">
+
  <div class="txt-regular txt-semibold global-flex" style:gap="4px">
+
    {title}
+
    <Icon name="chevron-right" />
    Issues
  </div>

modified src/components/IssueStateButton.svelte
@@ -57,13 +57,11 @@

  <Popover
    popoverPadding="0"
-
    popoverPositionTop="3rem"
+
    popoverPositionTop="2.5rem"
    popoverPositionRight="0">
    {#snippet toggle(onclick)}
      <Button flatLeft {onclick} variant="secondary">
-
        <div style:height="22px" class="global-flex">
-
          <Icon name="chevron-down" />
-
        </div>
+
        <Icon name="chevron-down" />
      </Button>
    {/snippet}
    {#snippet popover()}
modified src/components/IssuesSecondColumn.svelte
@@ -24,7 +24,6 @@
    flex-direction: column;
    height: 100%;
    justify-content: space-between;
-
    padding-bottom: 1rem;
  }
  .tab {
    align-items: center;
@@ -59,7 +58,9 @@

<div class="container">
  <div>
-
    <RepoTeaser name={project.data.name} seeding={repo.seeding} />
+
    <div style:margin-bottom="0.5rem" style:padding-left="0.75rem">
+
      <RepoTeaser name={project.data.name} seeding={repo.seeding} />
+
    </div>

    <Border
      variant="ghost"
modified src/components/NakedButton.svelte
@@ -14,7 +14,7 @@
    title,
    variant,
    onclick,
-
    styleHeight = "32px",
+
    styleHeight = "2rem",
  }: Props = $props();

  const style = $derived(
@@ -71,7 +71,7 @@
  }
  .p3-3 {
    grid-area: p3-3;
-
    padding: 2px 8px;
+
    padding: 0 8px;
    display: flex;
    align-items: center;
    gap: 0.5rem;
modified src/components/OutlineButton.svelte
@@ -68,7 +68,7 @@
  }
  .p3-3 {
    grid-area: p3-3;
-
    padding: 2px 8px;
+
    padding: 0 8px;
    display: flex;
    align-items: center;
    gap: 0.5rem;
@@ -224,6 +224,7 @@
  }

  .container {
+
    height: 2rem;
    cursor: pointer;
    white-space: nowrap;

modified src/components/PatchesSecondColumn.svelte
@@ -23,7 +23,6 @@
    flex-direction: column;
    height: 100%;
    justify-content: space-between;
-
    padding-bottom: 1rem;
  }
  .tab {
    align-items: center;
@@ -64,7 +63,9 @@

<div class="container">
  <div>
-
    <RepoTeaser name={project.data.name} seeding={repo.seeding} />
+
    <div style:margin-bottom="0.5rem" style:padding-left="0.75rem">
+
      <RepoTeaser name={project.data.name} seeding={repo.seeding} />
+
    </div>

    <div style:margin-bottom="0.5rem">
      <Link
modified src/components/RepoTeaser.svelte
@@ -12,8 +12,7 @@
<style>
  .teaser {
    align-items: center;
-
    height: 34px;
-
    margin: 0 4px 1rem 12px;
+
    min-height: 40px;
  }

  .seeding {
modified src/components/Sidebar.svelte
@@ -44,7 +44,7 @@
</style>

<div class="global-flex" style:flex-direction="column" style:gap="0.5rem">
-
  <div class="global-flex" style:margin-bottom="5px" style:height="40px">
+
  <div class="global-flex" style:height="40px">
    <Icon name="repo" />
  </div>
  {#if activeTab.type === "issues"}
modified src/views/repo/CreateIssue.svelte
@@ -33,6 +33,8 @@

  const { repo, issues, config, status }: Props = $props();

+
  const project = $derived(repo.payloads["xyz.radicle.project"]!);
+

  let preview: boolean = $state(false);
  let title: string = $state("");

@@ -95,7 +97,7 @@
  {/snippet}

  {#snippet secondColumn()}
-
    <IssueSecondColumn {repo} {issues} {status} />
+
    <IssueSecondColumn {repo} {issues} {status} title={project.data.name} />
  {/snippet}

  <div class="content">
modified src/views/repo/Issue.svelte
@@ -14,7 +14,12 @@
  import * as roles from "@app/lib/roles";
  import { invoke } from "@app/lib/invoke";
  import { nodeRunning } from "@app/lib/events";
-
  import { publicKeyFromDid, scrollIntoView } from "@app/lib/utils";
+
  import {
+
    issueStatusBackgroundColor,
+
    issueStatusColor,
+
    publicKeyFromDid,
+
    scrollIntoView,
+
  } from "@app/lib/utils";

  import { announce } from "@app/components/AnnounceSwitch.svelte";

@@ -29,8 +34,6 @@
  import IssueStateButton from "@app/components/IssueStateButton.svelte";
  import IssueTimelineLifecycleAction from "@app/components/IssueTimelineLifecycleAction.svelte";
  import LabelInput from "@app/components/LabelInput.svelte";
-
  import Link from "@app/components/Link.svelte";
-
  import NodeId from "@app/components/NodeId.svelte";
  import TextInput from "@app/components/TextInput.svelte";
  import ThreadComponent from "@app/components/Thread.svelte";

@@ -312,7 +315,13 @@
    align-items: center;
    justify-content: space-between;
    word-break: break-all;
-
    padding-top: 4px;
+
    min-height: 40px;
+
  }
+
  .status {
+
    padding: 0;
+
    margin-right: 0.75rem;
+
    height: 2rem;
+
    width: 2rem;
  }
  .issue-body {
    margin-top: 1rem;
@@ -344,7 +353,6 @@
    gap: 1rem;
    margin-left: 1rem;
    align-items: center;
-
    height: 40px;
  }
  .metadata-divider {
    width: 2px;
@@ -365,17 +373,6 @@
    margin-bottom: 0.5rem;
    color: var(--color-foreground-dim);
  }
-
  .breadcrumbs {
-
    display: flex;
-
    gap: 0.5rem;
-
    font-size: var(--font-size-tiny);
-
    font-weight: var(--font-weight-semibold);
-
    align-items: center;
-
    min-height: 1.5rem;
-
    width: 100%;
-
    margin-bottom: 1rem;
-
    color: var(--color-foreground-dim);
-
  }
</style>

<Layout publicKey={config.publicKey}>
@@ -388,13 +385,26 @@
  {/snippet}

  {#snippet secondColumn()}
-
    <IssueSecondColumn {repo} selectedIssueId={issue.id} {issues} {status} />
+
    <IssueSecondColumn
+
      {repo}
+
      selectedIssueId={issue.id}
+
      {issues}
+
      {status}
+
      title={project.data.name} />
  {/snippet}

  <div class="content">
-
    <div style:margin-bottom="1rem">
+
    <div style:margin-bottom="0.5rem">
      {#if editingTitle}
        <div class="title">
+
          <div
+
            class="global-counter status"
+
            style:color={issueStatusColor[issue.state.status]}
+
            style:background-color={issueStatusBackgroundColor[
+
              issue.state.status
+
            ]}>
+
            <Icon name="issue" />
+
          </div>
          <TextInput
            valid={updatedTitle.trim().length > 0}
            bind:value={updatedTitle}
@@ -427,7 +437,17 @@
        </div>
      {:else}
        <div class="title">
-
          <InlineTitle content={issue.title} fontSize="medium" />
+
          <div class="global-flex" style:gap="0">
+
            <div
+
              class="global-counter status"
+
              style:color={issueStatusColor[issue.state.status]}
+
              style:background-color={issueStatusBackgroundColor[
+
                issue.state.status
+
              ]}>
+
              <Icon name="issue" />
+
            </div>
+
            <InlineTitle content={issue.title} fontSize="medium" />
+
          </div>
          {#if roles.isDelegateOrAuthor( config.publicKey, repo.delegates.map(delegate => delegate.did), issue.body.author.did, )}
            <div class="title-icons">
              <Icon name="pen" onclick={() => (editingTitle = !editingTitle)} />
@@ -438,32 +458,6 @@
      {/if}
    </div>

-
    <div class="breadcrumbs txt-overflow">
-
      <Link route={{ resource: "home" }}>
-
        <NodeId
-
          publicKey={config.publicKey}
-
          alias={config.alias}
-
          styleFontFamily="var(--font-family-sans-serif)"
-
          styleFontSize="var(--font-size-tiny)" />
-
      </Link>
-
      <Icon name="chevron-right" />
-
      <Link
-
        route={{ resource: "repo.issues", rid: repo.rid, status: "open" }}
-
        styleColor="var(--color-foreground-dim)">
-
        {project.data.name}
-
      </Link>
-
      <Icon name="chevron-right" />
-
      <Link
-
        route={{ resource: "repo.issues", rid: repo.rid, status: "open" }}
-
        styleColor="var(--color-foreground-dim)">
-
        Issues
-
      </Link>
-
      <Icon name="chevron-right" />
-
      <div class="txt-overflow">
-
        {issue.title}
-
      </div>
-
    </div>
-

    <Border variant="ghost" styleGap="0">
      <div class="metadata-section" style:min-width="8rem">
        <div class="metadata-section-title">Status</div>
modified src/views/repo/Issues.svelte
@@ -13,9 +13,8 @@
  import Icon from "@app/components/Icon.svelte";
  import IssueTeaser from "@app/components/IssueTeaser.svelte";
  import IssuesSecondColumn from "@app/components/IssuesSecondColumn.svelte";
-
  import Link from "@app/components/Link.svelte";
-
  import NodeId from "@app/components/NodeId.svelte";
  import Sidebar from "@app/components/Sidebar.svelte";
+
  import Border from "@app/components/Border.svelte";

  interface Props {
    repo: RepoInfo;
@@ -30,31 +29,22 @@
</script>

<style>
+
  .container {
+
    padding: 1rem 1rem 1rem 0;
+
  }
  .list {
    display: flex;
    flex-direction: column;
    gap: 2px;
-
    padding: 0 1rem 1rem 0;
  }
  .header {
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-medium);
    display: flex;
-
    padding: 1rem 1rem 0.5rem 1rem;
    align-items: center;
    justify-content: space-between;
-
  }
-
  .breadcrumbs {
-
    display: flex;
-
    gap: 0.5rem;
-
    font-size: var(--font-size-tiny);
-
    font-weight: var(--font-weight-semibold);
-
    align-items: center;
-
    min-height: 1.5rem;
-
    width: 100%;
-
    margin-bottom: 1rem;
-
    padding-left: 1rem;
-
    color: var(--color-foreground-dim);
+
    min-height: 40px;
+
    margin-bottom: 0.5rem;
  }
</style>

@@ -71,59 +61,52 @@
  {/snippet}

  {#snippet secondColumn()}
-
    <div style:margin-left="1rem" style:height="100%">
-
      <IssuesSecondColumn {project} {status} {repo} />
-
    </div>
+
    <IssuesSecondColumn {project} {status} {repo} />
  {/snippet}

-
  <div class="header">
-
    <div>Issues</div>
-
    <div class="txt-regular txt-semibold">
-
      <Button
-
        variant="secondary"
-
        onclick={() => {
-
          void router.push({
-
            resource: "repo.createIssue",
-
            status,
-
            rid: repo.rid,
-
          });
-
        }}>
-
        <Icon name="plus" />New
-
      </Button>
+
  <div class="container">
+
    <div class="header">
+
      <div>Issues</div>
+
      <div class="txt-regular txt-semibold">
+
        <Button
+
          variant="secondary"
+
          onclick={() => {
+
            void router.push({
+
              resource: "repo.createIssue",
+
              status,
+
              rid: repo.rid,
+
            });
+
          }}>
+
          <Icon name="plus" />New
+
        </Button>
+
      </div>
    </div>
-
  </div>
-

-
  <div class="breadcrumbs">
-
    <Link route={{ resource: "home" }}>
-
      <NodeId
-
        publicKey={config.publicKey}
-
        alias={config.alias}
-
        styleFontFamily="var(--font-family-sans-serif)"
-
        styleFontSize="var(--font-size-tiny)" />
-
    </Link>
-
    <Icon name="chevron-right" />
-
    <Link
-
      route={{ resource: "repo.issues", rid: repo.rid, status: "open" }}
-
      styleColor="var(--color-foreground-dim)">
-
      {project.data.name}
-
    </Link>
-
    <Icon name="chevron-right" />
-
    Issues
-
  </div>

-
  <div class="list">
-
    {#each issues as issue}
-
      <IssueTeaser {issue} rid={repo.rid} {status} />
-
    {/each}
+
    <div class="list">
+
      {#each issues as issue}
+
        <IssueTeaser {issue} rid={repo.rid} {status} />
+
      {/each}

-
    {#if issues.length === 0}
-
      <div class="txt-missing txt-small" style:margin-left="1rem">
-
        {#if status === "all"}
-
          No issues.
-
        {:else}
-
          No {status} issues.
-
        {/if}
-
      </div>
-
    {/if}
+
      {#if issues.length === 0}
+
        <Border
+
          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>
  </div>
</Layout>
modified src/views/repo/Layout.svelte
@@ -108,22 +108,18 @@

  .sidebar {
    grid-column: 1 / 2;
-
    width: 40px;
-
    margin: 0 1rem;
+
    padding: 1rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
-
    margin-top: 13px;
-
    margin-bottom: 1rem;
  }

  .secondColumn {
    grid-column: 2 / 3;
-
    margin: 1rem 0 0 0;
    max-width: 28rem;
    min-width: 14rem;
-
    margin-right: 1rem;
+
    padding: 1rem 1rem 1rem 0;
  }

  .content {
@@ -139,12 +135,16 @@
    <Header {publicKey} center={headerCenter}></Header>
  </div>

-
  <div class="sidebar" style:display={hideSidebar ? "none" : "flex"}>
+
  <div
+
    class="sidebar"
+
    style:display={hideSidebar ? "none" : "flex"}
+
    style:padding-right="1rem">
    {@render sidebar()}
  </div>

  <div
    class="secondColumn"
+
    style:padding-left={hideSidebar ? "1rem" : "0"}
    bind:this={secondColumnContainer}
    style:display={oneColumnLayout && !hideSidebar ? "none" : undefined}
    style:overflow={styleSecondColumnOverflow}>
modified src/views/repo/Patch.svelte
@@ -9,7 +9,11 @@
  import type { Revision } from "@bindings/cob/patch/Revision";

  import * as roles from "@app/lib/roles";
-
  import { formatOid } from "@app/lib/utils";
+
  import {
+
    formatOid,
+
    patchStatusBackgroundColor,
+
    patchStatusColor,
+
  } from "@app/lib/utils";
  import { invoke } from "@app/lib/invoke";
  import { nodeRunning } from "@app/lib/events";

@@ -17,6 +21,7 @@

  import AssigneeInput from "@app/components/AssigneeInput.svelte";
  import Border from "@app/components/Border.svelte";
+
  import Button from "@app/components/Button.svelte";
  import Changeset from "@app/components/Changeset.svelte";
  import CommentComponent from "@app/components/Comment.svelte";
  import CopyableId from "@app/components/CopyableId.svelte";
@@ -24,12 +29,9 @@
  import InlineTitle from "@app/components/InlineTitle.svelte";
  import LabelInput from "@app/components/LabelInput.svelte";
  import Layout from "./Layout.svelte";
-
  import Link from "@app/components/Link.svelte";
-
  import NodeId from "@app/components/NodeId.svelte";
  import PatchStateBadge from "@app/components/PatchStateBadge.svelte";
  import PatchTeaser from "@app/components/PatchTeaser.svelte";
  import Sidebar from "@app/components/Sidebar.svelte";
-
  import Button from "@app/components/Button.svelte";

  interface Props {
    repo: RepoInfo;
@@ -171,7 +173,16 @@
    font-weight: var(--font-weight-medium);
    -webkit-user-select: text;
    user-select: text;
-
    margin-bottom: 1rem;
+
    display: flex;
+
    align-items: center;
+
    word-break: break-all;
+
    min-height: 40px;
+
  }
+
  .status {
+
    padding: 0;
+
    margin-right: 0.75rem;
+
    height: 2rem;
+
    width: 2rem;
  }
  .patch-list {
    margin-top: 0.5rem;
@@ -181,7 +192,7 @@
    padding-bottom: 1rem;
  }
  .content {
-
    padding: 1.5rem 1rem 1rem 0;
+
    padding: 1rem 1rem 1rem 0;
  }

  .patch-body {
@@ -219,17 +230,6 @@
    margin-bottom: 0.5rem;
    color: var(--color-foreground-dim);
  }
-
  .breadcrumbs {
-
    display: flex;
-
    gap: 0.5rem;
-
    font-size: var(--font-size-tiny);
-
    font-weight: var(--font-weight-semibold);
-
    align-items: center;
-
    min-height: 1.5rem;
-
    width: 100%;
-
    margin-bottom: 1rem;
-
    color: var(--color-foreground-dim);
-
  }
</style>

<Layout {loadMoreSecondColumn} publicKey={config.publicKey}>
@@ -243,9 +243,11 @@

  {#snippet secondColumn()}
    <div
-
      style:height="34px"
-
      class="global-flex txt-medium"
-
      style:font-weight="var(--font-weight-medium)">
+
      class="txt-regular txt-semibold global-flex"
+
      style:gap="4px"
+
      style:min-height="40px">
+
      {project.data.name}
+
      <Icon name="chevron-right" />
      Patches
    </div>
    <div class="patch-list">
@@ -262,32 +264,18 @@
  {/snippet}

  <div class="content">
-
    <div class="title">
-
      <InlineTitle content={patch.title} fontSize="medium" />
-
    </div>
-

-
    <div class="breadcrumbs">
-
      <Link route={{ resource: "home" }}>
-
        <NodeId
-
          publicKey={config.publicKey}
-
          alias={config.alias}
-
          styleFontFamily="var(--font-family-sans-serif)"
-
          styleFontSize="var(--font-size-tiny)" />
-
      </Link>
-
      <Icon name="chevron-right" />
-
      <Link
-
        route={{ resource: "repo.patches", rid: repo.rid, status: "open" }}
-
        styleColor="var(--color-foreground-dim)">
-
        {project.data.name}
-
      </Link>
-
      <Icon name="chevron-right" />
-
      <Link
-
        route={{ resource: "repo.patches", rid: repo.rid, status: "open" }}
-
        styleColor="var(--color-foreground-dim)">
-
        Patches
-
      </Link>
-
      <Icon name="chevron-right" />
-
      {patch.title}
+
    <div style:margin-bottom="0.5rem">
+
      <div class="title">
+
        <div
+
          class="global-counter status"
+
          style:color={patchStatusColor[patch.state.status]}
+
          style:background-color={patchStatusBackgroundColor[
+
            patch.state.status
+
          ]}>
+
          <Icon name="patch" />
+
        </div>
+
        <InlineTitle content={patch.title} fontSize="medium" />
+
      </div>
    </div>

    <Border variant="ghost" styleGap="0">
modified src/views/repo/Patches.svelte
@@ -10,11 +10,10 @@
  import CopyableId from "@app/components/CopyableId.svelte";
  import Icon from "@app/components/Icon.svelte";
  import Layout from "./Layout.svelte";
-
  import Link from "@app/components/Link.svelte";
-
  import NodeId from "@app/components/NodeId.svelte";
  import PatchTeaser from "@app/components/PatchTeaser.svelte";
  import PatchesSecondColumn from "@app/components/PatchesSecondColumn.svelte";
  import Sidebar from "@app/components/Sidebar.svelte";
+
  import Border from "@app/components/Border.svelte";

  interface Props {
    repo: RepoInfo;
@@ -54,31 +53,21 @@
</script>

<style>
+
  .container {
+
    padding: 1rem 1rem 1rem 0;
+
  }
  .list {
    display: flex;
    flex-direction: column;
    gap: 2px;
-
    padding: 0 1rem 1rem 0;
  }
  .header {
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-medium);
-
    padding: 1rem 1rem 0.5rem 1rem;
-
    display: flex;
-
    align-items: center;
-
    height: 58px;
-
  }
-
  .breadcrumbs {
    display: flex;
-
    gap: 0.5rem;
-
    font-size: var(--font-size-tiny);
-
    font-weight: var(--font-weight-semibold);
    align-items: center;
-
    min-height: 1.5rem;
-
    width: 100%;
-
    margin-bottom: 1rem;
-
    padding-left: 1rem;
-
    color: var(--color-foreground-dim);
+
    min-height: 40px;
+
    margin-bottom: 0.5rem;
  }
</style>

@@ -96,43 +85,37 @@
  {/snippet}

  {#snippet secondColumn()}
-
    <div style:margin-left="1rem" style:height="100%">
-
      <PatchesSecondColumn {project} {status} {repo} />
-
    </div>
+
    <PatchesSecondColumn {project} {status} {repo} />
  {/snippet}

-
  <div class="header">Patches</div>
-

-
  <div class="breadcrumbs">
-
    <Link route={{ resource: "home" }}>
-
      <NodeId
-
        publicKey={config.publicKey}
-
        alias={config.alias}
-
        styleFontFamily="var(--font-family-sans-serif)"
-
        styleFontSize="var(--font-size-tiny)" />
-
    </Link>
-
    <Icon name="chevron-right" />
-
    <Link
-
      route={{ resource: "repo.issues", rid: repo.rid, status: "open" }}
-
      styleColor="var(--color-foreground-dim)">
-
      {project.data.name}
-
    </Link>
-
    <Icon name="chevron-right" />
-
    Patches
-
  </div>
-
  <div class="list">
-
    {#each items as patch}
-
      <PatchTeaser rid={repo.rid} {patch} {status} />
-
    {/each}
-

-
    {#if patches.content.length === 0}
-
      <div class="txt-missing txt-small" style:margin-left="1rem">
-
        {#if status === undefined}
-
          No patches.
-
        {:else}
-
          No {status} patches.
-
        {/if}
-
      </div>
-
    {/if}
+
  <div class="container">
+
    <div class="header">Patches</div>
+

+
    <div class="list">
+
      {#each items as patch}
+
        <PatchTeaser rid={repo.rid} {patch} {status} />
+
      {/each}
+

+
      {#if patches.content.length === 0}
+
        <Border
+
          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 === undefined}
+
                No patches.
+
              {:else}
+
                No {status} patches.
+
              {/if}
+
            </div>
+
          </div>
+
        </Border>
+
      {/if}
+
    </div>
  </div>
</Layout>