Merge branch 'develop' into feature/create_gpg_signatures

This commit is contained in:
Konstantin Schaper
2020-08-12 13:40:45 +02:00
committed by GitHub
15 changed files with 4750 additions and 45 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React, { useEffect, useState } from "react";
import React, { ReactNode, useEffect, useState } from "react";
import { storiesOf } from "@storybook/react";
import Diff from "./Diff";
// @ts-ignore
@@ -29,11 +29,15 @@ import parser from "gitdiff-parser";
import simpleDiff from "../__resources__/Diff.simple";
import hunksDiff from "../__resources__/Diff.hunks";
import binaryDiff from "../__resources__/Diff.binary";
import { DiffEventContext, File } from "./DiffTypes";
import { DiffEventContext, File, FileControlFactory } from "./DiffTypes";
import Toast from "../toast/Toast";
import { getPath } from "./diffs";
import DiffButton from "./DiffButton";
import styled from "styled-components";
import { MemoryRouter } from "react-router-dom";
import { one, two } from "../__resources__/changesets";
import { Changeset } from "@scm-manager/ui-types";
import JumpToFileButton from "./JumpToFileButton";
const diffFiles = parser.parse(simpleDiff);
@@ -41,11 +45,46 @@ const Container = styled.div`
padding: 2rem 6rem;
`;
const RoutingDecorator = (story: () => ReactNode) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>;
const fileControlFactory: (changeset: Changeset) => FileControlFactory = changeset => file => {
const baseUrl = "/repo/hitchhiker/heartOfGold/code/changeset";
const sourceLink = {
url: `${baseUrl}/${changeset.id}/${file.newPath}/`,
label: "Jump to source"
};
const targetLink = changeset._embedded?.parents?.length === 1 && {
url: `${baseUrl}/${changeset._embedded.parents[0].id}/${file.oldPath}`,
label: "Jump to target"
};
const links = [];
switch (file.type) {
case "add":
links.push(sourceLink);
break;
case "delete":
if (targetLink) {
links.push(targetLink);
}
break;
default:
if (targetLink) {
links.push(sourceLink, targetLink);
} else {
links.push(sourceLink);
}
}
return links.map(({ url, label }) => <JumpToFileButton tooltip={label} link={url} />);
};
storiesOf("Diff", module)
.addDecorator(RoutingDecorator)
.addDecorator(storyFn => <Container>{storyFn()}</Container>)
.add("Default", () => <Diff diff={diffFiles} />)
.add("Side-By-Side", () => <Diff diff={diffFiles} sideBySide={true} />)
.add("Collapsed", () => <Diff diff={diffFiles} defaultCollapse={true} />)
.add("Collapsed", () => <Diff diff={diffFiles} defaultCollapse={true} fileControlFactory={fileControlFactory(two)} />)
.add("File Controls", () => (
<Diff
diff={diffFiles}
@@ -121,4 +160,5 @@ storiesOf("Diff", module)
return file;
});
return <Diff diff={filesWithLanguage} />;
});
})
.add("WithLinkToFile", () => <Diff diff={diffFiles} />);

View File

@@ -23,13 +23,14 @@
*/
import React from "react";
import DiffFile from "./DiffFile";
import { DiffObjectProps, File } from "./DiffTypes";
import { DiffObjectProps, File, FileControlFactory } from "./DiffTypes";
import Notification from "../Notification";
import { WithTranslation, withTranslation } from "react-i18next";
type Props = WithTranslation &
DiffObjectProps & {
diff: File[];
fileControlFactory?: FileControlFactory;
};
class Diff extends React.Component<Props> {

View File

@@ -309,7 +309,11 @@ class DiffFile extends React.Component<Props, State> {
if (file._links?.lines) {
items.push(this.createHunkHeader(expandableHunk));
} else if (i > 0) {
items.push(<Decoration><HunkDivider /></Decoration>);
items.push(
<Decoration>
<HunkDivider />
</Decoration>
);
}
items.push(
@@ -411,29 +415,31 @@ class DiffFile extends React.Component<Props, State> {
}
const collapseIcon = this.hasContent(file) ? <Icon name={icon} color="inherit" /> : null;
const fileControls = fileControlFactory ? fileControlFactory(file, this.setCollapse) : null;
const sideBySideToggle =
file.hunks && file.hunks.length > 0 ? (
<ButtonWrapper className={classNames("level-right", "is-flex")}>
<ButtonGroup>
<MenuContext.Consumer>
{({ setCollapsed }) => (
<DiffButton
icon={sideBySide ? "align-left" : "columns"}
tooltip={t(sideBySide ? "diff.combined" : "diff.sideBySide")}
onClick={() =>
this.toggleSideBySide(() => {
if (this.state.sideBySide) {
setCollapsed(true);
}
})
}
/>
)}
</MenuContext.Consumer>
{fileControls}
</ButtonGroup>
</ButtonWrapper>
) : null;
const sideBySideToggle = file.hunks && file.hunks.length && (
<MenuContext.Consumer>
{({ setCollapsed }) => (
<DiffButton
icon={sideBySide ? "align-left" : "columns"}
tooltip={t(sideBySide ? "diff.combined" : "diff.sideBySide")}
onClick={() =>
this.toggleSideBySide(() => {
if (this.state.sideBySide) {
setCollapsed(true);
}
})
}
/>
)}
</MenuContext.Consumer>
);
const headerButtons = (
<ButtonWrapper className={classNames("level-right", "is-flex")}>
<ButtonGroup>
{sideBySideToggle}
{fileControls}
</ButtonGroup>
</ButtonWrapper>
);
let errorModal;
if (expansionError) {
@@ -463,7 +469,7 @@ class DiffFile extends React.Component<Props, State> {
</TitleWrapper>
{this.renderChangeTag(file)}
</FullWidthTitleHeader>
{sideBySideToggle}
{headerButtons}
</FlexWrapLevel>
</div>
{body}

View File

@@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React, { FC } from "react";
import styled from "styled-components";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import Tooltip from "../Tooltip";
import Icon from "../Icon";
const Button = styled(Link)`
width: 50px;
cursor: pointer;
&:hover {
color: #33b2e8;
}
`;
type Props = {
link: string;
tooltip: string;
};
const JumpToFileButton: FC<Props> = ({ link, tooltip }) => {
return (
<Tooltip message={tooltip} location="top">
<Button aria-label={tooltip} className="button" to={link}>
<Icon name="file-code" color="inherit" />
</Button>
</Tooltip>
);
};
export default JumpToFileButton;

View File

@@ -22,14 +22,16 @@
* SOFTWARE.
*/
import React from "react";
import { Changeset, Link, Collection } from "@scm-manager/ui-types";
import { Changeset, Collection, Link } from "@scm-manager/ui-types";
import LoadingDiff from "../LoadingDiff";
import Notification from "../../Notification";
import { WithTranslation, withTranslation } from "react-i18next";
import { FileControlFactory } from "../DiffTypes";
type Props = WithTranslation & {
changeset: Changeset;
defaultCollapse?: boolean;
fileControlFactory?: FileControlFactory;
};
export const isDiffSupported = (changeset: Collection) => {
@@ -47,12 +49,19 @@ export const createUrl = (changeset: Collection) => {
class ChangesetDiff extends React.Component<Props> {
render() {
const { changeset, defaultCollapse, t } = this.props;
const { changeset, fileControlFactory, defaultCollapse, t } = this.props;
if (!isDiffSupported(changeset)) {
return <Notification type="danger">{t("changeset.diffNotSupported")}</Notification>;
} else {
const url = createUrl(changeset);
return <LoadingDiff url={url} defaultCollapse={defaultCollapse} sideBySide={false} />;
return (
<LoadingDiff
url={url}
defaultCollapse={defaultCollapse}
sideBySide={false}
fileControlFactory={fileControlFactory}
/>
);
}
}
}

View File

@@ -45,11 +45,13 @@ export * from "./changesets";
export { default as Diff } from "./Diff";
export { default as DiffFile } from "./DiffFile";
export { default as DiffButton } from "./DiffButton";
export { FileControlFactory } from "./DiffTypes";
export { default as LoadingDiff } from "./LoadingDiff";
export { DefaultCollapsed, DefaultCollapsedFunction } from "./defaultCollapsed";
export { default as RepositoryAvatar } from "./RepositoryAvatar";
export { default as RepositoryEntry } from "./RepositoryEntry";
export { default as RepositoryEntryLink } from "./RepositoryEntryLink";
export { default as JumpToFileButton } from "./JumpToFileButton";
export {
File,