mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-27 07:30:34 +08:00
154 lines
4.5 KiB
Svelte
154 lines
4.5 KiB
Svelte
<script lang="ts">
|
|
import type { BaseUrl, Embed, Project, Reaction } from "@httpd-client";
|
|
|
|
import * as modal from "@app/lib/modal";
|
|
import * as router from "@app/lib/router";
|
|
import * as utils from "@app/lib/utils";
|
|
import { HttpdClient } from "@httpd-client";
|
|
import { httpdStore } from "@app/lib/httpd";
|
|
|
|
import AssigneeInput from "@app/views/projects/Cob/AssigneeInput.svelte";
|
|
import ErrorModal from "@app/modals/ErrorModal.svelte";
|
|
import CobHeader from "@app/views/projects/Cob/CobHeader.svelte";
|
|
import ErrorMessage from "@app/components/ErrorMessage.svelte";
|
|
import ExtendedTextarea from "@app/components/ExtendedTextarea.svelte";
|
|
import LabelInput from "@app/views/projects/Cob/LabelInput.svelte";
|
|
import Layout from "@app/views/projects/Layout.svelte";
|
|
import TextInput from "@app/components/TextInput.svelte";
|
|
|
|
export let baseUrl: BaseUrl;
|
|
export let project: Project;
|
|
export let rawPath: (commit?: string) => string;
|
|
|
|
let issueTitle = "";
|
|
let assignees: Reaction["authors"] = [];
|
|
let labels: string[] = [];
|
|
|
|
const api = new HttpdClient(baseUrl);
|
|
|
|
async function createIssue(
|
|
sessionId: string,
|
|
title: string,
|
|
description: string,
|
|
embeds: Map<string, Embed>,
|
|
) {
|
|
try {
|
|
const result = await api.project.createIssue(
|
|
project.id,
|
|
{
|
|
title,
|
|
description,
|
|
assignees: assignees.map(a => a.id),
|
|
embeds: [...embeds.values()],
|
|
labels,
|
|
},
|
|
sessionId,
|
|
);
|
|
|
|
void router.push({
|
|
resource: "project.issue",
|
|
project: project.id,
|
|
node: baseUrl,
|
|
issue: result.id,
|
|
});
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
modal.show({
|
|
component: ErrorModal,
|
|
props: {
|
|
title: "Coult not create issue",
|
|
subtitle: [
|
|
"There was an error while updating the issue.",
|
|
"Make sure you're authenticated.",
|
|
"Check your radicle-httpd logs for details.",
|
|
],
|
|
error: {
|
|
message: error.message,
|
|
stack: error.stack,
|
|
},
|
|
},
|
|
});
|
|
} else {
|
|
console.error(error);
|
|
}
|
|
}
|
|
}
|
|
|
|
$: session =
|
|
$httpdStore.state === "authenticated" && utils.isLocal(baseUrl.hostname)
|
|
? $httpdStore.session
|
|
: undefined;
|
|
</script>
|
|
|
|
<style>
|
|
.form {
|
|
display: flex;
|
|
min-height: 100%;
|
|
}
|
|
.metadata {
|
|
display: flex;
|
|
flex-direction: column;
|
|
font-size: var(--font-size-small);
|
|
padding: 1rem;
|
|
border-left: 1px solid var(--color-border-hint);
|
|
gap: 1.5rem;
|
|
width: 20rem;
|
|
}
|
|
.editor {
|
|
flex: 2;
|
|
}
|
|
</style>
|
|
|
|
<Layout {baseUrl} {project} activeTab="issues">
|
|
{#if session}
|
|
{@const session_ = session}
|
|
<div class="form">
|
|
<div class="editor" style="padding: 1rem;">
|
|
<CobHeader>
|
|
<svelte:fragment slot="title">
|
|
<TextInput
|
|
placeholder="Title"
|
|
autofocus
|
|
bind:value={issueTitle}
|
|
showKeyHint={false} />
|
|
</svelte:fragment>
|
|
<svelte:fragment slot="description">
|
|
<ExtendedTextarea
|
|
rawPath={rawPath(project.head)}
|
|
disallowEmptyBody
|
|
isValid={() => issueTitle.length > 0}
|
|
enableAttachments
|
|
submitCaption="Submit"
|
|
placeholder="Write a description"
|
|
on:submit={async ({ detail: { comment, embeds } }) => {
|
|
await createIssue(session_.id, issueTitle, comment, embeds);
|
|
}}
|
|
on:close={() => {
|
|
void router.push({
|
|
resource: "project.issues",
|
|
project: project.id,
|
|
node: baseUrl,
|
|
});
|
|
}} />
|
|
</svelte:fragment>
|
|
</CobHeader>
|
|
</div>
|
|
<div class="metadata">
|
|
<AssigneeInput
|
|
locallyAuthenticated={session &&
|
|
project.delegates.includes(`did:key:${session.publicKey}`)}
|
|
on:save={({ detail: updatedAssignees }) =>
|
|
(assignees = updatedAssignees)} />
|
|
<LabelInput
|
|
locallyAuthenticated={session &&
|
|
project.delegates.includes(`did:key:${session.publicKey}`)}
|
|
on:save={({ detail: updatedLabels }) => (labels = updatedLabels)} />
|
|
</div>
|
|
</div>
|
|
{:else}
|
|
<ErrorMessage
|
|
title="Not able to create a new issue"
|
|
description="Couldn't access issue creation. Make sure you're authenticated." />
|
|
{/if}
|
|
</Layout>
|