mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-15 09:46:16 +01:00
Adds a new extension point repository.overview.listOptions that can be used to set the page size, whether to list archived repositories or not and potentially other options for the repository overview. If no extension is bound, the default values will be used.
Committed-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
This commit is contained in:
committed by
SCM-Manager
parent
34bfe49d3e
commit
6ba792e5bc
2
gradle/changelog/extension_point_for_page_size.yaml
Normal file
2
gradle/changelog/extension_point_for_page_size.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- type: added
|
||||
description: Extension point for page size
|
||||
@@ -125,6 +125,34 @@ describe("Test repository hooks", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should hide archived repositories", async () => {
|
||||
const queryClient = createInfiniteCachingClient();
|
||||
setIndexLink(queryClient, "repositories", "/repos");
|
||||
fetchMock.get("/api/v2/repos", repositoryCollection, {
|
||||
query: {
|
||||
showArchived: "false"
|
||||
}
|
||||
});
|
||||
|
||||
await expectCollection(queryClient, {
|
||||
showArchived: false
|
||||
});
|
||||
});
|
||||
|
||||
it("should set the page size", async () => {
|
||||
const queryClient = createInfiniteCachingClient();
|
||||
setIndexLink(queryClient, "repositories", "/repos");
|
||||
fetchMock.get("/api/v2/repos", repositoryCollection, {
|
||||
query: {
|
||||
pageSize: "25"
|
||||
}
|
||||
});
|
||||
|
||||
await expectCollection(queryClient, {
|
||||
pageSize: 25
|
||||
});
|
||||
});
|
||||
|
||||
it("should append search query", async () => {
|
||||
const queryClient = createInfiniteCachingClient();
|
||||
setIndexLink(queryClient, "repositories", "/repos");
|
||||
|
||||
@@ -47,6 +47,8 @@ export type UseRepositoriesRequest = {
|
||||
search?: string;
|
||||
page?: number | string;
|
||||
disabled?: boolean;
|
||||
pageSize?: number;
|
||||
showArchived?: boolean;
|
||||
};
|
||||
|
||||
export const useRepositories = (request?: UseRepositoriesRequest): ApiResult<RepositoryCollection> => {
|
||||
@@ -59,6 +61,12 @@ export const useRepositories = (request?: UseRepositoriesRequest): ApiResult<Rep
|
||||
if (request?.search) {
|
||||
queryParams.q = request.search;
|
||||
}
|
||||
if (request?.pageSize) {
|
||||
queryParams.pageSize = request.pageSize.toString();
|
||||
}
|
||||
if (request?.showArchived !== undefined) {
|
||||
queryParams.showArchived = request.showArchived.toString();
|
||||
}
|
||||
if (request?.page) {
|
||||
queryParams.page = request.page.toString();
|
||||
}
|
||||
|
||||
@@ -257,6 +257,14 @@ export type RepositoryOverviewTitle = RenderableExtensionPointDefinition<"reposi
|
||||
export type RepositoryOverviewSubtitleExtension = RepositoryOverviewSubtitle;
|
||||
export type RepositoryOverviewSubtitle = RenderableExtensionPointDefinition<"repository.overview.subtitle">;
|
||||
|
||||
/**
|
||||
* Specify options for the repository overview like the page size
|
||||
*/
|
||||
export type RepositoryOverviewListOptionsExtensionPoint = ExtensionPointDefinition<
|
||||
"repository.overview.listOptions",
|
||||
() => { pageSize?: number; showArchived?: boolean }
|
||||
>;
|
||||
|
||||
// From docs
|
||||
|
||||
export type AdminNavigation = RenderableExtensionPointDefinition<"admin.navigation", { links: Links; url: string }>;
|
||||
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
import RepositoryList from "../components/list";
|
||||
import { useNamespaceAndNameContext, useNamespaces, useRepositories } from "@scm-manager/ui-api";
|
||||
import { NamespaceCollection, RepositoryCollection } from "@scm-manager/ui-types";
|
||||
import { ExtensionPoint, extensionPoints, useBinder } from "@scm-manager/ui-extensions";
|
||||
import { binder, ExtensionPoint, extensionPoints, useBinder } from "@scm-manager/ui-extensions";
|
||||
import styled from "styled-components";
|
||||
|
||||
const StickyColumn = styled.div`
|
||||
@@ -64,12 +64,19 @@ const useOverviewData = () => {
|
||||
const location = useLocation();
|
||||
const search = urls.getQueryStringFromLocation(location);
|
||||
|
||||
const listOptions = binder.getExtension<extensionPoints.RepositoryOverviewListOptionsExtensionPoint>(
|
||||
"repository.overview.listOptions"
|
||||
);
|
||||
|
||||
const listOptionsValue = listOptions ? listOptions() : { pageSize: 10, showArchived: true };
|
||||
|
||||
const request = {
|
||||
namespace: namespaces?._embedded.namespaces.find((n) => n.namespace === namespace),
|
||||
// ui starts counting by 1,
|
||||
// but backend starts counting by 0
|
||||
page: page - 1,
|
||||
search,
|
||||
...listOptionsValue,
|
||||
// if a namespaces is selected we have to wait
|
||||
// until the list of namespaces are loaded from the server
|
||||
// also do not fetch repositories if an invalid namespace is selected
|
||||
|
||||
@@ -112,9 +112,10 @@ public class RepositoryCollectionResource {
|
||||
@DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize,
|
||||
@QueryParam("sortBy") String sortBy,
|
||||
@DefaultValue("false") @QueryParam("desc") boolean desc,
|
||||
@DefaultValue("true") @QueryParam("showArchived") boolean showArchived,
|
||||
@DefaultValue("") @QueryParam("q") String search
|
||||
) {
|
||||
return adapter.getAll(page, pageSize, createSearchPredicate(search), sortBy, desc,
|
||||
return adapter.getAll(page, pageSize, createSearchPredicate(search, showArchived), sortBy, desc,
|
||||
pageResult -> repositoryCollectionToDtoMapper.map(page, pageSize, pageResult));
|
||||
}
|
||||
|
||||
@@ -144,9 +145,10 @@ public class RepositoryCollectionResource {
|
||||
@DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize,
|
||||
@QueryParam("sortBy") String sortBy,
|
||||
@DefaultValue("false") @QueryParam("desc") boolean desc,
|
||||
@DefaultValue("true") @QueryParam("showArchived") boolean showArchived,
|
||||
@DefaultValue("") @QueryParam("q") String search
|
||||
) {
|
||||
return adapter.getAll(page, pageSize, createSearchPredicate(namespace, search), sortBy, desc,
|
||||
return adapter.getAll(page, pageSize, createSearchPredicate(namespace, search, showArchived), sortBy, desc,
|
||||
pageResult -> repositoryCollectionToDtoMapper.map(namespace, page, pageSize, pageResult));
|
||||
}
|
||||
|
||||
@@ -221,21 +223,24 @@ public class RepositoryCollectionResource {
|
||||
return SecurityUtils.getSubject().getPrincipals().oneByType(User.class).getName();
|
||||
}
|
||||
|
||||
private Predicate<Repository> createSearchPredicate(String namespace, String search) {
|
||||
if (isNullOrEmpty(search)) {
|
||||
private Predicate<Repository> createSearchPredicate(String namespace, String search, boolean showArchived) {
|
||||
if (isNullOrEmpty(search) && showArchived) {
|
||||
return repository -> repository.getNamespace().equals(namespace);
|
||||
}
|
||||
SearchRequest searchRequest = new SearchRequest(search, true);
|
||||
return repository -> repository.getNamespace().equals(namespace)
|
||||
&& (showArchived || !repository.isArchived())
|
||||
&& SearchUtil.matchesOne(searchRequest, repository.getName(), repository.getNamespace(), repository.getDescription());
|
||||
}
|
||||
|
||||
private Predicate<Repository> createSearchPredicate(String search) {
|
||||
if (isNullOrEmpty(search)) {
|
||||
private Predicate<Repository> createSearchPredicate(String search, boolean showArchived) {
|
||||
if (isNullOrEmpty(search) && showArchived) {
|
||||
return user -> true;
|
||||
}
|
||||
SearchRequest searchRequest = new SearchRequest(search, true);
|
||||
return repository -> SearchUtil.matchesOne(searchRequest, repository.getName(), repository.getNamespace(), repository.getDescription());
|
||||
return repository ->
|
||||
(showArchived || !repository.isArchived())
|
||||
&& SearchUtil.matchesOne(searchRequest, repository.getName(), repository.getNamespace(), repository.getDescription());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ import java.time.Instant;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.stream.Stream.of;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_ACCEPTED;
|
||||
@@ -223,7 +224,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
@Test
|
||||
public void shouldFindExistingRepository() throws URISyntaxException, UnsupportedEncodingException {
|
||||
createRepository("space", "repo");
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo");
|
||||
|
||||
@@ -237,7 +237,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
public void shouldGetAll() throws URISyntaxException, UnsupportedEncodingException {
|
||||
PageResult<Repository> singletonPageResult = createSingletonPageResult(createRepository("space", "repo"));
|
||||
when(repositoryManager.getPage(any(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2);
|
||||
|
||||
@@ -247,11 +246,40 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
assertTrue(response.getContentAsString().contains("\"name\":\"repo\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetAllButArchived() throws URISyntaxException {
|
||||
PageResult<Repository> singletonPageResult = new PageResult<>(emptyList(), 0);
|
||||
when(repositoryManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "?showArchived=false");
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
Predicate<Repository> predicate = filterCaptor.getValue();
|
||||
Repository repository = createRepository("hitchhiker", "hog");
|
||||
assertThat(predicate.test(repository)).isTrue();
|
||||
repository.setArchived(true);
|
||||
assertThat(predicate.test(repository)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetAllIncludingArchivedByDefault() throws URISyntaxException {
|
||||
PageResult<Repository> singletonPageResult = new PageResult<>(emptyList(), 0);
|
||||
when(repositoryManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
Predicate<Repository> predicate = filterCaptor.getValue();
|
||||
Repository repository = createRepository("hitchhiker", "hog");
|
||||
assertThat(predicate.test(repository)).isTrue();
|
||||
repository.setArchived(true);
|
||||
assertThat(predicate.test(repository)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateFilterForSearch() throws URISyntaxException {
|
||||
PageResult<Repository> singletonPageResult = createSingletonPageResult(createRepository("space", "repo"));
|
||||
when(repositoryManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "?q=Rep");
|
||||
|
||||
@@ -267,7 +295,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
public void shouldCreateFilterForNamespace() throws URISyntaxException {
|
||||
PageResult<Repository> singletonPageResult = createSingletonPageResult(createRepository("space", "repo"));
|
||||
when(repositoryManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space");
|
||||
|
||||
@@ -283,7 +310,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
public void shouldCreateFilterForNamespaceWithQuery() throws URISyntaxException {
|
||||
PageResult<Repository> singletonPageResult = createSingletonPageResult(createRepository("space", "repo"));
|
||||
when(repositoryManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space?q=Rep");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user