merge with 2.0.0-m3

This commit is contained in:
Sebastian Sdorra
2019-08-28 07:34:56 +02:00
248 changed files with 5931 additions and 4573 deletions

View File

@@ -1,7 +1,7 @@
// @flow
import React from "react";
import { AsyncCreatable, Async } from "react-select";
import type { AutocompleteObject, SelectValue } from "@scm-manager/ui-types";
import {Async, AsyncCreatable} from "react-select";
import type {AutocompleteObject, SelectValue} from "@scm-manager/ui-types";
import LabelWithHelpIcon from "./forms/LabelWithHelpIcon";
type Props = {

View File

@@ -25,12 +25,17 @@ const styles = {
},
content: {
display: "flex",
flexGrow: 1
flexGrow: 1,
alignItems: "center",
justifyContent: "space-between"
},
footer: {
display: "flex",
marginTop: "auto",
paddingBottom: "1.5rem"
},
noBottomMargin: {
marginBottom: "0 !important"
}
};
@@ -38,24 +43,37 @@ type Props = {
title: string,
description: string,
avatar: React.Node,
contentRight?: React.Node,
footerLeft: React.Node,
footerRight: React.Node,
link: string,
link?: string,
action?: () => void,
// context props
classes: any
};
class CardColumn extends React.Component<Props> {
createLink = () => {
const { link } = this.props;
const { link, action } = this.props;
if (link) {
return <Link className="overlay-column" to={link} />;
} else if (action) {
return <a className="overlay-column" onClick={e => {e.preventDefault(); action();}} href="#" />;
}
return null;
};
render() {
const { avatar, title, description, footerLeft, footerRight, classes } = this.props;
const {
avatar,
title,
description,
contentRight,
footerLeft,
footerRight,
classes
} = this.props;
const link = this.createLink();
return (
<>
@@ -64,16 +82,29 @@ class CardColumn extends React.Component<Props> {
<figure className={classNames(classes.centerImage, "media-left")}>
{avatar}
</figure>
<div className={classNames("media-content", "text-box", classes.flexFullHeight)}>
<div
className={classNames(
"media-content",
"text-box",
classes.flexFullHeight
)}
>
<div className={classes.content}>
<div className="content shorten-text">
<div
className={classNames(
"content",
"shorten-text",
classes.noBottomMargin
)}
>
<p className="is-marginless">
<strong>{title}</strong>
</p>
<p className="shorten-text">{description}</p>
</div>
{contentRight && contentRight}
</div>
<div className={classNames(classes.footer, "level")}>
<div className={classNames("level", classes.footer)}>
<div className="level-left is-hidden-mobile">{footerLeft}</div>
<div className="level-right is-mobile">{footerRight}</div>
</div>

View File

@@ -1,7 +1,7 @@
//@flow
import React from "react";
import { translate } from "react-i18next";
import { BackendError, ForbiddenError, UnauthorizedError } from "./errors";
import {translate} from "react-i18next";
import {BackendError, ForbiddenError, UnauthorizedError} from "./errors";
import Notification from "./Notification";
import BackendErrorNotification from "./BackendErrorNotification";

View File

@@ -1,6 +1,6 @@
// @flow
import React from "react";
import { translate } from "react-i18next";
import {translate} from "react-i18next";
import type AutocompleteProps from "./UserGroupAutocomplete";
import UserGroupAutocomplete from "./UserGroupAutocomplete";

View File

@@ -2,11 +2,18 @@
import * as React from "react";
import classNames from "classnames";
type NotificationType = "primary" | "info" | "success" | "warning" | "danger";
type NotificationType =
| "primary"
| "info"
| "success"
| "warning"
| "danger"
| "inherit";
type Props = {
type: NotificationType,
onClose?: () => void,
className?: string,
children?: React.Node
};
@@ -24,9 +31,12 @@ class Notification extends React.Component<Props> {
}
render() {
const { type, children } = this.props;
const { type, className, children } = this.props;
const color = type !== "inherit" ? "is-" + type : "";
return (
<div className={classNames("notification", "is-" + type)}>
<div className={classNames("notification", color, className)}>
{this.renderCloseButton()}
{children}
</div>

View File

@@ -1,6 +1,6 @@
// @flow
import React from "react";
import { translate } from "react-i18next";
import {translate} from "react-i18next";
import type AutocompleteProps from "./UserGroupAutocomplete";
import UserGroupAutocomplete from "./UserGroupAutocomplete";

View File

@@ -1,6 +1,6 @@
// @flow
import React from "react";
import type { SelectValue } from "@scm-manager/ui-types";
import type {SelectValue} from "@scm-manager/ui-types";
import Autocomplete from "./Autocomplete";
export type AutocompleteProps = {

View File

@@ -14,7 +14,7 @@ class ButtonGroup extends React.Component<Props> {
const childWrapper = [];
React.Children.forEach(children, child => {
if (child) {
childWrapper.push(<p className="control">{child}</p>);
childWrapper.push(<p className="control" key={childWrapper.length}>{child}</p>);
}
});

View File

@@ -1,10 +1,10 @@
//@flow
import React from "react";
import DiffFile from "./DiffFile";
import type { DiffObjectProps } from "./DiffTypes";
import type {DiffObjectProps, File} from "./DiffTypes";
type Props = DiffObjectProps & {
diff: any
diff: File[]
};
class Diff extends React.Component<Props> {

View File

@@ -1,17 +1,10 @@
//@flow
import React from "react";
import {
Hunk,
Diff as DiffComponent,
getChangeKey,
Change,
DiffObjectProps,
File
} from "react-diff-view";
import {Change, Diff as DiffComponent, DiffObjectProps, File, getChangeKey, Hunk} from "react-diff-view";
import injectSheets from "react-jss";
import classNames from "classnames";
import { translate } from "react-i18next";
import { ButtonGroup, Button } from "../buttons";
import {translate} from "react-i18next";
import {Button, ButtonGroup} from "../buttons";
const styles = {
panel: {
@@ -46,6 +39,7 @@ const styles = {
type Props = DiffObjectProps & {
file: File,
collapsible: true,
// context props
classes: any,
t: string => string
@@ -66,9 +60,11 @@ class DiffFile extends React.Component<Props, State> {
}
toggleCollapse = () => {
this.setState(state => ({
collapsed: !state.collapsed
}));
if (this.props.collapsable) {
this.setState(state => ({
collapsed: !state.collapsed
}));
}
};
toggleSideBySide = () => {
@@ -173,6 +169,9 @@ class DiffFile extends React.Component<Props, State> {
renderChangeTag = (file: any) => {
const { t, classes } = this.props;
if (!file.type) {
return;
}
const key = "diff.changes." + file.type;
let value = t(key);
if (key === value) {
@@ -205,6 +204,7 @@ class DiffFile extends React.Component<Props, State> {
file,
fileControlFactory,
fileAnnotationFactory,
collapsible,
classes,
t
} = this.props;
@@ -227,6 +227,7 @@ class DiffFile extends React.Component<Props, State> {
</div>
);
}
const collapseIcon = collapsible? <i className={icon} />: null;
const fileControls = fileControlFactory
? fileControlFactory(file, this.setCollapse)
@@ -240,7 +241,7 @@ class DiffFile extends React.Component<Props, State> {
onClick={this.toggleCollapse}
title={this.hoverFileTitle(file)}
>
<i className={icon} />
{collapseIcon}
<span
className={classNames("is-ellipsis-overflow", classes.title)}
>

View File

@@ -27,12 +27,17 @@ export type Hunk = {
content: string
};
export type ChangeType = "insert" | "delete" | "normal";
export type Change = {
content: string,
isNormal: boolean,
newLineNumber: number,
oldLineNumber: number,
type: string
isNormal?: boolean,
isInsert?: boolean,
isDelete?: boolean,
lineNumber?: number,
newLineNumber?: number,
oldLineNumber?: number,
type: ChangeType
};
export type BaseContext = {

View File

@@ -1,19 +1,19 @@
//@flow
import React from "react";
import { apiClient } from "../apiclient";
import {apiClient} from "../apiclient";
import ErrorNotification from "../ErrorNotification";
import parser from "gitdiff-parser";
import Loading from "../Loading";
import Diff from "./Diff";
import type {DiffObjectProps} from "./DiffTypes";
import type {DiffObjectProps, File} from "./DiffTypes";
type Props = DiffObjectProps & {
url: string
};
type State = {
diff?: any,
diff?: File[],
loading: boolean,
error?: Error
};
@@ -47,7 +47,8 @@ class LoadingDiff extends React.Component<Props, State> {
.get(url)
.then(response => response.text())
.then(parser.parse)
.then(diff => {
// $FlowFixMe
.then((diff: File[]) => {
this.setState({
loading: false,
diff: diff

View File

@@ -21,7 +21,7 @@ class ChangesetButtonGroup extends React.Component<Props> {
const sourcesLink = createSourcesLink(repository, changeset);
return (
<ButtonAddons className="is-pulled-right">
<ButtonAddons className="is-marginless">
<Button link={changesetLink} className="reduced-mobile">
<span className="icon">
<i className="fas fa-exchange-alt" />

View File

@@ -1,6 +1,6 @@
//@flow
import React from "react";
import type { Changeset, Repository, Tag } from "@scm-manager/ui-types";
import type { Changeset, Repository } from "@scm-manager/ui-types";
import classNames from "classnames";
import { Interpolate, translate } from "react-i18next";
@@ -26,21 +26,22 @@ const styles = {
},
avatarFigure: {
marginTop: ".25rem",
marginRight: ".5rem",
marginRight: ".5rem"
},
avatarImage: {
height: "35px",
width: "35px"
},
isVcentered: {
marginTop: "auto",
marginBottom: "auto"
},
metadata: {
marginLeft: 0
},
tag: {
marginTop: ".5rem"
isVcentered: {
alignSelf: "center"
},
flexVcenter: {
display: "flex",
alignItems: "center",
justifyContent: "flex-end"
}
};
@@ -65,52 +66,65 @@ class ChangesetRow extends React.Component<Props> {
return (
<div className={classes.changeset}>
<div className="columns">
<div className="columns is-gapless is-mobile">
<div className="column is-three-fifths">
<h4 className="has-text-weight-bold is-ellipsis-overflow">
<ExtensionPoint
name="changeset.description"
props={{ changeset, value: description.title }}
renderAll={false}
>
{description.title}
</ExtensionPoint>
</h4>
<div className="media">
<AvatarWrapper>
<figure className={classNames(classes.avatarFigure, "media-left")}>
<div className={classNames("image", classes.avatarImage)}>
<AvatarImage person={changeset.author} />
<div className="columns is-gapless">
<div className="column is-four-fifths">
<h4 className="has-text-weight-bold is-ellipsis-overflow">
<ExtensionPoint
name="changeset.description"
props={{ changeset, value: description.title }}
renderAll={false}
>
{description.title}
</ExtensionPoint>
</h4>
<div className="media">
<AvatarWrapper>
<figure
className={classNames(classes.avatarFigure, "media-left")}
>
<div className={classNames("image", classes.avatarImage)}>
<AvatarImage person={changeset.author} />
</div>
</figure>
</AvatarWrapper>
<div className={classNames(classes.metadata, "media-right")}>
<p className="is-hidden-touch">
<Interpolate
i18nKey="changeset.summary"
id={changesetId}
time={dateFromNow}
/>
</p>
<p className="is-hidden-desktop">
<Interpolate
i18nKey="changeset.shortSummary"
id={changesetId}
time={dateFromNow}
/>
</p>
<p className="is-size-7">
<ChangesetAuthor changeset={changeset} />
</p>
</div>
</figure>
</AvatarWrapper>
<div className={classNames(classes.metadata, "media-right")}>
<p className="is-hidden-mobile is-hidden-tablet-only">
<Interpolate
i18nKey="changeset.summary"
id={changesetId}
time={dateFromNow}
/>
</p>
<p className="is-hidden-desktop">
<Interpolate
i18nKey="changeset.shortSummary"
id={changesetId}
time={dateFromNow}
/>
</p>
<p className="is-size-7">
<ChangesetAuthor changeset={changeset} />
</p>
</div>
</div>
<div className={classNames("column", classes.isVcentered)}>
<ChangesetTags changeset={changeset} />
</div>
</div>
</div>
<div className={classNames("column", classes.isVcentered)}>
<ChangesetTags changeset={changeset} />
<ChangesetButtonGroup repository={repository} changeset={changeset} />
<div className={classNames("column", classes.flexVcenter)}>
<ChangesetButtonGroup
repository={repository}
changeset={changeset}
/>
<ExtensionPoint
name="changeset.right"
props={{ repository, changeset }}
renderAll={true}
/>
</div>
</div>
</div>

View File

@@ -4,9 +4,6 @@ import injectSheet from "react-jss";
import classNames from "classnames";
const styles = {
tag: {
marginTop: ".5rem"
},
spacing: {
marginRight: ".25rem"
}
@@ -24,7 +21,7 @@ class ChangesetTagBase extends React.Component<Props> {
render() {
const { icon, label, classes } = this.props;
return (
<span className={classNames(classes.tag, "tag", "is-info")}>
<span className={classNames("tag", "is-info")}>
<span className={classNames("fa", icon, classes.spacing)} /> {label}
</span>
);

View File

@@ -1,10 +1,12 @@
// @flow
import * as diffs from "./diffs";
export { diffs };
export * from "./changesets";
export { default as Diff } from "./Diff";
export { default as DiffFile } from "./DiffFile";
export { default as LoadingDiff } from "./LoadingDiff";
export type {
@@ -12,6 +14,7 @@ export type {
FileChangeType,
Hunk,
Change,
ChangeType,
BaseContext,
AnnotationFactory,
AnnotationFactoryContext,