Radish alpha
r
Radicle desktop app
Radicle
Git (anonymous pull)
Log in to clone via SSH
Implement changing patch states
Rūdolfs Ošiņš committed 1 year ago
commit 8622dba11189b93ad5c242fb19eea97c09d93182
parent 2ac0c54a8560000a787e35b99769a1ec12716eb0
2 files changed +127 -8
added src/components/PatchStateButton.svelte
@@ -0,0 +1,86 @@
+
<script lang="ts">
+
  import type { State } from "@bindings/cob/patch/State";
+

+
  import isEqual from "lodash/isEqual";
+

+
  import { closeFocused } from "@app/components/Popover.svelte";
+

+
  import Border from "@app/components/Border.svelte";
+
  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 Popover from "@app/components/Popover.svelte";
+

+
  const {
+
    save,
+
    patchState,
+
  }: {
+
    save: (state: State) => Promise<void>;
+
    patchState: State;
+
  } = $props();
+

+
  const actions: { caption: string; state: State }[] = [
+
    {
+
      caption: "Reopen",
+
      state: { status: "open" },
+
    },
+
    { caption: "Convert to draft", state: { status: "draft" } },
+
    { caption: "Archive", state: { status: "archived" } },
+
  ];
+

+
  let selectedAction = $state(
+
    patchState.status === "open" ? actions[1] : actions[0],
+
  );
+

+
  // React to state changes that come from outside of this button.
+
  $effect(() => {
+
    selectedAction = patchState.status === "open" ? actions[1] : actions[0];
+
  });
+
</script>
+

+
<style>
+
  .main {
+
    display: flex;
+
    flex-direction: row;
+
    justify-content: center;
+
  }
+
</style>
+

+
<div class="main">
+
  <Button
+
    variant="secondary"
+
    flatRight
+
    onclick={() =>
+
      void save($state.snapshot(selectedAction["state"]) as State)}>
+
    {selectedAction["caption"]}
+
  </Button>
+

+
  <Popover
+
    popoverPadding="0"
+
    popoverPositionTop="2.5rem"
+
    popoverPositionRight="0">
+
    {#snippet toggle(onclick)}
+
      <Button flatLeft {onclick} variant="secondary">
+
        <Icon name="chevron-down" />
+
      </Button>
+
    {/snippet}
+
    {#snippet popover()}
+
      <Border variant="ghost">
+
        <DropdownList
+
          items={actions.filter(a => !isEqual(a.state, patchState))}>
+
          {#snippet item(action)}
+
            <DropdownListItem
+
              selected={isEqual(selectedAction, action)}
+
              onclick={() => {
+
                selectedAction = action;
+
                closeFocused();
+
              }}>
+
              {action.caption}
+
            </DropdownListItem>
+
          {/snippet}
+
        </DropdownList>
+
      </Border>
+
    {/snippet}
+
  </Popover>
+
</div>
modified src/views/repo/Patch.svelte
@@ -34,6 +34,7 @@
  import LabelInput from "@app/components/LabelInput.svelte";
  import Layout from "./Layout.svelte";
  import PatchStateBadge from "@app/components/PatchStateBadge.svelte";
+
  import PatchStateButton from "@app/components/PatchStateButton.svelte";
  import PatchTeaser from "@app/components/PatchTeaser.svelte";
  import Sidebar from "@app/components/Sidebar.svelte";

@@ -220,6 +221,24 @@
      await reload();
    }
  }
+

+
  async function saveState(state: Patch["state"]) {
+
    try {
+
      await invoke("edit_patch", {
+
        rid: repo.rid,
+
        cobId: patch.id,
+
        action: {
+
          type: "lifecycle",
+
          state,
+
        },
+
        opts: { announce: $nodeRunning && $announce },
+
      });
+
    } catch (error) {
+
      console.error("Editing reactions failed", error);
+
    } finally {
+
      await reload();
+
    }
+
  }
</script>

<style>
@@ -230,9 +249,16 @@
    user-select: text;
    display: flex;
    align-items: center;
+
    justify-content: space-between;
    word-break: break-all;
    min-height: 40px;
  }
+
  .title-icons {
+
    display: flex;
+
    gap: 1rem;
+
    margin-left: 1rem;
+
    align-items: center;
+
  }
  .status {
    padding: 0;
    margin-right: 0.75rem;
@@ -321,15 +347,22 @@
  <div class="content">
    <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 class="global-flex" style:gap="0">
+
          <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>
-
        <InlineTitle content={patch.title} fontSize="medium" />
+
        {#if roles.isDelegateOrAuthor( config.publicKey, repo.delegates.map(delegate => delegate.did), patch.author.did, )}
+
          <div class="title-icons">
+
            <PatchStateButton patchState={patch.state} save={saveState} />
+
          </div>
+
        {/if}
      </div>
    </div>