Bootstrapped BranchRoot

This commit is contained in:
Philipp Czora
2018-10-11 17:29:50 +02:00
parent 306388af7b
commit 2de0287bf9
7 changed files with 163 additions and 85 deletions

View File

@@ -12,6 +12,8 @@ type Props = {
};
class LinkPaginator extends React.Component<Props> {
//TODO: HATEOAS-Links verwenden
renderFirstButton() {
return (
<Button

View File

@@ -1,7 +1,7 @@
//@flow
import React from "react";
import classNames from "classnames";
import {Link} from "react-router-dom";
import { Link, withRouter } from "react-router-dom";
export type ButtonProps = {
label: string,
@@ -16,7 +16,9 @@ export type ButtonProps = {
type Props = ButtonProps & {
type: string,
color: string
color: string,
// context prop
history: History
};
class Button extends React.Component<Props> {
@@ -25,14 +27,22 @@ class Button extends React.Component<Props> {
color: "default"
};
renderButton = () => {
onClick = (event: Event) => {
const { action, link, history } = this.props;
if (action) {
action(event);
} else if (link) {
history.push(link);
}
};
render() {
const {
label,
loading,
disabled,
type,
color,
action,
fullWidth,
className
} = this.props;
@@ -42,7 +52,7 @@ class Button extends React.Component<Props> {
<button
type={type}
disabled={disabled}
onClick={action ? action : (event: Event) => {}}
onClick={this.onClick}
className={classNames(
"button",
"is-" + color,
@@ -56,14 +66,6 @@ class Button extends React.Component<Props> {
);
};
render() {
const { link } = this.props;
if (link) {
return <Link to={link}>{this.renderButton()}</Link>; // TODO: className does only apply to button, not the Link
} else {
return this.renderButton();
}
}
}
export default Button;
export default withRouter(Button);

View File

@@ -45,6 +45,8 @@
}
},
"changesets": {
"error-title": "Error",
"error-subtitle": "Could not fetch changesets",
"changeset": {
"id": "ID",
"description": "Description",
@@ -55,7 +57,10 @@
"author": {
"name": "Author",
"mail": "Mail"
}
},
"branchselector-label": "Branch:"
"branch-chooser": {
"error-title": "Error",
"error-subtitle": "Could not fetch branches"
}
}

View File

@@ -5,6 +5,7 @@ import { connect } from "react-redux";
import {
fetchBranches,
getBranch,
getBranches,
getBranchNames,
getFetchBranchesFailure,
isFetchBranchesPending
@@ -13,11 +14,11 @@ import DropDown from "../components/DropDown";
import type { History } from "history";
import { withRouter } from "react-router-dom";
import { ErrorPage, Loading } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
type Props = {
repository: Repository,
branches: Branch[],
branchNames: string[],
fetchBranches: Repository => void,
history: History,
match: any,
@@ -26,24 +27,34 @@ type Props = {
loading: boolean,
branchSelected: string => void,
error: Error,
children: React.Node
children: React.Node,
t: string => string
};
type State = {
selectedBranch?: Branch
};
type State = {};
class BranchChooser extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {};
}
componentDidMount() {
console.log("BC CDM");
this.props.fetchBranches(this.props.repository);
}
render() {
const { selectedBranch, loading, error } = this.props;
console.log("Branch chooser render");
const { loading, error, t } = this.props;
// TODO: i18n
if (error) {
return (
<ErrorPage
title={"Failed loading branches"}
subtitle={"Somethin went wrong"}
title={t("branch-chooser.error-title")}
subtitle={t("branch-chooser.error-subtitle")}
error={error}
/>
);
@@ -53,6 +64,8 @@ class BranchChooser extends React.Component<Props, State> {
return <Loading />;
}
const { selectedBranch } = this.state;
const childrenWithBranch = React.Children.map(
this.props.children,
child => {
@@ -71,10 +84,11 @@ class BranchChooser extends React.Component<Props, State> {
}
renderBranchChooser() {
const { branchNames, label, branchSelected, match } = this.props;
const selectedBranchName = match.params.branch;
const { label, match, branches } = this.props;
const selectedBranchName = "";
// const selectedBranchName = match.params.branch;
if (!branchNames || branchNames.length === 0) {
if (!branches || branches.length === 0) {
return null;
}
@@ -82,13 +96,23 @@ class BranchChooser extends React.Component<Props, State> {
<div className={"box"}>
<label className="label">{label}</label>
<DropDown
options={branchNames}
options={branches.map(b => b.name)}
preselectedOption={selectedBranchName}
optionSelected={branch => branchSelected(branch)}
optionSelected={this.branchSelected}
/>
</div>
);
}
branchSelected = (branch: string) => {
for (let b of this.props.branches) {
if (b.name === branch) {
this.setState({ selectedBranch: b });
this.props.branchSelected(b.name);
break;
}
}
};
}
const mapDispatchToProps = dispatch => {
@@ -103,23 +127,22 @@ const mapStateToProps = (state: any, ownProps: Props) => {
const { repository, match } = ownProps;
const loading = isFetchBranchesPending(state, repository);
const error = getFetchBranchesFailure(state, repository);
const branchNames = getBranchNames(state, repository);
const selectedBranch = getBranch(
state,
repository,
decodeURIComponent(match.params.branch)
);
// const selectedBranch = getBranch(
// state,
// repository,
// decodeURIComponent(match.params.branch)
// );
const selectedBranch = "";
const branches = getBranches(state, repository);
return {
loading,
branchNames,
// loading,
selectedBranch,
error
// error,
branches
};
};
export default withRouter(
connect(
export default connect(
mapStateToProps,
mapDispatchToProps
)(BranchChooser)
);
)(translate("repos")(BranchChooser));

View File

@@ -0,0 +1,63 @@
// @flow
import React from "react";
import type { Repository } from "@scm-manager/ui-types";
import BranchChooser from "./BranchChooser";
import { Route, withRouter } from "react-router-dom";
import Changesets from "./Changesets";
type Props = {
repository: Repository,
history: History,
match: any
};
class BranchRoot extends React.Component<Props> {
stripEndingSlash = (url: string) => {
if (url.endsWith("/")) {
return url.substring(0, url.length - 2);
}
return url;
};
matchedUrl = () => {
return this.stripEndingSlash(this.props.match.url);
};
branchSelected = (branchName: string) => {
const url = this.matchedUrl();
if (branchName === "") {
this.props.history.push(`${url}/changesets/`);
} else {
this.props.history.push(
`${url}/${encodeURIComponent(branchName)}/changesets/`
);
}
};
render() {
const url = this.matchedUrl();
return (
<BranchChooser
repository={this.props.repository}
label={"Branches"}
branchSelected={this.branchSelected}
>
<Changesets repository={this.props.repository} />
{/*<RouteDelegate repository={this.props.repository} url={url} />*/}
</BranchChooser>
);
}
}
function RouteDelegate(props) {
return (
<Route
path={`${props.url}/:branch/changesets/:page?`}
component={() => <Changesets repository={props.repository} {...props} />}
/>
);
}
export default withRouter(BranchRoot);

View File

@@ -19,6 +19,7 @@ import {
import { connect } from "react-redux";
import ChangesetList from "../components/changesets/ChangesetList";
import { ErrorPage, LinkPaginator, Loading } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
type Props = {
fetchChangesetsByBranch: (Repository, Branch) => void,
@@ -29,7 +30,8 @@ type Props = {
loading: boolean,
match: any,
list: PagedCollection,
error: Error
error: Error,
t: string => string
};
type State = {};
@@ -52,14 +54,13 @@ class ChangesetContainer extends React.Component<Props, State> {
}
render() {
const { changesets, loading, error } = this.props;
const { changesets, loading, error, t } = this.props;
// TODO: i18n
if (error) {
return (
<ErrorPage
title={"Failed loading branches"}
subtitle={"Somethin went wrong"}
title={t("changesets.error-title")}
subtitle={t("changesets.error-title")}
error={error}
/>
);
@@ -120,5 +121,5 @@ export default withRouter(
connect(
mapStateToProps,
mapDispatchToProps
)(ChangesetContainer)
)(translate("repos")(ChangesetContainer))
);

View File

@@ -27,6 +27,7 @@ import type { History } from "history";
import EditNavLink from "../components/EditNavLink";
import BranchChooser from "./BranchChooser";
import Changesets from "./Changesets";
import BranchRoot from "./BranchRoot";
type Props = {
namespace: string,
@@ -73,19 +74,10 @@ class RepositoryRoot extends React.Component<Props> {
matches = (route: any) => {
const url = this.matchedUrl();
const regex = new RegExp(`${url}/?[a-zA-Z0-9_%]*/changesets?.*`);
return route.location.pathname.match(regex);
};
branchSelected = (branchName: string) => {
const url = this.matchedUrl();
if (branchName === "") {
this.props.history.push(`${url}/changesets/`);
} else {
this.props.history.push(
`${url}/branches/${encodeURIComponent(branchName)}/changesets/`
const regex = new RegExp(
`${url}(/branches)?/?[a-zA-Z0-9_%]*/changesets?.*`
);
}
return route.location.pathname.match(regex);
};
render() {
@@ -120,31 +112,21 @@ class RepositoryRoot extends React.Component<Props> {
path={`${url}/edit`}
component={() => <Edit repository={repository} />}
/>
{/*<Route*/}
{/*path={`${url}/changesets/:page?`}*/}
{/*component={() => (*/}
{/*<BranchChooser*/}
{/*repository={repository}*/}
{/*label={"Branches"}*/}
{/*branchSelected={this.branchSelected}*/}
{/*>*/}
{/*<Changesets repository={repository} />*/}
{/*</BranchChooser>*/}
{/*)}*/}
{/*/>*/}
<Route
path={`${url}/changesets/:page?`}
component={() => (
<BranchChooser
repository={repository}
label={"Branches"}
branchSelected={this.branchSelected}
>
<Changesets repository={repository} />
</BranchChooser>
)}
/>
<Route
path={`${url}/branches/:branch/changesets/:page?`}
component={() => (
<BranchChooser
repository={repository}
label={"Branches"}
branchSelected={this.branchSelected}
>
<Changesets repository={repository} />
</BranchChooser>
)}
path={`${url}/branches`}
render={() => <BranchRoot repository={repository} />}
/>
</div>
<div className="column">