mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 06:55:47 +01:00
Introduce new extension point for changeset description
This new extension point will only be rendered when the old extension point is not bound.
This commit is contained in:
@@ -24,10 +24,10 @@
|
||||
import React, { FC, ReactNode } from "react";
|
||||
import textSplitAndReplace from "./textSplitAndReplace";
|
||||
|
||||
type Replacement = {
|
||||
export type Replacement = {
|
||||
textToReplace: string;
|
||||
replacement: ReactNode;
|
||||
replaceAll: boolean;
|
||||
replaceAll?: boolean;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -218,6 +218,54 @@ const four: Changeset = {
|
||||
}
|
||||
};
|
||||
|
||||
const five: Changeset = {
|
||||
id: "d21cc6c359270aef2196796f4d96af65f51866dc",
|
||||
author: { mail: "scm-admin@scm-manager.org", name: "SCM Administrator" },
|
||||
date: new Date("2020-06-09T05:39:50Z"),
|
||||
description: "HOG-42 Change mail to arthur@guide.galaxy\n\n",
|
||||
_links: {
|
||||
self: {
|
||||
href:
|
||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/d21cc6c359270aef2196796f4d96af65f51866dc"
|
||||
},
|
||||
diff: {
|
||||
href:
|
||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc"
|
||||
},
|
||||
sources: {
|
||||
href:
|
||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/sources/d21cc6c359270aef2196796f4d96af65f51866dc"
|
||||
},
|
||||
modifications: {
|
||||
href:
|
||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/modifications/d21cc6c359270aef2196796f4d96af65f51866dc"
|
||||
},
|
||||
diffParsed: {
|
||||
href:
|
||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/d21cc6c359270aef2196796f4d96af65f51866dc/parsed"
|
||||
}
|
||||
},
|
||||
_embedded: {
|
||||
tags: [],
|
||||
branches: [],
|
||||
parents: [
|
||||
{
|
||||
id: "e163c8f632db571c9aa51a8eb440e37cf550b825",
|
||||
_links: {
|
||||
self: {
|
||||
href:
|
||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/changesets/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
||||
},
|
||||
diff: {
|
||||
href:
|
||||
"http://localhost:8081/scm/api/v2/repositories/hitchhiker/heart-of-gold/diff/e163c8f632db571c9aa51a8eb440e37cf550b825"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const changesets: PagedCollection = {
|
||||
page: 0,
|
||||
pageTotal: 1,
|
||||
@@ -246,5 +294,5 @@ const changesets: PagedCollection = {
|
||||
}
|
||||
};
|
||||
|
||||
export { one, two, three, four };
|
||||
export { one, two, three, four, five };
|
||||
export default changesets;
|
||||
|
||||
@@ -78,6 +78,7 @@ export { default as CardColumnGroup } from "./CardColumnGroup";
|
||||
export { default as CardColumn } from "./CardColumn";
|
||||
export { default as CardColumnSmall } from "./CardColumnSmall";
|
||||
export { default as CommaSeparatedList } from "./CommaSeparatedList";
|
||||
export { default as SplitAndReplace, Replacement } from "./SplitAndReplace";
|
||||
|
||||
export { default as comparators } from "./comparators";
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 { Changeset } from "@scm-manager/ui-types";
|
||||
import { useBinder } from "@scm-manager/ui-extensions";
|
||||
import { SplitAndReplace, Replacement } from "@scm-manager/ui-components";
|
||||
|
||||
type Props = {
|
||||
changeset: Changeset;
|
||||
value: string;
|
||||
};
|
||||
|
||||
const ChangesetDescription: FC<Props> = ({ changeset, value }) => {
|
||||
const binder = useBinder();
|
||||
|
||||
const replacements: Replacement[][] = binder.getExtensions("changeset.description.tokens", {
|
||||
changeset,
|
||||
value
|
||||
});
|
||||
return <SplitAndReplace text={value} replacements={replacements.flatMap(r => r)} />;
|
||||
};
|
||||
|
||||
export default ChangesetDescription;
|
||||
@@ -34,6 +34,7 @@ import ChangesetId from "./ChangesetId";
|
||||
import ChangesetAuthor from "./ChangesetAuthor";
|
||||
import ChangesetTags from "./ChangesetTags";
|
||||
import ChangesetButtonGroup from "./ChangesetButtonGroup";
|
||||
import ChangesetDescription from "./ChangesetDescription";
|
||||
|
||||
type Props = WithTranslation & {
|
||||
repository: Repository;
|
||||
@@ -100,7 +101,7 @@ class ChangesetRow extends React.Component<Props> {
|
||||
<AvatarWrapper>
|
||||
<AvatarFigure className="media-left">
|
||||
<FixedSizedAvatar className="image">
|
||||
<AvatarImage person={changeset.author} />
|
||||
<AvatarImage person={changeset.author}/>
|
||||
</FixedSizedAvatar>
|
||||
</AvatarFigure>
|
||||
</AvatarWrapper>
|
||||
@@ -114,28 +115,28 @@ class ChangesetRow extends React.Component<Props> {
|
||||
}}
|
||||
renderAll={false}
|
||||
>
|
||||
{description.title}
|
||||
<ChangesetDescription changeset={changeset} value={description.title} />
|
||||
</ExtensionPoint>
|
||||
</h4>
|
||||
<p className="is-hidden-touch">
|
||||
<Trans i18nKey="repos:changeset.summary" components={[changesetId, dateFromNow]} />
|
||||
<Trans i18nKey="repos:changeset.summary" components={[changesetId, dateFromNow]}/>
|
||||
</p>
|
||||
<p className="is-hidden-desktop">
|
||||
<Trans i18nKey="repos:changeset.shortSummary" components={[changesetId, dateFromNow]} />
|
||||
<Trans i18nKey="repos:changeset.shortSummary" components={[changesetId, dateFromNow]}/>
|
||||
</p>
|
||||
<AuthorWrapper className="is-size-7 is-ellipsis-overflow">
|
||||
<ChangesetAuthor changeset={changeset} />
|
||||
<ChangesetAuthor changeset={changeset}/>
|
||||
</AuthorWrapper>
|
||||
</Metadata>
|
||||
</div>
|
||||
</div>
|
||||
<VCenteredColumn className="column">
|
||||
<ChangesetTags changeset={changeset} />
|
||||
<ChangesetTags changeset={changeset}/>
|
||||
</VCenteredColumn>
|
||||
</div>
|
||||
</div>
|
||||
<VCenteredChildColumn className={classNames("column", "is-flex")}>
|
||||
<ChangesetButtonGroup repository={repository} changeset={changeset} />
|
||||
<ChangesetButtonGroup repository={repository} changeset={changeset}/>
|
||||
<ExtensionPoint
|
||||
name="changeset.right"
|
||||
props={{
|
||||
|
||||
@@ -28,12 +28,13 @@ import styled from "styled-components";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import repository from "../../__resources__/repository";
|
||||
import ChangesetRow from "./ChangesetRow";
|
||||
import {one, two, three, four} from "../../__resources__/changesets";
|
||||
import {Binder, BinderContext} from "@scm-manager/ui-extensions";
|
||||
import { one, two, three, four, five } from "../../__resources__/changesets";
|
||||
import { Binder, BinderContext } from "@scm-manager/ui-extensions";
|
||||
// @ts-ignore
|
||||
import hitchhiker from "../../__resources__/hitchhiker.png";
|
||||
import {Person} from "../../avatar/Avatar";
|
||||
import {Changeset} from "@scm-manager/ui-types/src";
|
||||
import { Person } from "../../avatar/Avatar";
|
||||
import { Changeset } from "@scm-manager/ui-types";
|
||||
import { Replacement } from "../../SplitAndReplace";
|
||||
|
||||
const Wrapper = styled.div`
|
||||
margin: 2rem;
|
||||
@@ -41,7 +42,7 @@ const Wrapper = styled.div`
|
||||
|
||||
const robohash = (person: Person) => {
|
||||
return `https://robohash.org/${person.mail}`;
|
||||
}
|
||||
};
|
||||
|
||||
const withAvatarFactory = (factory: (person: Person) => string, changeset: Changeset) => {
|
||||
const binder = new Binder("changeset stories");
|
||||
@@ -53,21 +54,23 @@ const withAvatarFactory = (factory: (person: Person) => string, changeset: Chang
|
||||
);
|
||||
};
|
||||
|
||||
const withReplacements = (replacements: Replacement[][], changeset: Changeset) => {
|
||||
const binder = new Binder("changeset stories");
|
||||
replacements.forEach(replacement => binder.bind("changeset.description.tokens", replacement));
|
||||
return (
|
||||
<BinderContext.Provider value={binder}>
|
||||
<ChangesetRow repository={repository} changeset={changeset} />
|
||||
</BinderContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf("Changesets", module)
|
||||
.addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||
.addDecorator(storyFn => <Wrapper className="box box-link-shadow">{storyFn()}</Wrapper>)
|
||||
.add("Default", () => (
|
||||
<ChangesetRow repository={repository} changeset={three} />
|
||||
))
|
||||
.add("With Committer", () => (
|
||||
<ChangesetRow repository={repository} changeset={two} />
|
||||
))
|
||||
.add("With Committer and Co-Author", () => (
|
||||
<ChangesetRow repository={repository} changeset={one} />
|
||||
))
|
||||
.add("With multiple Co-Authors", () => (
|
||||
<ChangesetRow repository={repository} changeset={four} />
|
||||
))
|
||||
.add("Default", () => <ChangesetRow repository={repository} changeset={three} />)
|
||||
.add("With Committer", () => <ChangesetRow repository={repository} changeset={two} />)
|
||||
.add("With Committer and Co-Author", () => <ChangesetRow repository={repository} changeset={one} />)
|
||||
.add("With multiple Co-Authors", () => <ChangesetRow repository={repository} changeset={four} />)
|
||||
.add("With avatar", () => {
|
||||
return withAvatarFactory(person => hitchhiker, three);
|
||||
})
|
||||
@@ -76,4 +79,15 @@ storiesOf("Changesets", module)
|
||||
})
|
||||
.add("Co-Authors with avatar", () => {
|
||||
return withAvatarFactory(robohash, four);
|
||||
})
|
||||
.add("Replacements", () => {
|
||||
const link = <a href={"http://example.com/hog"}>HOG-42</a>;
|
||||
const mail = <a href={"mailto:hog@example.com"}>Arthur</a>;
|
||||
return withReplacements(
|
||||
[
|
||||
[{ textToReplace: "HOG-42", replacement: link }],
|
||||
[{ textToReplace: "arthur@guide.galaxy", replacement: mail }]
|
||||
],
|
||||
five
|
||||
);
|
||||
});
|
||||
|
||||
@@ -27,6 +27,7 @@ export { changesets };
|
||||
|
||||
export { default as ChangesetAuthor, SingleContributor } from "./ChangesetAuthor";
|
||||
export { default as ChangesetButtonGroup } from "./ChangesetButtonGroup";
|
||||
export { default as ChangesetDescription } from "./ChangesetDescription";
|
||||
export { default as ChangesetDiff } from "./ChangesetDiff";
|
||||
export { default as ChangesetId } from "./ChangesetId";
|
||||
export { default as ChangesetList } from "./ChangesetList";
|
||||
|
||||
Reference in New Issue
Block a user