[Custom File annotation for {file.newPath}
]}
/>
))
.add("Line Annotation", () => (
{
return {
N2: Line Annotation
@@ -94,7 +128,7 @@ storiesOf("Diff", module)
return (
<>
{changeId && }
-
+
>
);
};
@@ -102,11 +136,11 @@ storiesOf("Diff", module)
})
.add("Hunks", () => {
const hunkDiffFiles = parser.parse(hunksDiff);
- return ;
+ return ;
})
.add("Binaries", () => {
const binaryDiffFiles = parser.parse(binaryDiff);
- return ;
+ return ;
})
.add("SyntaxHighlighting", () => {
const filesWithLanguage = diffFiles.map((file: File) => {
@@ -118,22 +152,20 @@ storiesOf("Diff", module)
}
return file;
});
- return ;
+ return ;
})
.add("CollapsingWithFunction", () => (
- oldPath.endsWith(".java")} />
+ oldPath.endsWith(".java")} />
))
.add("Expandable", () => {
const filesWithLanguage = diffFiles.map((file: File) => {
file._links = { lines: { href: "http://example.com/" } };
return file;
});
- return ;
+ return ;
})
.add("WithLinkToFile", () => (
));
diff --git a/scm-ui/ui-components/src/repos/Diff.tsx b/scm-ui/ui-components/src/repos/Diff.tsx
index 8978c61d72..627b52027c 100644
--- a/scm-ui/ui-components/src/repos/Diff.tsx
+++ b/scm-ui/ui-components/src/repos/Diff.tsx
@@ -23,17 +23,15 @@
*/
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";
-import {Changeset} from "@scm-manager/ui-types";
+import {WithTranslation, withTranslation} from "react-i18next";
type Props = WithTranslation &
DiffObjectProps & {
- diff: File[];
- changeset: Changeset;
- baseUrl?: string;
- };
+ diff: File[];
+ fileControlFactory?: FileControlFactory;
+};
class Diff extends React.Component {
static defaultProps: Partial = {
@@ -41,7 +39,7 @@ class Diff extends React.Component {
};
render() {
- const { diff, t, ...fileProps } = this.props;
+ const {diff, t, ...fileProps} = this.props;
return (
<>
{diff.length === 0 ? (
diff --git a/scm-ui/ui-components/src/repos/DiffFile.tsx b/scm-ui/ui-components/src/repos/DiffFile.tsx
index dc5070ddd3..3702cd5817 100644
--- a/scm-ui/ui-components/src/repos/DiffFile.tsx
+++ b/scm-ui/ui-components/src/repos/DiffFile.tsx
@@ -22,34 +22,30 @@
* SOFTWARE.
*/
import React from "react";
-import { withTranslation, WithTranslation } from "react-i18next";
+import {withTranslation, WithTranslation} from "react-i18next";
import classNames from "classnames";
import styled from "styled-components";
// @ts-ignore
-import { Decoration, getChangeKey, Hunk } from "react-diff-view";
-import { ButtonGroup } from "../buttons";
+import {Decoration, getChangeKey, Hunk} from "react-diff-view";
+import {ButtonGroup} from "../buttons";
import Tag from "../Tag";
import Icon from "../Icon";
-import { Change, ChangeEvent, DiffObjectProps, File, Hunk as HunkType } from "./DiffTypes";
+import {Change, ChangeEvent, DiffObjectProps, File, Hunk as HunkType} from "./DiffTypes";
import TokenizedDiffView from "./TokenizedDiffView";
import DiffButton from "./DiffButton";
-import { MenuContext } from "@scm-manager/ui-components";
-import DiffExpander, { ExpandableHunk } from "./DiffExpander";
+import {MenuContext} from "@scm-manager/ui-components";
+import DiffExpander, {ExpandableHunk} from "./DiffExpander";
import HunkExpandLink from "./HunkExpandLink";
-import { Modal } from "../modals";
+import {Modal} from "../modals";
import ErrorNotification from "../ErrorNotification";
import HunkExpandDivider from "./HunkExpandDivider";
-import JumpToFileButton from "./JumpToFileButton";
-import {Changeset} from "@scm-manager/ui-types";
const EMPTY_ANNOTATION_FACTORY = {};
type Props = DiffObjectProps &
WithTranslation & {
- file: File;
- changeset: Changeset;
- baseUrl?: string;
- };
+ file: File;
+};
type Collapsible = {
collapsed?: boolean;
@@ -119,7 +115,7 @@ class DiffFile extends React.Component {
}
defaultCollapse: () => boolean = () => {
- const { defaultCollapse, file } = this.props;
+ const {defaultCollapse, file} = this.props;
if (typeof defaultCollapse === "boolean") {
return defaultCollapse;
} else if (typeof defaultCollapse === "function") {
@@ -130,7 +126,7 @@ class DiffFile extends React.Component {
};
toggleCollapse = () => {
- const { file } = this.state;
+ const {file} = this.state;
if (this.hasContent(file)) {
this.setState(state => ({
collapsed: !state.collapsed
@@ -161,7 +157,7 @@ class DiffFile extends React.Component {
);
@@ -171,19 +167,19 @@ class DiffFile extends React.Component {
{" "}
);
}
}
// hunk header must be defined
- return ;
+ return ;
};
createHunkFooter = (expandableHunk: ExpandableHunk) => {
@@ -194,7 +190,7 @@ class DiffFile extends React.Component {
);
@@ -204,19 +200,19 @@ class DiffFile extends React.Component {
{" "}
);
}
}
// hunk footer must be defined
- return ;
+ return ;
};
createLastHunkFooter = (expandableHunk: ExpandableHunk) => {
@@ -226,7 +222,7 @@ class DiffFile extends React.Component {
{" "}
{
);
}
// hunk header must be defined
- return ;
+ return ;
};
expandHead = (expandableHunk: ExpandableHunk, count: number) => {
@@ -259,16 +255,16 @@ class DiffFile extends React.Component {
};
diffExpanded = (newFile: File) => {
- this.setState({ file: newFile, diffExpander: new DiffExpander(newFile) });
+ this.setState({file: newFile, diffExpander: new DiffExpander(newFile)});
};
diffExpansionFailed = (err: any) => {
- this.setState({ expansionError: err });
+ this.setState({expansionError: err});
};
collectHunkAnnotations = (hunk: HunkType) => {
- const { annotationFactory } = this.props;
- const { file } = this.state;
+ const {annotationFactory} = this.props;
+ const {file} = this.state;
if (annotationFactory) {
return annotationFactory({
hunk,
@@ -280,8 +276,8 @@ class DiffFile extends React.Component {
};
handleClickEvent = (change: Change, hunk: HunkType) => {
- const { onClick } = this.props;
- const { file } = this.state;
+ const {onClick} = this.props;
+ const {file} = this.state;
const context = {
changeId: getChangeKey(change),
change,
@@ -294,7 +290,7 @@ class DiffFile extends React.Component {
};
createGutterEvents = (hunk: HunkType) => {
- const { onClick } = this.props;
+ const {onClick} = this.props;
if (onClick) {
return {
onClick: (event: ChangeEvent) => {
@@ -315,7 +311,7 @@ class DiffFile extends React.Component {
} else if (i > 0) {
items.push(
-
+
);
}
@@ -358,7 +354,7 @@ class DiffFile extends React.Component {
if (file.oldPath !== file.newPath && (file.type === "copy" || file.type === "rename")) {
return (
<>
- {file.oldPath} {file.newPath}
+ {file.oldPath} {file.newPath}
>
);
} else if (file.type === "delete") {
@@ -377,7 +373,7 @@ class DiffFile extends React.Component {
};
renderChangeTag = (file: File) => {
- const { t } = this.props;
+ const {t} = this.props;
if (!file.type) {
return;
}
@@ -389,14 +385,14 @@ class DiffFile extends React.Component {
const color =
value === "added" ? "success is-outlined" : value === "deleted" ? "danger is-outlined" : "info is-outlined";
- return ;
+ return ;
};
hasContent = (file: File) => file && !file.isBinary && file.hunks && file.hunks.length > 0;
render() {
- const { fileControlFactory, fileAnnotationFactory, changeset: { id: changesetId, _embedded: { parents } }, baseUrl, t } = this.props;
- const { file, collapsed, sideBySide, diffExpander, expansionError } = this.state;
+ const {fileControlFactory, fileAnnotationFactory, t} = this.props;
+ const {file, collapsed, sideBySide, diffExpander, expansionError} = this.state;
const viewType = sideBySide ? "split" : "unified";
let body = null;
@@ -417,37 +413,14 @@ class DiffFile extends React.Component {
);
}
- const collapseIcon = this.hasContent(file) ? : null;
+ const collapseIcon = this.hasContent(file) ? : null;
const fileControls = fileControlFactory ? fileControlFactory(file, this.setCollapse) : null;
- let jumpToSource = null;
- let jumpToTarget = null;
- if (changesetId && baseUrl) {
- const jumpToSourceButton = ;
- const jumpToTargetButton = parents?.length === 1 && ;
- switch (file.type) {
- case "add":
- jumpToSource = jumpToSourceButton;
- break;
- case "delete":
- jumpToTarget = jumpToTargetButton;
- break;
- default:
- jumpToSource = jumpToSourceButton;
- jumpToTarget = jumpToTargetButton;
- }
- }
const sideBySideToggle =
- file.hunks && file.hunks.length > 0 ? (
+ file.hunks && file.hunks.length > 0 && (
- {({ setCollapsed }) => (
+ {({setCollapsed}) => (
{
)}
{fileControls}
- {jumpToSource}
- {jumpToTarget}
-
-
- ) : (
-
-
- {jumpToSource}
- {jumpToTarget}
);
@@ -480,8 +444,8 @@ class DiffFile extends React.Component {
errorModal = (
this.setState({ expansionError: undefined })}
- body={}
+ closeFunction={() => this.setState({expansionError: undefined})}
+ body={}
active={true}
/>
);
diff --git a/scm-ui/ui-components/src/repos/LoadingDiff.tsx b/scm-ui/ui-components/src/repos/LoadingDiff.tsx
index 5086977ff4..59db938a6a 100644
--- a/scm-ui/ui-components/src/repos/LoadingDiff.tsx
+++ b/scm-ui/ui-components/src/repos/LoadingDiff.tsx
@@ -22,25 +22,22 @@
* SOFTWARE.
*/
import React from "react";
-import { apiClient } from "../apiclient";
+import {apiClient} from "../apiclient";
import ErrorNotification from "../ErrorNotification";
// @ts-ignore
import parser from "gitdiff-parser";
import Loading from "../Loading";
import Diff from "./Diff";
-import { DiffObjectProps, File } from "./DiffTypes";
-import { NotFoundError } from "../errors";
-import { Notification } from "../index";
-import { withTranslation, WithTranslation } from "react-i18next";
-import {Changeset} from "@scm-manager/ui-types";
+import {DiffObjectProps, File} from "./DiffTypes";
+import {NotFoundError} from "../errors";
+import {Notification} from "../index";
+import {withTranslation, WithTranslation} from "react-i18next";
type Props = WithTranslation &
DiffObjectProps & {
- url: string;
- changeset: Changeset;
- baseUrl: string;
- };
+ url: string;
+};
type State = {
diff?: File[];
@@ -71,8 +68,8 @@ class LoadingDiff extends React.Component {
}
fetchDiff = () => {
- const { url } = this.props;
- this.setState({ loading: true });
+ const {url} = this.props;
+ this.setState({loading: true});
apiClient
.get(url)
.then(response => {
@@ -98,14 +95,14 @@ class LoadingDiff extends React.Component {
};
render() {
- const { diff, loading, error } = this.state;
+ const {diff, loading, error} = this.state;
if (error) {
if (error instanceof NotFoundError) {
return {this.props.t("changesets.noChangesets")};
}
- return ;
+ return ;
} else if (loading) {
- return ;
+ return ;
} else if (!diff) {
return null;
} else {
diff --git a/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx b/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx
index ccbbc521ae..8ec86cab41 100644
--- a/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx
+++ b/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx
@@ -22,15 +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 {WithTranslation, withTranslation} from "react-i18next";
+import {FileControlFactory} from "../DiffTypes";
type Props = WithTranslation & {
changeset: Changeset;
- baseUrl: string;
defaultCollapse?: boolean;
+ fileControlFactory?: FileControlFactory;
};
export const isDiffSupported = (changeset: Collection) => {
@@ -48,12 +49,12 @@ export const createUrl = (changeset: Collection) => {
class ChangesetDiff extends React.Component {
render() {
- const { changeset, baseUrl, defaultCollapse, t } = this.props;
+ const {changeset, fileControlFactory, defaultCollapse, t} = this.props;
if (!isDiffSupported(changeset)) {
return {t("changeset.diffNotSupported")};
} else {
const url = createUrl(changeset);
- return ;
+ return ;
}
}
}
diff --git a/scm-ui/ui-components/src/repos/changesets/ChangesetRow.tsx b/scm-ui/ui-components/src/repos/changesets/ChangesetRow.tsx
index 46a30a6fd4..cf8adcebd5 100644
--- a/scm-ui/ui-components/src/repos/changesets/ChangesetRow.tsx
+++ b/scm-ui/ui-components/src/repos/changesets/ChangesetRow.tsx
@@ -35,6 +35,7 @@ import ChangesetAuthor from "./ChangesetAuthor";
import ChangesetTags from "./ChangesetTags";
import ChangesetButtonGroup from "./ChangesetButtonGroup";
import ChangesetDescription from "./ChangesetDescription";
+import {FileControlFactory} from "../DiffTypes";
type Props = WithTranslation & {
repository: Repository;
diff --git a/scm-ui/ui-components/src/repos/index.ts b/scm-ui/ui-components/src/repos/index.ts
index a3551ed6b5..36b26495b8 100644
--- a/scm-ui/ui-components/src/repos/index.ts
+++ b/scm-ui/ui-components/src/repos/index.ts
@@ -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,
diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json
index 078ec13c65..a0f37eefdf 100644
--- a/scm-ui/ui-webapp/public/locales/de/repos.json
+++ b/scm-ui/ui-webapp/public/locales/de/repos.json
@@ -224,7 +224,7 @@
},
"diff": {
"jumpToSource": "Zur Quelldatei springen",
- "jumpToTarget": "Zur Zieldatei springen",
+ "jumpToTarget": "Zur vorherigen Version der Datei springen",
"sideBySide": "Zur zweispaltigen Ansicht wechseln",
"combined": "Zur kombinierten Ansicht wechseln",
"noDiffFound": "Kein Diff zwischen den ausgewählten Branches gefunden.",
diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json
index 121c82e806..f4b9c7c89b 100644
--- a/scm-ui/ui-webapp/public/locales/en/repos.json
+++ b/scm-ui/ui-webapp/public/locales/en/repos.json
@@ -231,7 +231,7 @@
"copy": "copied"
},
"jumpToSource": "Jump to source file",
- "jumpToTarget": "Jump to target file",
+ "jumpToTarget": "Jump to the previous version of the file",
"sideBySide": "Switch to side-by-side view",
"combined": "Switch to combined view",
"noDiffFound": "No Diff between the selected branches found.",
diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx
index e807f8d4cf..c5868258c8 100644
--- a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx
+++ b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx
@@ -43,11 +43,12 @@ import {
} from "@scm-manager/ui-components";
import ContributorTable from "./ContributorTable";
import { Link as ReactLink } from "react-router-dom";
+import {FileControlFactory} from "@scm-manager/ui-components";
type Props = WithTranslation & {
changeset: Changeset;
repository: Repository;
- baseUrl: string;
+ fileControlFactory?: FileControlFactory;
};
type State = {
@@ -131,6 +132,7 @@ const Contributors: FC<{ changeset: Changeset }> = ({ changeset }) => {
);
}
+
return (
<>
setOpen(!open)}>
@@ -158,7 +160,7 @@ class ChangesetDetails extends React.Component {
}
render() {
- const { changeset, repository, baseUrl, t } = this.props;
+ const { changeset, repository, fileControlFactory, t } = this.props;
const { collapsed } = this.state;
const description = changesets.parseDescription(changeset.description);
@@ -239,7 +241,7 @@ class ChangesetDetails extends React.Component {
/>
}
/>
-
+
>
);
diff --git a/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx b/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx
index 636707c8a6..958221f533 100644
--- a/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx
+++ b/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx
@@ -22,12 +22,12 @@
* SOFTWARE.
*/
import React from "react";
-import { connect } from "react-redux";
-import { compose } from "redux";
-import { withRouter } from "react-router-dom";
-import { WithTranslation, withTranslation } from "react-i18next";
-import { Changeset, Repository } from "@scm-manager/ui-types";
-import { ErrorPage, Loading } from "@scm-manager/ui-components";
+import {connect} from "react-redux";
+import {compose} from "redux";
+import {withRouter} from "react-router-dom";
+import {WithTranslation, withTranslation} from "react-i18next";
+import {Changeset, Repository} from "@scm-manager/ui-types";
+import {ErrorPage, Loading} from "@scm-manager/ui-components";
import {
fetchChangesetIfNeeded,
getChangeset,
@@ -35,12 +35,13 @@ import {
isFetchChangesetPending
} from "../modules/changesets";
import ChangesetDetails from "../components/changesets/ChangesetDetails";
+import {FileControlFactory} from "@scm-manager/ui-components";
type Props = WithTranslation & {
id: string;
changeset: Changeset;
repository: Repository;
- baseUrl: string;
+ fileControlFactoryFactory?: (changeset: Changeset) => FileControlFactory;
loading: boolean;
error: Error;
fetchChangesetIfNeeded: (repository: Repository, id: string) => void;
@@ -49,27 +50,28 @@ type Props = WithTranslation & {
class ChangesetView extends React.Component {
componentDidMount() {
- const { fetchChangesetIfNeeded, repository, id } = this.props;
+ const {fetchChangesetIfNeeded, repository, id} = this.props;
fetchChangesetIfNeeded(repository, id);
}
componentDidUpdate(prevProps: Props) {
- const { fetchChangesetIfNeeded, repository, id } = this.props;
+ const {fetchChangesetIfNeeded, repository, id} = this.props;
if (prevProps.id !== id) {
fetchChangesetIfNeeded(repository, id);
}
}
render() {
- const { changeset, loading, error, t, repository, baseUrl } = this.props;
+ const {changeset, loading, error, t, repository, fileControlFactoryFactory} = this.props;
if (error) {
- return ;
+ return ;
}
- if (!changeset || loading) return ;
+ if (!changeset || loading) return ;
- return ;
+ return ;
}
}
diff --git a/scm-ui/ui-webapp/src/repos/containers/RepositoryRoot.tsx b/scm-ui/ui-webapp/src/repos/containers/RepositoryRoot.tsx
index 4a73a19d3a..6235854bf6 100644
--- a/scm-ui/ui-webapp/src/repos/containers/RepositoryRoot.tsx
+++ b/scm-ui/ui-webapp/src/repos/containers/RepositoryRoot.tsx
@@ -22,24 +22,24 @@
* SOFTWARE.
*/
import React from "react";
-import { connect } from "react-redux";
-import { Redirect, Route, Switch, RouteComponentProps } from "react-router-dom";
-import { WithTranslation, withTranslation } from "react-i18next";
-import { binder, ExtensionPoint } from "@scm-manager/ui-extensions";
-import { Repository } from "@scm-manager/ui-types";
+import {connect} from "react-redux";
+import {Redirect, Route, RouteComponentProps, Switch} from "react-router-dom";
+import {WithTranslation, withTranslation} from "react-i18next";
+import {binder, ExtensionPoint} from "@scm-manager/ui-extensions";
+import {Changeset, Repository} from "@scm-manager/ui-types";
import {
+ CustomQueryFlexWrappedColumns,
ErrorPage,
Loading,
NavLink,
Page,
- CustomQueryFlexWrappedColumns,
PrimaryContentColumn,
- SecondaryNavigationColumn,
SecondaryNavigation,
- SubNavigation,
- StateMenuContextProvider
+ SecondaryNavigationColumn,
+ StateMenuContextProvider,
+ SubNavigation
} from "@scm-manager/ui-components";
-import { fetchRepoByName, getFetchRepoFailure, getRepository, isFetchRepoPending } from "../modules/repos";
+import {fetchRepoByName, getFetchRepoFailure, getRepository, isFetchRepoPending} from "../modules/repos";
import RepositoryDetails from "../components/RepositoryDetails";
import EditRepo from "./EditRepo";
import BranchesOverview from "../branches/containers/BranchesOverview";
@@ -49,33 +49,34 @@ import EditRepoNavLink from "../components/EditRepoNavLink";
import BranchRoot from "../branches/containers/BranchRoot";
import PermissionsNavLink from "../components/PermissionsNavLink";
import RepositoryNavLink from "../components/RepositoryNavLink";
-import { getLinks, getRepositoriesLink } from "../../modules/indexResource";
+import {getLinks, getRepositoriesLink} from "../../modules/indexResource";
import CodeOverview from "../codeSection/containers/CodeOverview";
import ChangesetView from "./ChangesetView";
import SourceExtensions from "../sources/containers/SourceExtensions";
+import {FileControlFactory, JumpToFileButton} from "@scm-manager/ui-components";
type Props = RouteComponentProps &
WithTranslation & {
- namespace: string;
- name: string;
- repository: Repository;
- loading: boolean;
- error: Error;
- repoLink: string;
- indexLinks: object;
+ namespace: string;
+ name: string;
+ repository: Repository;
+ loading: boolean;
+ error: Error;
+ repoLink: string;
+ indexLinks: object;
- // dispatch functions
- fetchRepoByName: (link: string, namespace: string, name: string) => void;
- };
+ // dispatch functions
+ fetchRepoByName: (link: string, namespace: string, name: string) => void;
+};
class RepositoryRoot extends React.Component {
componentDidMount() {
- const { fetchRepoByName, namespace, name, repoLink } = this.props;
+ const {fetchRepoByName, namespace, name, repoLink} = this.props;
fetchRepoByName(repoLink, namespace, name);
}
componentDidUpdate(prevProps: Props) {
- const { fetchRepoByName, namespace, name, repoLink } = this.props;
+ const {fetchRepoByName, namespace, name, repoLink} = this.props;
if (namespace !== prevProps.namespace || name !== prevProps.name) {
fetchRepoByName(repoLink, namespace, name);
}
@@ -105,7 +106,7 @@ class RepositoryRoot extends React.Component {
};
getCodeLinkname = () => {
- const { repository } = this.props;
+ const {repository} = this.props;
if (repository?._links?.sources) {
return "sources";
}
@@ -116,8 +117,8 @@ class RepositoryRoot extends React.Component {
};
evaluateDestinationForCodeLink = () => {
- const { repository } = this.props;
- let url = `${this.matchedUrl()}/code`;
+ const {repository} = this.props;
+ const url = `${this.matchedUrl()}/code`;
if (repository?._links?.sources) {
return `${url}/sources/`;
}
@@ -125,16 +126,16 @@ class RepositoryRoot extends React.Component {
};
render() {
- const { loading, error, indexLinks, repository, t } = this.props;
+ const {loading, error, indexLinks, repository, t} = this.props;
if (error) {
return (
-
+
);
}
if (!repository || loading) {
- return ;
+ return ;
}
const url = this.matchedUrl();
@@ -153,66 +154,102 @@ class RepositoryRoot extends React.Component {
redirectedUrl = url + "/info";
}
+ const fileControlFactoryFactory: (changeset: Changeset) => FileControlFactory = (changeset) => (file) => {
+ const baseUrl = `${url}/code/sources`;
+ const sourceLink = {
+ url: `${baseUrl}/${changeset.id}/${file.newPath}/`,
+ label: t("diff.jumpToSource")
+ };
+ const targetLink = changeset._embedded?.parents?.length === 1 && {
+ url: `${baseUrl}/${changeset._embedded.parents[0].id}/${file.oldPath}`,
+ label: t("diff.jumpToTarget")
+ };
+
+ 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}) => );
+ };
+
return (
}
+ afterTitle={}
>
-
+
{/* redirect pre 2.0.0-rc2 links */}
-
-
-
-
-
+
+
+
+
+
- } />
- } />
+ }/>
+ }/>
(
-
+
)}
/>
}
+ render={() => }
/>
}
+ render={() => }
/>
}
+ render={() => }
/>
}
+ render={() => }
/>
}
+ render={() => }
/>
}
+ render={() => }
/>
- } />
-
+ }/>
+
-
+
{
activeOnlyWhenExact={false}
title={t("repositoryRoot.menu.sourcesNavLink")}
/>
-
+
-
-
-
+
+
+
@@ -259,7 +296,7 @@ class RepositoryRoot extends React.Component {
}
const mapStateToProps = (state: any, ownProps: Props) => {
- const { namespace, name } = ownProps.match.params;
+ const {namespace, name} = ownProps.match.params;
const repository = getRepository(state, namespace, name);
const loading = isFetchRepoPending(state, namespace, name);
const error = getFetchRepoFailure(state, namespace, name);