Simplify project view component

We refactor the project view by moving all sub-view related variables
into the respective sub-views.

Signed-off-by: Rūdolfs Ošiņš <rudolfs@osins.org>
This commit is contained in:
Rūdolfs Ošiņš
2023-06-20 14:59:58 +02:00
parent 7dab02c273
commit d4650ab482
6 changed files with 132 additions and 142 deletions
+86 -65
View File
@@ -1,10 +1,9 @@
<script lang="ts" strictEvents>
<script lang="ts">
import type { BaseUrl } from "@httpd-client";
import type { Session } from "@app/lib/httpd";
import { createEventDispatcher } from "svelte";
import * as httpd from "@app/lib/httpd";
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";
@@ -18,13 +17,12 @@
import Markdown from "@app/components/Markdown.svelte";
import TagInput from "@app/views/projects/Cob/TagInput.svelte";
import Textarea from "@app/components/Textarea.svelte";
import ErrorMessage from "@app/components/ErrorMessage.svelte";
export let session: Session;
export let projectId: string;
export let projectHead: string;
export let baseUrl: BaseUrl;
const dispatch = createEventDispatcher<{ create: string }>();
let preview: boolean = false;
let action: "create" | "view";
$: action =
@@ -41,7 +39,7 @@
const api = new HttpdClient(baseUrl);
async function createIssue() {
async function createIssue(sessionId: string) {
try {
const result = await api.project.createIssue(
projectId,
@@ -51,9 +49,20 @@
assignees: utils.stripDidPrefix(assignees),
tags: tags,
},
session.id,
sessionId,
);
dispatch("create", result.id);
void router.push({
resource: "projects",
params: {
id: projectId,
hostAndPort: httpd.api.hostAndPort,
view: {
resource: "issue",
params: { issue: result.id },
},
},
});
} catch {
modal.show({
component: AuthenticationErrorModal,
@@ -123,63 +132,75 @@
</style>
<main>
<div class="form">
<div class="editor">
<CobHeader {action} bind:title={issueTitle}>
<svelte:fragment slot="state">
{#if action === "view"}
<Badge variant="positive">open</Badge>
{/if}
</svelte:fragment>
<svelte:fragment slot="description">
{#if action === "create"}
<Textarea
resizable
bind:value={issueText}
on:submit={createIssue}
placeholder="Write a description" />
{:else if !issueText}
<p class="txt-missing">No description</p>
{:else}
<Markdown
content={issueText}
rawPath={utils.getRawBasePath(projectId, baseUrl, projectHead)} />
{/if}
</svelte:fragment>
<div class="author" slot="author">
{#if action === "view"}
opened by <Authorship authorId={session.publicKey} /> now
{/if}
{#if $httpdStore.state === "authenticated"}
{@const session = $httpdStore.session}
<div class="form">
<div class="editor">
<CobHeader {action} bind:title={issueTitle}>
<svelte:fragment slot="state">
{#if action === "view"}
<Badge variant="positive">open</Badge>
{/if}
</svelte:fragment>
<svelte:fragment slot="description">
{#if action === "create"}
<Textarea
resizable
bind:value={issueText}
on:submit={() => {
void createIssue(session.id);
}}
placeholder="Write a description" />
{:else if !issueText}
<p class="txt-missing">No description</p>
{:else}
<Markdown
content={issueText}
rawPath={utils.getRawBasePath(
projectId,
baseUrl,
projectHead,
)} />
{/if}
</svelte:fragment>
<div class="author" slot="author">
{#if action === "view"}
opened by <Authorship authorId={$httpdStore.session.publicKey} /> now
{/if}
</div>
</CobHeader>
<div class="actions">
<Button
size="small"
variant="text"
on:click={() => (preview = !preview)}>
{#if preview}
Resume editing
{:else}
Preview
{/if}
</Button>
<Button
disabled={!issueTitle}
size="small"
variant="secondary"
on:click={() => void createIssue(session.id)}>
Submit
</Button>
</div>
</CobHeader>
<div class="actions">
<Button
size="small"
variant="text"
on:click={() => (preview = !preview)}>
{#if preview}
Resume editing
{:else}
Preview
{/if}
</Button>
<Button
disabled={!issueTitle}
size="small"
variant="secondary"
on:click={createIssue}>
Submit
</Button>
</div>
<div class="metadata">
<AssigneeInput
{action}
on:save={({ detail: updatedAssignees }) =>
(assignees = updatedAssignees)} />
<TagInput
{action}
on:save={({ detail: updatedTags }) => (tags = updatedTags)} />
</div>
</div>
<div class="metadata">
<AssigneeInput
{action}
on:save={({ detail: updatedAssignees }) =>
(assignees = updatedAssignees)} />
<TagInput
{action}
on:save={({ detail: updatedTags }) => (tags = updatedTags)} />
</div>
</div>
{:else}
<ErrorMessage
message="Couldn't access issue creation. Make sure you're still logged in." />
{/if}
</main>
+4 -1
View File
@@ -21,11 +21,14 @@
import ProjectLink from "@app/components/ProjectLink.svelte";
import SquareButton from "@app/components/SquareButton.svelte";
export let search: string | undefined = undefined;
export let projectId: string;
export let state: IssueStatus;
export let baseUrl: BaseUrl;
export let issueCounters: { open: number; closed: number };
$: searchParams = new URLSearchParams(search || "");
$: state = (searchParams.get("state") as IssueStatus) || "open";
const perPage = 10;
let loading = false;
+9 -4
View File
@@ -63,14 +63,18 @@
import SquareButton from "@app/components/SquareButton.svelte";
import TagInput from "@app/views/projects/Cob/TagInput.svelte";
export let search: string | undefined = undefined;
export let projectId: string;
export let baseUrl: BaseUrl;
export let patch: Patch;
export let projectHead: string;
export let projectDefaultBranch: string;
export let revision: string;
export let currentTab: "activity" | "commits" | "files";
export let diff: string | undefined = undefined;
export let revision: string | undefined = undefined;
$: searchParams = new URLSearchParams(search || "");
$: currentTab =
(searchParams.get("tab") as "activity" | "commits" | "files") || "activity";
$: diff = searchParams.get("diff") || undefined;
const api = new HttpdClient(baseUrl);
@@ -136,7 +140,8 @@
}));
$: currentRevision =
patch.revisions.find(r => r.id === revision) || patch.revisions[0];
(revision && patch.revisions.find(r => r.id === revision)) ||
patch.revisions[patch.revisions.length - 1];
$: timelineTuple = patch.revisions.map<
[
{
+4 -1
View File
@@ -18,8 +18,8 @@
import ProjectLink from "@app/components/ProjectLink.svelte";
import SquareButton from "@app/components/SquareButton.svelte";
export let search: string | undefined = undefined;
export let projectId: string;
export let state: PatchStatus;
export let baseUrl: BaseUrl;
export let patchCounters: {
draft: number;
@@ -28,6 +28,9 @@
merged: number;
};
$: searchParams = new URLSearchParams(search || "");
$: state = (searchParams.get("state") as PatchStatus) || "open";
const perPage = 10;
let loading = false;
+8 -71
View File
@@ -1,18 +1,10 @@
<script lang="ts">
import type { IssueStatus } from "./Issues.svelte";
import type { PatchStatus } from "./Patches.svelte";
import type { Project } from "@httpd-client";
import type { ProjectLoadedView } from "@app/views/projects/router";
import * as httpd from "@app/lib/httpd";
import * as router from "@app/lib/router";
import * as utils from "@app/lib/utils";
import { HttpdClient } from "@httpd-client";
import { unreachable } from "@app/lib/utils";
import { httpdStore } from "@app/lib/httpd";
import Loading from "@app/components/Loading.svelte";
import ErrorMessage from "@app/components/ErrorMessage.svelte";
import SourceBrowsingHeader from "./SourceBrowsingHeader.svelte";
import Browser from "./Browser.svelte";
@@ -37,28 +29,7 @@
export let revision: string | undefined = undefined;
export let search: string | undefined = undefined;
$: searchParams = new URLSearchParams(search || "");
$: issueFilter = (searchParams.get("state") as IssueStatus) || "open";
$: patchTabFilter =
(searchParams.get("tab") as "activity" | "commits" | "files") || "activity";
$: patchFilter = (searchParams.get("state") as PatchStatus) || "open";
$: patchDiffFilter = searchParams.get("diff") || undefined;
$: baseUrl = utils.extractBaseUrl(hostAndPort);
$: api = new HttpdClient(baseUrl);
function handleIssueCreation({ detail: issueId }: CustomEvent<string>) {
void router.push({
resource: "projects",
params: {
id,
hostAndPort: httpd.api.hostAndPort,
view: {
resource: "issue",
params: { issue: issueId },
},
},
});
}
</script>
<style>
@@ -74,14 +45,7 @@
min-width: var(--content-min-width);
padding-bottom: 4rem;
}
main > .message {
padding: 0 2rem 0 8rem;
}
@media (max-width: 960px) {
main > .message {
padding-left: 2rem;
}
main {
padding-top: 2rem;
min-width: 0;
@@ -133,36 +97,12 @@
totalCommitCount={view.totalCommitCount}
commitHeaders={view.commitHeaders} />
{:else if view.resource === "commits"}
{#await api.project.getCommitBySha(id, view.params.selectedCommit)}
<Loading center />
{:then fetchedCommit}
<Commit commit={fetchedCommit} />
{:catch e}
<div class="message">
<ErrorMessage message="Couln't load commit." stackTrace={e} />
</div>
{/await}
<Commit commit={view.commit} />
{/if}
{:else if view.resource === "issues" && view.params?.view.resource === "new"}
{#if $httpdStore.state === "authenticated"}
<NewIssue
on:create={handleIssueCreation}
session={$httpdStore.session}
projectId={id}
projectHead={project.head}
{baseUrl} />
{:else}
<div class="message">
<ErrorMessage
message="Couldn't access issue creation. Make sure you're still logged in." />
</div>
{/if}
<NewIssue projectId={id} projectHead={project.head} {baseUrl} />
{:else if view.resource === "issues"}
<Issues
{baseUrl}
projectId={id}
issueCounters={project.issues}
state={issueFilter} />
<Issues {baseUrl} projectId={id} issueCounters={project.issues} {search} />
{:else if view.resource === "issue"}
<Issue
projectId={id}
@@ -173,20 +113,17 @@
<Patches
{baseUrl}
projectId={id}
state={patchFilter}
patchCounters={project.patches} />
patchCounters={project.patches}
{search} />
{:else if view.resource === "patch"}
{@const patch = view.params.loadedPatch}
{@const latestRevision = patch.revisions[patch.revisions.length - 1]}
<Patch
{patch}
patch={view.params.loadedPatch}
{baseUrl}
projectId={id}
projectDefaultBranch={project.defaultBranch}
projectHead={project.head}
revision={view.params.revision ?? latestRevision.id}
currentTab={patchTabFilter}
diff={patchDiffFilter} />
revision={view.params.revision}
{search} />
{:else}
{unreachable(view)}
{/if}
+21
View File
@@ -1,5 +1,6 @@
import type { LoadError } from "@app/lib/router/definitions";
import type {
Commit,
CommitHeader,
Issue,
Patch,
@@ -83,6 +84,7 @@ export type ProjectLoadedView =
| {
resource: "commits";
params: LoadedSourceBrowsingParams;
commit: Commit;
}
| {
resource: "history";
@@ -224,6 +226,25 @@ export async function loadProjectRoute(
},
},
};
}
if (params.view.resource === "commits") {
const loadedCommit = await api.project.getCommitBySha(
params.id,
commit,
);
return {
resource: "projects",
params: {
...params,
project,
view: {
resource: params.view.resource,
params: viewParams,
commit: loadedCommit,
},
},
};
} else {
return {
resource: "projects",