mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-11 16:05:44 +01:00
merge with 2.0.0-m3
This commit is contained in:
@@ -1,30 +1,40 @@
|
||||
// @flow
|
||||
|
||||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
type Props = {
|
||||
options: string[],
|
||||
optionSelected: string => void,
|
||||
preselectedOption: string
|
||||
}
|
||||
preselectedOption?: string,
|
||||
className: any
|
||||
};
|
||||
|
||||
class DropDown extends React.Component<Props> {
|
||||
render() {
|
||||
const {options, preselectedOption} = this.props;
|
||||
return <div className="select">
|
||||
<select value={preselectedOption} onChange={this.change}>
|
||||
<option key=""></option>
|
||||
{options.map(option => {
|
||||
return <option key={option}
|
||||
value={option}>{option}</option>
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
const { options, preselectedOption, className } = this.props;
|
||||
return (
|
||||
<div className={classNames(className, "select")}>
|
||||
<select
|
||||
value={preselectedOption ? preselectedOption : ""}
|
||||
onChange={this.change}
|
||||
>
|
||||
<option key="" />
|
||||
{options.map(option => {
|
||||
return (
|
||||
<option key={option} value={option}>
|
||||
{option}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
change = (event) => {
|
||||
change = (event: SyntheticInputEvent<HTMLSelectElement>) => {
|
||||
this.props.optionSelected(event.target.value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default DropDown;
|
||||
|
||||
@@ -4,7 +4,6 @@ import "../../tests/enzyme";
|
||||
import "../../tests/i18n";
|
||||
import ReactRouterEnzymeContext from "react-router-enzyme-context";
|
||||
import PermissionsNavLink from "./PermissionsNavLink";
|
||||
import EditNavLink from "./EditNavLink";
|
||||
|
||||
describe("PermissionsNavLink", () => {
|
||||
const options = new ReactRouterEnzymeContext();
|
||||
|
||||
@@ -10,18 +10,28 @@ type Props = {
|
||||
export default class ChangesetAuthor extends React.Component<Props> {
|
||||
render() {
|
||||
const { changeset } = this.props;
|
||||
if (!changeset.author) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { name } = changeset.author;
|
||||
return (
|
||||
<>
|
||||
{changeset.author.name}{" "}
|
||||
<a
|
||||
className="is-hidden-mobile"
|
||||
href={"mailto:" + changeset.author.mail}
|
||||
>
|
||||
<
|
||||
{changeset.author.mail}
|
||||
>
|
||||
</a>
|
||||
{name} {this.renderMail()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
renderMail() {
|
||||
const { mail } = this.props.changeset.author;
|
||||
if (mail) {
|
||||
return (
|
||||
<a className="is-hidden-mobile" href={"mailto:" + mail}>
|
||||
<
|
||||
{mail}
|
||||
>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
scm-ui/src/repos/components/changesets/ChangesetAvatar.js
Normal file
30
scm-ui/src/repos/components/changesets/ChangesetAvatar.js
Normal file
@@ -0,0 +1,30 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
||||
import type { Changeset } from "@scm-manager/ui-types";
|
||||
|
||||
type Props = {
|
||||
changeset: Changeset
|
||||
};
|
||||
|
||||
class ChangesetAvatar extends React.Component<Props> {
|
||||
render() {
|
||||
const { changeset } = this.props;
|
||||
return (
|
||||
<ExtensionPoint
|
||||
name="repos.changeset-table.information"
|
||||
renderAll={true}
|
||||
props={{ changeset }}
|
||||
>
|
||||
{/* extension should render something like this: */}
|
||||
{/* <div className="image is-64x64"> */}
|
||||
{/* <figure className="media-left"> */}
|
||||
{/* <Image src="/some/image.jpg" alt="Logo" /> */}
|
||||
{/* </figure> */}
|
||||
{/* </div> */}
|
||||
</ExtensionPoint>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ChangesetAvatar;
|
||||
@@ -12,8 +12,14 @@ type Props = {
|
||||
class ChangesetList extends React.Component<Props> {
|
||||
render() {
|
||||
const { repository, changesets } = this.props;
|
||||
const content = changesets.map((changeset, index) => {
|
||||
return <ChangesetRow key={index} repository={repository} changeset={changeset} />;
|
||||
const content = changesets.map(changeset => {
|
||||
return (
|
||||
<ChangesetRow
|
||||
key={changeset.id}
|
||||
repository={repository}
|
||||
changeset={changeset}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return <div className={classNames("box")}>{content}</div>;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import type { Changeset, Repository } from "@scm-manager/ui-types";
|
||||
import type { Changeset, Repository, Tag } from "@scm-manager/ui-types";
|
||||
import classNames from "classnames";
|
||||
import { translate, Interpolate } from "react-i18next";
|
||||
import ChangesetAvatar from "./ChangesetAvatar";
|
||||
@@ -8,6 +8,8 @@ import ChangesetId from "./ChangesetId";
|
||||
import injectSheet from "react-jss";
|
||||
import { DateFromNow } from "@scm-manager/ui-components";
|
||||
import ChangesetAuthor from "./ChangesetAuthor";
|
||||
import ChangesetTag from "./ChangesetTag";
|
||||
import { compose } from "redux";
|
||||
|
||||
const styles = {
|
||||
pointer: {
|
||||
@@ -34,33 +36,55 @@ class ChangesetRow extends React.Component<Props> {
|
||||
return <ChangesetId changeset={changeset} repository={repository} />;
|
||||
};
|
||||
|
||||
getTags = () => {
|
||||
const { changeset } = this.props;
|
||||
return changeset._embedded.tags || [];
|
||||
};
|
||||
|
||||
render() {
|
||||
const { changeset, classes } = this.props;
|
||||
const changesetLink = this.createLink(changeset);
|
||||
const dateFromNow = <DateFromNow date={changeset.date} />;
|
||||
const authorLine = <ChangesetAuthor changeset={changeset}/>;
|
||||
const authorLine = <ChangesetAuthor changeset={changeset} />;
|
||||
|
||||
return (
|
||||
<article className={classNames("media", classes.inner)}>
|
||||
<figure className="media-left">
|
||||
<ChangesetAvatar changeset={changeset} />
|
||||
</figure>
|
||||
<ChangesetAvatar changeset={changeset} />
|
||||
<div className={classNames("media-content", classes.withOverflow)}>
|
||||
<div className="content">
|
||||
<p className="is-ellipsis-overflow">
|
||||
{changeset.description}
|
||||
<br />
|
||||
<Interpolate
|
||||
i18nKey="changeset.summary"
|
||||
i18nKey="changesets.changeset.summary"
|
||||
id={changesetLink}
|
||||
time={dateFromNow}
|
||||
/>
|
||||
</p>{" "}
|
||||
<p className="is-size-7">{authorLine}</p>
|
||||
<div className="is-size-7">{authorLine}</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.renderTags()}
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
renderTags = () => {
|
||||
const tags = this.getTags();
|
||||
if (tags.length > 0) {
|
||||
return (
|
||||
<div className="media-right">
|
||||
{tags.map((tag: Tag) => {
|
||||
return <ChangesetTag key={tag.name} tag={tag} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
export default injectSheet(styles)(translate("changesets")(ChangesetRow));
|
||||
export default compose(
|
||||
injectSheet(styles),
|
||||
translate("repos")
|
||||
)(ChangesetRow);
|
||||
32
scm-ui/src/repos/components/changesets/ChangesetTag.js
Normal file
32
scm-ui/src/repos/components/changesets/ChangesetTag.js
Normal file
@@ -0,0 +1,32 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import type { Tag } from "@scm-manager/ui-types";
|
||||
import injectSheet from "react-jss";
|
||||
import classNames from "classnames";
|
||||
|
||||
const styles = {
|
||||
spacing: {
|
||||
marginRight: "4px"
|
||||
}
|
||||
};
|
||||
|
||||
type Props = {
|
||||
tag: Tag,
|
||||
|
||||
// context props
|
||||
classes: Object
|
||||
};
|
||||
|
||||
class ChangesetTag extends React.Component<Props> {
|
||||
render() {
|
||||
const { tag, classes } = this.props;
|
||||
return (
|
||||
<span className="tag is-info">
|
||||
<span className={classNames("fa", "fa-tag", classes.spacing)} />{" "}
|
||||
{tag.name}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectSheet(styles)(ChangesetTag);
|
||||
Reference in New Issue
Block a user