diff --git a/scm-ui/ui-components/src/LinkPaginator.tsx b/scm-ui/ui-components/src/LinkPaginator.tsx index cf6c55bbd4..0adbc7554c 100644 --- a/scm-ui/ui-components/src/LinkPaginator.tsx +++ b/scm-ui/ui-components/src/LinkPaginator.tsx @@ -132,9 +132,9 @@ class LinkPaginator extends React.Component { diff --git a/scm-ui/ui-components/src/urls.test.ts b/scm-ui/ui-components/src/urls.test.ts index 28346c9def..79557a2b02 100644 --- a/scm-ui/ui-components/src/urls.test.ts +++ b/scm-ui/ui-components/src/urls.test.ts @@ -22,7 +22,12 @@ * SOFTWARE. */ -import { concat, getPageFromMatch, getQueryStringFromLocation, withEndingSlash } from "./urls"; +import { + concat, + getNamespaceAndPageFromMatch, + getQueryStringFromLocation, + withEndingSlash +} from "./urls"; describe("tests for withEndingSlash", () => { it("should append missing slash", () => { @@ -42,28 +47,41 @@ describe("concat tests", () => { }); }); -describe("tests for getPageFromMatch", () => { - function createMatch(page: string) { +describe("tests for getNamespaceAndPageFromMatch", () => { + function createMatch(namespace?: string, page?: string) { return { - params: { - page - } + params: { namespace, page } }; } - it("should return 1 for NaN", () => { - const match = createMatch("any"); - expect(getPageFromMatch(match)).toBe(1); + it("should return no namespace and page 1 for neither namespace nor page", () => { + const match = createMatch(); + expect(getNamespaceAndPageFromMatch(match)).toEqual({ namespace: undefined, page: 1 }); }); - it("should return 1 for 0", () => { + it("should return no namespace and page 1 for 0 as only parameter", () => { const match = createMatch("0"); - expect(getPageFromMatch(match)).toBe(1); + expect(getNamespaceAndPageFromMatch(match)).toEqual({ namespace: undefined, page: 1 }); }); - it("should return the given number", () => { + it("should return no namespace and given number as page, when only a number is given", () => { const match = createMatch("42"); - expect(getPageFromMatch(match)).toBe(42); + expect(getNamespaceAndPageFromMatch(match)).toEqual({ namespace: undefined, page: 42 }); + }); + + it("should return big number as namespace and page 1, when only a big number is given", () => { + const match = createMatch("1337"); + expect(getNamespaceAndPageFromMatch(match)).toEqual({ namespace: "1337", page: 1 }); + }); + + it("should namespace and page 1, when only a string is given", () => { + const match = createMatch("something"); + expect(getNamespaceAndPageFromMatch(match)).toEqual({ namespace: "something", page: 1 }); + }); + + it("should namespace and given page, when namespace and page are given", () => { + const match = createMatch("something", "42"); + expect(getNamespaceAndPageFromMatch(match)).toEqual({ namespace: "something", page: 42 }); }); }); diff --git a/scm-ui/ui-components/src/urls.ts b/scm-ui/ui-components/src/urls.ts index c8fff6efa1..98bdb7137b 100644 --- a/scm-ui/ui-components/src/urls.ts +++ b/scm-ui/ui-components/src/urls.ts @@ -46,10 +46,33 @@ export function concat(base: string, ...parts: string[]) { return url; } +export function getNamespaceAndPageFromMatch(match: any) { + const namespaceFromMatch: string = match.params.namespace; + const pageFromMatch: string = match.params.page; + + if (!namespaceFromMatch && !pageFromMatch) { + return { namespace: undefined, page: 1 }; + } + + if (!pageFromMatch) { + if (namespaceFromMatch.match(/^\d{1,3}$/)) { + return { namespace: undefined, page: parsePageNumber(namespaceFromMatch) }; + } else { + return { namespace: namespaceFromMatch, page: 1 }; + } + } + + return { namespace: namespaceFromMatch, page: parsePageNumber(pageFromMatch) }; +} + export function getPageFromMatch(match: any) { - let page = parseInt(match.params.page, 10); + return parsePageNumber(match.params.page); +} + +function parsePageNumber(pageAsString: string) { + const page = parseInt(pageAsString, 10); if (isNaN(page) || !page) { - page = 1; + return 1; } return page; } diff --git a/scm-ui/ui-webapp/src/containers/Main.tsx b/scm-ui/ui-webapp/src/containers/Main.tsx index ec72e372eb..48e6f37a76 100644 --- a/scm-ui/ui-webapp/src/containers/Main.tsx +++ b/scm-ui/ui-webapp/src/containers/Main.tsx @@ -77,7 +77,8 @@ class Main extends React.Component { - + + diff --git a/scm-ui/ui-webapp/src/repos/containers/Overview.tsx b/scm-ui/ui-webapp/src/repos/containers/Overview.tsx index abbaf74eed..09cb66defb 100644 --- a/scm-ui/ui-webapp/src/repos/containers/Overview.tsx +++ b/scm-ui/ui-webapp/src/repos/containers/Overview.tsx @@ -52,30 +52,33 @@ type Props = WithTranslation & showCreateButton: boolean; collection: RepositoryCollection; page: number; + namespace: string; reposLink: string; // dispatched functions - fetchReposByPage: (link: string, page: number, filter?: string) => void; + fetchReposByPage: (link: string, page: number, namespace?: string, filter?: string) => void; }; class Overview extends React.Component { componentDidMount() { - const { fetchReposByPage, reposLink, page, location } = this.props; - fetchReposByPage(reposLink, page, urls.getQueryStringFromLocation(location)); + const { fetchReposByPage, reposLink, namespace, page, location } = this.props; + fetchReposByPage(reposLink, page, namespace, urls.getQueryStringFromLocation(location)); } componentDidUpdate = (prevProps: Props) => { - const { loading, collection, page, reposLink, location, fetchReposByPage } = this.props; + const { loading, collection, namespace, page, reposLink, location, fetchReposByPage } = this.props; if (collection && page && !loading) { const statePage: number = collection.page + 1; if (page !== statePage || prevProps.location.search !== location.search) { - fetchReposByPage(reposLink, page, urls.getQueryStringFromLocation(location)); + fetchReposByPage(reposLink, page, namespace, urls.getQueryStringFromLocation(location)); } } }; render() { - const { error, loading, showCreateButton, t } = this.props; + const { error, loading, showCreateButton, namespace, t } = this.props; + + const link = namespace ? `repos/${namespace}` : "repos"; return ( @@ -83,7 +86,7 @@ class Overview extends React.Component { @@ -133,7 +136,7 @@ const mapStateToProps = (state: any, ownProps: Props) => { const collection = getRepositoryCollection(state); const loading = isFetchReposPending(state); const error = getFetchReposFailure(state); - const page = urls.getPageFromMatch(match); + const { namespace, page } = urls.getNamespaceAndPageFromMatch(match); const showCreateButton = isAbleToCreateRepos(state); const reposLink = getRepositoriesLink(state); return { @@ -141,6 +144,7 @@ const mapStateToProps = (state: any, ownProps: Props) => { loading, error, page, + namespace, showCreateButton, reposLink }; @@ -148,9 +152,10 @@ const mapStateToProps = (state: any, ownProps: Props) => { const mapDispatchToProps = (dispatch: any) => { return { - fetchReposByPage: (link: string, page: number, filter?: string) => { - dispatch(fetchReposByPage(link, page, filter)); + fetchReposByPage: (link: string, page: number, namespace?: string, filter?: string) => { + dispatch(fetchReposByPage(link, page, namespace, filter)); } }; }; + export default connect(mapStateToProps, mapDispatchToProps)(withTranslation("repos")(withRouter(Overview))); diff --git a/scm-ui/ui-webapp/src/repos/modules/repos.ts b/scm-ui/ui-webapp/src/repos/modules/repos.ts index fc20ddd6f0..6c56748e98 100644 --- a/scm-ui/ui-webapp/src/repos/modules/repos.ts +++ b/scm-ui/ui-webapp/src/repos/modules/repos.ts @@ -67,11 +67,13 @@ export function fetchRepos(link: string) { return fetchReposByLink(link); } -export function fetchReposByPage(link: string, page: number, filter?: string) { +export function fetchReposByPage(link: string, page: number, namespace?: string, filter?: string) { + const namespacePath = namespace ? `${namespace}/` : ""; + const linkWithPage = `${link}${namespacePath}?page=${page - 1}`; if (filter) { - return fetchReposByLink(`${link}?page=${page - 1}&q=${decodeURIComponent(filter)}`); + return fetchReposByLink(`${linkWithPage}}&q=${decodeURIComponent(filter)}`); } - return fetchReposByLink(`${link}?page=${page - 1}`); + return fetchReposByLink(linkWithPage); } function appendSortByLink(url: string) {