mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-02 19:45:51 +01:00
Add settings icon to namespace group header
This commit is contained in:
@@ -27,7 +27,7 @@ import classNames from "classnames";
|
||||
import styled from "styled-components";
|
||||
|
||||
type Props = {
|
||||
name: string;
|
||||
name: ReactNode;
|
||||
url?: string;
|
||||
elements: ReactNode[];
|
||||
};
|
||||
|
||||
@@ -58,5 +58,6 @@ export type NamespaceCollection = {
|
||||
|
||||
export type RepositoryGroup = {
|
||||
name: string;
|
||||
namespace: Namespace;
|
||||
repositories: Repository[];
|
||||
};
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { CardColumnGroup, RepositoryEntry } from "@scm-manager/ui-components";
|
||||
import { RepositoryGroup } from "@scm-manager/ui-types";
|
||||
import { Icon } from "@scm-manager/ui-components";
|
||||
|
||||
type Props = {
|
||||
group: RepositoryGroup;
|
||||
@@ -32,10 +34,23 @@ type Props = {
|
||||
class RepositoryGroupEntry extends React.Component<Props> {
|
||||
render() {
|
||||
const { group } = this.props;
|
||||
const settingsLink = group.namespace?._links?.permissions && (
|
||||
<Link to={`/namespace/${group.name}/settings`}>
|
||||
<Icon color={"is-link"} name={"cog"} />
|
||||
</Link>
|
||||
);
|
||||
const namespaceHeader = (
|
||||
<>
|
||||
<Link to={`/repos/${group.name}/`} className={"has-text-dark"}>
|
||||
{group.name}
|
||||
</Link>{" "}
|
||||
{settingsLink}
|
||||
</>
|
||||
);
|
||||
const entries = group.repositories.map((repository, index) => {
|
||||
return <RepositoryEntry repository={repository} key={index} />;
|
||||
});
|
||||
return <CardColumnGroup name={group.name} url={`/repos/${group.name}/`} elements={entries} />;
|
||||
return <CardColumnGroup name={namespaceHeader} elements={entries} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,20 +23,21 @@
|
||||
*/
|
||||
import React from "react";
|
||||
|
||||
import { Repository } from "@scm-manager/ui-types";
|
||||
import { NamespaceCollection, Repository } from "@scm-manager/ui-types";
|
||||
|
||||
import groupByNamespace from "./groupByNamespace";
|
||||
import RepositoryGroupEntry from "./RepositoryGroupEntry";
|
||||
|
||||
type Props = {
|
||||
repositories: Repository[];
|
||||
namespaces: NamespaceCollection;
|
||||
};
|
||||
|
||||
class RepositoryList extends React.Component<Props> {
|
||||
render() {
|
||||
const { repositories } = this.props;
|
||||
const { repositories, namespaces } = this.props;
|
||||
|
||||
const groups = groupByNamespace(repositories);
|
||||
const groups = groupByNamespace(repositories, namespaces);
|
||||
return (
|
||||
<div className="content">
|
||||
{groups.map(group => {
|
||||
|
||||
@@ -73,21 +73,29 @@ it("should group the repositories by their namespace", () => {
|
||||
hitchhikerHeartOfGold,
|
||||
hitchhikerPuzzle42
|
||||
];
|
||||
const namespaces = {
|
||||
_embedded: {
|
||||
namespaces: [{ namespace: "hitchhiker" }, { namespace: "slarti" }, { namespace: "zaphod" }]
|
||||
}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
{
|
||||
name: "hitchhiker",
|
||||
namespace: { namespace: "hitchhiker" },
|
||||
repositories: [hitchhikerHeartOfGold, hitchhikerPuzzle42, hitchhikerRestand]
|
||||
},
|
||||
{
|
||||
name: "slarti",
|
||||
namespace: { namespace: "slarti" },
|
||||
repositories: [slartiFjords, slartiBlueprintsFjords]
|
||||
},
|
||||
{
|
||||
name: "zaphod",
|
||||
namespace: { namespace: "zaphod" },
|
||||
repositories: [zaphodMarvinFirmware]
|
||||
}
|
||||
];
|
||||
|
||||
expect(groupByNamespace(repositories)).toEqual(expected);
|
||||
expect(groupByNamespace(repositories, namespaces)).toEqual(expected);
|
||||
});
|
||||
|
||||
@@ -22,17 +22,22 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Repository, RepositoryGroup } from "@scm-manager/ui-types";
|
||||
import { NamespaceCollection, Repository, RepositoryGroup } from "@scm-manager/ui-types";
|
||||
|
||||
export default function groupByNamespace(repositories: Repository[]): RepositoryGroup[] {
|
||||
export default function groupByNamespace(
|
||||
repositories: Repository[],
|
||||
namespaces: NamespaceCollection
|
||||
): RepositoryGroup[] {
|
||||
const groups = {};
|
||||
for (const repository of repositories) {
|
||||
const groupName = repository.namespace;
|
||||
|
||||
let group = groups[groupName];
|
||||
if (!group) {
|
||||
const namespace = findNamespace(namespaces, groupName);
|
||||
group = {
|
||||
name: groupName,
|
||||
namespace: namespace,
|
||||
repositories: []
|
||||
};
|
||||
groups[groupName] = group;
|
||||
@@ -58,3 +63,7 @@ function sortByName(a, b) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function findNamespace(namespaces: NamespaceCollection, namespaceToFind: string) {
|
||||
return namespaces._embedded.namespaces.filter(namespace => namespace.namespace === namespaceToFind)[0];
|
||||
}
|
||||
|
||||
@@ -133,12 +133,12 @@ class Overview extends React.Component<Props> {
|
||||
}
|
||||
|
||||
renderRepositoryList() {
|
||||
const { collection, page, location, t } = this.props;
|
||||
const { collection, page, location, namespaces, t } = this.props;
|
||||
|
||||
if (collection._embedded && collection._embedded.repositories.length > 0) {
|
||||
return (
|
||||
<>
|
||||
<RepositoryList repositories={collection._embedded.repositories} />
|
||||
<RepositoryList repositories={collection._embedded.repositories} namespaces={namespaces} />
|
||||
<LinkPaginator collection={collection} page={page} filter={urls.getQueryStringFromLocation(location)} />
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user