apply eslint and prettier rules

This commit is contained in:
Sebastian Sdorra
2019-10-21 10:57:56 +02:00
parent 85773186db
commit 4bb8e6153b
227 changed files with 1147 additions and 4076 deletions

View File

@@ -15,27 +15,15 @@ class BranchButtonGroup extends React.Component<Props> {
render() {
const { repository, branch, t } = this.props;
const changesetLink = `/repo/${repository.namespace}/${
repository.name
}/branch/${encodeURIComponent(branch.name)}/changesets/`;
const sourcesLink = `/repo/${repository.namespace}/${
repository.name
}/sources/${encodeURIComponent(branch.name)}/`;
const changesetLink = `/repo/${repository.namespace}/${repository.name}/branch/${encodeURIComponent(
branch.name
)}/changesets/`;
const sourcesLink = `/repo/${repository.namespace}/${repository.name}/sources/${encodeURIComponent(branch.name)}/`;
return (
<ButtonAddons>
<Button
link={changesetLink}
icon="exchange-alt"
label={t("branch.commits")}
reducedMobile={true}
/>
<Button
link={sourcesLink}
icon="code"
label={t("branch.sources")}
reducedMobile={true}
/>
<Button link={changesetLink} icon="exchange-alt" label={t("branch.commits")} reducedMobile={true} />
<Button link={sourcesLink} icon="code" label={t("branch.sources")} reducedMobile={true} />
</ButtonAddons>
);
}

View File

@@ -18,8 +18,7 @@ class BranchDetail extends React.Component<Props> {
return (
<div className="media">
<div className="media-content subtitle">
<strong>{t("branch.name")}</strong> {branch.name}{" "}
<DefaultBranchTag defaultBranch={branch.defaultBranch} />
<strong>{t("branch.name")}</strong> {branch.name} <DefaultBranchTag defaultBranch={branch.defaultBranch} />
</div>
<div className="media-right">
<BranchButtonGroup repository={repository} branch={branch} />

View File

@@ -1,12 +1,7 @@
import React from "react";
import { translate } from "react-i18next";
import { Repository, Branch, BranchRequest } from "@scm-manager/ui-types";
import {
Select,
InputField,
SubmitButton,
validation as validator
} from "@scm-manager/ui-components";
import { Select, InputField, SubmitButton, validation as validator } from "@scm-manager/ui-components";
import { orderBranches } from "../util/orderBranches";
type Props = {
@@ -41,11 +36,7 @@ class BranchForm extends React.Component<Props, State> {
isValid = () => {
const { source, name } = this.state;
return !(
this.state.nameValidationError ||
this.isFalsy(source) ||
this.isFalsy(name)
);
return !(this.state.nameValidationError || this.isFalsy(source) || this.isFalsy(name));
};
submit = (event: Event) => {

View File

@@ -3,12 +3,7 @@ import BranchView from "../components/BranchView";
import { connect } from "react-redux";
import { Redirect, Route, Switch, withRouter } from "react-router-dom";
import { Repository, Branch } from "@scm-manager/ui-types";
import {
fetchBranch,
getBranch,
getFetchBranchFailure,
isFetchBranchPending
} from "../modules/branches";
import { fetchBranch, getBranch, getFetchBranchFailure, isFetchBranchPending } from "../modules/branches";
import { ErrorNotification, Loading } from "@scm-manager/ui-components";
import { History } from "history";
import { NotFoundError } from "@scm-manager/ui-components";
@@ -54,10 +49,7 @@ class BranchRoot extends React.Component<Props> {
const url = this.matchedUrl();
if (error) {
if (
error instanceof NotFoundError &&
queryString.parse(location.search).create === "true"
) {
if (error instanceof NotFoundError && queryString.parse(location.search).create === "true") {
return (
<Redirect
to={`/repo/${repository.namespace}/${repository.name}/branches/create?name=${match.params.branch}`}
@@ -75,12 +67,7 @@ class BranchRoot extends React.Component<Props> {
return (
<Switch>
<Redirect exact from={url} to={`${url}/info`} />
<Route
path={`${url}/info`}
component={() => (
<BranchView repository={repository} branch={branch} />
)}
/>
<Route path={`${url}/info`} component={() => <BranchView repository={repository} branch={branch} />} />
</Switch>
);
}

View File

@@ -12,13 +12,7 @@ import { Branch, Repository } from "@scm-manager/ui-types";
import { compose } from "redux";
import { translate } from "react-i18next";
import { withRouter } from "react-router-dom";
import {
CreateButton,
ErrorNotification,
Loading,
Notification,
Subtitle
} from "@scm-manager/ui-components";
import { CreateButton, ErrorNotification, Loading, Notification, Subtitle } from "@scm-manager/ui-components";
import BranchTable from "../components/BranchTable";
type Props = {
@@ -70,22 +64,13 @@ class BranchesOverview extends React.Component<Props> {
orderBranches(branches);
return <BranchTable baseUrl={baseUrl} branches={branches} />;
}
return (
<Notification type="info">
{t("branches.overview.noBranches")}
</Notification>
);
return <Notification type="info">{t("branches.overview.noBranches")}</Notification>;
}
renderCreateButton() {
const { showCreateButton, t } = this.props;
if (showCreateButton) {
return (
<CreateButton
label={t("branches.overview.createButton")}
link="./create"
/>
);
return <CreateButton label={t("branches.overview.createButton")} link="./create" />;
}
return null;
}

View File

@@ -1,9 +1,5 @@
import React from "react";
import {
ErrorNotification,
Loading,
Subtitle
} from "@scm-manager/ui-components";
import { ErrorNotification, Loading, Subtitle } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
import BranchForm from "../components/BranchForm";
import { Repository, Branch, BranchRequest } from "@scm-manager/ui-types";
@@ -56,19 +52,12 @@ class CreateBranch extends React.Component<Props> {
branchCreated = (branch: Branch) => {
const { history, repository } = this.props;
history.push(
`/repo/${repository.namespace}/${
repository.name
}/branch/${encodeURIComponent(branch.name)}/info`
);
history.push(`/repo/${repository.namespace}/${repository.name}/branch/${encodeURIComponent(branch.name)}/info`);
};
createBranch = (branch: BranchRequest) => {
this.props.createBranch(
this.props.createBranchesLink,
this.props.repository,
branch,
newBranch => this.branchCreated(newBranch)
this.props.createBranch(this.props.createBranchesLink, this.props.repository, branch, newBranch =>
this.branchCreated(newBranch)
);
};
@@ -78,15 +67,7 @@ class CreateBranch extends React.Component<Props> {
};
render() {
const {
t,
loading,
error,
repository,
branches,
createBranchesLink,
location
} = this.props;
const { t, loading, error, repository, branches, createBranchesLink, location } = this.props;
if (error) {
return <ErrorNotification error={error} />;
@@ -133,11 +114,8 @@ const mapDispatchToProps = dispatch => {
const mapStateToProps = (state, ownProps) => {
const { repository } = ownProps;
const loading =
isFetchBranchesPending(state, repository) ||
isCreateBranchPending(state, repository);
const error =
getFetchBranchesFailure(state, repository) || getCreateBranchFailure(state);
const loading = isFetchBranchesPending(state, repository) || isCreateBranchPending(state, repository);
const error = getFetchBranchesFailure(state, repository) || getCreateBranchFailure(state);
const branches = getBranches(state, repository);
const createBranchesLink = getBranchCreateLink(state, repository);
return {

View File

@@ -168,13 +168,11 @@ describe("branches", () => {
fetchMock.getOnce(URL + "/newBranch", newBranch);
const store = mockStore({});
return store
.dispatch(createBranch(URL, repository, branchRequest))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(CREATE_BRANCH_PENDING);
expect(actions[1].type).toEqual(CREATE_BRANCH_SUCCESS);
});
return store.dispatch(createBranch(URL, repository, branchRequest)).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(CREATE_BRANCH_PENDING);
expect(actions[1].type).toEqual(CREATE_BRANCH_SUCCESS);
});
});
it("should call the callback with the branch from the location header", () => {
@@ -197,11 +195,9 @@ describe("branches", () => {
receivedBranch = branch;
};
return store
.dispatch(createBranch(URL, repository, branchRequest, callback))
.then(() => {
expect(receivedBranch).toEqual(newBranch);
});
return store.dispatch(createBranch(URL, repository, branchRequest, callback)).then(() => {
expect(receivedBranch).toEqual(newBranch);
});
});
it("should fail creating a branch on HTTP 500", () => {
@@ -210,13 +206,11 @@ describe("branches", () => {
});
const store = mockStore({});
return store
.dispatch(createBranch(URL, repository, branchRequest))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(CREATE_BRANCH_PENDING);
expect(actions[1].type).toEqual(CREATE_BRANCH_FAILURE);
});
return store.dispatch(createBranch(URL, repository, branchRequest)).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(CREATE_BRANCH_PENDING);
expect(actions[1].type).toEqual(CREATE_BRANCH_FAILURE);
});
});
});

View File

@@ -1,16 +1,6 @@
import {
FAILURE_SUFFIX,
PENDING_SUFFIX,
SUCCESS_SUFFIX,
RESET_SUFFIX
} from "../../../modules/types";
import { FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX, RESET_SUFFIX } from "../../../modules/types";
import { apiClient } from "@scm-manager/ui-components";
import {
Action,
Branch,
BranchRequest,
Repository
} from "@scm-manager/ui-types";
import { Action, Branch, BranchRequest, Repository } from "@scm-manager/ui-types";
import { isPending } from "../../../modules/pending";
import { getFailure } from "../../../modules/failure";
@@ -32,8 +22,7 @@ export const CREATE_BRANCH_SUCCESS = `${CREATE_BRANCH}_${SUCCESS_SUFFIX}`;
export const CREATE_BRANCH_FAILURE = `${CREATE_BRANCH}_${FAILURE_SUFFIX}`;
export const CREATE_BRANCH_RESET = `${CREATE_BRANCH}_${RESET_SUFFIX}`;
const CONTENT_TYPE_BRANCH_REQUEST =
"application/vnd.scmm-branchRequest+json;v=2";
const CONTENT_TYPE_BRANCH_REQUEST = "application/vnd.scmm-branchRequest+json;v=2";
// Fetching branches
@@ -127,12 +116,7 @@ export function getBranches(state: object, repository: Repository) {
export function getBranchCreateLink(state: object, repository: Repository) {
const repoState = getRepoState(state, repository);
if (
repoState &&
repoState.list &&
repoState.list._links &&
repoState.list._links.create
) {
if (repoState && repoState.list && repoState.list._links && repoState.list._links.create) {
return repoState.list._links.create.href;
}
}
@@ -145,24 +129,12 @@ function getRepoState(state: object, repository: Repository) {
}
}
export const isPermittedToCreateBranches = (
state: object,
repository: Repository
): boolean => {
export const isPermittedToCreateBranches = (state: object, repository: Repository): boolean => {
const repoState = getRepoState(state, repository);
return !!(
repoState &&
repoState.list &&
repoState.list._links &&
repoState.list._links.create
);
return !!(repoState && repoState.list && repoState.list._links && repoState.list._links.create);
};
export function getBranch(
state: object,
repository: Repository,
name: string
): Branch | null | undefined {
export function getBranch(state: object, repository: Repository, name: string): Branch | null | undefined {
const repoState = getRepoState(state, repository);
if (repoState) {
return repoState.byName[name];
@@ -170,10 +142,7 @@ export function getBranch(
}
// Action creators
export function isFetchBranchesPending(
state: object,
repository: Repository
): boolean {
export function isFetchBranchesPending(state: object, repository: Repository): boolean {
return isPending(state, FETCH_BRANCHES, createKey(repository));
}
@@ -241,10 +210,7 @@ export function createBranchSuccess(repository: Repository): Action {
};
}
export function createBranchFailure(
repository: Repository,
error: Error
): Action {
export function createBranchFailure(repository: Repository, error: Error): Action {
return {
type: CREATE_BRANCH_FAILURE,
payload: {
@@ -265,26 +231,15 @@ export function createBranchReset(repository: Repository): Action {
};
}
export function isFetchBranchPending(
state: object,
repository: Repository,
name: string
) {
export function isFetchBranchPending(state: object, repository: Repository, name: string) {
return isPending(state, FETCH_BRANCH, createKey(repository) + "/" + name);
}
export function getFetchBranchFailure(
state: object,
repository: Repository,
name: string
) {
export function getFetchBranchFailure(state: object, repository: Repository, name: string) {
return getFailure(state, FETCH_BRANCH, createKey(repository) + "/" + name);
}
export function fetchBranchPending(
repository: Repository,
name: string
): Action {
export function fetchBranchPending(repository: Repository, name: string): Action {
return {
type: FETCH_BRANCH_PENDING,
payload: {
@@ -295,10 +250,7 @@ export function fetchBranchPending(
};
}
export function fetchBranchSuccess(
repository: Repository,
branch: Branch
): Action {
export function fetchBranchSuccess(repository: Repository, branch: Branch): Action {
return {
type: FETCH_BRANCH_SUCCESS,
payload: {
@@ -309,11 +261,7 @@ export function fetchBranchSuccess(
};
}
export function fetchBranchFailure(
repository: Repository,
name: string,
error: Error
): Action {
export function fetchBranchFailure(repository: Repository, name: string, error: Error): Action {
return {
type: FETCH_BRANCH_FAILURE,
payload: {
@@ -339,7 +287,7 @@ const reduceByBranchesSuccess = (state, payload) => {
if (response._embedded) {
const branches = response._embedded.branches;
response._embedded.branches = branches.map(b => b.name);
for (let branch of branches) {
for (const branch of branches) {
byName[branch.name] = branch;
}
return {

View File

@@ -31,31 +31,26 @@ const masterBranch = {
describe("order branches", () => {
it("should return branches", () => {
let branches = [branch1, branch2];
const branches = [branch1, branch2];
orderBranches(branches);
expect(branches).toEqual([branch1, branch2]);
});
it("should return defaultBranch first", () => {
let branches = [branch1, branch2, branch3];
const branches = [branch1, branch2, branch3];
orderBranches(branches);
expect(branches).toEqual([branch3, branch1, branch2]);
});
it("should order special branches as follows: master > default > develop", () => {
let branches = [defaultBranch, developBranch, masterBranch];
const branches = [defaultBranch, developBranch, masterBranch];
orderBranches(branches);
expect(branches).toEqual([masterBranch, defaultBranch, developBranch]);
});
it("should order special branches but starting with defaultBranch", () => {
let branches = [masterBranch, developBranch, defaultBranch, branch3];
const branches = [masterBranch, developBranch, defaultBranch, branch3];
orderBranches(branches);
expect(branches).toEqual([
branch3,
masterBranch,
defaultBranch,
developBranch
]);
expect(branches).toEqual([branch3, masterBranch, defaultBranch, developBranch]);
});
});

View File

@@ -11,9 +11,7 @@ describe("GeneralNavLink", () => {
_links: {}
};
const navLink = shallow(
<EditRepoNavLink repository={repository} editUrl="" />
);
const navLink = shallow(<EditRepoNavLink repository={repository} editUrl="" />);
expect(navLink.text()).toBe("");
});
@@ -26,9 +24,7 @@ describe("GeneralNavLink", () => {
}
};
const navLink = mount(
<EditRepoNavLink repository={repository} editUrl="" />
);
const navLink = mount(<EditRepoNavLink repository={repository} editUrl="" />);
expect(navLink.text()).toBe("repositoryRoot.menu.generalNavLink");
});
});

View File

@@ -20,9 +20,7 @@ class EditRepoNavLink extends React.Component<Props> {
if (!this.isEditable()) {
return null;
}
return (
<NavLink to={editUrl} label={t("repositoryRoot.menu.generalNavLink")} />
);
return <NavLink to={editUrl} label={t("repositoryRoot.menu.generalNavLink")} />;
}
}

View File

@@ -10,9 +10,7 @@ describe("PermissionsNavLink", () => {
_links: {}
};
const navLink = shallow(
<PermissionsNavLink repository={repository} permissionUrl="" />
);
const navLink = shallow(<PermissionsNavLink repository={repository} permissionUrl="" />);
expect(navLink.text()).toBe("");
});
@@ -25,9 +23,7 @@ describe("PermissionsNavLink", () => {
}
};
const navLink = mount(
<PermissionsNavLink repository={repository} permissionUrl="" />
);
const navLink = mount(<PermissionsNavLink repository={repository} permissionUrl="" />);
expect(navLink.text()).toBe("repositoryRoot.menu.permissionsNavLink");
});
});

View File

@@ -18,12 +18,7 @@ class PermissionsNavLink extends React.Component<Props> {
return null;
}
const { permissionUrl, t } = this.props;
return (
<NavLink
to={permissionUrl}
label={t("repositoryRoot.menu.permissionsNavLink")}
/>
);
return <NavLink to={permissionUrl} label={t("repositoryRoot.menu.permissionsNavLink")} />;
}
}

View File

@@ -56,9 +56,7 @@ class ChangesetDetails extends React.Component<Props, State> {
const { collapsed } = this.state;
const description = changesets.parseDescription(changeset.description);
const id = (
<ChangesetId repository={repository} changeset={changeset} link={false} />
);
const id = <ChangesetId repository={repository} changeset={changeset} link={false} />;
const date = <DateFromNow date={changeset.date} />;
return (

View File

@@ -1,12 +1,6 @@
import React from "react";
import { translate } from "react-i18next";
import {
Subtitle,
InputField,
Select,
SubmitButton,
Textarea
} from "@scm-manager/ui-components";
import { Subtitle, InputField, Select, SubmitButton, Textarea } from "@scm-manager/ui-components";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
import { Repository, RepositoryType } from "@scm-manager/ui-types";
import * as validator from "./repositoryValidation";
@@ -74,8 +68,7 @@ class RepositoryForm extends React.Component<Props, State> {
this.state.nameValidationError ||
this.state.contactValidationError ||
this.isFalsy(repository.name) ||
(namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY &&
this.isFalsy(repository.namespace))
(namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY && this.isFalsy(repository.namespace))
);
};
@@ -101,11 +94,7 @@ class RepositoryForm extends React.Component<Props, State> {
const disabled = !this.isModifiable() && !this.isCreateMode();
const submitButton = disabled ? null : (
<SubmitButton
disabled={!this.isValid()}
loading={loading}
label={t("repositoryForm.submit")}
/>
<SubmitButton disabled={!this.isValid()} loading={loading} label={t("repositoryForm.submit")} />
);
let subtitle = null;
@@ -167,13 +156,7 @@ class RepositoryForm extends React.Component<Props, State> {
return <InputField {...props} />;
}
return (
<ExtensionPoint
name="repos.create.namespace"
props={props}
renderAll={false}
/>
);
return <ExtensionPoint name="repos.create.namespace" props={props} renderAll={false} />;
};
renderCreateOnlyFields() {

View File

@@ -13,17 +13,7 @@ describe("repository name validation", () => {
});
it("should allow same names as the backend", () => {
const validPaths = [
"scm",
"s",
"sc",
".hiddenrepo",
"b.",
"...",
"..c",
"d..",
"a..c"
];
const validPaths = ["scm", "s", "sc", ".hiddenrepo", "b.", "...", "..c", "d..", "a..c"];
validPaths.forEach(path => expect(validator.isNameValid(path)).toBe(true));
});
@@ -80,9 +70,7 @@ describe("repository name validation", () => {
"scm/plugins/git-plugin"
];
invalidPaths.forEach(path =>
expect(validator.isNameValid(path)).toBe(false)
);
invalidPaths.forEach(path => expect(validator.isNameValid(path)).toBe(false));
});
});
@@ -93,9 +81,7 @@ describe("repository contact validation", () => {
// we don't need rich tests, because they are in validation.test.js
it("should allow real mail addresses", () => {
expect(validator.isContactValid("trici.mcmillian@hitchhiker.com")).toBe(
true
);
expect(validator.isContactValid("trici.mcmillian@hitchhiker.com")).toBe(true);
});
it("should fail on invalid mail addresses", () => {

View File

@@ -15,45 +15,28 @@ class RepositoryEntry extends React.Component<Props> {
renderBranchesLink = (repository: Repository, repositoryLink: string) => {
if (repository._links["branches"]) {
return (
<RepositoryEntryLink
icon="code-branch"
to={repositoryLink + "/branches"}
/>
);
return <RepositoryEntryLink icon="code-branch" to={repositoryLink + "/branches"} />;
}
return null;
};
renderChangesetsLink = (repository: Repository, repositoryLink: string) => {
if (repository._links["changesets"]) {
return (
<RepositoryEntryLink
icon="exchange-alt"
to={repositoryLink + "/changesets"}
/>
);
return <RepositoryEntryLink icon="exchange-alt" to={repositoryLink + "/changesets"} />;
}
return null;
};
renderSourcesLink = (repository: Repository, repositoryLink: string) => {
if (repository._links["sources"]) {
return (
<RepositoryEntryLink icon="code" to={repositoryLink + "/sources"} />
);
return <RepositoryEntryLink icon="code" to={repositoryLink + "/sources"} />;
}
return null;
};
renderModifyLink = (repository: Repository, repositoryLink: string) => {
if (repository._links["update"]) {
return (
<RepositoryEntryLink
icon="cog"
to={repositoryLink + "/settings/general"}
/>
);
return <RepositoryEntryLink icon="cog" to={repositoryLink + "/settings/general"} />;
}
return null;
};

View File

@@ -53,11 +53,7 @@ it("should group the repositories by their namespace", () => {
const expected = [
{
name: "hitchhiker",
repositories: [
hitchhikerHeartOfGold,
hitchhikerPuzzle42,
hitchhikerRestand
]
repositories: [hitchhikerHeartOfGold, hitchhikerPuzzle42, hitchhikerRestand]
},
{
name: "slarti",

View File

@@ -1,10 +1,8 @@
import { Repository, RepositoryGroup } from "@scm-manager/ui-types";
export default function groupByNamespace(
repositories: Repository[]
): RepositoryGroup[] {
let groups = {};
for (let repository of repositories) {
export default function groupByNamespace(repositories: Repository[]): RepositoryGroup[] {
const groups = {};
for (const repository of repositories) {
const groupName = repository.namespace;
let group = groups[groupName];
@@ -18,8 +16,8 @@ export default function groupByNamespace(
group.repositories.push(repository);
}
let groupArray = [];
for (let groupName in groups) {
const groupArray = [];
for (const groupName in groups) {
const group = groups[groupName];
group.repositories.sort(sortByName);
groupArray.push(groups[groupName]);

View File

@@ -34,13 +34,7 @@ class ChangesetView extends React.Component<Props> {
const { changeset, loading, error, t, repository } = this.props;
if (error) {
return (
<ErrorPage
title={t("changesets.errorTitle")}
subtitle={t("changesets.errorSubtitle")}
error={error}
/>
);
return <ErrorPage title={t("changesets.errorTitle")} subtitle={t("changesets.errorSubtitle")} error={error} />;
}
if (!changeset || loading) return <Loading />;

View File

@@ -1,11 +1,6 @@
import React from "react";
import { withRouter } from "react-router-dom";
import {
Branch,
Changeset,
PagedCollection,
Repository
} from "@scm-manager/ui-types";
import { Branch, Changeset, PagedCollection, Repository } from "@scm-manager/ui-types";
import {
fetchChangesets,
getChangesets,
@@ -66,9 +61,7 @@ class Changesets extends React.Component<Props> {
if (!changesets || changesets.length === 0) {
return (
<div className="panel-block">
<Notification type="info">
{t("changesets.noChangesets")}
</Notification>
<Notification type="info">{t("changesets.noChangesets")}</Notification>
</div>
);
}

View File

@@ -4,11 +4,7 @@ import { translate } from "react-i18next";
import { Route, withRouter } from "react-router-dom";
import Changesets from "./Changesets";
import { connect } from "react-redux";
import {
BranchSelector,
ErrorNotification,
Loading
} from "@scm-manager/ui-components";
import { BranchSelector, ErrorNotification, Loading } from "@scm-manager/ui-components";
import {
fetchBranches,
getBranches,
@@ -46,9 +42,7 @@ class ChangesetsRoot extends React.Component<Props> {
redirectToDefaultBranch = () => {
if (this.shouldRedirectToDefaultBranch()) {
const defaultBranches = this.props.branches.filter(
b => b.defaultBranch === true
);
const defaultBranches = this.props.branches.filter(b => b.defaultBranch === true);
if (defaultBranches.length > 0) {
this.branchSelected(defaultBranches[0]);
}
@@ -59,8 +53,7 @@ class ChangesetsRoot extends React.Component<Props> {
return (
this.props.branches &&
this.props.branches.length > 0 &&
this.props.selected !==
this.props.branches.filter(b => b.defaultBranch === true)[0]
this.props.selected !== this.props.branches.filter(b => b.defaultBranch === true)[0]
);
};
@@ -74,9 +67,7 @@ class ChangesetsRoot extends React.Component<Props> {
branchSelected = (branch?: Branch) => {
let url;
if (branch) {
url = `${this.props.baseUrlWithBranch}/${encodeURIComponent(
branch.name
)}/changesets/`;
url = `${this.props.baseUrlWithBranch}/${encodeURIComponent(branch.name)}/changesets/`;
} else {
url = `${this.props.baseUrlWithoutBranch}/`;
}

View File

@@ -3,23 +3,14 @@ import { connect } from "react-redux";
import { translate } from "react-i18next";
import { Page } from "@scm-manager/ui-components";
import RepositoryForm from "../components/form";
import {
Repository,
RepositoryType,
NamespaceStrategies
} from "@scm-manager/ui-types";
import { Repository, RepositoryType, NamespaceStrategies } from "@scm-manager/ui-types";
import {
fetchRepositoryTypesIfNeeded,
getFetchRepositoryTypesFailure,
getRepositoryTypes,
isFetchRepositoryTypesPending
} from "../modules/repositoryTypes";
import {
createRepo,
createRepoReset,
getCreateRepoFailure,
isCreateRepoPending
} from "../modules/repos";
import { createRepo, createRepoReset, getCreateRepoFailure, isCreateRepoPending } from "../modules/repos";
import { History } from "history";
import { getRepositoriesLink } from "../../modules/indexResource";
import {
@@ -40,11 +31,7 @@ type Props = {
// dispatch functions
fetchNamespaceStrategiesIfNeeded: () => void;
fetchRepositoryTypesIfNeeded: () => void;
createRepo: (
link: string,
p2: Repository,
callback: (repo: Repository) => void
) => void;
createRepo: (link: string, p2: Repository, callback: (repo: Repository) => void) => void;
resetForm: () => void;
// context props
@@ -66,14 +53,7 @@ class Create extends React.Component<Props> {
};
render() {
const {
pageLoading,
createLoading,
repositoryTypes,
namespaceStrategies,
createRepo,
error
} = this.props;
const { pageLoading, createLoading, repositoryTypes, namespaceStrategies, createRepo, error } = this.props;
const { t, repoLink } = this.props;
return (
@@ -89,9 +69,7 @@ class Create extends React.Component<Props> {
loading={createLoading}
namespaceStrategy={namespaceStrategies.current}
submitForm={repo => {
createRepo(repoLink, repo, (repo: Repository) =>
this.repoCreated(repo)
);
createRepo(repoLink, repo, (repo: Repository) => this.repoCreated(repo));
}}
/>
</Page>
@@ -102,14 +80,10 @@ class Create extends React.Component<Props> {
const mapStateToProps = state => {
const repositoryTypes = getRepositoryTypes(state);
const namespaceStrategies = getNamespaceStrategies(state);
const pageLoading =
isFetchRepositoryTypesPending(state) ||
isFetchNamespaceStrategiesPending(state);
const pageLoading = isFetchRepositoryTypesPending(state) || isFetchNamespaceStrategiesPending(state);
const createLoading = isCreateRepoPending(state);
const error =
getFetchRepositoryTypesFailure(state) ||
getCreateRepoFailure(state) ||
getFetchNamespaceStrategiesFailure(state);
getFetchRepositoryTypesFailure(state) || getCreateRepoFailure(state) || getFetchNamespaceStrategiesFailure(state);
const repoLink = getRepositoriesLink(state);
return {
repositoryTypes,
@@ -129,11 +103,7 @@ const mapDispatchToProps = dispatch => {
fetchNamespaceStrategiesIfNeeded: () => {
dispatch(fetchNamespaceStrategiesIfNeeded());
},
createRepo: (
link: string,
repository: Repository,
callback: () => void
) => {
createRepo: (link: string, repository: Repository, callback: () => void) => {
dispatch(createRepo(link, repository, callback));
},
resetForm: () => {

View File

@@ -1,17 +1,8 @@
import React from "react";
import { translate } from "react-i18next";
import { Repository } from "@scm-manager/ui-types";
import {
Subtitle,
DeleteButton,
confirmAlert,
ErrorNotification
} from "@scm-manager/ui-components";
import {
deleteRepo,
getDeleteRepoFailure,
isDeleteRepoPending
} from "../modules/repos";
import { Subtitle, DeleteButton, confirmAlert, ErrorNotification } from "@scm-manager/ui-components";
import { deleteRepo, getDeleteRepoFailure, isDeleteRepoPending } from "../modules/repos";
import { connect } from "react-redux";
import { withRouter } from "react-router-dom";
import { History } from "history";
@@ -78,11 +69,7 @@ class DeleteRepo extends React.Component<Props> {
<ErrorNotification error={error} />
<div className="columns">
<div className="column">
<DeleteButton
label={t("deleteRepo.button")}
action={action}
loading={loading}
/>
<DeleteButton label={t("deleteRepo.button")} action={action} loading={loading} />
</div>
</div>
</>

View File

@@ -4,12 +4,7 @@ import { withRouter } from "react-router-dom";
import RepositoryForm from "../components/form";
import DeleteRepo from "./DeleteRepo";
import { Repository } from "@scm-manager/ui-types";
import {
modifyRepo,
isModifyRepoPending,
getModifyRepoFailure,
modifyRepoReset
} from "../modules/repos";
import { modifyRepo, isModifyRepoPending, getModifyRepoFailure, modifyRepoReset } from "../modules/repos";
import { History } from "history";
import { ErrorNotification } from "@scm-manager/ui-components";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
@@ -69,11 +64,7 @@ class EditRepo extends React.Component<Props> {
this.props.modifyRepo(repo, this.repoModified);
}}
/>
<ExtensionPoint
name="repo-config.route"
props={extensionProps}
renderAll={true}
/>
<ExtensionPoint name="repo-config.route" props={extensionProps} renderAll={true} />
<DeleteRepo repository={repository} />
</div>
);

View File

@@ -43,30 +43,15 @@ type Props = {
class Overview extends React.Component<Props> {
componentDidMount() {
const { fetchReposByPage, reposLink, page, location } = this.props;
fetchReposByPage(
reposLink,
page,
urls.getQueryStringFromLocation(location)
);
fetchReposByPage(reposLink, page, urls.getQueryStringFromLocation(location));
}
componentDidUpdate = (prevProps: Props) => {
const {
loading,
collection,
page,
reposLink,
location,
fetchReposByPage
} = this.props;
const { loading, collection, 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, urls.getQueryStringFromLocation(location));
}
}
};
@@ -74,19 +59,10 @@ class Overview extends React.Component<Props> {
render() {
const { error, loading, showCreateButton, t } = this.props;
return (
<Page
title={t("overview.title")}
subtitle={t("overview.subtitle")}
loading={loading}
error={error}
>
<Page title={t("overview.title")} subtitle={t("overview.subtitle")} loading={loading} error={error}>
{this.renderOverview()}
<PageActions>
<OverviewPageActions
showCreateButton={showCreateButton}
link="repos"
label={t("overview.createButton")}
/>
<OverviewPageActions showCreateButton={showCreateButton} link="repos" label={t("overview.createButton")} />
</PageActions>
</Page>
);
@@ -99,17 +75,11 @@ class Overview extends React.Component<Props> {
return (
<>
<RepositoryList repositories={collection._embedded.repositories} />
<LinkPaginator
collection={collection}
page={page}
filter={urls.getQueryStringFromLocation(location)}
/>
<LinkPaginator collection={collection} page={page} filter={urls.getQueryStringFromLocation(location)} />
</>
);
}
return (
<Notification type="info">{t("overview.noRepositories")}</Notification>
);
return <Notification type="info">{t("overview.noRepositories")}</Notification>;
}
renderOverview() {
@@ -128,9 +98,7 @@ class Overview extends React.Component<Props> {
renderCreateButton() {
const { showCreateButton, t } = this.props;
if (showCreateButton) {
return (
<CreateButton label={t("overview.createButton")} link="/repos/create" />
);
return <CreateButton label={t("overview.createButton")} link="/repos/create" />;
}
return null;
}

View File

@@ -1,24 +1,11 @@
import React from "react";
import {
fetchRepoByName,
getFetchRepoFailure,
getRepository,
isFetchRepoPending
} from "../modules/repos";
import { fetchRepoByName, getFetchRepoFailure, getRepository, isFetchRepoPending } from "../modules/repos";
import { connect } from "react-redux";
import { Redirect, Route, Switch } from "react-router-dom";
import { Repository } from "@scm-manager/ui-types";
import {
ErrorPage,
Loading,
Navigation,
NavLink,
Page,
Section,
SubNavigation
} from "@scm-manager/ui-components";
import { ErrorPage, Loading, Navigation, NavLink, Page, Section, SubNavigation } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
import RepositoryDetails from "../components/RepositoryDetails";
import EditRepo from "./EditRepo";
@@ -90,11 +77,7 @@ class RepositoryRoot extends React.Component<Props> {
if (error) {
return (
<ErrorPage
title={t("repositoryRoot.errorTitle")}
subtitle={t("repositoryRoot.errorSubtitle")}
error={error}
/>
<ErrorPage title={t("repositoryRoot.errorTitle")} subtitle={t("repositoryRoot.errorSubtitle")} error={error} />
);
}
@@ -110,10 +93,7 @@ class RepositoryRoot extends React.Component<Props> {
indexLinks
};
const redirectUrlFactory = binder.getExtension(
"repository.redirect",
this.props
);
const redirectUrlFactory = binder.getExtension("repository.redirect", this.props);
let redirectedUrl;
if (redirectUrlFactory) {
redirectedUrl = url + redirectUrlFactory(this.props);
@@ -127,41 +107,23 @@ class RepositoryRoot extends React.Component<Props> {
<div className="column is-three-quarters">
<Switch>
<Redirect exact from={this.props.match.url} to={redirectedUrl} />
<Route
path={`${url}/info`}
exact
component={() => <RepositoryDetails repository={repository} />}
/>
<Route
path={`${url}/settings/general`}
component={() => <EditRepo repository={repository} />}
/>
<Route path={`${url}/info`} exact component={() => <RepositoryDetails repository={repository} />} />
<Route path={`${url}/settings/general`} component={() => <EditRepo repository={repository} />} />
<Route
path={`${url}/settings/permissions`}
render={() => (
<Permissions
namespace={this.props.repository.namespace}
repoName={this.props.repository.name}
/>
<Permissions namespace={this.props.repository.namespace} repoName={this.props.repository.name} />
)}
/>
<Route
exact
path={`${url}/changeset/:id`}
render={() => <ChangesetView repository={repository} />}
/>
<Route exact path={`${url}/changeset/:id`} render={() => <ChangesetView repository={repository} />} />
<Route
path={`${url}/sources`}
exact={true}
render={() => (
<Sources repository={repository} baseUrl={`${url}/sources`} />
)}
render={() => <Sources repository={repository} baseUrl={`${url}/sources`} />}
/>
<Route
path={`${url}/sources/:revision/:path*`}
render={() => (
<Sources repository={repository} baseUrl={`${url}/sources`} />
)}
render={() => <Sources repository={repository} baseUrl={`${url}/sources`} />}
/>
<Route
path={`${url}/changesets`}
@@ -185,42 +147,21 @@ class RepositoryRoot extends React.Component<Props> {
/>
<Route
path={`${url}/branch/:branch`}
render={() => (
<BranchRoot
repository={repository}
baseUrl={`${url}/branch`}
/>
)}
render={() => <BranchRoot repository={repository} baseUrl={`${url}/branch`} />}
/>
<Route
path={`${url}/branches`}
exact={true}
render={() => (
<BranchesOverview
repository={repository}
baseUrl={`${url}/branch`}
/>
)}
/>
<Route
path={`${url}/branches/create`}
render={() => <CreateBranch repository={repository} />}
/>
<ExtensionPoint
name="repository.route"
props={extensionProps}
renderAll={true}
render={() => <BranchesOverview repository={repository} baseUrl={`${url}/branch`} />}
/>
<Route path={`${url}/branches/create`} render={() => <CreateBranch repository={repository} />} />
<ExtensionPoint name="repository.route" props={extensionProps} renderAll={true} />
</Switch>
</div>
<div className="column">
<Navigation>
<Section label={t("repositoryRoot.menu.navigationLabel")}>
<ExtensionPoint
name="repository.navigation.topLevel"
props={extensionProps}
renderAll={true}
/>
<ExtensionPoint name="repository.navigation.topLevel" props={extensionProps} renderAll={true} />
<NavLink
to={`${url}/info`}
icon="fas fa-info-circle"
@@ -252,28 +193,11 @@ class RepositoryRoot extends React.Component<Props> {
label={t("repositoryRoot.menu.sourcesNavLink")}
activeOnlyWhenExact={false}
/>
<ExtensionPoint
name="repository.navigation"
props={extensionProps}
renderAll={true}
/>
<SubNavigation
to={`${url}/settings/general`}
label={t("repositoryRoot.menu.settingsNavLink")}
>
<EditRepoNavLink
repository={repository}
editUrl={`${url}/settings/general`}
/>
<PermissionsNavLink
permissionUrl={`${url}/settings/permissions`}
repository={repository}
/>
<ExtensionPoint
name="repository.setting"
props={extensionProps}
renderAll={true}
/>
<ExtensionPoint name="repository.navigation" props={extensionProps} renderAll={true} />
<SubNavigation to={`${url}/settings/general`} label={t("repositoryRoot.menu.settingsNavLink")}>
<EditRepoNavLink repository={repository} editUrl={`${url}/settings/general`} />
<PermissionsNavLink permissionUrl={`${url}/settings/permissions`} repository={repository} />
<ExtensionPoint name="repository.setting" props={extensionProps} renderAll={true} />
</SubNavigation>
</Section>
</Navigation>

View File

@@ -30,8 +30,7 @@ const branch = {
revision: "123",
_links: {
history: {
href:
"http://scm.hitchhicker.com/api/v2/repositories/foo/bar/branches/specific/changesets"
href: "http://scm.hitchhicker.com/api/v2/repositories/foo/bar/branches/specific/changesets"
}
}
};
@@ -48,8 +47,7 @@ const repository = {
href: "http://scm.hitchhicker.com/api/v2/repositories/foo/bar/changesets"
},
branches: {
href:
"http://scm.hitchhicker.com/api/v2/repositories/foo/bar/branches/specific/branches"
href: "http://scm.hitchhicker.com/api/v2/repositories/foo/bar/branches/specific/branches"
}
}
};
@@ -58,10 +56,8 @@ const changesets = {};
describe("changesets", () => {
describe("fetching of changesets", () => {
const DEFAULT_BRANCH_URL =
"http://scm.hitchhicker.com/api/v2/repositories/foo/bar/changesets";
const SPECIFIC_BRANCH_URL =
"http://scm.hitchhicker.com/api/v2/repositories/foo/bar/branches/specific/changesets";
const DEFAULT_BRANCH_URL = "http://scm.hitchhicker.com/api/v2/repositories/foo/bar/changesets";
const SPECIFIC_BRANCH_URL = "http://scm.hitchhicker.com/api/v2/repositories/foo/bar/branches/specific/changesets";
const mockStore = configureMockStore([thunk]);
@@ -92,11 +88,9 @@ describe("changesets", () => {
];
const store = mockStore({});
return store
.dispatch(fetchChangeset(repository, changesetId))
.then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
return store.dispatch(fetchChangeset(repository, changesetId)).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it("should fail fetching changeset on error", () => {
@@ -110,13 +104,11 @@ describe("changesets", () => {
];
const store = mockStore({});
return store
.dispatch(fetchChangeset(repository, changesetId))
.then(() => {
expect(store.getActions()[0]).toEqual(expectedActions[0]);
expect(store.getActions()[1].type).toEqual(FETCH_CHANGESET_FAILURE);
expect(store.getActions()[1].payload).toBeDefined();
});
return store.dispatch(fetchChangeset(repository, changesetId)).then(() => {
expect(store.getActions()[0]).toEqual(expectedActions[0]);
expect(store.getActions()[1].type).toEqual(FETCH_CHANGESET_FAILURE);
expect(store.getActions()[1].payload).toBeDefined();
});
});
it("should fetch changeset if needed", () => {
@@ -139,11 +131,9 @@ describe("changesets", () => {
];
const store = mockStore({});
return store
.dispatch(fetchChangesetIfNeeded(repository, "id3"))
.then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
return store.dispatch(fetchChangesetIfNeeded(repository, "id3")).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it("should not fetch changeset if not needed", () => {
@@ -165,9 +155,7 @@ describe("changesets", () => {
};
const store = mockStore(state);
return expect(
store.dispatch(fetchChangesetIfNeeded(repository, "id1"))
).toEqual(undefined);
return expect(store.dispatch(fetchChangesetIfNeeded(repository, "id1"))).toEqual(undefined);
});
it("should fetch changesets for default branch", () => {
@@ -279,11 +267,9 @@ describe("changesets", () => {
];
const store = mockStore({});
return store
.dispatch(fetchChangesets(repository, undefined, 5))
.then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
return store.dispatch(fetchChangesets(repository, undefined, 5)).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it("should fetch changesets by branch and page", () => {
@@ -344,14 +330,9 @@ describe("changesets", () => {
};
it("should set state to received changesets", () => {
const newState = reducer(
{},
fetchChangesetsSuccess(repository, undefined, responseBody)
);
const newState = reducer({}, fetchChangesetsSuccess(repository, undefined, responseBody));
expect(newState).toBeDefined();
expect(newState["foo/bar"].byId["changeset1"].author.mail).toEqual(
"z@phod.com"
);
expect(newState["foo/bar"].byId["changeset1"].author.mail).toEqual("z@phod.com");
expect(newState["foo/bar"].byId["changeset2"].description).toEqual("foo");
expect(newState["foo/bar"].byId["changeset3"].description).toEqual("bar");
expect(newState["foo/bar"].byBranch[""]).toEqual({
@@ -365,17 +346,10 @@ describe("changesets", () => {
});
it("should store the changeset list to branch", () => {
const newState = reducer(
{},
fetchChangesetsSuccess(repository, branch, responseBody)
);
const newState = reducer({}, fetchChangesetsSuccess(repository, branch, responseBody));
expect(newState["foo/bar"].byId["changeset1"]).toBeDefined();
expect(newState["foo/bar"].byBranch["specific"].entries).toEqual([
"changeset1",
"changeset2",
"changeset3"
]);
expect(newState["foo/bar"].byBranch["specific"].entries).toEqual(["changeset1", "changeset2", "changeset3"]);
});
it("should not remove existing changesets", () => {
@@ -397,18 +371,11 @@ describe("changesets", () => {
}
};
const newState = reducer(
state,
fetchChangesetsSuccess(repository, undefined, responseBody)
);
const newState = reducer(state, fetchChangesetsSuccess(repository, undefined, responseBody));
const fooBar = newState["foo/bar"];
expect(fooBar.byBranch[""].entries).toEqual([
"changeset1",
"changeset2",
"changeset3"
]);
expect(fooBar.byBranch[""].entries).toEqual(["changeset1", "changeset2", "changeset3"]);
expect(fooBar.byId["id2"]).toEqual({
id: "id2"
});
@@ -459,9 +426,7 @@ describe("changesets", () => {
);
expect(newState).toBeDefined();
expect(newState["foo/bar"].byId["id3"].description).toEqual(
"added testChangeset"
);
expect(newState["foo/bar"].byId["id3"].description).toEqual("added testChangeset");
expect(newState["foo/bar"].byId["id3"].author.mail).toEqual("z@phod.com");
expect(newState["foo/bar"].byId["id2"]).toBeDefined();
expect(newState["foo/bar"].byId["id3"]).toBeDefined();

View File

@@ -1,17 +1,8 @@
import {
FAILURE_SUFFIX,
PENDING_SUFFIX,
SUCCESS_SUFFIX
} from "../../modules/types";
import { FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX } from "../../modules/types";
import { apiClient, urls } from "@scm-manager/ui-components";
import { isPending } from "../../modules/pending";
import { getFailure } from "../../modules/failure";
import {
Action,
Branch,
PagedCollection,
Repository
} from "@scm-manager/ui-types";
import { Action, Branch, PagedCollection, Repository } from "@scm-manager/ui-types";
export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS";
export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`;
@@ -51,21 +42,14 @@ function createChangesetUrl(repository: Repository, id: string) {
return urls.concat(repository._links.changesets.href, id);
}
export function fetchChangesetPending(
repository: Repository,
id: string
): Action {
export function fetchChangesetPending(repository: Repository, id: string): Action {
return {
type: FETCH_CHANGESET_PENDING,
itemId: createChangesetItemId(repository, id)
};
}
export function fetchChangesetSuccess(
changeset: any,
repository: Repository,
id: string
): Action {
export function fetchChangesetSuccess(changeset: any, repository: Repository, id: string): Action {
return {
type: FETCH_CHANGESET_SUCCESS,
payload: {
@@ -77,11 +61,7 @@ export function fetchChangesetSuccess(
};
}
function fetchChangesetFailure(
repository: Repository,
id: string,
error: Error
): Action {
function fetchChangesetFailure(repository: Repository, id: string, error: Error): Action {
return {
type: FETCH_CHANGESET_FAILURE,
payload: {
@@ -93,11 +73,7 @@ function fetchChangesetFailure(
};
}
export function fetchChangesets(
repository: Repository,
branch?: Branch,
page?: number
) {
export function fetchChangesets(repository: Repository, branch?: Branch, page?: number) {
const link = createChangesetsLink(repository, branch, page);
return function(dispatch: any) {
@@ -114,11 +90,7 @@ export function fetchChangesets(
};
}
function createChangesetsLink(
repository: Repository,
branch?: Branch,
page?: number
) {
function createChangesetsLink(repository: Repository, branch?: Branch, page?: number) {
let link = repository._links.changesets.href;
if (branch) {
@@ -131,10 +103,7 @@ function createChangesetsLink(
return link;
}
export function fetchChangesetsPending(
repository: Repository,
branch?: Branch
): Action {
export function fetchChangesetsPending(repository: Repository, branch?: Branch): Action {
const itemId = createItemId(repository, branch);
return {
@@ -143,11 +112,7 @@ export function fetchChangesetsPending(
};
}
export function fetchChangesetsSuccess(
repository: Repository,
branch?: Branch,
changesets: any
): Action {
export function fetchChangesetsSuccess(repository: Repository, branch?: Branch, changesets: any): Action {
return {
type: FETCH_CHANGESETS_SUCCESS,
payload: {
@@ -159,11 +124,7 @@ export function fetchChangesetsSuccess(
};
}
function fetchChangesetsFailure(
repository: Repository,
branch?: Branch,
error: Error
): Action {
function fetchChangesetsFailure(repository: Repository, branch?: Branch, error: Error): Action {
return {
type: FETCH_CHANGESETS_FAILURE,
payload: {
@@ -270,7 +231,7 @@ export default function reducer(
function extractChangesetsByIds(changesets: any) {
const changesetsByIds = {};
for (let changeset of changesets) {
for (const changeset of changesets) {
changesetsByIds[changeset.id] = changeset;
}
@@ -278,11 +239,7 @@ function extractChangesetsByIds(changesets: any) {
}
//selectors
export function getChangesets(
state: object,
repository: Repository,
branch?: Branch
) {
export function getChangesets(state: object, repository: Repository, branch?: Branch) {
const repoKey = createItemId(repository);
const stateRoot = state.changesets[repoKey];
@@ -302,70 +259,35 @@ export function getChangesets(
});
}
export function getChangeset(
state: object,
repository: Repository,
id: string
) {
export function getChangeset(state: object, repository: Repository, id: string) {
const key = createItemId(repository);
const changesets =
state.changesets && state.changesets[key]
? state.changesets[key].byId
: null;
const changesets = state.changesets && state.changesets[key] ? state.changesets[key].byId : null;
if (changesets != null && changesets[id]) {
return changesets[id];
}
return null;
}
export function shouldFetchChangeset(
state: object,
repository: Repository,
id: string
) {
export function shouldFetchChangeset(state: object, repository: Repository, id: string) {
if (getChangeset(state, repository, id)) {
return false;
}
return true;
}
export function isFetchChangesetPending(
state: object,
repository: Repository,
id: string
) {
return isPending(
state,
FETCH_CHANGESET,
createChangesetItemId(repository, id)
);
export function isFetchChangesetPending(state: object, repository: Repository, id: string) {
return isPending(state, FETCH_CHANGESET, createChangesetItemId(repository, id));
}
export function getFetchChangesetFailure(
state: object,
repository: Repository,
id: string
) {
return getFailure(
state,
FETCH_CHANGESET,
createChangesetItemId(repository, id)
);
export function getFetchChangesetFailure(state: object, repository: Repository, id: string) {
return getFailure(state, FETCH_CHANGESET, createChangesetItemId(repository, id));
}
export function isFetchChangesetsPending(
state: object,
repository: Repository,
branch?: Branch
) {
export function isFetchChangesetsPending(state: object, repository: Repository, branch?: Branch) {
return isPending(state, FETCH_CHANGESETS, createItemId(repository, branch));
}
export function getFetchChangesetsFailure(
state: object,
repository: Repository,
branch?: Branch
) {
export function getFetchChangesetsFailure(state: object, repository: Repository, branch?: Branch) {
return getFailure(state, FETCH_CHANGESETS, createItemId(repository, branch));
}
@@ -383,11 +305,7 @@ const selectList = (state: object, repository: Repository, branch?: Branch) => {
return {};
};
const selectListEntry = (
state: object,
repository: Repository,
branch?: Branch
): object => {
const selectListEntry = (state: object, repository: Repository, branch?: Branch): object => {
const list = selectList(state, repository, branch);
if (list.entry) {
return list.entry;
@@ -395,10 +313,6 @@ const selectListEntry = (
return {};
};
export const selectListAsCollection = (
state: object,
repository: Repository,
branch?: Branch
): PagedCollection => {
export const selectListAsCollection = (state: object, repository: Repository, branch?: Branch): PagedCollection => {
return selectListEntry(state, repository, branch);
};

View File

@@ -67,24 +67,19 @@ const hitchhikerPuzzle42: Repository = {
href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42"
},
permissions: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/permissions/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/permissions/"
},
tags: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/tags/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/tags/"
},
branches: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/branches/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/branches/"
},
changesets: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/changesets/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/changesets/"
},
sources: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/sources/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/sources/"
}
}
};
@@ -107,24 +102,19 @@ const hitchhikerRestatend: Repository = {
href: "http://localhost:8081/api/v2/repositories/hitchhiker/restatend"
},
permissions: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/restatend/permissions/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/permissions/"
},
tags: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/restatend/tags/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/tags/"
},
branches: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/restatend/branches/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/branches/"
},
changesets: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/restatend/changesets/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/changesets/"
},
sources: {
href:
"http://localhost:8081/api/v2/repositories/hitchhiker/restatend/sources/"
href: "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/sources/"
}
}
};
@@ -147,8 +137,7 @@ const slartiFjords: Repository = {
href: "http://localhost:8081/api/v2/repositories/slarti/fjords"
},
permissions: {
href:
"http://localhost:8081/api/v2/repositories/slarti/fjords/permissions/"
href: "http://localhost:8081/api/v2/repositories/slarti/fjords/permissions/"
},
tags: {
href: "http://localhost:8081/api/v2/repositories/slarti/fjords/tags/"
@@ -157,8 +146,7 @@ const slartiFjords: Repository = {
href: "http://localhost:8081/api/v2/repositories/slarti/fjords/branches/"
},
changesets: {
href:
"http://localhost:8081/api/v2/repositories/slarti/fjords/changesets/"
href: "http://localhost:8081/api/v2/repositories/slarti/fjords/changesets/"
},
sources: {
href: "http://localhost:8081/api/v2/repositories/slarti/fjords/sources/"
@@ -206,11 +194,7 @@ const repositoryCollectionWithNames: RepositoryCollection = {
}
},
_embedded: {
repositories: [
"hitchhiker/puzzle42",
"hitchhiker/restatend",
"slarti/fjords"
]
repositories: ["hitchhiker/puzzle42", "hitchhiker/restatend", "slarti/fjords"]
}
};
@@ -267,10 +251,7 @@ describe("repos fetch", () => {
});
it("should successfully fetch repos from link", () => {
fetchMock.getOnce(
REPOS_URL + "?" + SORT + "&page=42",
repositoryCollection
);
fetchMock.getOnce(REPOS_URL + "?" + SORT + "&page=42", repositoryCollection);
const expectedActions = [
{
@@ -283,20 +264,13 @@ describe("repos fetch", () => {
];
const store = mockStore({});
return store
.dispatch(
fetchReposByLink("/repositories?sortBy=namespaceAndName&page=42")
)
.then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
return store.dispatch(fetchReposByLink("/repositories?sortBy=namespaceAndName&page=42")).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it("should append sortby parameter and successfully fetch repos from link", () => {
fetchMock.getOnce(
"/api/v2/repositories?one=1&sortBy=namespaceAndName",
repositoryCollection
);
fetchMock.getOnce("/api/v2/repositories?one=1&sortBy=namespaceAndName", repositoryCollection);
const expectedActions = [
{
@@ -372,10 +346,7 @@ describe("repos fetch", () => {
});
it("should successfully fetch repo slarti/fjords", () => {
fetchMock.getOnce(
"http://localhost:8081/api/v2/repositories/slarti/fjords",
slartiFjords
);
fetchMock.getOnce("http://localhost:8081/api/v2/repositories/slarti/fjords", slartiFjords);
const expectedActions = [
{
@@ -400,12 +371,9 @@ describe("repos fetch", () => {
});
it("should dispatch FETCH_REPO_FAILURE, it the request for slarti/fjords fails", () => {
fetchMock.getOnce(
"http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 500
}
);
fetchMock.getOnce("http://localhost:8081/api/v2/repositories/slarti/fjords", {
status: 500
});
const store = mockStore({});
return store.dispatch(fetchRepoByLink(slartiFjords)).then(() => {
@@ -482,12 +450,9 @@ describe("repos fetch", () => {
});
it("should successfully delete repo slarti/fjords", () => {
fetchMock.delete(
"http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 204
}
);
fetchMock.delete("http://localhost:8081/api/v2/repositories/slarti/fjords", {
status: 204
});
const expectedActions = [
{
@@ -509,12 +474,9 @@ describe("repos fetch", () => {
});
it("should successfully delete repo slarti/fjords and call the callback", () => {
fetchMock.delete(
"http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 204
}
);
fetchMock.delete("http://localhost:8081/api/v2/repositories/slarti/fjords", {
status: 204
});
let callMe = "not yet";
@@ -529,12 +491,9 @@ describe("repos fetch", () => {
});
it("should disapatch failure on delete, if server returns status code 500", () => {
fetchMock.delete(
"http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 500
}
);
fetchMock.delete("http://localhost:8081/api/v2/repositories/slarti/fjords", {
status: 500
});
const store = mockStore({});
return store.dispatch(deleteRepo(slartiFjords)).then(() => {
@@ -550,14 +509,11 @@ describe("repos fetch", () => {
fetchMock.putOnce(slartiFjords._links.update.href, {
status: 204
});
fetchMock.getOnce(
"http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 500
}
);
fetchMock.getOnce("http://localhost:8081/api/v2/repositories/slarti/fjords", {
status: 500
});
let editedFjords = {
const editedFjords = {
...slartiFjords
};
editedFjords.description = "coast of africa";
@@ -576,14 +532,11 @@ describe("repos fetch", () => {
fetchMock.putOnce(slartiFjords._links.update.href, {
status: 204
});
fetchMock.getOnce(
"http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 500
}
);
fetchMock.getOnce("http://localhost:8081/api/v2/repositories/slarti/fjords", {
status: 500
});
let editedFjords = {
const editedFjords = {
...slartiFjords
};
editedFjords.description = "coast of africa";
@@ -609,7 +562,7 @@ describe("repos fetch", () => {
status: 500
});
let editedFjords = {
const editedFjords = {
...slartiFjords
};
editedFjords.description = "coast of africa";
@@ -737,9 +690,7 @@ describe("repos selectors", () => {
};
const link = getPermissionsLink(state, "slarti", "fjords");
expect(link).toEqual(
"http://localhost:8081/api/v2/repositories/slarti/fjords/permissions/"
);
expect(link).toEqual("http://localhost:8081/api/v2/repositories/slarti/fjords/permissions/");
});
it("should return true, when fetch repo is pending", () => {

View File

@@ -1,10 +1,6 @@
import { apiClient } from "@scm-manager/ui-components";
import * as types from "../../modules/types";
import {
Action,
Repository,
RepositoryCollection
} from "@scm-manager/ui-types";
import { Action, Repository, RepositoryCollection } from "@scm-manager/ui-types";
import { isPending } from "../../modules/pending";
import { getFailure } from "../../modules/failure";
@@ -47,9 +43,7 @@ export function fetchRepos(link: string) {
export function fetchReposByPage(link: string, page: number, filter?: string) {
if (filter) {
return fetchReposByLink(
`${link}?page=${page - 1}&q=${decodeURIComponent(filter)}`
);
return fetchReposByLink(`${link}?page=${page - 1}&q=${decodeURIComponent(filter)}`);
}
return fetchReposByLink(`${link}?page=${page - 1}`);
}
@@ -147,11 +141,7 @@ export function fetchRepoSuccess(repository: Repository): Action {
};
}
export function fetchRepoFailure(
namespace: string,
name: string,
error: Error
): Action {
export function fetchRepoFailure(namespace: string, name: string, error: Error): Action {
return {
type: FETCH_REPO_FAILURE,
payload: {
@@ -165,11 +155,7 @@ export function fetchRepoFailure(
// create repo
export function createRepo(
link: string,
repository: Repository,
callback?: (repo: Repository) => void
) {
export function createRepo(link: string, repository: Repository, callback?: (repo: Repository) => void) {
return function(dispatch: any) {
dispatch(createRepoPending());
return apiClient
@@ -255,10 +241,7 @@ export function modifyRepoSuccess(repository: Repository): Action {
};
}
export function modifyRepoFailure(
repository: Repository,
error: Error
): Action {
export function modifyRepoFailure(repository: Repository, error: Error): Action {
return {
type: MODIFY_REPO_FAILURE,
payload: {
@@ -314,10 +297,7 @@ export function deleteRepoSuccess(repository: Repository): Action {
};
}
export function deleteRepoFailure(
repository: Repository,
error: Error
): Action {
export function deleteRepoFailure(repository: Repository, error: Error): Action {
return {
type: DELETE_REPO_FAILURE,
payload: {
@@ -334,9 +314,7 @@ function createIdentifier(repository: Repository) {
return repository.namespace + "/" + repository.name;
}
function normalizeByNamespaceAndName(
repositoryCollection: RepositoryCollection
) {
function normalizeByNamespaceAndName(repositoryCollection: RepositoryCollection) {
const names = [];
const byNames = {};
for (const repository of repositoryCollection._embedded.repositories) {
@@ -391,7 +369,7 @@ export default function reducer(
export function getRepositoryCollection(state: object) {
if (state.repos && state.repos.list && state.repos.byNames) {
const repositories = [];
for (let repositoryName of state.repos.list._embedded.repositories) {
for (const repositoryName of state.repos.list._embedded.repositories) {
repositories.push(state.repos.byNames[repositoryName]);
}
return {
@@ -417,29 +395,16 @@ export function getRepository(state: object, namespace: string, name: string) {
}
}
export function isFetchRepoPending(
state: object,
namespace: string,
name: string
) {
export function isFetchRepoPending(state: object, namespace: string, name: string) {
return isPending(state, FETCH_REPO, namespace + "/" + name);
}
export function getFetchRepoFailure(
state: object,
namespace: string,
name: string
) {
export function getFetchRepoFailure(state: object, namespace: string, name: string) {
return getFailure(state, FETCH_REPO, namespace + "/" + name);
}
export function isAbleToCreateRepos(state: object) {
return !!(
state.repos &&
state.repos.list &&
state.repos.list._links &&
state.repos.list._links.create
);
return !!(state.repos && state.repos.list && state.repos.list._links && state.repos.list._links.create);
}
export function isCreateRepoPending(state: object) {
@@ -450,43 +415,23 @@ export function getCreateRepoFailure(state: object) {
return getFailure(state, CREATE_REPO);
}
export function isModifyRepoPending(
state: object,
namespace: string,
name: string
) {
export function isModifyRepoPending(state: object, namespace: string, name: string) {
return isPending(state, MODIFY_REPO, namespace + "/" + name);
}
export function getModifyRepoFailure(
state: object,
namespace: string,
name: string
) {
export function getModifyRepoFailure(state: object, namespace: string, name: string) {
return getFailure(state, MODIFY_REPO, namespace + "/" + name);
}
export function isDeleteRepoPending(
state: object,
namespace: string,
name: string
) {
export function isDeleteRepoPending(state: object, namespace: string, name: string) {
return isPending(state, DELETE_REPO, namespace + "/" + name);
}
export function getDeleteRepoFailure(
state: object,
namespace: string,
name: string
) {
export function getDeleteRepoFailure(state: object, namespace: string, name: string) {
return getFailure(state, DELETE_REPO, namespace + "/" + name);
}
export function getPermissionsLink(
state: object,
namespace: string,
name: string
) {
export function getPermissionsLink(state: object, namespace: string, name: string) {
const repo = getRepository(state, namespace, name);
return repo && repo._links ? repo._links.permissions.href : undefined;
}

View File

@@ -1,9 +1,5 @@
import * as types from "../../modules/types";
import {
Action,
RepositoryType,
RepositoryTypeCollection
} from "@scm-manager/ui-types";
import { Action, RepositoryType, RepositoryTypeCollection } from "@scm-manager/ui-types";
import { apiClient } from "@scm-manager/ui-components";
import { isPending } from "../../modules/pending";
import { getFailure } from "../../modules/failure";
@@ -35,10 +31,7 @@ function fetchRepositoryTypes(dispatch: any) {
}
export function shouldFetchRepositoryTypes(state: object) {
if (
isFetchRepositoryTypesPending(state) ||
getFetchRepositoryTypesFailure(state)
) {
if (isFetchRepositoryTypesPending(state) || getFetchRepositoryTypesFailure(state)) {
return false;
}
return !(state.repositoryTypes && state.repositoryTypes.length > 0);
@@ -50,9 +43,7 @@ export function fetchRepositoryTypesPending(): Action {
};
}
export function fetchRepositoryTypesSuccess(
repositoryTypes: RepositoryTypeCollection
): Action {
export function fetchRepositoryTypesSuccess(repositoryTypes: RepositoryTypeCollection): Action {
return {
type: FETCH_REPOSITORY_TYPES_SUCCESS,
payload: repositoryTypes

View File

@@ -14,20 +14,11 @@ type Props = {
class RoleSelector extends React.Component<Props> {
render() {
const {
availableRoles,
role,
handleRoleChange,
loading,
label,
helpText
} = this.props;
const { availableRoles, role, handleRoleChange, loading, label, helpText } = this.props;
if (!availableRoles) return null;
const options = role
? this.createSelectOptions(availableRoles)
: ["", ...this.createSelectOptions(availableRoles)];
const options = role ? this.createSelectOptions(availableRoles) : ["", ...this.createSelectOptions(availableRoles)];
return (
<Select

View File

@@ -16,12 +16,7 @@ describe("DeletePermissionButton", () => {
_links: {}
};
const navLink = shallow(
<DeletePermissionButton
permission={permission}
deletePermission={() => {}}
/>
);
const navLink = shallow(<DeletePermissionButton permission={permission} deletePermission={() => {}} />);
expect(navLink.text()).toBe("");
});
@@ -34,12 +29,7 @@ describe("DeletePermissionButton", () => {
}
};
const deleteIcon = mount(
<DeletePermissionButton
permission={permission}
deletePermission={() => {}}
/>
);
const deleteIcon = mount(<DeletePermissionButton permission={permission} deletePermission={() => {}} />);
expect(deleteIcon.html()).not.toBe("");
});
@@ -52,12 +42,7 @@ describe("DeletePermissionButton", () => {
}
};
const button = mount(
<DeletePermissionButton
permission={permission}
deletePermission={() => {}}
/>
);
const button = mount(<DeletePermissionButton permission={permission} deletePermission={() => {}} />);
button.find(".fa-trash").simulate("click");
expect(confirmAlert.mock.calls.length).toBe(1);
@@ -78,11 +63,7 @@ describe("DeletePermissionButton", () => {
}
const button = mount(
<DeletePermissionButton
permission={permission}
confirmDialog={false}
deletePermission={capture}
/>
<DeletePermissionButton permission={permission} confirmDialog={false} deletePermission={capture} />
);
button.find(".fa-trash").simulate("click");

View File

@@ -9,11 +9,7 @@ type Props = {
repoName: string;
confirmDialog?: boolean;
t: (p: string) => string;
deletePermission: (
permission: Permission,
namespace: string,
repoName: string
) => void;
deletePermission: (permission: Permission, namespace: string, repoName: string) => void;
loading: boolean;
};
@@ -23,11 +19,7 @@ class DeletePermissionButton extends React.Component<Props> {
};
deletePermission = () => {
this.props.deletePermission(
this.props.permission,
this.props.namespace,
this.props.repoName
);
this.props.deletePermission(this.props.permission, this.props.namespace, this.props.repoName);
};
confirmDelete = () => {

View File

@@ -6,9 +6,7 @@ describe("permission validation", () => {
const name = "PermissionName";
const groupPermission = false;
expect(
validator.isPermissionValid(name, groupPermission, permissions)
).toBe(true);
expect(validator.isPermissionValid(name, groupPermission, permissions)).toBe(true);
});
it("should return true if permission is valid and does not exists with same group permission", () => {
@@ -24,9 +22,7 @@ describe("permission validation", () => {
const name = "PermissionName";
const groupPermission = false;
expect(
validator.isPermissionValid(name, groupPermission, permissions)
).toBe(true);
expect(validator.isPermissionValid(name, groupPermission, permissions)).toBe(true);
});
it("should return false if permission is valid but exists", () => {
@@ -42,9 +38,7 @@ describe("permission validation", () => {
const name = "PermissionName";
const groupPermission = false;
expect(
validator.isPermissionValid(name, groupPermission, permissions)
).toBe(false);
expect(validator.isPermissionValid(name, groupPermission, permissions)).toBe(false);
});
it("should return false if permission does not exist but is invalid", () => {
@@ -52,9 +46,7 @@ describe("permission validation", () => {
const name = "@PermissionName";
const groupPermission = false;
expect(
validator.isPermissionValid(name, groupPermission, permissions)
).toBe(false);
expect(validator.isPermissionValid(name, groupPermission, permissions)).toBe(false);
});
it("should return false if permission is not valid and does not exist", () => {
@@ -62,8 +54,6 @@ describe("permission validation", () => {
const name = "@PermissionName";
const groupPermission = false;
expect(
validator.isPermissionValid(name, groupPermission, permissions)
).toBe(false);
expect(validator.isPermissionValid(name, groupPermission, permissions)).toBe(false);
});
});

View File

@@ -5,28 +5,13 @@ const isNameValid = validation.isNameValid;
export { isNameValid };
export const isPermissionValid = (
name: string,
groupPermission: boolean,
permissions: PermissionCollection
) => {
return (
isNameValid(name) &&
!currentPermissionIncludeName(name, groupPermission, permissions)
);
export const isPermissionValid = (name: string, groupPermission: boolean, permissions: PermissionCollection) => {
return isNameValid(name) && !currentPermissionIncludeName(name, groupPermission, permissions);
};
const currentPermissionIncludeName = (
name: string,
groupPermission: boolean,
permissions: PermissionCollection
) => {
const currentPermissionIncludeName = (name: string, groupPermission: boolean, permissions: PermissionCollection) => {
for (let i = 0; i < permissions.length; i++) {
if (
permissions[i].name === name &&
permissions[i].groupPermission === groupPermission
)
return true;
if (permissions[i].name === name && permissions[i].groupPermission === groupPermission) return true;
}
return false;
};

View File

@@ -1,10 +1,5 @@
import React from "react";
import {
ButtonGroup,
Button,
SubmitButton,
Modal
} from "@scm-manager/ui-components";
import { ButtonGroup, Button, SubmitButton, Modal } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
import PermissionCheckbox from "../components/PermissionCheckbox";
@@ -29,10 +24,7 @@ class AdvancedPermissionsDialog extends React.Component<Props, State> {
const verbs = {};
props.availableVerbs.forEach(
verb =>
(verbs[verb] = props.selectedVerbs
? props.selectedVerbs.includes(verb)
: false)
verb => (verbs[verb] = props.selectedVerbs ? props.selectedVerbs.includes(verb) : false)
);
this.state = {
verbs
@@ -44,18 +36,10 @@ class AdvancedPermissionsDialog extends React.Component<Props, State> {
const { verbs } = this.state;
const verbSelectBoxes = Object.entries(verbs).map(e => (
<PermissionCheckbox
key={e[0]}
disabled={readOnly}
name={e[0]}
checked={e[1]}
onChange={this.handleChange}
/>
<PermissionCheckbox key={e[0]} disabled={readOnly} name={e[0]} checked={e[1]} onChange={this.handleChange} />
));
const submitButton = !readOnly ? (
<SubmitButton label={t("permission.advanced.dialog.submit")} />
) : null;
const submitButton = !readOnly ? <SubmitButton label={t("permission.advanced.dialog.submit")} /> : null;
const body = <>{verbSelectBoxes}</>;
@@ -63,10 +47,7 @@ class AdvancedPermissionsDialog extends React.Component<Props, State> {
<form onSubmit={this.onSubmit}>
<ButtonGroup>
{submitButton}
<Button
label={t("permission.advanced.dialog.abort")}
action={onClose}
/>
<Button label={t("permission.advanced.dialog.abort")} action={onClose} />
</ButtonGroup>
</form>
);

View File

@@ -1,11 +1,6 @@
import React from "react";
import { translate } from "react-i18next";
import {
PermissionCollection,
PermissionCreateEntry,
RepositoryRole,
SelectValue
} from "@scm-manager/ui-types";
import { PermissionCollection, PermissionCreateEntry, RepositoryRole, SelectValue } from "@scm-manager/ui-types";
import {
Button,
GroupAutocomplete,
@@ -103,11 +98,7 @@ class CreatePermissionForm extends React.Component<Props, State> {
this.setState({
value,
name: value.value.id,
valid: validator.isPermissionValid(
value.value.id,
this.state.groupPermission,
this.props.currentPermissions
)
valid: validator.isPermissionValid(value.value.id, this.state.groupPermission, this.props.currentPermissions)
});
};
@@ -131,9 +122,7 @@ class CreatePermissionForm extends React.Component<Props, State> {
return (
<>
<hr />
<Subtitle
subtitle={t("permission.add-permission.add-permission-heading")}
/>
<Subtitle subtitle={t("permission.add-permission.add-permission-heading")} />
{advancedDialog}
<form onSubmit={this.submit}>
<div className="field is-grouped">
@@ -155,9 +144,7 @@ class CreatePermissionForm extends React.Component<Props, State> {
</div>
</div>
<div className="columns">
<div className="column is-three-fifths">
{this.renderAutocompletionField()}
</div>
<div className="column is-three-fifths">{this.renderAutocompletionField()}</div>
<div className="column is-two-fifths">
<div className="columns">
<div className="column is-narrow">
@@ -174,10 +161,7 @@ class CreatePermissionForm extends React.Component<Props, State> {
label={t("permission.permissions")}
helpText={t("permission.help.permissionsHelpText")}
/>
<Button
label={t("permission.advanced-button.label")}
action={this.toggleAdvancedPermissionsDialog}
/>
<Button label={t("permission.advanced-button.label")} action={this.toggleAdvancedPermissionsDialog} />
</div>
</div>
</div>

View File

@@ -22,18 +22,8 @@ import {
isFetchPermissionsPending,
modifyPermissionReset
} from "../modules/permissions";
import {
ErrorPage,
LabelWithHelpIcon,
Loading,
Subtitle
} from "@scm-manager/ui-components";
import {
Permission,
PermissionCollection,
PermissionCreateEntry,
RepositoryRole
} from "@scm-manager/ui-types";
import { ErrorPage, LabelWithHelpIcon, Loading, Subtitle } from "@scm-manager/ui-components";
import { Permission, PermissionCollection, PermissionCreateEntry, RepositoryRole } from "@scm-manager/ui-types";
import SinglePermission from "./SinglePermission";
import CreatePermissionForm from "./CreatePermissionForm";
import { History } from "history";
@@ -63,10 +53,7 @@ type Props = {
userAutocompleteLink: string;
//dispatch functions
fetchAvailablePermissionsIfNeeded: (
repositoryRolesLink: string,
repositoryVerbsLink: string
) => void;
fetchAvailablePermissionsIfNeeded: (repositoryRolesLink: string, repositoryVerbsLink: string) => void;
fetchPermissions: (link: string, namespace: string, repoName: string) => void;
createPermission: (
link: string,
@@ -107,12 +94,7 @@ class Permissions extends React.Component<Props> {
}
createPermission = (permission: Permission) => {
this.props.createPermission(
this.props.permissionsLink,
permission,
this.props.namespace,
this.props.repoName
);
this.props.createPermission(this.props.permissionsLink, permission, this.props.namespace, this.props.repoName);
};
render() {
@@ -132,13 +114,7 @@ class Permissions extends React.Component<Props> {
groupAutocompleteLink
} = this.props;
if (error) {
return (
<ErrorPage
title={t("permission.error-title")}
subtitle={t("permission.error-subtitle")}
error={error}
/>
);
return <ErrorPage title={t("permission.error-title")} subtitle={t("permission.error-subtitle")} error={error} />;
}
if (loading || !permissions || !availablePermissions) {
@@ -164,16 +140,10 @@ class Permissions extends React.Component<Props> {
<thead>
<tr>
<th>
<LabelWithHelpIcon
label={t("permission.name")}
helpText={t("permission.help.nameHelpText")}
/>
<LabelWithHelpIcon label={t("permission.name")} helpText={t("permission.help.nameHelpText")} />
</th>
<th>
<LabelWithHelpIcon
label={t("permission.role")}
helpText={t("permission.help.roleHelpText")}
/>
<LabelWithHelpIcon label={t("permission.role")} helpText={t("permission.help.roleHelpText")} />
</th>
<th>
<LabelWithHelpIcon
@@ -214,15 +184,9 @@ const mapStateToProps = (state, ownProps) => {
getDeletePermissionsFailure(state, namespace, repoName) ||
getModifyPermissionsFailure(state, namespace, repoName) ||
getFetchAvailablePermissionsFailure(state);
const loading =
isFetchPermissionsPending(state, namespace, repoName) ||
isFetchAvailablePermissionsPending(state);
const loading = isFetchPermissionsPending(state, namespace, repoName) || isFetchAvailablePermissionsPending(state);
const permissions = getPermissionsOfRepo(state, namespace, repoName);
const loadingCreatePermission = isCreatePermissionPending(
state,
namespace,
repoName
);
const loadingCreatePermission = isCreatePermissionPending(state, namespace, repoName);
const hasPermissionToCreate = hasCreatePermission(state, namespace, repoName);
const repositoryRolesLink = getRepositoryRolesLink(state);
const repositoryVerbsLink = getRepositoryVerbsLink(state);
@@ -257,16 +221,8 @@ const mapDispatchToProps = dispatch => {
fetchPermissions: (link: string, namespace: string, repoName: string) => {
dispatch(fetchPermissions(link, namespace, repoName));
},
fetchAvailablePermissionsIfNeeded: (
repositoryRolesLink: string,
repositoryVerbsLink: string
) => {
dispatch(
fetchAvailablePermissionsIfNeeded(
repositoryRolesLink,
repositoryVerbsLink
)
);
fetchAvailablePermissionsIfNeeded: (repositoryRolesLink: string, repositoryVerbsLink: string) => {
dispatch(fetchAvailablePermissionsIfNeeded(repositoryRolesLink, repositoryVerbsLink));
},
createPermission: (
link: string,
@@ -275,9 +231,7 @@ const mapDispatchToProps = dispatch => {
repoName: string,
callback?: () => void
) => {
dispatch(
createPermission(link, permission, namespace, repoName, callback)
);
dispatch(createPermission(link, permission, namespace, repoName, callback));
},
createPermissionReset: (namespace: string, repoName: string) => {
dispatch(createPermissionReset(namespace, repoName));

View File

@@ -20,11 +20,7 @@ type Props = {
availableRepositoryRoles: RepositoryRole[];
availableRepositoryVerbs: string[];
submitForm: (p: Permission) => void;
modifyPermission: (
permission: Permission,
namespace: string,
name: string
) => void;
modifyPermission: (permission: Permission, namespace: string, name: string) => void;
permission: Permission;
t: (p: string) => string;
namespace: string;
@@ -32,11 +28,7 @@ type Props = {
match: any;
history: History;
loading: boolean;
deletePermission: (
permission: Permission,
namespace: string,
name: string
) => void;
deletePermission: (permission: Permission, namespace: string, name: string) => void;
deleteLoading: boolean;
};
@@ -58,9 +50,7 @@ class SinglePermission extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
const defaultPermission = props.availableRepositoryRoles
? props.availableRepositoryRoles[0]
: {};
const defaultPermission = props.availableRepositoryRoles ? props.availableRepositoryRoles[0] : {};
this.state = {
permission: {
@@ -91,25 +81,13 @@ class SinglePermission extends React.Component<Props, State> {
}
deletePermission = () => {
this.props.deletePermission(
this.props.permission,
this.props.namespace,
this.props.repoName
);
this.props.deletePermission(this.props.permission, this.props.namespace, this.props.repoName);
};
render() {
const {
availableRepositoryRoles,
availableRepositoryVerbs,
loading,
namespace,
repoName,
t
} = this.props;
const { availableRepositoryRoles, availableRepositoryVerbs, loading, namespace, repoName, t } = this.props;
const { permission, showAdvancedDialog } = this.state;
const availableRoleNames =
!!availableRepositoryRoles && availableRepositoryRoles.map(r => r.name);
const availableRoleNames = !!availableRepositoryRoles && availableRepositoryRoles.map(r => r.name);
const readOnly = !this.mayChangePermissions();
const roleSelector = readOnly ? (
<td>{permission.role ? permission.role : t("permission.custom")}</td>
@@ -152,10 +130,7 @@ class SinglePermission extends React.Component<Props, State> {
</VCenteredTd>
{roleSelector}
<VCenteredTd>
<Button
label={t("permission.advanced-button.label")}
action={this.handleDetailedPermissionsPressed}
/>
<Button label={t("permission.advanced-button.label")} action={this.handleDetailedPermissionsPressed} />
</VCenteredTd>
<VCenteredTd className="is-darker">
<DeletePermissionButton
@@ -222,40 +197,22 @@ class SinglePermission extends React.Component<Props, State> {
};
modifyPermissionRole = (role: string) => {
let permission = this.state.permission;
const permission = this.state.permission;
permission.role = role;
this.props.modifyPermission(
permission,
this.props.namespace,
this.props.repoName
);
this.props.modifyPermission(permission, this.props.namespace, this.props.repoName);
};
modifyPermissionVerbs = (verbs: string[]) => {
let permission = this.state.permission;
const permission = this.state.permission;
permission.verbs = verbs;
this.props.modifyPermission(
permission,
this.props.namespace,
this.props.repoName
);
this.props.modifyPermission(permission, this.props.namespace, this.props.repoName);
};
}
const mapStateToProps = (state, ownProps) => {
const permission = ownProps.permission;
const loading = isModifyPermissionPending(
state,
ownProps.namespace,
ownProps.repoName,
permission
);
const deleteLoading = isDeletePermissionPending(
state,
ownProps.namespace,
ownProps.repoName,
permission
);
const loading = isModifyPermissionPending(state, ownProps.namespace, ownProps.repoName, permission);
const deleteLoading = isDeletePermissionPending(state, ownProps.namespace, ownProps.repoName, permission);
return {
loading,
@@ -265,18 +222,10 @@ const mapStateToProps = (state, ownProps) => {
const mapDispatchToProps = dispatch => {
return {
modifyPermission: (
permission: Permission,
namespace: string,
repoName: string
) => {
modifyPermission: (permission: Permission, namespace: string, repoName: string) => {
dispatch(modifyPermission(permission, namespace, repoName));
},
deletePermission: (
permission: Permission,
namespace: string,
repoName: string
) => {
deletePermission: (permission: Permission, namespace: string, repoName: string) => {
dispatch(deletePermission(permission, namespace, repoName));
}
};

View File

@@ -47,16 +47,13 @@ const hitchhiker_puzzle42Permission_user_eins: Permission = {
groupPermission: false,
_links: {
self: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
href: "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
},
delete: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
href: "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
},
update: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
href: "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
}
},
verbs: []
@@ -68,16 +65,13 @@ const hitchhiker_puzzle42Permission_user_zwei: Permission = {
groupPermission: true,
_links: {
self: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
href: "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
},
delete: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
href: "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
},
update: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
href: "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
}
},
verbs: []
@@ -94,8 +88,7 @@ const hitchhiker_puzzle42RepoPermissions = {
},
_links: {
create: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions"
href: "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions"
}
}
};
@@ -111,10 +104,7 @@ describe("permission fetch", () => {
});
it("should successfully fetch permissions to repo hitchhiker/puzzle42", () => {
fetchMock.getOnce(
REPOS_URL + "/hitchhiker/puzzle42/permissions",
hitchhiker_puzzle42RepoPermissions
);
fetchMock.getOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", hitchhiker_puzzle42RepoPermissions);
const expectedActions = [
{
@@ -134,13 +124,7 @@ describe("permission fetch", () => {
const store = mockStore({});
return store
.dispatch(
fetchPermissions(
URL + "/hitchhiker/puzzle42/permissions",
"hitchhiker",
"puzzle42"
)
)
.dispatch(fetchPermissions(URL + "/hitchhiker/puzzle42/permissions", "hitchhiker", "puzzle42"))
.then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
@@ -153,13 +137,7 @@ describe("permission fetch", () => {
const store = mockStore({});
return store
.dispatch(
fetchPermissions(
URL + "/hitchhiker/puzzle42/permissions",
"hitchhiker",
"puzzle42"
)
)
.dispatch(fetchPermissions(URL + "/hitchhiker/puzzle42/permissions", "hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(FETCH_PERMISSIONS_PENDING);
@@ -169,38 +147,30 @@ describe("permission fetch", () => {
});
it("should successfully modify user_eins permission", () => {
fetchMock.putOnce(
hitchhiker_puzzle42Permission_user_eins._links.update.href,
{
status: 204
}
);
fetchMock.putOnce(hitchhiker_puzzle42Permission_user_eins._links.update.href, {
status: 204
});
let editedPermission = {
const editedPermission = {
...hitchhiker_puzzle42Permission_user_eins,
type: "OWNER"
};
const store = mockStore({});
return store
.dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
});
return store.dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42")).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
});
});
it("should successfully modify user_eins permission and call the callback", () => {
fetchMock.putOnce(
hitchhiker_puzzle42Permission_user_eins._links.update.href,
{
status: 204
}
);
fetchMock.putOnce(hitchhiker_puzzle42Permission_user_eins._links.update.href, {
status: 204
});
let editedPermission = {
const editedPermission = {
...hitchhiker_puzzle42Permission_user_eins,
type: "OWNER"
};
@@ -212,41 +182,32 @@ describe("permission fetch", () => {
called = true;
};
return store
.dispatch(
modifyPermission(editedPermission, "hitchhiker", "puzzle42", callback)
)
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
expect(called).toBe(true);
});
return store.dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42", callback)).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
expect(called).toBe(true);
});
});
it("should fail modifying on HTTP 500", () => {
fetchMock.putOnce(
hitchhiker_puzzle42Permission_user_eins._links.update.href,
{
status: 500
}
);
fetchMock.putOnce(hitchhiker_puzzle42Permission_user_eins._links.update.href, {
status: 500
});
let editedPermission = {
const editedPermission = {
...hitchhiker_puzzle42Permission_user_eins,
type: "OWNER"
};
const store = mockStore({});
return store
.dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_FAILURE);
expect(actions[1].payload).toBeDefined();
});
return store.dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42")).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_FAILURE);
expect(actions[1].payload).toBeDefined();
});
});
it("should add a permission successfully", () => {
@@ -338,40 +299,26 @@ describe("permission fetch", () => {
});
});
it("should delete successfully permission user_eins", () => {
fetchMock.deleteOnce(
hitchhiker_puzzle42Permission_user_eins._links.delete.href,
{
status: 204
}
);
fetchMock.deleteOnce(hitchhiker_puzzle42Permission_user_eins._links.delete.href, {
status: 204
});
const store = mockStore({});
return store
.dispatch(
deletePermission(
hitchhiker_puzzle42Permission_user_eins,
"hitchhiker",
"puzzle42"
)
)
.dispatch(deletePermission(hitchhiker_puzzle42Permission_user_eins, "hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions.length).toBe(2);
expect(actions[0].type).toEqual(DELETE_PERMISSION_PENDING);
expect(actions[0].payload).toBe(
hitchhiker_puzzle42Permission_user_eins
);
expect(actions[0].payload).toBe(hitchhiker_puzzle42Permission_user_eins);
expect(actions[1].type).toEqual(DELETE_PERMISSION_SUCCESS);
});
});
it("should call the callback, after successful delete", () => {
fetchMock.deleteOnce(
hitchhiker_puzzle42Permission_user_eins._links.delete.href,
{
status: 204
}
);
fetchMock.deleteOnce(hitchhiker_puzzle42Permission_user_eins._links.delete.href, {
status: 204
});
let called = false;
const callMe = () => {
@@ -380,42 +327,24 @@ describe("permission fetch", () => {
const store = mockStore({});
return store
.dispatch(
deletePermission(
hitchhiker_puzzle42Permission_user_eins,
"hitchhiker",
"puzzle42",
callMe
)
)
.dispatch(deletePermission(hitchhiker_puzzle42Permission_user_eins, "hitchhiker", "puzzle42", callMe))
.then(() => {
expect(called).toBeTruthy();
});
});
it("should fail to delete permission", () => {
fetchMock.deleteOnce(
hitchhiker_puzzle42Permission_user_eins._links.delete.href,
{
status: 500
}
);
fetchMock.deleteOnce(hitchhiker_puzzle42Permission_user_eins._links.delete.href, {
status: 500
});
const store = mockStore({});
return store
.dispatch(
deletePermission(
hitchhiker_puzzle42Permission_user_eins,
"hitchhiker",
"puzzle42"
)
)
.dispatch(deletePermission(hitchhiker_puzzle42Permission_user_eins, "hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(DELETE_PERMISSION_PENDING);
expect(actions[0].payload).toBe(
hitchhiker_puzzle42Permission_user_eins
);
expect(actions[0].payload).toBe(hitchhiker_puzzle42Permission_user_eins);
expect(actions[1].type).toEqual(DELETE_PERMISSION_FAILURE);
expect(actions[1].payload).toBeDefined();
});
@@ -446,18 +375,9 @@ describe("permissions reducer", () => {
});
it("should store the permissions on FETCH_PERMISSION_SUCCESS", () => {
const newState = reducer(
{},
fetchPermissionsSuccess(
hitchhiker_puzzle42RepoPermissions,
"hitchhiker",
"puzzle42"
)
);
const newState = reducer({}, fetchPermissionsSuccess(hitchhiker_puzzle42RepoPermissions, "hitchhiker", "puzzle42"));
expect(newState["hitchhiker/puzzle42"].entries).toBe(
hitchhiker_puzzle42Permissions
);
expect(newState["hitchhiker/puzzle42"].entries).toBe(hitchhiker_puzzle42Permissions);
});
it("should update permission", () => {
@@ -466,31 +386,23 @@ describe("permissions reducer", () => {
entries: [hitchhiker_puzzle42Permission_user_eins]
}
};
let permissionEdited = {
const permissionEdited = {
...hitchhiker_puzzle42Permission_user_eins,
type: "OWNER"
};
let expectedState = {
const expectedState = {
"hitchhiker/puzzle42": {
entries: [permissionEdited]
}
};
const newState = reducer(
oldState,
modifyPermissionSuccess(permissionEdited, "hitchhiker", "puzzle42")
);
expect(newState["hitchhiker/puzzle42"]).toEqual(
expectedState["hitchhiker/puzzle42"]
);
const newState = reducer(oldState, modifyPermissionSuccess(permissionEdited, "hitchhiker", "puzzle42"));
expect(newState["hitchhiker/puzzle42"]).toEqual(expectedState["hitchhiker/puzzle42"]);
});
it("should remove permission from state when delete succeeds", () => {
const state = {
"hitchhiker/puzzle42": {
entries: [
hitchhiker_puzzle42Permission_user_eins,
hitchhiker_puzzle42Permission_user_zwei
]
entries: [hitchhiker_puzzle42Permission_user_eins, hitchhiker_puzzle42Permission_user_zwei]
}
};
@@ -502,15 +414,9 @@ describe("permissions reducer", () => {
const newState = reducer(
state,
deletePermissionSuccess(
hitchhiker_puzzle42Permission_user_eins,
"hitchhiker",
"puzzle42"
)
);
expect(newState["hitchhiker/puzzle42"]).toEqual(
expectedState["hitchhiker/puzzle42"]
deletePermissionSuccess(hitchhiker_puzzle42Permission_user_eins, "hitchhiker", "puzzle42")
);
expect(newState["hitchhiker/puzzle42"]).toEqual(expectedState["hitchhiker/puzzle42"]);
});
it("should add permission", () => {
@@ -520,25 +426,16 @@ describe("permissions reducer", () => {
entries: [hitchhiker_puzzle42Permission_user_eins]
}
};
let expectedState = {
const expectedState = {
"hitchhiker/puzzle42": {
entries: [
hitchhiker_puzzle42Permission_user_eins,
hitchhiker_puzzle42Permission_user_zwei
]
entries: [hitchhiker_puzzle42Permission_user_eins, hitchhiker_puzzle42Permission_user_zwei]
}
};
const newState = reducer(
oldState,
createPermissionSuccess(
hitchhiker_puzzle42Permission_user_zwei,
"hitchhiker",
"puzzle42"
)
);
expect(newState["hitchhiker/puzzle42"]).toEqual(
expectedState["hitchhiker/puzzle42"]
createPermissionSuccess(hitchhiker_puzzle42Permission_user_zwei, "hitchhiker", "puzzle42")
);
expect(newState["hitchhiker/puzzle42"]).toEqual(expectedState["hitchhiker/puzzle42"]);
});
});
@@ -554,11 +451,7 @@ describe("permissions selectors", () => {
}
};
const repoPermissions = getPermissionsOfRepo(
state,
"hitchhiker",
"puzzle42"
);
const repoPermissions = getPermissionsOfRepo(state, "hitchhiker", "puzzle42");
expect(repoPermissions).toEqual(hitchhiker_puzzle42Permissions);
});
@@ -568,15 +461,11 @@ describe("permissions selectors", () => {
[FETCH_PERMISSIONS + "/hitchhiker/puzzle42"]: true
}
};
expect(isFetchPermissionsPending(state, "hitchhiker", "puzzle42")).toEqual(
true
);
expect(isFetchPermissionsPending(state, "hitchhiker", "puzzle42")).toEqual(true);
});
it("should return false, when fetch permissions is not pending", () => {
expect(isFetchPermissionsPending({}, "hitchiker", "puzzle42")).toEqual(
false
);
expect(isFetchPermissionsPending({}, "hitchiker", "puzzle42")).toEqual(false);
});
it("should return error when fetch permissions did fail", () => {
@@ -585,15 +474,11 @@ describe("permissions selectors", () => {
[FETCH_PERMISSIONS + "/hitchhiker/puzzle42"]: error
}
};
expect(getFetchPermissionsFailure(state, "hitchhiker", "puzzle42")).toEqual(
error
);
expect(getFetchPermissionsFailure(state, "hitchhiker", "puzzle42")).toEqual(error);
});
it("should return undefined when fetch permissions did not fail", () => {
expect(getFetchPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
expect(getFetchPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(undefined);
});
it("should return true, when modify permission is pending", () => {
@@ -602,25 +487,15 @@ describe("permissions selectors", () => {
[MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: true
}
};
expect(
isModifyPermissionPending(
state,
"hitchhiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
).toEqual(true);
expect(isModifyPermissionPending(state, "hitchhiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)).toEqual(
true
);
});
it("should return false, when modify permission is not pending", () => {
expect(
isModifyPermissionPending(
{},
"hitchiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
).toEqual(false);
expect(isModifyPermissionPending({}, "hitchiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)).toEqual(
false
);
});
it("should return error when modify permission did fail", () => {
@@ -630,24 +505,14 @@ describe("permissions selectors", () => {
}
};
expect(
getModifyPermissionFailure(
state,
"hitchhiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
getModifyPermissionFailure(state, "hitchhiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)
).toEqual(error);
});
it("should return undefined when modify permission did not fail", () => {
expect(
getModifyPermissionFailure(
{},
"hitchhiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
).toBe(undefined);
expect(getModifyPermissionFailure({}, "hitchhiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)).toBe(
undefined
);
});
it("should return error when one of the modify permissions did fail", () => {
@@ -661,15 +526,11 @@ describe("permissions selectors", () => {
[MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
}
};
expect(
getModifyPermissionsFailure(state, "hitchhiker", "puzzle42")
).toEqual(error);
expect(getModifyPermissionsFailure(state, "hitchhiker", "puzzle42")).toEqual(error);
});
it("should return undefined when no modify permissions did not fail", () => {
expect(getModifyPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
expect(getModifyPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(undefined);
});
it("should return true, when createPermission is true", () => {
@@ -700,25 +561,15 @@ describe("permissions selectors", () => {
[DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: true
}
};
expect(
isDeletePermissionPending(
state,
"hitchhiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
).toEqual(true);
expect(isDeletePermissionPending(state, "hitchhiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)).toEqual(
true
);
});
it("should return false, when delete permission is not pending", () => {
expect(
isDeletePermissionPending(
{},
"hitchiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
).toEqual(false);
expect(isDeletePermissionPending({}, "hitchiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)).toEqual(
false
);
});
it("should return error when delete permission did fail", () => {
@@ -728,24 +579,14 @@ describe("permissions selectors", () => {
}
};
expect(
getDeletePermissionFailure(
state,
"hitchhiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
getDeletePermissionFailure(state, "hitchhiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)
).toEqual(error);
});
it("should return undefined when delete permission did not fail", () => {
expect(
getDeletePermissionFailure(
{},
"hitchhiker",
"puzzle42",
hitchhiker_puzzle42Permission_user_eins
)
).toBe(undefined);
expect(getDeletePermissionFailure({}, "hitchhiker", "puzzle42", hitchhiker_puzzle42Permission_user_eins)).toBe(
undefined
);
});
it("should return error when one of the delete permissions did fail", () => {
@@ -759,15 +600,11 @@ describe("permissions selectors", () => {
[DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
}
};
expect(
getDeletePermissionsFailure(state, "hitchhiker", "puzzle42")
).toEqual(error);
expect(getDeletePermissionsFailure(state, "hitchhiker", "puzzle42")).toEqual(error);
});
it("should return undefined when no delete permissions did not fail", () => {
expect(getDeletePermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
expect(getDeletePermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(undefined);
});
it("should return true, when create permission is pending", () => {
@@ -776,15 +613,11 @@ describe("permissions selectors", () => {
[CREATE_PERMISSION + "/hitchhiker/puzzle42"]: true
}
};
expect(isCreatePermissionPending(state, "hitchhiker", "puzzle42")).toEqual(
true
);
expect(isCreatePermissionPending(state, "hitchhiker", "puzzle42")).toEqual(true);
});
it("should return false, when create permissions is not pending", () => {
expect(isCreatePermissionPending({}, "hitchiker", "puzzle42")).toEqual(
false
);
expect(isCreatePermissionPending({}, "hitchiker", "puzzle42")).toEqual(false);
});
it("should return error when create permissions did fail", () => {
@@ -793,14 +626,10 @@ describe("permissions selectors", () => {
[CREATE_PERMISSION + "/hitchhiker/puzzle42"]: error
}
};
expect(getCreatePermissionFailure(state, "hitchhiker", "puzzle42")).toEqual(
error
);
expect(getCreatePermissionFailure(state, "hitchhiker", "puzzle42")).toEqual(error);
});
it("should return undefined when create permissions did not fail", () => {
expect(getCreatePermissionFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
expect(getCreatePermissionFailure({}, "hitchhiker", "puzzle42")).toBe(undefined);
});
});

View File

@@ -1,12 +1,7 @@
import { Action } from "@scm-manager/ui-components";
import { apiClient } from "@scm-manager/ui-components";
import * as types from "../../../modules/types";
import {
RepositoryRole,
Permission,
PermissionCollection,
PermissionCreateEntry
} from "@scm-manager/ui-types";
import { RepositoryRole, Permission, PermissionCollection, PermissionCreateEntry } from "@scm-manager/ui-types";
import { isPending } from "../../../modules/pending";
import { getFailure } from "../../../modules/failure";
import { Dispatch } from "redux";
@@ -39,18 +34,10 @@ const CONTENT_TYPE = "application/vnd.scmm-repositoryPermission+json";
// fetch available permissions
export function fetchAvailablePermissionsIfNeeded(
repositoryRolesLink: string,
repositoryVerbsLink: string
) {
export function fetchAvailablePermissionsIfNeeded(repositoryRolesLink: string, repositoryVerbsLink: string) {
return function(dispatch: any, getState: () => object) {
if (shouldFetchAvailablePermissions(getState())) {
return fetchAvailablePermissions(
dispatch,
getState,
repositoryRolesLink,
repositoryVerbsLink
);
return fetchAvailablePermissions(dispatch, getState, repositoryRolesLink, repositoryVerbsLink);
}
};
}
@@ -87,10 +74,7 @@ export function fetchAvailablePermissions(
}
export function shouldFetchAvailablePermissions(state: object) {
if (
isFetchAvailablePermissionsPending(state) ||
getFetchAvailablePermissionsFailure(state)
) {
if (isFetchAvailablePermissionsPending(state) || getFetchAvailablePermissionsFailure(state)) {
return false;
}
return !state.available;
@@ -104,9 +88,7 @@ export function fetchAvailablePending(): Action {
};
}
export function fetchAvailableSuccess(
available: [RepositoryRole[], string[]]
): Action {
export function fetchAvailableSuccess(available: [RepositoryRole[], string[]]): Action {
return {
type: FETCH_AVAILABLE_SUCCESS,
payload: available,
@@ -126,11 +108,7 @@ export function fetchAvailableFailure(error: Error): Action {
// fetch permissions
export function fetchPermissions(
link: string,
namespace: string,
repoName: string
) {
export function fetchPermissions(link: string, namespace: string, repoName: string) {
return function(dispatch: any) {
dispatch(fetchPermissionsPending(namespace, repoName));
return apiClient
@@ -145,10 +123,7 @@ export function fetchPermissions(
};
}
export function fetchPermissionsPending(
namespace: string,
repoName: string
): Action {
export function fetchPermissionsPending(namespace: string, repoName: string): Action {
return {
type: FETCH_PERMISSIONS_PENDING,
payload: {
@@ -159,11 +134,7 @@ export function fetchPermissionsPending(
};
}
export function fetchPermissionsSuccess(
permissions: any,
namespace: string,
repoName: string
): Action {
export function fetchPermissionsSuccess(permissions: any, namespace: string, repoName: string): Action {
return {
type: FETCH_PERMISSIONS_SUCCESS,
payload: permissions,
@@ -171,11 +142,7 @@ export function fetchPermissionsSuccess(
};
}
export function fetchPermissionsFailure(
namespace: string,
repoName: string,
error: Error
): Action {
export function fetchPermissionsFailure(namespace: string, repoName: string, error: Error): Action {
return {
type: FETCH_PERMISSIONS_FAILURE,
payload: {
@@ -189,12 +156,7 @@ export function fetchPermissionsFailure(
// modify permission
export function modifyPermission(
permission: Permission,
namespace: string,
repoName: string,
callback?: () => void
) {
export function modifyPermission(permission: Permission, namespace: string, repoName: string, callback?: () => void) {
return function(dispatch: any) {
dispatch(modifyPermissionPending(permission, namespace, repoName));
return apiClient
@@ -211,11 +173,7 @@ export function modifyPermission(
};
}
export function modifyPermissionPending(
permission: Permission,
namespace: string,
repoName: string
): Action {
export function modifyPermissionPending(permission: Permission, namespace: string, repoName: string): Action {
return {
type: MODIFY_PERMISSION_PENDING,
payload: permission,
@@ -223,11 +181,7 @@ export function modifyPermissionPending(
};
}
export function modifyPermissionSuccess(
permission: Permission,
namespace: string,
repoName: string
): Action {
export function modifyPermissionSuccess(permission: Permission, namespace: string, repoName: string): Action {
return {
type: MODIFY_PERMISSION_SUCCESS,
payload: {
@@ -254,10 +208,7 @@ export function modifyPermissionFailure(
};
}
function newPermissions(
oldPermissions: PermissionCollection,
newPermission: Permission
) {
function newPermissions(oldPermissions: PermissionCollection, newPermission: Permission) {
for (let i = 0; i < oldPermissions.length; i++) {
if (oldPermissions[i].name === newPermission.name) {
oldPermissions.splice(i, 1, newPermission);
@@ -295,16 +246,12 @@ export function createPermission(
})
.then(response => response.json())
.then(createdPermission => {
dispatch(
createPermissionSuccess(createdPermission, namespace, repoName)
);
dispatch(createPermissionSuccess(createdPermission, namespace, repoName));
if (callback) {
callback();
}
})
.catch(err =>
dispatch(createPermissionFailure(err, namespace, repoName))
);
.catch(err => dispatch(createPermissionFailure(err, namespace, repoName)));
};
}
@@ -335,11 +282,7 @@ export function createPermissionSuccess(
};
}
export function createPermissionFailure(
error: Error,
namespace: string,
repoName: string
): Action {
export function createPermissionFailure(error: Error, namespace: string, repoName: string): Action {
return {
type: CREATE_PERMISSION_FAILURE,
payload: error,
@@ -356,12 +299,7 @@ export function createPermissionReset(namespace: string, repoName: string) {
// delete permission
export function deletePermission(
permission: Permission,
namespace: string,
repoName: string,
callback?: () => void
) {
export function deletePermission(permission: Permission, namespace: string, repoName: string, callback?: () => void) {
return function(dispatch: any) {
dispatch(deletePermissionPending(permission, namespace, repoName));
return apiClient
@@ -378,11 +316,7 @@ export function deletePermission(
};
}
export function deletePermissionPending(
permission: Permission,
namespace: string,
repoName: string
): Action {
export function deletePermissionPending(permission: Permission, namespace: string, repoName: string): Action {
return {
type: DELETE_PERMISSION_PENDING,
payload: permission,
@@ -390,11 +324,7 @@ export function deletePermissionPending(
};
}
export function deletePermissionSuccess(
permission: Permission,
namespace: string,
repoName: string
): Action {
export function deletePermissionSuccess(permission: Permission, namespace: string, repoName: string): Action {
return {
type: DELETE_PERMISSION_SUCCESS,
payload: {
@@ -432,11 +362,8 @@ export function deletePermissionReset(namespace: string, repoName: string) {
};
}
function deletePermissionFromState(
oldPermissions: PermissionCollection,
permission: Permission
) {
let newPermission = [];
function deletePermissionFromState(oldPermissions: PermissionCollection, permission: Permission) {
const newPermission = [];
for (let i = 0; i < oldPermissions.length; i++) {
if (
oldPermissions[i].name !== permission.name ||
@@ -448,12 +375,8 @@ function deletePermissionFromState(
return newPermission;
}
function createItemId(
permission: Permission,
namespace: string,
repoName: string
) {
let groupPermission = permission.groupPermission ? "@" : "";
function createItemId(permission: Permission, namespace: string, repoName: string) {
const groupPermission = permission.groupPermission ? "@" : "";
return namespace + "/" + repoName + "/" + groupPermission + permission.name;
}
@@ -483,10 +406,7 @@ export default function reducer(
};
case MODIFY_PERMISSION_SUCCESS:
const positionOfPermission = action.payload.position;
const newPermission = newPermissions(
state[action.payload.position].entries,
action.payload.permission
);
const newPermission = newPermissions(state[action.payload.position].entries, action.payload.permission);
return {
...state,
[positionOfPermission]: {
@@ -547,11 +467,7 @@ function available(state: object) {
return {};
}
export function getPermissionsOfRepo(
state: object,
namespace: string,
repoName: string
) {
export function getPermissionsOfRepo(state: object, namespace: string, repoName: string) {
if (state.permissions && state.permissions[namespace + "/" + repoName]) {
return state.permissions[namespace + "/" + repoName].entries;
}
@@ -561,11 +477,7 @@ export function isFetchAvailablePermissionsPending(state: object) {
return isPending(state, FETCH_AVAILABLE, "available");
}
export function isFetchPermissionsPending(
state: object,
namespace: string,
repoName: string
) {
export function isFetchPermissionsPending(state: object, namespace: string, repoName: string) {
return isPending(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
}
@@ -573,147 +485,70 @@ export function getFetchAvailablePermissionsFailure(state: object) {
return getFailure(state, FETCH_AVAILABLE, "available");
}
export function getFetchPermissionsFailure(
state: object,
namespace: string,
repoName: string
) {
export function getFetchPermissionsFailure(state: object, namespace: string, repoName: string) {
return getFailure(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
}
export function isModifyPermissionPending(
state: object,
namespace: string,
repoName: string,
permission: Permission
) {
return isPending(
state,
MODIFY_PERMISSION,
createItemId(permission, namespace, repoName)
);
export function isModifyPermissionPending(state: object, namespace: string, repoName: string, permission: Permission) {
return isPending(state, MODIFY_PERMISSION, createItemId(permission, namespace, repoName));
}
export function getModifyPermissionFailure(
state: object,
namespace: string,
repoName: string,
permission: Permission
) {
return getFailure(
state,
MODIFY_PERMISSION,
createItemId(permission, namespace, repoName)
);
export function getModifyPermissionFailure(state: object, namespace: string, repoName: string, permission: Permission) {
return getFailure(state, MODIFY_PERMISSION, createItemId(permission, namespace, repoName));
}
export function hasCreatePermission(
state: object,
namespace: string,
repoName: string
) {
export function hasCreatePermission(state: object, namespace: string, repoName: string) {
if (state.permissions && state.permissions[namespace + "/" + repoName])
return state.permissions[namespace + "/" + repoName].createPermission;
else return null;
}
export function isCreatePermissionPending(
state: object,
namespace: string,
repoName: string
) {
export function isCreatePermissionPending(state: object, namespace: string, repoName: string) {
return isPending(state, CREATE_PERMISSION, namespace + "/" + repoName);
}
export function getCreatePermissionFailure(
state: object,
namespace: string,
repoName: string
) {
export function getCreatePermissionFailure(state: object, namespace: string, repoName: string) {
return getFailure(state, CREATE_PERMISSION, namespace + "/" + repoName);
}
export function isDeletePermissionPending(
state: object,
namespace: string,
repoName: string,
permission: Permission
) {
return isPending(
state,
DELETE_PERMISSION,
createItemId(permission, namespace, repoName)
);
export function isDeletePermissionPending(state: object, namespace: string, repoName: string, permission: Permission) {
return isPending(state, DELETE_PERMISSION, createItemId(permission, namespace, repoName));
}
export function getDeletePermissionFailure(
state: object,
namespace: string,
repoName: string,
permission: Permission
) {
return getFailure(
state,
DELETE_PERMISSION,
createItemId(permission, namespace, repoName)
);
export function getDeletePermissionFailure(state: object, namespace: string, repoName: string, permission: Permission) {
return getFailure(state, DELETE_PERMISSION, createItemId(permission, namespace, repoName));
}
export function getDeletePermissionsFailure(
state: object,
namespace: string,
repoName: string
) {
export function getDeletePermissionsFailure(state: object, namespace: string, repoName: string) {
const permissions =
state.permissions && state.permissions[namespace + "/" + repoName]
? state.permissions[namespace + "/" + repoName].entries
: null;
if (permissions == null) return undefined;
for (let i = 0; i < permissions.length; i++) {
if (
getDeletePermissionFailure(state, namespace, repoName, permissions[i])
) {
return getFailure(
state,
DELETE_PERMISSION,
createItemId(permissions[i], namespace, repoName)
);
if (getDeletePermissionFailure(state, namespace, repoName, permissions[i])) {
return getFailure(state, DELETE_PERMISSION, createItemId(permissions[i], namespace, repoName));
}
}
return null;
}
export function getModifyPermissionsFailure(
state: object,
namespace: string,
repoName: string
) {
export function getModifyPermissionsFailure(state: object, namespace: string, repoName: string) {
const permissions =
state.permissions && state.permissions[namespace + "/" + repoName]
? state.permissions[namespace + "/" + repoName].entries
: null;
if (permissions == null) return undefined;
for (let i = 0; i < permissions.length; i++) {
if (
getModifyPermissionFailure(state, namespace, repoName, permissions[i])
) {
return getFailure(
state,
MODIFY_PERMISSION,
createItemId(permissions[i], namespace, repoName)
);
if (getModifyPermissionFailure(state, namespace, repoName, permissions[i])) {
return getFailure(state, MODIFY_PERMISSION, createItemId(permissions[i], namespace, repoName));
}
}
return null;
}
export function findVerbsForRole(
availableRepositoryRoles: RepositoryRole[],
roleName: string
) {
const matchingRole = availableRepositoryRoles.find(
role => roleName === role.name
);
export function findVerbsForRole(availableRepositoryRoles: RepositoryRole[], roleName: string) {
const matchingRole = availableRepositoryRoles.find(role => roleName === role.name);
if (matchingRole) {
return matchingRole.verbs;
} else {

View File

@@ -6,16 +6,8 @@ import { translate } from "react-i18next";
import styled from "styled-components";
import { binder } from "@scm-manager/ui-extensions";
import { Repository, File } from "@scm-manager/ui-types";
import {
ErrorNotification,
Loading,
Notification
} from "@scm-manager/ui-components";
import {
getFetchSourcesFailure,
isFetchSourcesPending,
getSources
} from "../modules/sources";
import { ErrorNotification, Loading, Notification } from "@scm-manager/ui-components";
import { getFetchSourcesFailure, isFetchSourcesPending, getSources } from "../modules/sources";
import FileTreeLeaf from "./FileTreeLeaf";
type Props = {
@@ -113,27 +105,15 @@ class FileTree extends React.Component<Props> {
<tr>
<FixedWidthTh />
<th>{t("sources.file-tree.name")}</th>
<th className="is-hidden-mobile">
{t("sources.file-tree.length")}
</th>
<th className="is-hidden-mobile">
{t("sources.file-tree.lastModified")}
</th>
<th className="is-hidden-mobile">
{t("sources.file-tree.description")}
</th>
{binder.hasExtension("repos.sources.tree.row.right") && (
<th className="is-hidden-mobile" />
)}
<th className="is-hidden-mobile">{t("sources.file-tree.length")}</th>
<th className="is-hidden-mobile">{t("sources.file-tree.lastModified")}</th>
<th className="is-hidden-mobile">{t("sources.file-tree.description")}</th>
{binder.hasExtension("repos.sources.tree.row.right") && <th className="is-hidden-mobile" />}
</tr>
</thead>
<tbody>
{files.map(file => (
<FileTreeLeaf
key={file.name}
file={file}
baseUrl={baseUrlWithRevision}
/>
<FileTreeLeaf key={file.name} file={file} baseUrl={baseUrlWithRevision} />
))}
</tbody>
</table>

View File

@@ -66,16 +66,12 @@ export default class FileTreeLeaf extends React.Component<Props> {
return (
<tr>
<td>{this.createFileIcon(file)}</td>
<MinWidthTd className="is-word-break">
{this.createFileName(file)}
</MinWidthTd>
<MinWidthTd className="is-word-break">{this.createFileName(file)}</MinWidthTd>
<td className="is-hidden-mobile">{fileSize}</td>
<td className="is-hidden-mobile">
<DateFromNow date={file.lastModified} />
</td>
<MinWidthTd className={classNames("is-word-break", "is-hidden-mobile")}>
{file.description}
</MinWidthTd>
<MinWidthTd className={classNames("is-word-break", "is-hidden-mobile")}>{file.description}</MinWidthTd>
{binder.hasExtension("repos.sources.tree.row.right") && (
<td className="is-hidden-mobile">
{!file.directory && (

View File

@@ -13,10 +13,7 @@ class DownloadViewer extends React.Component<Props> {
const { t, file } = this.props;
return (
<div className="has-text-centered">
<DownloadButton
url={file._links.self.href}
displayName={t("sources.content.downloadButton")}
/>
<DownloadButton url={file._links.self.href} displayName={t("sources.content.downloadButton")} />
</div>
);
}

View File

@@ -28,22 +28,14 @@ class FileButtonAddons extends React.Component<Props> {
return (
<ButtonAddons className={className}>
<div title={t("sources.content.sourcesButton")}>
<Button
action={this.showSources}
className="reduced"
color={this.color(!historyIsSelected)}
>
<Button action={this.showSources} className="reduced" color={this.color(!historyIsSelected)}>
<span className="icon">
<i className="fas fa-code" />
</span>
</Button>
</div>
<div title={t("sources.content.historyButton")}>
<Button
action={this.showHistory}
className="reduced"
color={this.color(historyIsSelected)}
>
<Button action={this.showHistory} className="reduced" color={this.color(historyIsSelected)}>
<span className="icon">
<i className="fas fa-history" />
</span>

View File

@@ -63,9 +63,7 @@ class SourcecodeViewer extends React.Component<Props, State> {
return null;
}
return (
<SyntaxHighlighter language={getLanguage(language)} value={content} />
);
return <SyntaxHighlighter language={getLanguage(language)} value={content} />;
}
}

View File

@@ -5,12 +5,7 @@ import classNames from "classnames";
import styled from "styled-components";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
import { File, Repository } from "@scm-manager/ui-types";
import {
DateFromNow,
ErrorNotification,
FileSize,
Icon
} from "@scm-manager/ui-components";
import { DateFromNow, ErrorNotification, FileSize, Icon } from "@scm-manager/ui-components";
import { getSources } from "../modules/sources";
import FileButtonAddons from "../components/content/FileButtonAddons";
import SourcesView from "./SourcesView";
@@ -91,9 +86,7 @@ class Content extends React.Component<Props, State> {
<RightMarginFileButtonAddons
file={file}
historyIsSelected={showHistory}
showHistory={(changeShowHistory: boolean) =>
this.setShowHistoryState(changeShowHistory)
}
showHistory={(changeShowHistory: boolean) => this.setShowHistoryState(changeShowHistory)}
/>
) : null;
@@ -189,12 +182,7 @@ class Content extends React.Component<Props, State> {
showHistory && file._links.history ? (
<HistoryView file={file} repository={repository} />
) : (
<SourcesView
revision={revision}
file={file}
repository={repository}
path={path}
/>
<SourcesView revision={revision} file={file} repository={repository} path={path} />
);
const moreInformation = this.showMoreInformation();

View File

@@ -1,16 +1,6 @@
import React from "react";
import {
File,
Changeset,
Repository,
PagedCollection
} from "@scm-manager/ui-types";
import {
ErrorNotification,
Loading,
StatePaginator,
ChangesetList
} from "@scm-manager/ui-components";
import { File, Changeset, Repository, PagedCollection } from "@scm-manager/ui-types";
import { ErrorNotification, Loading, StatePaginator, ChangesetList } from "@scm-manager/ui-components";
import { getHistory } from "./history";
type Props = {
@@ -67,9 +57,7 @@ class HistoryView extends React.Component<Props, State> {
updatePage(page: number) {
const { file } = this.props;
const internalPage = page - 1;
this.updateHistory(
file._links.history.href + "?page=" + internalPage.toString()
);
this.updateHistory(file._links.history.href + "?page=" + internalPage.toString());
}
showHistory() {

View File

@@ -3,12 +3,7 @@ import { connect } from "react-redux";
import { withRouter } from "react-router-dom";
import { Branch, Repository } from "@scm-manager/ui-types";
import FileTree from "../components/FileTree";
import {
BranchSelector,
Breadcrumb,
ErrorNotification,
Loading
} from "@scm-manager/ui-components";
import { BranchSelector, Breadcrumb, ErrorNotification, Loading } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
import {
fetchBranches,
@@ -55,13 +50,7 @@ class Sources extends React.Component<Props, State> {
}
componentDidMount() {
const {
fetchBranches,
repository,
revision,
path,
fetchSources
} = this.props;
const { fetchBranches, repository, revision, path, fetchSources } = this.props;
fetchBranches(repository);
fetchSources(repository, revision, path);
@@ -116,15 +105,7 @@ class Sources extends React.Component<Props, State> {
};
render() {
const {
repository,
baseUrl,
loading,
error,
revision,
path,
currentFileIsDirectory
} = this.props;
const { repository, baseUrl, loading, error, revision, path, currentFileIsDirectory } = this.props;
if (error) {
return <ErrorNotification error={error} />;
@@ -139,18 +120,11 @@ class Sources extends React.Component<Props, State> {
<div className="panel">
{this.renderBranchSelector()}
{this.renderBreadcrumb()}
<FileTree
repository={repository}
revision={revision}
path={path}
baseUrl={baseUrl}
/>
<FileTree repository={repository} revision={revision} path={path} baseUrl={baseUrl} />
</div>
);
} else {
return (
<Content repository={repository} revision={revision} path={path} />
);
return <Content repository={repository} revision={revision} path={path} />;
}
}
@@ -185,9 +159,7 @@ class Sources extends React.Component<Props, State> {
path={path}
baseUrl={baseUrl}
branch={selectedBranch}
defaultBranch={
branches && branches.filter(b => b.defaultBranch === true)[0]
}
defaultBranch={branches && branches.filter(b => b.defaultBranch === true)[0]}
branches={branches}
repository={repository}
/>

View File

@@ -10,7 +10,7 @@ describe("get content type", () => {
});
it("should return content", done => {
let headers = {
const headers = {
"Content-Type": "application/text",
"X-Programming-Language": "JAVA"
};

View File

@@ -16,8 +16,7 @@ import {
isDirectory
} from "./sources";
const sourcesUrl =
"http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/";
const sourcesUrl = "http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/";
const repository: Repository = {
name: "core",
@@ -185,21 +184,14 @@ describe("reducer tests", () => {
const expectedState = {
"scm/core/_/": collection
};
expect(
reducer({}, fetchSourcesSuccess(repository, "", "", collection))
).toEqual(expectedState);
expect(reducer({}, fetchSourcesSuccess(repository, "", "", collection))).toEqual(expectedState);
});
it("should store the collection, with revision and path", () => {
const expectedState = {
"scm/core/abc/src/main": collection
};
expect(
reducer(
{},
fetchSourcesSuccess(repository, "abc", "src/main", collection)
)
).toEqual(expectedState);
expect(reducer({}, fetchSourcesSuccess(repository, "abc", "src/main", collection))).toEqual(expectedState);
});
});
@@ -212,9 +204,7 @@ describe("selector tests", () => {
}
}
};
expect(
isDirectory(state, repository, "abc", "src/main/package.json")
).toBeFalsy();
expect(isDirectory(state, repository, "abc", "src/main/package.json")).toBeFalsy();
});
it("should return true if it is directory", () => {

View File

@@ -9,11 +9,7 @@ export const FETCH_SOURCES_PENDING = `${FETCH_SOURCES}_${types.PENDING_SUFFIX}`;
export const FETCH_SOURCES_SUCCESS = `${FETCH_SOURCES}_${types.SUCCESS_SUFFIX}`;
export const FETCH_SOURCES_FAILURE = `${FETCH_SOURCES}_${types.FAILURE_SUFFIX}`;
export function fetchSources(
repository: Repository,
revision: string,
path: string
) {
export function fetchSources(repository: Repository, revision: string, path: string) {
return function(dispatch: any) {
dispatch(fetchSourcesPending(repository, revision, path));
return apiClient
@@ -39,23 +35,14 @@ function createUrl(repository: Repository, revision: string, path: string) {
return `${base}${encodeURIComponent(revision)}/${pathDefined}`;
}
export function fetchSourcesPending(
repository: Repository,
revision: string,
path: string
): Action {
export function fetchSourcesPending(repository: Repository, revision: string, path: string): Action {
return {
type: FETCH_SOURCES_PENDING,
itemId: createItemId(repository, revision, path)
};
}
export function fetchSourcesSuccess(
repository: Repository,
revision: string,
path: string,
sources: File
) {
export function fetchSourcesSuccess(repository: Repository, revision: string, path: string, sources: File) {
return {
type: FETCH_SOURCES_SUCCESS,
payload: sources,
@@ -63,12 +50,7 @@ export function fetchSourcesSuccess(
};
}
export function fetchSourcesFailure(
repository: Repository,
revision: string,
path: string,
error: Error
): Action {
export function fetchSourcesFailure(repository: Repository, revision: string, path: string, error: Error): Action {
return {
type: FETCH_SOURCES_FAILURE,
payload: error,
@@ -101,12 +83,7 @@ export default function reducer(
// selectors
export function isDirectory(
state: any,
repository: Repository,
revision: string,
path: string
): boolean {
export function isDirectory(state: any, repository: Repository, revision: string, path: string): boolean {
const currentFile = getSources(state, repository, revision, path);
if (currentFile && !currentFile.directory) {
return false;
@@ -127,17 +104,8 @@ export function getSources(
return null;
}
export function isFetchSourcesPending(
state: any,
repository: Repository,
revision: string,
path: string
): boolean {
return isPending(
state,
FETCH_SOURCES,
createItemId(repository, revision, path)
);
export function isFetchSourcesPending(state: any, repository: Repository, revision: string, path: string): boolean {
return isPending(state, FETCH_SOURCES, createItemId(repository, revision, path));
}
export function getFetchSourcesFailure(
@@ -146,9 +114,5 @@ export function getFetchSourcesFailure(
revision: string,
path: string
): Error | null | undefined {
return getFailure(
state,
FETCH_SOURCES,
createItemId(repository, revision, path)
);
return getFailure(state, FETCH_SOURCES, createItemId(repository, revision, path));
}