mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-15 19:30:38 +08:00
Add missing moved and copied file operations to Changeset
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
This commit is contained in:
@@ -106,7 +106,7 @@ const diffAddedDeletedModifiedChangesetSchema = object({
|
||||
}),
|
||||
}) satisfies ZodSchema<DiffAddedDeletedModifiedChangeset>;
|
||||
|
||||
interface DiffCopiedMovedChangeset {
|
||||
export interface DiffCopiedMovedChangeset {
|
||||
newPath: string;
|
||||
oldPath: string;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,18 @@
|
||||
import { pluralize } from "@app/lib/pluralize";
|
||||
|
||||
import FileDiff from "@app/views/projects/SourceBrowser/FileDiff.svelte";
|
||||
import FileLocationChange from "@app/views/projects/SourceBrowser/FileLocationChange.svelte";
|
||||
|
||||
export let diff: Diff;
|
||||
export let revision: string;
|
||||
|
||||
const diffDescription = ({ modified, added, deleted }: Diff): string => {
|
||||
const diffDescription = ({
|
||||
modified,
|
||||
added,
|
||||
deleted,
|
||||
moved,
|
||||
copied,
|
||||
}: Diff): string => {
|
||||
const s = [];
|
||||
|
||||
if (modified.length) {
|
||||
@@ -22,6 +29,12 @@
|
||||
if (deleted.length) {
|
||||
s.push(`${deleted.length} ${pluralize("file", deleted.length)} deleted`);
|
||||
}
|
||||
if (copied.length) {
|
||||
s.push(`${copied.length} ${pluralize("file", copied.length)} copied`);
|
||||
}
|
||||
if (moved.length) {
|
||||
s.push(`${moved.length} ${pluralize("file", moved.length)} moved`);
|
||||
}
|
||||
return s.join(", ");
|
||||
};
|
||||
</script>
|
||||
@@ -54,12 +67,18 @@
|
||||
</div>
|
||||
<div class="diff-listing">
|
||||
{#each diff.added as file}
|
||||
<FileDiff on:browse {file} {revision} mode="added" />
|
||||
<FileDiff {file} {revision} headerBadgeCaption="added" />
|
||||
{/each}
|
||||
{#each diff.deleted as file}
|
||||
<FileDiff on:browse {file} {revision} mode="deleted" />
|
||||
<FileDiff {file} {revision} headerBadgeCaption="deleted" />
|
||||
{/each}
|
||||
{#each diff.modified as file}
|
||||
<FileDiff on:browse {file} {revision} />
|
||||
<FileDiff {file} {revision} />
|
||||
{/each}
|
||||
{#each diff.moved as file}
|
||||
<FileLocationChange {file} {revision} mode="moved" />
|
||||
{/each}
|
||||
{#each diff.copied as file}
|
||||
<FileLocationChange {file} {revision} mode="copied" />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
export let file: DiffAddedDeletedModifiedChangeset;
|
||||
export let revision: string;
|
||||
export let mode: string | null = null;
|
||||
export let headerBadgeCaption: "added" | "deleted" | undefined = undefined;
|
||||
|
||||
let collapsed = false;
|
||||
|
||||
@@ -163,9 +163,9 @@
|
||||
</div>
|
||||
<div class="actions">
|
||||
<p class="txt-regular">{file.path}</p>
|
||||
{#if mode === "added"}
|
||||
{#if headerBadgeCaption === "added"}
|
||||
<Badge variant="positive">added</Badge>
|
||||
{:else if mode === "deleted"}
|
||||
{:else if headerBadgeCaption === "deleted"}
|
||||
<Badge variant="negative">deleted</Badge>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<script lang="ts">
|
||||
import type { DiffCopiedMovedChangeset } from "@httpd-client/lib/project/commit";
|
||||
|
||||
import Badge from "@app/components/Badge.svelte";
|
||||
import Icon from "@app/components/Icon.svelte";
|
||||
import ProjectLink from "@app/components/ProjectLink.svelte";
|
||||
|
||||
export let file: DiffCopiedMovedChangeset;
|
||||
export let revision: string;
|
||||
export let mode: "moved" | "copied";
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
border: 1px solid var(--color-foreground-4);
|
||||
border-radius: var(--border-radius-small);
|
||||
margin-bottom: 2rem;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
.header {
|
||||
align-items: center;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 3rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
.browse {
|
||||
margin-left: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id={file.newPath} class="wrapper">
|
||||
<header class="header">
|
||||
<div class="actions">
|
||||
<p class="txt-regular">{file.oldPath} → {file.newPath}</p>
|
||||
{#if mode === "moved"}
|
||||
<Badge variant="foreground">moved</Badge>
|
||||
{:else if mode === "copied"}
|
||||
<Badge variant="foreground">copied</Badge>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="browse" title="View file">
|
||||
<ProjectLink
|
||||
projectParams={{
|
||||
view: { resource: "tree" },
|
||||
path: file.newPath,
|
||||
revision,
|
||||
search: undefined,
|
||||
}}>
|
||||
<Icon name="browse" />
|
||||
</ProjectLink>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
@@ -81,6 +81,17 @@ test("deleted file", async ({ page }) => {
|
||||
await expect(page.locator("text=.hidden deleted")).toBeVisible();
|
||||
});
|
||||
|
||||
test("moved file", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${sourceBrowsingUrl}/remotes/${aliceRemote}/commits/835d9a52066c46d86cdee88f2863e9a804c7fa50/commits/`,
|
||||
);
|
||||
await expect(
|
||||
page.locator("header").filter({ hasText: "moves/111.txt → moves/222.txt" }),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
// TODO: Add copy operation detection spec.
|
||||
|
||||
test("navigation to source tree at specific revision", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${sourceBrowsingUrl}/commits/0801aceeab500033f8d608778218657bd626ef73`,
|
||||
|
||||
BIN
Binary file not shown.
@@ -251,6 +251,9 @@ export async function createSourceBrowsingFixture(
|
||||
|
||||
await alice.git(["clone", sourceBrowsingDir], { cwd: alice.checkoutPath });
|
||||
await alice.git(["checkout", "feature/branch"], { cwd: aliceProjectPath });
|
||||
await alice.git(["checkout", "feature/move-copy-files"], {
|
||||
cwd: aliceProjectPath,
|
||||
});
|
||||
await alice.git(["checkout", "orphaned-branch"], { cwd: aliceProjectPath });
|
||||
await alice.git(["checkout", "main"], { cwd: aliceProjectPath });
|
||||
await alice.rad(
|
||||
|
||||
Reference in New Issue
Block a user