mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-15 16:50:18 +01:00
Link directly to file sources from file history view (#1945)
Link directly to the selected file with the file history sources link instead of the root dir.
This commit is contained in:
2
gradle/changelog/file_history_source_link.yaml
Normal file
2
gradle/changelog/file_history_source_link.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- type: changed
|
||||
description: Link directly to file with file history sources link ([#1945](https://github.com/scm-manager/scm-manager/pull/1945))
|
||||
@@ -21,29 +21,28 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import React from "react";
|
||||
import { Changeset, Repository } from "@scm-manager/ui-types";
|
||||
import { ButtonAddons, Button } from "../../buttons";
|
||||
import React, { FC } from "react";
|
||||
import { Changeset, File, Repository } from "@scm-manager/ui-types";
|
||||
import { Button, ButtonAddons } from "../../buttons";
|
||||
import { createChangesetLink, createSourcesLink } from "./changesets";
|
||||
import { WithTranslation, withTranslation } from "react-i18next";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
type Props = WithTranslation & {
|
||||
type Props = {
|
||||
repository: Repository;
|
||||
changeset: Changeset;
|
||||
file?: File;
|
||||
};
|
||||
|
||||
class ChangesetButtonGroup extends React.Component<Props> {
|
||||
render() {
|
||||
const { repository, changeset, t } = this.props;
|
||||
const changesetLink = createChangesetLink(repository, changeset);
|
||||
const sourcesLink = createSourcesLink(repository, changeset);
|
||||
return (
|
||||
<ButtonAddons className="m-0">
|
||||
<Button link={changesetLink} icon="exchange-alt" label={t("changeset.buttons.details")} reducedMobile={true} />
|
||||
<Button link={sourcesLink} icon="code" label={t("changeset.buttons.sources")} reducedMobile={true} />
|
||||
</ButtonAddons>
|
||||
);
|
||||
}
|
||||
}
|
||||
const ChangesetButtonGroup: FC<Props> = ({ repository, changeset, file }) => {
|
||||
const [t] = useTranslation("repos");
|
||||
const changesetLink = createChangesetLink(repository, changeset);
|
||||
const sourcesLink = createSourcesLink(repository, changeset, file);
|
||||
return (
|
||||
<ButtonAddons className="m-0">
|
||||
<Button link={changesetLink} icon="exchange-alt" label={t("changeset.buttons.details")} reducedMobile={true} />
|
||||
<Button link={sourcesLink} icon="code" label={t("changeset.buttons.sources")} reducedMobile={true} />
|
||||
</ButtonAddons>
|
||||
);
|
||||
};
|
||||
|
||||
export default withTranslation("repos")(ChangesetButtonGroup);
|
||||
export default ChangesetButtonGroup;
|
||||
|
||||
@@ -22,23 +22,20 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import ChangesetRow from "./ChangesetRow";
|
||||
import React from "react";
|
||||
|
||||
import { Changeset, Repository } from "@scm-manager/ui-types";
|
||||
import React, { FC } from "react";
|
||||
import { Changeset, File, Repository } from "@scm-manager/ui-types";
|
||||
|
||||
type Props = {
|
||||
repository: Repository;
|
||||
changesets: Changeset[];
|
||||
file?: File;
|
||||
};
|
||||
|
||||
class ChangesetList extends React.Component<Props> {
|
||||
render() {
|
||||
const { repository, changesets } = this.props;
|
||||
const content = changesets.map((changeset) => {
|
||||
return <ChangesetRow key={changeset.id} repository={repository} changeset={changeset} />;
|
||||
});
|
||||
return <>{content}</>;
|
||||
}
|
||||
}
|
||||
const ChangesetList: FC<Props> = ({ repository, changesets, file }) => {
|
||||
const content = changesets.map(changeset => {
|
||||
return <ChangesetRow key={changeset.id} repository={repository} changeset={changeset} file={file} />;
|
||||
});
|
||||
return <>{content}</>;
|
||||
};
|
||||
|
||||
export default ChangesetList;
|
||||
|
||||
@@ -25,13 +25,14 @@ import React, { FC } from "react";
|
||||
import classNames from "classnames";
|
||||
import styled from "styled-components";
|
||||
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
||||
import { Changeset, Repository } from "@scm-manager/ui-types";
|
||||
import { Changeset, File, Repository } from "@scm-manager/ui-types";
|
||||
import ChangesetButtonGroup from "./ChangesetButtonGroup";
|
||||
import SingleChangeset from "./SingleChangeset";
|
||||
|
||||
type Props = {
|
||||
repository: Repository;
|
||||
changeset: Changeset;
|
||||
file?: File;
|
||||
};
|
||||
|
||||
const Wrapper = styled.div`
|
||||
@@ -44,7 +45,7 @@ const Wrapper = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const ChangesetRow: FC<Props> = ({ repository, changeset }) => {
|
||||
const ChangesetRow: FC<Props> = ({ repository, changeset, file }) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<div className={classNames("columns", "is-gapless", "is-mobile")}>
|
||||
@@ -52,12 +53,12 @@ const ChangesetRow: FC<Props> = ({ repository, changeset }) => {
|
||||
<SingleChangeset repository={repository} changeset={changeset} />
|
||||
</div>
|
||||
<div className={classNames("column", "is-flex", "is-justify-content-flex-end", "is-align-items-center")}>
|
||||
<ChangesetButtonGroup repository={repository} changeset={changeset} />
|
||||
<ChangesetButtonGroup repository={repository} changeset={changeset} file={file} />
|
||||
<ExtensionPoint
|
||||
name="changeset.right"
|
||||
props={{
|
||||
repository,
|
||||
changeset,
|
||||
changeset
|
||||
}}
|
||||
renderAll={true}
|
||||
/>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Changeset, Repository } from "@scm-manager/ui-types";
|
||||
import { Changeset, File, Repository } from "@scm-manager/ui-types";
|
||||
|
||||
export type Description = {
|
||||
title: string;
|
||||
@@ -33,8 +33,13 @@ export function createChangesetLink(repository: Repository, changeset: Changeset
|
||||
return `/repo/${repository.namespace}/${repository.name}/code/changeset/${changeset.id}`;
|
||||
}
|
||||
|
||||
export function createSourcesLink(repository: Repository, changeset: Changeset) {
|
||||
return `/repo/${repository.namespace}/${repository.name}/code/sources/${changeset.id}`;
|
||||
export function createSourcesLink(repository: Repository, changeset: Changeset, file?: File) {
|
||||
let url = `/repo/${repository.namespace}/${repository.name}/code/sources/${changeset.id}`;
|
||||
|
||||
if (file) {
|
||||
url += `/${encodeURIComponent(file.path)}/`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
export function parseDescription(description?: string): Description {
|
||||
@@ -53,6 +58,6 @@ export function parseDescription(description?: string): Description {
|
||||
|
||||
return {
|
||||
title,
|
||||
message,
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ const HistoryView: FC<Props> = ({ repository, file, revision }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="panel-block">
|
||||
<ChangesetList repository={repository} changesets={history._embedded.changesets} />
|
||||
<ChangesetList repository={repository} changesets={history?._embedded?.changesets || []} file={file} />
|
||||
</div>
|
||||
<div className="panel-footer">
|
||||
<StatePaginator page={page + 1} collection={history} updatePage={(newPage: number) => setPage(newPage - 1)} />
|
||||
|
||||
Reference in New Issue
Block a user