This commit is contained in:
Florian Scholdei
2019-02-07 11:57:06 +01:00
199 changed files with 2057 additions and 1748 deletions

View File

@@ -13,10 +13,11 @@ const styles = {
minWidthOfLabel: {
minWidth: "4.5rem"
},
wrapper: {
padding: "1rem 1.5rem 0.25rem 1.5rem",
border: "1px solid #eee",
borderRadius: "5px 5px 0 0"
labelSizing: {
fontSize: "1rem !important"
},
noBottomMargin: {
marginBottom: "0 !important"
}
};
@@ -52,9 +53,9 @@ class BranchSelector extends React.Component<Props, State> {
return (
<div
className={classNames(
"has-background-light field",
"field",
"is-horizontal",
classes.wrapper
classes.noBottomMargin
)}
>
<div
@@ -65,10 +66,14 @@ class BranchSelector extends React.Component<Props, State> {
classes.minWidthOfLabel
)}
>
<label className="label">{label}</label>
<label className={classNames("label", classes.labelSizing)}>
{label}
</label>
</div>
<div className="field-body">
<div className="field is-narrow">
<div
className={classNames("field is-narrow", classes.noBottomMargin)}
>
<div className="control">
<DropDown
className="is-fullwidth"

View File

@@ -3,14 +3,17 @@ import React from "react";
type Props = {
displayName: string,
url: string
url: string,
disabled: boolean,
onClick?: () => void
};
class DownloadButton extends React.Component<Props> {
render() {
const { displayName, url } = this.props;
const { displayName, url, disabled, onClick } = this.props;
const onClickOrDefault = !!onClick ? onClick : () => {};
return (
<a className="button is-large is-link" href={url}>
<a className="button is-large is-link" href={url} disabled={disabled} onClick={onClickOrDefault}>
<span className="icon is-medium">
<i className="fas fa-arrow-circle-down" />
</span>

View File

@@ -72,6 +72,33 @@ class ConfigurationBinder {
binder.bind("repository.route", RepoRoute, repoPredicate);
}
bindRepositorySetting(to: string, labelI18nKey: string, linkName: string, RepositoryComponent: any) {
// create predicate based on the link name of the current repository route
// if the linkname is not available, the navigation link and the route are not bound to the extension points
const repoPredicate = (props: Object) => {
return props.repository && props.repository._links && props.repository._links[linkName];
};
// create NavigationLink with translated label
const RepoNavLink = translate(this.i18nNamespace)(({t, url}) => {
return this.navLink(url + "/settings" + to, labelI18nKey, t);
});
// bind navigation link to extension point
binder.bind("repository.subnavigation", RepoNavLink, repoPredicate);
// route for global configuration, passes the current repository to component
const RepoRoute = ({url, repository, ...additionalProps}) => {
const link = repository._links[linkName].href;
return this.route(url + "/settings" + to, <RepositoryComponent repository={repository} link={link} {...additionalProps}/>);
};
// bind config route to extension point
binder.bind("repository.route", RepoRoute, repoPredicate);
}
}
export default new ConfigurationBinder();

View File

@@ -10,7 +10,8 @@ type Props = {
buttonLabel: string,
fieldLabel: string,
errorMessage: string,
helpText?: string
helpText?: string,
validateEntry?: string => boolean
};
type State = {
@@ -25,6 +26,15 @@ class AddEntryToTableField extends React.Component<Props, State> {
};
}
isValid = () => {
const {validateEntry} = this.props;
if (!this.state.entryToAdd || this.state.entryToAdd === "" || !validateEntry) {
return true;
} else {
return validateEntry(this.state.entryToAdd);
}
};
render() {
const {
disabled,
@@ -39,7 +49,7 @@ class AddEntryToTableField extends React.Component<Props, State> {
label={fieldLabel}
errorMessage={errorMessage}
onChange={this.handleAddEntryChange}
validationError={false}
validationError={!this.isValid()}
value={this.state.entryToAdd}
onReturnPressed={this.appendEntry}
disabled={disabled}
@@ -48,7 +58,7 @@ class AddEntryToTableField extends React.Component<Props, State> {
<AddButton
label={buttonLabel}
action={this.addButtonClicked}
disabled={disabled || this.state.entryToAdd ===""}
disabled={disabled || this.state.entryToAdd ==="" || !this.isValid()}
/>
</div>
);

View File

@@ -28,7 +28,7 @@ class NavLink extends React.Component<Props> {
let showIcon = null;
if (icon) {
showIcon = (<><i className={icon}></i>{" "}</>);
showIcon = (<><i className={icon} />{" "}</>);
}
return (

View File

@@ -50,8 +50,19 @@ class PrimaryNavigation extends React.Component<Props> {
createNavigationItems = () => {
const navigationItems = [];
const { t, links } = this.props;
const props = {
links,
label: t("primary-navigation.first-menu")
};
const append = this.createNavigationAppender(navigationItems);
if (binder.hasExtension("primary-navigation.first-menu", props)) {
navigationItems.push(
<ExtensionPoint name="primary-navigation.first-menu" props={props} />
);
}
append("/repos", "/(repo|repos)", "primary-navigation.repositories", "repositories");
append("/users", "/(user|users)", "primary-navigation.users", "users");
append("/groups", "/(group|groups)", "primary-navigation.groups", "groups");

View File

@@ -0,0 +1,65 @@
//@flow
import * as React from "react";
import { Link, Route } from "react-router-dom";
type Props = {
to: string,
icon?: string,
label: string,
activeOnlyWhenExact?: boolean,
activeWhenMatch?: (route: any) => boolean,
children?: React.Node
};
class SubNavigation extends React.Component<Props> {
static defaultProps = {
activeOnlyWhenExact: false
};
isActive(route: any) {
const { activeWhenMatch } = this.props;
return route.match || (activeWhenMatch && activeWhenMatch(route));
}
renderLink = (route: any) => {
const { to, icon, label } = this.props;
let defaultIcon = "fas fa-cog";
if (icon) {
defaultIcon = icon;
}
let children = null;
if (this.isActive(route)) {
children = <ul className="sub-menu">{this.props.children}</ul>;
}
return (
<li>
<Link className={this.isActive(route) ? "is-active" : ""} to={to}>
<i className={defaultIcon} /> {label}
</Link>
{children}
</li>
);
};
render() {
const { to, activeOnlyWhenExact } = this.props;
// removes last part of url
let parents = to.split("/");
parents.splice(-1, 1);
let parent = parents.join("/");
return (
<Route
path={parent}
exact={activeOnlyWhenExact}
children={this.renderLink}
/>
);
}
}
export default SubNavigation;

View File

@@ -3,6 +3,7 @@
export { default as NavAction } from "./NavAction.js";
export { default as NavLink } from "./NavLink.js";
export { default as Navigation } from "./Navigation.js";
export { default as SubNavigation } from "./SubNavigation.js";
export { default as PrimaryNavigation } from "./PrimaryNavigation.js";
export { default as PrimaryNavigationLink } from "./PrimaryNavigationLink.js";
export { default as Section } from "./Section.js";

View File

@@ -28,7 +28,7 @@ class ChangesetAuthor extends React.Component<Props> {
renderWithMail(name: string, mail: string) {
const { t } = this.props;
return (
<a href={"mailto: " + mail} title={t("changesets.author.mailto") + " " + mail}>
<a href={"mailto: " + mail} title={t("changeset.author.mailto") + " " + mail}>
{name}
</a>
);
@@ -38,7 +38,7 @@ class ChangesetAuthor extends React.Component<Props> {
const { t } = this.props;
return (
<>
{t("changesets.author.prefix")} {child}
{t("changeset.author.prefix")} {child}
<ExtensionPoint
name="changesets.author.suffix"
props={{ changeset: this.props.changeset }}

View File

@@ -29,7 +29,7 @@ class ChangesetButtonGroup extends React.Component<Props> {
<i className="fas fa-code-branch"></i>
</span>
<span className="is-hidden-mobile is-hidden-tablet-only">
{t("changesets.buttons.details")}
{t("changeset.buttons.details")}
</span>
</Button>
<Button link={sourcesLink}>
@@ -37,7 +37,7 @@ class ChangesetButtonGroup extends React.Component<Props> {
<i className="fas fa-code"></i>
</span>
<span className="is-hidden-mobile is-hidden-tablet-only">
{t("changesets.buttons.sources")}
{t("changeset.buttons.sources")}
</span>
</Button>
</ButtonGroup>

View File

@@ -25,7 +25,7 @@ class ChangesetDiff extends React.Component<Props> {
render() {
const { changeset, t } = this.props;
if (!this.isDiffSupported(changeset)) {
return <Notification type="danger">{t("changesets.diff.not-supported")}</Notification>;
return <Notification type="danger">{t("changeset.diffNotSupported")}</Notification>;
} else {
const url = this.createUrl(changeset);
return <LoadingDiff url={url} />;

View File

@@ -21,7 +21,7 @@ class ChangesetList extends React.Component<Props> {
/>
);
});
return <div className="box">{content}</div>;
return <>{content}</>;
}
}

View File

@@ -70,7 +70,7 @@ class ChangesetRow extends React.Component<Props> {
<h4 className="has-text-weight-bold is-ellipsis-overflow">
<ExtensionPoint
name="changesets.changeset.description"
name="changeset.description"
props={{ changeset, value: description.title }}
renderAll={false}
>
@@ -89,14 +89,14 @@ class ChangesetRow extends React.Component<Props> {
<div className={classNames(classes.metadata, "media-right")}>
<p className="is-hidden-mobile is-hidden-tablet-only">
<Interpolate
i18nKey="changesets.changeset.summary"
i18nKey="changeset.summary"
id={changesetId}
time={dateFromNow}
/>
</p>
<p className="is-hidden-desktop">
<Interpolate
i18nKey="changesets.changeset.short-summary"
i18nKey="changeset.shortSummary"
id={changesetId}
time={dateFromNow}
/>

View File

@@ -18,7 +18,7 @@ class ChangesetTagsCollapsed extends React.Component<Props> {
const message = tags.map((tag) => tag.name).join(", ");
return (
<Tooltip location="top" message={message}>
<ChangesetTagBase icon={"fa-tags"} label={ tags.length + " " + t("changesets.tags") } />
<ChangesetTagBase icon={"fa-tags"} label={ tags.length + " " + t("changeset.tags") } />
</Tooltip>
);
}