Collapse folders with only one child folder (#1951)

Collapses a folder in code view which only has another folder as its only child. This lets you access a sub-folder which has content directly instead of navigating down the folder tree by clicking every folder separately.

Co-authored-by: René Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
Matthias Thieroff
2022-02-15 10:59:32 +01:00
committed by GitHub
parent 8d9c18c23c
commit 44f0046f25
13 changed files with 572 additions and 127 deletions

View File

@@ -126,7 +126,7 @@ describe("Test sources hooks", () => {
describe("useSources tests", () => {
it("should return root directory", async () => {
const queryClient = createInfiniteCachingClient();
fetchMock.getOnce("/api/v2/src", rootDirectory);
fetchMock.getOnce("/api/v2/src?collapse=true", rootDirectory);
const { result, waitFor } = renderHook(() => useSources(puzzle42), {
wrapper: createWrapper(undefined, queryClient),
});
@@ -136,7 +136,7 @@ describe("Test sources hooks", () => {
it("should return file from url with revision and path", async () => {
const queryClient = createInfiniteCachingClient();
fetchMock.getOnce("/api/v2/src/abc/README.md", readmeMd);
fetchMock.getOnce("/api/v2/src/abc/README.md?collapse=true", readmeMd);
const { result, waitFor } = renderHook(() => useSources(puzzle42, { revision: "abc", path: "README.md" }), {
wrapper: createWrapper(undefined, queryClient),
});
@@ -146,7 +146,7 @@ describe("Test sources hooks", () => {
it("should fetch next page", async () => {
const queryClient = createInfiniteCachingClient();
fetchMock.getOnce("/api/v2/src", mainDirectoryTruncated);
fetchMock.getOnce("/api/v2/src?collapse=true", mainDirectoryTruncated);
fetchMock.getOnce("/api/v2/src/2", mainDirectory);
const { result, waitFor, waitForNextUpdate } = renderHook(() => useSources(puzzle42), {
wrapper: createWrapper(undefined, queryClient),
@@ -168,7 +168,7 @@ describe("Test sources hooks", () => {
it("should refetch if partial files exists", async () => {
const queryClient = createInfiniteCachingClient();
fetchMock.get(
"/api/v2/src",
"/api/v2/src?collapse=true",
{
...mainDirectory,
_embedded: {
@@ -180,7 +180,7 @@ describe("Test sources hooks", () => {
}
);
fetchMock.get(
"/api/v2/src",
"/api/v2/src?collapse=true",
{
...mainDirectory,
_embedded: {
@@ -206,9 +206,9 @@ describe("Test sources hooks", () => {
it("should not refetch if computation is aborted", async () => {
const queryClient = createInfiniteCachingClient();
fetchMock.getOnce("/api/v2/src/abc/main/special.md", sepecialMdComputationAborted, { repeat: 1 });
fetchMock.getOnce("/api/v2/src/abc/main/special.md?collapse=true", sepecialMdComputationAborted, { repeat: 1 });
// should never be called
fetchMock.getOnce("/api/v2/src/abc/main/special.md", sepecialMd, {
fetchMock.getOnce("/api/v2/src/abc/main/special.md?collapse=true", sepecialMd, {
repeat: 1,
overwriteRoutes: false,
});

View File

@@ -28,17 +28,20 @@ import * as urls from "./urls";
import { useInfiniteQuery } from "react-query";
import { repoQueryKey } from "./keys";
import { useEffect } from "react";
import { createQueryString } from "./utils";
export type UseSourcesOptions = {
revision?: string;
path?: string;
refetchPartialInterval?: number;
enabled?: boolean;
collapse?: boolean;
};
const UseSourcesDefaultOptions: UseSourcesOptions = {
enabled: true,
refetchPartialInterval: 3000,
collapse: true
};
export const useSources = (repository: Repository, opts: UseSourcesOptions = UseSourcesDefaultOptions) => {
@@ -48,7 +51,7 @@ export const useSources = (repository: Repository, opts: UseSourcesOptions = Use
};
const link = createSourcesLink(repository, options);
const { isLoading, error, data, isFetchingNextPage, fetchNextPage, refetch } = useInfiniteQuery<File, Error, File>(
repoQueryKey(repository, "sources", options.revision || "", options.path || ""),
repoQueryKey(repository, "sources", options.revision || "", options.path || "", options.collapse ? "collapse" : ""),
({ pageParam }) => {
return apiClient.get(pageParam || link).then((response) => response.json());
},
@@ -93,6 +96,9 @@ const createSourcesLink = (repository: Repository, options: UseSourcesOptions) =
link = urls.concat(link, options.path);
}
}
if (options.collapse) {
return `${link}?${createQueryString({ collapse: "true" })}`;
}
return link;
};