mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-04 03:00:32 +08:00
Implement changing patch states
This commit is contained in:
committed by
Sebastian Martinez
parent
2ac0c54a85
commit
8622dba111
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user