scm-ui: new repository layout

This commit is contained in:
Sebastian Sdorra
2019-10-07 10:57:09 +02:00
parent 09c7def874
commit c05798e254
417 changed files with 3620 additions and 52971 deletions

View File

@@ -0,0 +1,45 @@
//@flow
import React from "react";
import type { Repository, Branch } from "@scm-manager/ui-types";
import { ButtonAddons, Button } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
type Props = {
repository: Repository,
branch: Branch,
// context props
t: string => string
};
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)}/`;
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}
/>
</ButtonAddons>
);
}
}
export default translate("repos")(BranchButtonGroup);

View File

@@ -0,0 +1,33 @@
//@flow
import React from "react";
import type { Repository, Branch } from "@scm-manager/ui-types";
import { translate } from "react-i18next";
import BranchButtonGroup from "./BranchButtonGroup";
import DefaultBranchTag from "./DefaultBranchTag";
type Props = {
repository: Repository,
branch: Branch,
// context props
t: string => string
};
class BranchDetail extends React.Component<Props> {
render() {
const { repository, branch, t } = this.props;
return (
<div className="media">
<div className="media-content subtitle">
<strong>{t("branch.name")}</strong> {branch.name}{" "}
<DefaultBranchTag defaultBranch={branch.defaultBranch} />
</div>
<div className="media-right">
<BranchButtonGroup repository={repository} branch={branch} />
</div>
</div>
);
}
}
export default translate("repos")(BranchDetail);

View File

@@ -0,0 +1,125 @@
// @flow
import React from "react";
import { translate } from "react-i18next";
import type { Repository, Branch, BranchRequest } from "@scm-manager/ui-types";
import {
Select,
InputField,
SubmitButton,
validation as validator
} from "@scm-manager/ui-components";
import { orderBranches } from "../util/orderBranches";
type Props = {
submitForm: BranchRequest => void,
repository: Repository,
branches: Branch[],
loading?: boolean,
transmittedName?: string,
disabled?: boolean,
t: string => string
};
type State = {
source?: string,
name?: string,
nameValidationError: boolean
};
class BranchForm extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
nameValidationError: false,
name: props.transmittedName
};
}
isFalsy(value) {
return !value;
}
isValid = () => {
const { source, name } = this.state;
return !(
this.state.nameValidationError ||
this.isFalsy(source) ||
this.isFalsy(name)
);
};
submit = (event: Event) => {
event.preventDefault();
if (this.isValid()) {
this.props.submitForm({
name: this.state.name,
parent: this.state.source
});
}
};
render() {
const { t, branches, loading, transmittedName, disabled } = this.props;
const { name } = this.state;
orderBranches(branches);
const options = branches.map(branch => ({
label: branch.name,
value: branch.name
}));
return (
<>
<form onSubmit={this.submit}>
<div className="columns">
<div className="column">
<Select
name="source"
label={t("branches.create.source")}
options={options}
onChange={this.handleSourceChange}
loading={loading}
disabled={disabled}
/>
<InputField
name="name"
label={t("branches.create.name")}
onChange={this.handleNameChange}
value={name ? name : ""}
validationError={this.state.nameValidationError}
errorMessage={t("validation.branch.nameInvalid")}
disabled={!!transmittedName || disabled}
/>
</div>
</div>
<div className="columns">
<div className="column">
<SubmitButton
disabled={disabled || !this.isValid()}
loading={loading}
label={t("branches.create.submit")}
/>
</div>
</div>
</form>
</>
);
}
handleSourceChange = (source: string) => {
this.setState({
...this.state,
source
});
};
handleNameChange = (name: string) => {
this.setState({
nameValidationError: !validator.isNameValid(name),
...this.state,
name
});
};
}
export default translate("repos")(BranchForm);

View File

@@ -0,0 +1,32 @@
// @flow
import React from "react";
import { Link } from "react-router-dom";
import type { Branch } from "@scm-manager/ui-types";
import DefaultBranchTag from "./DefaultBranchTag";
type Props = {
baseUrl: string,
branch: Branch
};
class BranchRow extends React.Component<Props> {
renderLink(to: string, label: string, defaultBranch?: boolean) {
return (
<Link to={to}>
{label} <DefaultBranchTag defaultBranch={defaultBranch} />
</Link>
);
}
render() {
const { baseUrl, branch } = this.props;
const to = `${baseUrl}/${encodeURIComponent(branch.name)}/info`;
return (
<tr>
<td>{this.renderLink(to, branch.name, branch.defaultBranch)}</td>
</tr>
);
}
}
export default BranchRow;

View File

@@ -0,0 +1,40 @@
// @flow
import React from "react";
import { translate } from "react-i18next";
import BranchRow from "./BranchRow";
import type { Branch } from "@scm-manager/ui-types";
type Props = {
baseUrl: string,
t: string => string,
branches: Branch[]
};
class BranchTable extends React.Component<Props> {
render() {
const { t } = this.props;
return (
<table className="card-table table is-hoverable is-fullwidth">
<thead>
<tr>
<th>{t("branches.table.branches")}</th>
</tr>
</thead>
<tbody>{this.renderRow()}</tbody>
</table>
);
}
renderRow() {
const { baseUrl, branches } = this.props;
let rowContent = null;
if (branches) {
rowContent = branches.map((branch, index) => {
return <BranchRow key={index} baseUrl={baseUrl} branch={branch} />;
});
}
return rowContent;
}
}
export default translate("repos")(BranchTable);

View File

@@ -0,0 +1,32 @@
// @flow
import React from "react";
import BranchDetail from "./BranchDetail";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
import type { Repository, Branch } from "@scm-manager/ui-types";
type Props = {
repository: Repository,
branch: Branch
};
class BranchView extends React.Component<Props> {
render() {
const { repository, branch } = this.props;
return (
<div>
<BranchDetail repository={repository} branch={branch} />
<hr />
<div className="content">
<ExtensionPoint
name="repos.branch-details.information"
renderAll={true}
props={{ repository, branch }}
/>
</div>
</div>
);
}
}
export default BranchView;

View File

@@ -0,0 +1,39 @@
//@flow
import React from "react";
import injectSheet from "react-jss";
import { translate } from "react-i18next";
import { Tag } from "@scm-manager/ui-components";
type Props = {
defaultBranch?: boolean,
// context props
classes: any,
t: string => string
};
const styles = {
tag: {
marginLeft: "0.75rem",
verticalAlign: "inherit"
}
};
class DefaultBranchTag extends React.Component<Props> {
render() {
const { defaultBranch, classes, t } = this.props;
if (defaultBranch) {
return (
<Tag
className={classes.tag}
color="dark"
label={t("branch.defaultTag")}
/>
);
}
return null;
}
}
export default injectSheet(styles)(translate("repos")(DefaultBranchTag));