@scm-manager/ui-components 2.32.2 → 2.32.3-20220229-134553
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/Breadcrumb.tsx +16 -4
- package/src/avatar/Avatar.ts +2 -1
- package/src/avatar/AvatarWrapper.tsx +2 -2
- package/src/layout/Footer.stories.tsx +3 -6
- package/src/layout/Footer.tsx +7 -3
- package/src/markdown/MarkdownCodeRenderer.tsx +6 -5
- package/src/markdown/MarkdownView.stories.tsx +8 -8
- package/src/markdown/markdownExtensions.ts +9 -10
- package/src/navigation/PrimaryNavigation.tsx +8 -9
- package/src/repos/RepositoryAvatar.tsx +3 -3
- package/src/repos/RepositoryEntry.tsx +6 -3
- package/src/repos/RepositoryFlags.tsx +6 -2
- package/src/repos/changesets/ChangesetAuthor.tsx +5 -3
- package/src/repos/changesets/ChangesetDescription.tsx +9 -10
- package/src/repos/changesets/ChangesetRow.tsx +2 -2
- package/src/repos/changesets/SingleChangeset.tsx +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scm-manager/ui-components",
|
|
3
|
-
"version": "2.32.
|
|
3
|
+
"version": "2.32.3-20220229-134553",
|
|
4
4
|
"description": "UI Components for SCM-Manager and its plugins",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"files": [
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@scm-manager/jest-preset": "^2.13.0",
|
|
26
26
|
"@scm-manager/prettier-config": "^2.10.1",
|
|
27
27
|
"@scm-manager/tsconfig": "^2.12.0",
|
|
28
|
-
"@scm-manager/ui-tests": "^2.32.
|
|
28
|
+
"@scm-manager/ui-tests": "^2.32.3-20220229-134553",
|
|
29
29
|
"@storybook/addon-actions": "^6.3.12",
|
|
30
30
|
"@storybook/addon-storyshots": "^6.3.12",
|
|
31
31
|
"@storybook/builder-webpack5": "^6.3.12",
|
|
@@ -66,9 +66,9 @@
|
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"@headlessui/react": "^1.4.3",
|
|
69
|
-
"@scm-manager/ui-api": "^2.32.
|
|
70
|
-
"@scm-manager/ui-extensions": "^2.32.
|
|
71
|
-
"@scm-manager/ui-types": "^2.32.
|
|
69
|
+
"@scm-manager/ui-api": "^2.32.3-20220229-134553",
|
|
70
|
+
"@scm-manager/ui-extensions": "^2.32.3-20220229-134553",
|
|
71
|
+
"@scm-manager/ui-types": "^2.32.3-20220229-134553",
|
|
72
72
|
"classnames": "^2.2.6",
|
|
73
73
|
"date-fns": "^2.4.1",
|
|
74
74
|
"deepmerge": "^4.2.2",
|
package/src/Breadcrumb.tsx
CHANGED
|
@@ -255,13 +255,25 @@ const Breadcrumb: FC<Props> = ({
|
|
|
255
255
|
|
|
256
256
|
const renderExtensionPoints = () => {
|
|
257
257
|
if (
|
|
258
|
-
binder.hasExtension<extensionPoints.ReposSourcesEmptyActionbar>("repos.sources.empty.actionbar") &&
|
|
258
|
+
binder.hasExtension<extensionPoints.ReposSourcesEmptyActionbar>("repos.sources.empty.actionbar", extProps) &&
|
|
259
259
|
sources?._embedded?.children?.length === 0
|
|
260
260
|
) {
|
|
261
|
-
return
|
|
261
|
+
return (
|
|
262
|
+
<ExtensionPoint<extensionPoints.ReposSourcesEmptyActionbar>
|
|
263
|
+
name="repos.sources.empty.actionbar"
|
|
264
|
+
props={{ repository, sources }}
|
|
265
|
+
renderAll={true}
|
|
266
|
+
/>
|
|
267
|
+
);
|
|
262
268
|
}
|
|
263
|
-
if (binder.hasExtension<extensionPoints.ReposSourcesActionbar>("repos.sources.actionbar")) {
|
|
264
|
-
return
|
|
269
|
+
if (binder.hasExtension<extensionPoints.ReposSourcesActionbar>("repos.sources.actionbar", extProps)) {
|
|
270
|
+
return (
|
|
271
|
+
<ExtensionPoint<extensionPoints.ReposSourcesActionbar>
|
|
272
|
+
name="repos.sources.actionbar"
|
|
273
|
+
props={extProps}
|
|
274
|
+
renderAll={true}
|
|
275
|
+
/>
|
|
276
|
+
);
|
|
265
277
|
}
|
|
266
278
|
return null;
|
|
267
279
|
};
|
package/src/avatar/Avatar.ts
CHANGED
|
@@ -23,9 +23,10 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { Person } from "@scm-manager/ui-types";
|
|
26
|
+
import { extensionPoints } from "@scm-manager/ui-extensions";
|
|
26
27
|
|
|
27
28
|
// re export type to avoid breaking changes,
|
|
28
29
|
// after the type was moved to ui-types
|
|
29
30
|
export { Person };
|
|
30
31
|
|
|
31
|
-
export const EXTENSION_POINT = "avatar.factory";
|
|
32
|
+
export const EXTENSION_POINT: extensionPoints.AvatarFactory["name"] = "avatar.factory";
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
import React, { FC } from "react";
|
|
25
|
-
import { useBinder } from "@scm-manager/ui-extensions";
|
|
25
|
+
import { extensionPoints, useBinder } from "@scm-manager/ui-extensions";
|
|
26
26
|
import { EXTENSION_POINT } from "./Avatar";
|
|
27
27
|
|
|
28
28
|
const AvatarWrapper: FC = ({ children }) => {
|
|
29
29
|
const binder = useBinder();
|
|
30
|
-
if (binder.hasExtension(EXTENSION_POINT)) {
|
|
30
|
+
if (binder.hasExtension<extensionPoints.AvatarFactory>(EXTENSION_POINT)) {
|
|
31
31
|
return <>{children}</>;
|
|
32
32
|
}
|
|
33
33
|
return null;
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import React from "react";
|
|
25
25
|
import { storiesOf } from "@storybook/react";
|
|
26
26
|
import Footer from "./Footer";
|
|
27
|
-
import { Binder, BinderContext } from "@scm-manager/ui-extensions";
|
|
27
|
+
import { Binder, BinderContext, extensionPoints } from "@scm-manager/ui-extensions";
|
|
28
28
|
import { Me } from "@scm-manager/ui-types";
|
|
29
29
|
import { EXTENSION_POINT } from "../avatar/Avatar";
|
|
30
30
|
// @ts-ignore ignore unknown png
|
|
@@ -43,11 +43,8 @@ const trillian: Me = {
|
|
|
43
43
|
_links: {},
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
const bindAvatar = (binder: Binder, avatar: string) =>
|
|
47
|
-
binder.bind(EXTENSION_POINT, () =>
|
|
48
|
-
return avatar;
|
|
49
|
-
});
|
|
50
|
-
};
|
|
46
|
+
const bindAvatar = (binder: Binder, avatar: string) =>
|
|
47
|
+
binder.bind<extensionPoints.AvatarFactory>(EXTENSION_POINT, () => avatar);
|
|
51
48
|
|
|
52
49
|
const bindLinks = (binder: Binder) => {
|
|
53
50
|
binder.bind("footer.information", () => <ExternalNavLink to="#" label="REST API" />);
|
package/src/layout/Footer.tsx
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import React, { FC } from "react";
|
|
25
25
|
import { Links, Me } from "@scm-manager/ui-types";
|
|
26
|
-
import { ExtensionPoint, useBinder } from "@scm-manager/ui-extensions";
|
|
26
|
+
import { ExtensionPoint, extensionPoints, useBinder } from "@scm-manager/ui-extensions";
|
|
27
27
|
import { AvatarImage } from "../avatar";
|
|
28
28
|
import NavLink from "../navigation/NavLink";
|
|
29
29
|
import FooterSection from "./FooterSection";
|
|
@@ -84,7 +84,7 @@ const Footer: FC<Props> = ({ me, version, links }) => {
|
|
|
84
84
|
const extensionProps = { me, url: "/me", links };
|
|
85
85
|
let meSectionTile;
|
|
86
86
|
if (me) {
|
|
87
|
-
if (binder.hasExtension(EXTENSION_POINT)) {
|
|
87
|
+
if (binder.hasExtension<extensionPoints.AvatarFactory>(EXTENSION_POINT)) {
|
|
88
88
|
meSectionTile = <TitleWithAvatar me={me} />;
|
|
89
89
|
} else {
|
|
90
90
|
meSectionTile = <TitleWithIcon title={me.displayName} icon="user-circle" />;
|
|
@@ -105,7 +105,11 @@ const Footer: FC<Props> = ({ me, version, links }) => {
|
|
|
105
105
|
<NavLink to="/me/settings/publicKeys" label={t("profile.publicKeysNavLink")} />
|
|
106
106
|
)}
|
|
107
107
|
{me?._links?.apiKeys && <NavLink to="/me/settings/apiKeys" label={t("profile.apiKeysNavLink")} />}
|
|
108
|
-
<ExtensionPoint
|
|
108
|
+
<ExtensionPoint<extensionPoints.ProfileSetting>
|
|
109
|
+
name="profile.setting"
|
|
110
|
+
props={extensionProps}
|
|
111
|
+
renderAll={true}
|
|
112
|
+
/>
|
|
109
113
|
</FooterSection>
|
|
110
114
|
) : null}
|
|
111
115
|
<FooterSection title={<TitleWithIcon title={t("footer.information.title")} icon="info-circle" />}>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
import React, { FC } from "react";
|
|
26
26
|
import SyntaxHighlighter from "../SyntaxHighlighter";
|
|
27
|
-
import { ExtensionPoint, useBinder } from "@scm-manager/ui-extensions";
|
|
27
|
+
import { ExtensionPoint, extensionPoints, useBinder } from "@scm-manager/ui-extensions";
|
|
28
28
|
import { useIndexLinks } from "@scm-manager/ui-api";
|
|
29
29
|
|
|
30
30
|
type Props = {
|
|
@@ -32,14 +32,15 @@ type Props = {
|
|
|
32
32
|
value: string;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
const MarkdownCodeRenderer: FC<Props> =
|
|
35
|
+
const MarkdownCodeRenderer: FC<Props> = props => {
|
|
36
36
|
const binder = useBinder();
|
|
37
37
|
const indexLinks = useIndexLinks();
|
|
38
38
|
const { language } = props;
|
|
39
39
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
const extensionProps = { ...props, indexLinks };
|
|
41
|
+
const extensionKey = `markdown-renderer.code.${language}` as const;
|
|
42
|
+
if (binder.hasExtension<extensionPoints.MarkdownCodeRenderer>(extensionKey, extensionProps)) {
|
|
43
|
+
return <ExtensionPoint<extensionPoints.MarkdownCodeRenderer> name={extensionKey} props={extensionProps} />;
|
|
43
44
|
}
|
|
44
45
|
return <SyntaxHighlighter {...props} />;
|
|
45
46
|
};
|
|
@@ -38,8 +38,8 @@ import MarkdownChangelog from "../__resources__/markdown-changelog.md";
|
|
|
38
38
|
import Title from "../layout/Title";
|
|
39
39
|
import { Subtitle } from "../layout";
|
|
40
40
|
import { MemoryRouter } from "react-router-dom";
|
|
41
|
-
import { Binder, BinderContext } from "@scm-manager/ui-extensions";
|
|
42
|
-
import {
|
|
41
|
+
import { Binder, BinderContext, extensionPoints } from "@scm-manager/ui-extensions";
|
|
42
|
+
import { ProtocolLinkRendererProps } from "./markdownExtensions";
|
|
43
43
|
|
|
44
44
|
const Spacing = styled.div`
|
|
45
45
|
padding: 2em;
|
|
@@ -64,10 +64,10 @@ storiesOf("MarkdownView", module)
|
|
|
64
64
|
))
|
|
65
65
|
.add("Links", () => {
|
|
66
66
|
const binder = new Binder("custom protocol link renderer");
|
|
67
|
-
binder.bind("markdown-renderer.link.protocol", {
|
|
67
|
+
binder.bind<extensionPoints.MarkdownLinkProtocolRenderer<"scw">>("markdown-renderer.link.protocol", {
|
|
68
68
|
protocol: "scw",
|
|
69
69
|
renderer: ProtocolLinkRenderer
|
|
70
|
-
}
|
|
70
|
+
});
|
|
71
71
|
return (
|
|
72
72
|
<BinderContext.Provider value={binder}>
|
|
73
73
|
<MarkdownView content={MarkdownLinks} basePath="/scm/" />
|
|
@@ -76,10 +76,10 @@ storiesOf("MarkdownView", module)
|
|
|
76
76
|
})
|
|
77
77
|
.add("Links without Base Path", () => {
|
|
78
78
|
const binder = new Binder("custom protocol link renderer");
|
|
79
|
-
binder.bind("markdown-renderer.link.protocol", {
|
|
79
|
+
binder.bind<extensionPoints.MarkdownLinkProtocolRenderer<"scw">>("markdown-renderer.link.protocol", {
|
|
80
80
|
protocol: "scw",
|
|
81
81
|
renderer: ProtocolLinkRenderer
|
|
82
|
-
}
|
|
82
|
+
});
|
|
83
83
|
return (
|
|
84
84
|
<BinderContext.Provider value={binder}>
|
|
85
85
|
<MarkdownView content={MarkdownLinks} />
|
|
@@ -107,7 +107,7 @@ storiesOf("MarkdownView", module)
|
|
|
107
107
|
</div>
|
|
108
108
|
);
|
|
109
109
|
};
|
|
110
|
-
binder.bind("markdown-renderer.code.uml", Container);
|
|
110
|
+
binder.bind<extensionPoints.MarkdownCodeRenderer<"uml">>("markdown-renderer.code.uml", Container);
|
|
111
111
|
return (
|
|
112
112
|
<BinderContext.Provider value={binder}>
|
|
113
113
|
<MarkdownView content={MarkdownUmlCodeBlock} />
|
|
@@ -116,7 +116,7 @@ storiesOf("MarkdownView", module)
|
|
|
116
116
|
})
|
|
117
117
|
.add("XSS Prevention", () => <MarkdownView content={MarkdownXss} skipHtml={false} />);
|
|
118
118
|
|
|
119
|
-
export const ProtocolLinkRenderer: FC<ProtocolLinkRendererProps
|
|
119
|
+
export const ProtocolLinkRenderer: FC<ProtocolLinkRendererProps<"scw">> = ({ protocol, href, children }) => {
|
|
120
120
|
return (
|
|
121
121
|
<div style={{ border: "1px dashed lightgray", padding: "2px" }}>
|
|
122
122
|
<h4>
|
|
@@ -21,18 +21,17 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
import {
|
|
24
|
+
import { extensionPoints, ExtractProps } from "@scm-manager/ui-extensions";
|
|
25
25
|
|
|
26
|
-
export type ProtocolLinkRendererProps =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
26
|
+
export type ProtocolLinkRendererProps<Protocol extends string | undefined = undefined> = ExtractProps<
|
|
27
|
+
extensionPoints.MarkdownLinkProtocolRenderer<Protocol>["type"]["renderer"]
|
|
28
|
+
>;
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated use {@link MarkdownLinkProtocolRenderer}`["type"]` instead
|
|
32
|
+
*/
|
|
33
|
+
export type ProtocolLinkRendererExtension = extensionPoints.MarkdownLinkProtocolRenderer["type"];
|
|
35
34
|
|
|
36
35
|
export type ProtocolLinkRendererExtensionMap = {
|
|
37
|
-
[protocol: string]:
|
|
36
|
+
[protocol: string]: extensionPoints.MarkdownLinkProtocolRenderer["type"]["renderer"] | undefined;
|
|
38
37
|
};
|
|
@@ -24,9 +24,7 @@
|
|
|
24
24
|
import React, { FC, ReactNode } from "react";
|
|
25
25
|
import PrimaryNavigationLink from "./PrimaryNavigationLink";
|
|
26
26
|
import { Links } from "@scm-manager/ui-types";
|
|
27
|
-
import { binder, ExtensionPoint } from "@scm-manager/ui-extensions";
|
|
28
|
-
import { urls } from "@scm-manager/ui-api";
|
|
29
|
-
import { useLocation } from "react-router-dom";
|
|
27
|
+
import { binder, ExtensionPoint, extensionPoints } from "@scm-manager/ui-extensions";
|
|
30
28
|
import { useTranslation } from "react-i18next";
|
|
31
29
|
|
|
32
30
|
type Props = {
|
|
@@ -37,7 +35,6 @@ type Appender = (to: string, match: string, label: string, linkName: string) =>
|
|
|
37
35
|
|
|
38
36
|
const PrimaryNavigation: FC<Props> = ({ links }) => {
|
|
39
37
|
const [t] = useTranslation("commons");
|
|
40
|
-
const location = useLocation();
|
|
41
38
|
|
|
42
39
|
const createNavigationAppender = (navItems: ReactNode[]): Appender => {
|
|
43
40
|
return (to: string, match: string, label: string, linkName: string) => {
|
|
@@ -63,13 +60,15 @@ const PrimaryNavigation: FC<Props> = ({ links }) => {
|
|
|
63
60
|
|
|
64
61
|
const extensionProps = {
|
|
65
62
|
links,
|
|
66
|
-
label: t("primary-navigation.first-menu")
|
|
63
|
+
label: t("primary-navigation.first-menu")
|
|
67
64
|
};
|
|
68
65
|
|
|
69
66
|
const append = createNavigationAppender(navItems);
|
|
70
|
-
if (
|
|
67
|
+
if (
|
|
68
|
+
binder.hasExtension<extensionPoints.PrimaryNavigationFirstMenu>("primary-navigation.first-menu", extensionProps)
|
|
69
|
+
) {
|
|
71
70
|
navItems.push(
|
|
72
|
-
<ExtensionPoint
|
|
71
|
+
<ExtensionPoint<extensionPoints.PrimaryNavigationFirstMenu>
|
|
73
72
|
key="primary-navigation.first-menu"
|
|
74
73
|
name="primary-navigation.first-menu"
|
|
75
74
|
props={extensionProps}
|
|
@@ -82,12 +81,12 @@ const PrimaryNavigation: FC<Props> = ({ links }) => {
|
|
|
82
81
|
append("/admin", "/admin", "primary-navigation.admin", "config");
|
|
83
82
|
|
|
84
83
|
navItems.push(
|
|
85
|
-
<ExtensionPoint
|
|
84
|
+
<ExtensionPoint<extensionPoints.PrimaryNavigation>
|
|
86
85
|
key="primary-navigation"
|
|
87
86
|
name="primary-navigation"
|
|
88
87
|
renderAll={true}
|
|
89
88
|
props={{
|
|
90
|
-
links
|
|
89
|
+
links
|
|
91
90
|
}}
|
|
92
91
|
/>
|
|
93
92
|
);
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
import React, { FC } from "react";
|
|
25
|
-
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
|
25
|
+
import { ExtensionPoint, extensionPoints } from "@scm-manager/ui-extensions";
|
|
26
26
|
import { Repository } from "@scm-manager/ui-types";
|
|
27
27
|
import { Image } from "@scm-manager/ui-components";
|
|
28
28
|
import styled from "styled-components";
|
|
@@ -38,13 +38,13 @@ type Props = {
|
|
|
38
38
|
|
|
39
39
|
const renderExtensionPoint = (repository: Repository) => {
|
|
40
40
|
return (
|
|
41
|
-
<ExtensionPoint
|
|
41
|
+
<ExtensionPoint<extensionPoints.PrimaryRepositoryAvatar>
|
|
42
42
|
name="repos.repository-avatar.primary"
|
|
43
43
|
props={{
|
|
44
44
|
repository,
|
|
45
45
|
}}
|
|
46
46
|
>
|
|
47
|
-
<ExtensionPoint
|
|
47
|
+
<ExtensionPoint<extensionPoints.RepositoryAvatar>
|
|
48
48
|
name="repos.repository-avatar"
|
|
49
49
|
props={{
|
|
50
50
|
repository,
|
|
@@ -25,7 +25,7 @@ import React, { FC, useState } from "react";
|
|
|
25
25
|
import { Repository } from "@scm-manager/ui-types";
|
|
26
26
|
import { DateFromNow, Modal } from "@scm-manager/ui-components";
|
|
27
27
|
import RepositoryAvatar from "./RepositoryAvatar";
|
|
28
|
-
import { binder, ExtensionPoint } from "@scm-manager/ui-extensions";
|
|
28
|
+
import { binder, ExtensionPoint, extensionPoints } from "@scm-manager/ui-extensions";
|
|
29
29
|
import GroupEntry from "../layout/GroupEntry";
|
|
30
30
|
import RepositoryFlags from "./RepositoryFlags";
|
|
31
31
|
import styled from "styled-components";
|
|
@@ -103,7 +103,7 @@ const RepositoryEntry: FC<Props> = ({ repository, baseDate }) => {
|
|
|
103
103
|
active={openCloneModal}
|
|
104
104
|
title={t("overview.clone")}
|
|
105
105
|
body={
|
|
106
|
-
<ExtensionPoint
|
|
106
|
+
<ExtensionPoint<extensionPoints.RepositoryDetailsInformation>
|
|
107
107
|
name="repos.repository-details.information"
|
|
108
108
|
renderAll={true}
|
|
109
109
|
props={{
|
|
@@ -144,7 +144,10 @@ const RepositoryEntry: FC<Props> = ({ repository, baseDate }) => {
|
|
|
144
144
|
const actions = createContentRight();
|
|
145
145
|
const name = (
|
|
146
146
|
<div className="is-flex">
|
|
147
|
-
<ExtensionPoint
|
|
147
|
+
<ExtensionPoint<extensionPoints.RepositoryCardBeforeTitle>
|
|
148
|
+
name="repository.card.beforeTitle"
|
|
149
|
+
props={{ repository }}
|
|
150
|
+
/>
|
|
148
151
|
<Name>{repository.name}</Name> <RepositoryFlags repository={repository} className="is-hidden-mobile" />
|
|
149
152
|
</div>
|
|
150
153
|
);
|
|
@@ -26,7 +26,7 @@ import { useTranslation } from "react-i18next";
|
|
|
26
26
|
import classNames from "classnames";
|
|
27
27
|
import styled from "styled-components";
|
|
28
28
|
import { Repository } from "@scm-manager/ui-types";
|
|
29
|
-
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
|
29
|
+
import { ExtensionPoint, extensionPoints } from "@scm-manager/ui-extensions";
|
|
30
30
|
import { TooltipLocation } from "../Tooltip";
|
|
31
31
|
import RepositoryFlag from "./RepositoryFlag";
|
|
32
32
|
import HealthCheckFailureDetail from "./HealthCheckFailureDetail";
|
|
@@ -90,7 +90,11 @@ const RepositoryFlags: FC<Props> = ({ repository, className, tooltipLocation = "
|
|
|
90
90
|
{modal}
|
|
91
91
|
<RepositoryFlagContainer>
|
|
92
92
|
{repositoryFlags}
|
|
93
|
-
<ExtensionPoint
|
|
93
|
+
<ExtensionPoint<extensionPoints.RepositoryFlags>
|
|
94
|
+
name="repository.flags"
|
|
95
|
+
props={{ repository, tooltipLocation }}
|
|
96
|
+
renderAll={true}
|
|
97
|
+
/>
|
|
94
98
|
</RepositoryFlagContainer>
|
|
95
99
|
</div>
|
|
96
100
|
);
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import React, { FC } from "react";
|
|
25
25
|
import { Changeset, Person } from "@scm-manager/ui-types";
|
|
26
26
|
import { useTranslation } from "react-i18next";
|
|
27
|
-
import { useBinder } from "@scm-manager/ui-extensions";
|
|
27
|
+
import { extensionPoints, useBinder } from "@scm-manager/ui-extensions";
|
|
28
28
|
import { EXTENSION_POINT } from "../../avatar/Avatar";
|
|
29
29
|
import styled from "styled-components";
|
|
30
30
|
import CommaSeparatedList from "../../CommaSeparatedList";
|
|
@@ -42,7 +42,7 @@ type PersonProps = {
|
|
|
42
42
|
|
|
43
43
|
const useAvatar = (person: Person): string | undefined => {
|
|
44
44
|
const binder = useBinder();
|
|
45
|
-
const factory
|
|
45
|
+
const factory = binder.getExtension<extensionPoints.AvatarFactory>(EXTENSION_POINT);
|
|
46
46
|
if (factory) {
|
|
47
47
|
return factory(person);
|
|
48
48
|
}
|
|
@@ -171,7 +171,9 @@ const ChangesetAuthor: FC<Props> = ({ changeset }) => {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
// extensions
|
|
174
|
-
const extensions = binder.getExtensions("changesets.author.suffix", {
|
|
174
|
+
const extensions = binder.getExtensions<extensionPoints.ChangesetsAuthorSuffix>("changesets.author.suffix", {
|
|
175
|
+
changeset
|
|
176
|
+
});
|
|
175
177
|
if (extensions) {
|
|
176
178
|
authorLine.push(...extensions);
|
|
177
179
|
}
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
|
|
25
25
|
import React, { FC } from "react";
|
|
26
26
|
import { Changeset } from "@scm-manager/ui-types";
|
|
27
|
-
import { useBinder } from "@scm-manager/ui-extensions";
|
|
28
|
-
import {
|
|
27
|
+
import { extensionPoints, useBinder } from "@scm-manager/ui-extensions";
|
|
28
|
+
import { Replacement, SplitAndReplace } from "@scm-manager/ui-components";
|
|
29
29
|
|
|
30
30
|
type Props = {
|
|
31
31
|
changeset: Changeset;
|
|
@@ -35,15 +35,14 @@ type Props = {
|
|
|
35
35
|
const ChangesetDescription: FC<Props> = ({ changeset, value }) => {
|
|
36
36
|
const binder = useBinder();
|
|
37
37
|
|
|
38
|
-
const replacements: ((changeset: Changeset, value: string) => Replacement[])[] = binder.getExtensions
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
);
|
|
38
|
+
const replacements: ((changeset: Changeset, value: string) => Replacement[])[] = binder.getExtensions<
|
|
39
|
+
extensionPoints.ChangesetDescriptionTokens
|
|
40
|
+
>("changeset.description.tokens", {
|
|
41
|
+
changeset,
|
|
42
|
+
value
|
|
43
|
+
});
|
|
45
44
|
|
|
46
|
-
return <SplitAndReplace text={value} replacements={replacements.flatMap(
|
|
45
|
+
return <SplitAndReplace text={value} replacements={replacements.flatMap(r => r(changeset, value))} />;
|
|
47
46
|
};
|
|
48
47
|
|
|
49
48
|
export default ChangesetDescription;
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import React, { FC } from "react";
|
|
25
25
|
import classNames from "classnames";
|
|
26
26
|
import styled from "styled-components";
|
|
27
|
-
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
|
27
|
+
import { ExtensionPoint, extensionPoints } from "@scm-manager/ui-extensions";
|
|
28
28
|
import { Changeset, File, Repository } from "@scm-manager/ui-types";
|
|
29
29
|
import ChangesetButtonGroup from "./ChangesetButtonGroup";
|
|
30
30
|
import SingleChangeset from "./SingleChangeset";
|
|
@@ -54,7 +54,7 @@ const ChangesetRow: FC<Props> = ({ repository, changeset, file }) => {
|
|
|
54
54
|
</div>
|
|
55
55
|
<div className={classNames("column", "is-flex", "is-justify-content-flex-end", "is-align-items-center")}>
|
|
56
56
|
<ChangesetButtonGroup repository={repository} changeset={changeset} file={file} />
|
|
57
|
-
<ExtensionPoint
|
|
57
|
+
<ExtensionPoint<extensionPoints.ChangesetRight>
|
|
58
58
|
name="changeset.right"
|
|
59
59
|
props={{
|
|
60
60
|
repository,
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import React, { FC } from "react";
|
|
25
25
|
import classNames from "classnames";
|
|
26
26
|
import { AvatarImage, AvatarWrapper } from "../../avatar";
|
|
27
|
-
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
|
27
|
+
import { ExtensionPoint, extensionPoints } from "@scm-manager/ui-extensions";
|
|
28
28
|
import ChangesetDescription from "./ChangesetDescription";
|
|
29
29
|
import { Trans } from "react-i18next";
|
|
30
30
|
import ChangesetAuthor from "./ChangesetAuthor";
|
|
@@ -72,7 +72,7 @@ const SingleChangeset: FC<Props> = ({ repository, changeset }) => {
|
|
|
72
72
|
</AvatarWrapper>
|
|
73
73
|
<FullWidthDiv className={classNames("media-right", "ml-0")}>
|
|
74
74
|
<h4 className={classNames("has-text-weight-bold", "is-ellipsis-overflow")}>
|
|
75
|
-
<ExtensionPoint
|
|
75
|
+
<ExtensionPoint<extensionPoints.ChangesetDescription>
|
|
76
76
|
name="changeset.description"
|
|
77
77
|
props={{
|
|
78
78
|
changeset,
|