@scm-manager/ui-components 3.10.2-20250728-184027 → 3.10.2-20250802-135601
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scm-manager/ui-components",
|
|
3
|
-
"version": "3.10.2-
|
|
3
|
+
"version": "3.10.2-20250802-135601",
|
|
4
4
|
"description": "UI Components for SCM-Manager and its plugins",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"files": [
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"react-query": "^3.39.2"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@scm-manager/ui-tests": "3.10.2-
|
|
36
|
-
"@scm-manager/ui-types": "3.10.2-
|
|
35
|
+
"@scm-manager/ui-tests": "3.10.2-20250802-135601",
|
|
36
|
+
"@scm-manager/ui-types": "3.10.2-20250802-135601",
|
|
37
37
|
"@types/fetch-mock": "^7.3.1",
|
|
38
38
|
"@types/react-select": "^2.0.19",
|
|
39
39
|
"@types/unist": "^2.0.3",
|
|
@@ -68,17 +68,17 @@
|
|
|
68
68
|
"@scm-manager/jest-preset": "^2.14.1",
|
|
69
69
|
"@scm-manager/prettier-config": "^2.12.0",
|
|
70
70
|
"@scm-manager/tsconfig": "^2.13.0",
|
|
71
|
-
"@scm-manager/ui-syntaxhighlighting": "3.10.2-
|
|
72
|
-
"@scm-manager/ui-shortcuts": "3.10.2-
|
|
73
|
-
"@scm-manager/ui-text": "3.10.2-
|
|
71
|
+
"@scm-manager/ui-syntaxhighlighting": "3.10.2-20250802-135601",
|
|
72
|
+
"@scm-manager/ui-shortcuts": "3.10.2-20250802-135601",
|
|
73
|
+
"@scm-manager/ui-text": "3.10.2-20250802-135601"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@scm-manager/ui-core": "3.10.2-
|
|
77
|
-
"@scm-manager/ui-overlays": "3.10.2-
|
|
78
|
-
"@scm-manager/ui-layout": "3.10.2-
|
|
79
|
-
"@scm-manager/ui-buttons": "3.10.2-
|
|
80
|
-
"@scm-manager/ui-api": "3.10.2-
|
|
81
|
-
"@scm-manager/ui-extensions": "3.10.2-
|
|
76
|
+
"@scm-manager/ui-core": "3.10.2-20250802-135601",
|
|
77
|
+
"@scm-manager/ui-overlays": "3.10.2-20250802-135601",
|
|
78
|
+
"@scm-manager/ui-layout": "3.10.2-20250802-135601",
|
|
79
|
+
"@scm-manager/ui-buttons": "3.10.2-20250802-135601",
|
|
80
|
+
"@scm-manager/ui-api": "3.10.2-20250802-135601",
|
|
81
|
+
"@scm-manager/ui-extensions": "3.10.2-20250802-135601",
|
|
82
82
|
"deepmerge": "^4.2.2",
|
|
83
83
|
"hast-util-sanitize": "^3.0.2",
|
|
84
84
|
"react-diff-view": "^2.4.10",
|
|
@@ -20389,7 +20389,7 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
|
|
|
20389
20389
|
className="media-left mt-2 mr-2"
|
|
20390
20390
|
>
|
|
20391
20391
|
<div
|
|
20392
|
-
className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0
|
|
20392
|
+
className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 gwbxYG image"
|
|
20393
20393
|
>
|
|
20394
20394
|
<img
|
|
20395
20395
|
alt="SCM Administrator"
|
|
@@ -20448,6 +20448,7 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
|
|
|
20448
20448
|
<img
|
|
20449
20449
|
alt="Ford Prefect"
|
|
20450
20450
|
className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
|
|
20451
|
+
crossOrigin="anonymous"
|
|
20451
20452
|
src="https://robohash.org/ford.prefect@hitchhiker.com"
|
|
20452
20453
|
/>
|
|
20453
20454
|
</a>
|
|
@@ -20458,6 +20459,7 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
|
|
|
20458
20459
|
<img
|
|
20459
20460
|
alt="Zaphod Beeblebrox"
|
|
20460
20461
|
className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
|
|
20462
|
+
crossOrigin="anonymous"
|
|
20461
20463
|
src="https://robohash.org/zaphod.beeblebrox@hitchhiker.cm"
|
|
20462
20464
|
/>
|
|
20463
20465
|
</a>
|
|
@@ -20468,6 +20470,7 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
|
|
|
20468
20470
|
<img
|
|
20469
20471
|
alt="Tricia Marie McMillan"
|
|
20470
20472
|
className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
|
|
20473
|
+
crossOrigin="anonymous"
|
|
20471
20474
|
src="https://robohash.org/trillian@hitchhiker.cm"
|
|
20472
20475
|
/>
|
|
20473
20476
|
</a>
|
|
@@ -20564,7 +20567,7 @@ exports[`Storyshots Repositories/Changesets Commiter and Co-Authors with avatar
|
|
|
20564
20567
|
className="media-left mt-2 mr-2"
|
|
20565
20568
|
>
|
|
20566
20569
|
<div
|
|
20567
|
-
className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0
|
|
20570
|
+
className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 gwbxYG image"
|
|
20568
20571
|
>
|
|
20569
20572
|
<img
|
|
20570
20573
|
alt="SCM Administrator"
|
|
@@ -20618,6 +20621,7 @@ exports[`Storyshots Repositories/Changesets Commiter and Co-Authors with avatar
|
|
|
20618
20621
|
<img
|
|
20619
20622
|
alt="Zaphod Beeblebrox"
|
|
20620
20623
|
className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
|
|
20624
|
+
crossOrigin="anonymous"
|
|
20621
20625
|
src="https://robohash.org/zaphod.beeblebrox@hitchhiker.cm"
|
|
20622
20626
|
/>
|
|
20623
20627
|
</a>
|
|
@@ -20633,6 +20637,7 @@ exports[`Storyshots Repositories/Changesets Commiter and Co-Authors with avatar
|
|
|
20633
20637
|
<img
|
|
20634
20638
|
alt="Ford Prefect"
|
|
20635
20639
|
className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
|
|
20640
|
+
crossOrigin="anonymous"
|
|
20636
20641
|
src="https://robohash.org/ford.prefect@hitchhiker.com"
|
|
20637
20642
|
/>
|
|
20638
20643
|
</a>
|
|
@@ -21637,7 +21642,7 @@ exports[`Storyshots Repositories/Changesets With avatar 1`] = `
|
|
|
21637
21642
|
className="media-left mt-2 mr-2"
|
|
21638
21643
|
>
|
|
21639
21644
|
<div
|
|
21640
|
-
className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0
|
|
21645
|
+
className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 gwbxYG image"
|
|
21641
21646
|
>
|
|
21642
21647
|
<img
|
|
21643
21648
|
alt="SCM Administrator"
|
package/src/repos/DiffTypes.ts
CHANGED
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { ReactNode } from "react";
|
|
17
|
+
import { FC, ReactNode } from "react";
|
|
18
18
|
import { DefaultCollapsed } from "./defaultCollapsed";
|
|
19
|
-
import { Change, Hunk, FileDiff as File } from "@scm-manager/ui-types";
|
|
19
|
+
import { Change, Hunk, FileDiff as File, FileChangeType } from "@scm-manager/ui-types";
|
|
20
20
|
|
|
21
21
|
export type ChangeEvent = {
|
|
22
22
|
change: Change;
|
|
@@ -31,6 +31,18 @@ export type AnnotationFactoryContext = BaseContext;
|
|
|
31
31
|
|
|
32
32
|
export type FileAnnotationFactory = (file: File) => ReactNode[];
|
|
33
33
|
|
|
34
|
+
export type FileTreeNodeWrapper = FC<{
|
|
35
|
+
name: string;
|
|
36
|
+
path: string;
|
|
37
|
+
changeType?: FileChangeType;
|
|
38
|
+
iconName: string;
|
|
39
|
+
iconColor: string;
|
|
40
|
+
isFile: boolean;
|
|
41
|
+
originalIcon: ReactNode;
|
|
42
|
+
originalLabel: ReactNode;
|
|
43
|
+
isCurrentFile: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
|
|
34
46
|
// key = change id, value = react component
|
|
35
47
|
export type AnnotationFactory = (context: AnnotationFactoryContext) => {
|
|
36
48
|
[key: string]: any;
|
|
@@ -57,11 +57,11 @@ const ContributorWithAvatar: FC<PersonAvatarProps> = ({ person, avatar }) => {
|
|
|
57
57
|
if (person.mail) {
|
|
58
58
|
return (
|
|
59
59
|
<a href={"mailto:" + person.mail} title={t("changeset.contributors.mailto") + " " + person.mail}>
|
|
60
|
-
<ContributorAvatar src={avatar} alt={person.name} />
|
|
60
|
+
<ContributorAvatar src={avatar} alt={person.name} crossOrigin="anonymous" />
|
|
61
61
|
</a>
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
|
-
return <ContributorAvatar src={avatar} alt={person.name} title={person.name} />;
|
|
64
|
+
return <ContributorAvatar src={avatar} alt={person.name} title={person.name} crossOrigin="anonymous" />;
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
export const SingleContributor: FC<PersonProps> = ({ person, className, displayTextOnly }) => {
|
|
@@ -18,12 +18,19 @@ import React, { FC } from "react";
|
|
|
18
18
|
import { Link } from "react-router-dom";
|
|
19
19
|
import { useTranslation } from "react-i18next";
|
|
20
20
|
import classNames from "classnames";
|
|
21
|
-
import { FileTree } from "@scm-manager/ui-types";
|
|
21
|
+
import { FileChangeType, FileTree } from "@scm-manager/ui-types";
|
|
22
22
|
import { FileDiffContent, StackedSpan, StyledIcon } from "./styledElements";
|
|
23
|
+
import { FileTreeNodeWrapper } from "../DiffTypes";
|
|
23
24
|
|
|
24
|
-
type Props = {
|
|
25
|
+
type Props = {
|
|
26
|
+
tree: FileTree;
|
|
27
|
+
currentFile: string;
|
|
28
|
+
setCurrentFile: (path: string) => void;
|
|
29
|
+
gap?: number;
|
|
30
|
+
FileTreeNodeWrapper?: FileTreeNodeWrapper;
|
|
31
|
+
};
|
|
25
32
|
|
|
26
|
-
const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15 }) => {
|
|
33
|
+
const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15, FileTreeNodeWrapper }) => {
|
|
27
34
|
return (
|
|
28
35
|
<FileDiffContent gap={gap}>
|
|
29
36
|
{Object.keys(tree.children).map((key) => (
|
|
@@ -33,6 +40,7 @@ const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15 }
|
|
|
33
40
|
parentPath=""
|
|
34
41
|
currentFile={currentFile}
|
|
35
42
|
setCurrentFile={setCurrentFile}
|
|
43
|
+
FileTreeNodeWrapper={FileTreeNodeWrapper}
|
|
36
44
|
/>
|
|
37
45
|
))}
|
|
38
46
|
</FileDiffContent>
|
|
@@ -41,9 +49,13 @@ const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15 }
|
|
|
41
49
|
|
|
42
50
|
export default DiffFileTree;
|
|
43
51
|
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
type NodeProps = {
|
|
53
|
+
node: FileTree;
|
|
54
|
+
parentPath: string;
|
|
55
|
+
currentFile: string;
|
|
56
|
+
setCurrentFile: (path: string) => void;
|
|
57
|
+
FileTreeNodeWrapper?: FileTreeNodeWrapper;
|
|
58
|
+
};
|
|
47
59
|
|
|
48
60
|
const addPath = (parentPath: string, path: string) => {
|
|
49
61
|
if ("" === parentPath) {
|
|
@@ -52,16 +64,31 @@ const addPath = (parentPath: string, path: string) => {
|
|
|
52
64
|
return parentPath + "/" + path;
|
|
53
65
|
};
|
|
54
66
|
|
|
55
|
-
const TreeNode: FC<NodeProps> = ({ node, parentPath, currentFile, setCurrentFile }) => {
|
|
67
|
+
const TreeNode: FC<NodeProps> = ({ node, parentPath, currentFile, setCurrentFile, FileTreeNodeWrapper }) => {
|
|
56
68
|
const [t] = useTranslation("repos");
|
|
57
69
|
|
|
70
|
+
FileTreeNodeWrapper = FileTreeNodeWrapper || (({ children }) => <>{children}</>);
|
|
71
|
+
|
|
72
|
+
const label = <div className="ml-1">{node.nodeName}</div>;
|
|
73
|
+
const icon = <StyledIcon alt={t("diff.showContent")}>folder</StyledIcon>;
|
|
58
74
|
return (
|
|
59
75
|
<li>
|
|
60
76
|
{Object.keys(node.children).length > 0 ? (
|
|
61
77
|
<ul className="py-1 pl-3">
|
|
62
78
|
<li className="is-flex has-text-grey">
|
|
63
|
-
<
|
|
64
|
-
|
|
79
|
+
<FileTreeNodeWrapper
|
|
80
|
+
path={addPath(parentPath, node.nodeName)}
|
|
81
|
+
isFile={false}
|
|
82
|
+
isCurrentFile={false}
|
|
83
|
+
name={node.nodeName}
|
|
84
|
+
iconName={"folder"}
|
|
85
|
+
iconColor={"grey"}
|
|
86
|
+
originalIcon={icon}
|
|
87
|
+
originalLabel={label}
|
|
88
|
+
>
|
|
89
|
+
{icon}
|
|
90
|
+
{label}
|
|
91
|
+
</FileTreeNodeWrapper>
|
|
65
92
|
</li>
|
|
66
93
|
{Object.keys(node.children).map((key) => (
|
|
67
94
|
<TreeNode
|
|
@@ -70,23 +97,25 @@ const TreeNode: FC<NodeProps> = ({ node, parentPath, currentFile, setCurrentFile
|
|
|
70
97
|
parentPath={addPath(parentPath, node.nodeName)}
|
|
71
98
|
currentFile={currentFile}
|
|
72
99
|
setCurrentFile={setCurrentFile}
|
|
100
|
+
FileTreeNodeWrapper={FileTreeNodeWrapper}
|
|
73
101
|
/>
|
|
74
102
|
))}
|
|
75
103
|
</ul>
|
|
76
104
|
) : (
|
|
77
105
|
<TreeFile
|
|
78
|
-
changeType={node.changeType.toLowerCase() as
|
|
106
|
+
changeType={node.changeType.toLowerCase() as FileChangeType}
|
|
79
107
|
path={node.nodeName}
|
|
80
108
|
parentPath={parentPath}
|
|
81
109
|
currentFile={currentFile}
|
|
82
110
|
setCurrentFile={setCurrentFile}
|
|
111
|
+
FileTreeNodeWrapper={FileTreeNodeWrapper}
|
|
83
112
|
/>
|
|
84
113
|
)}
|
|
85
114
|
</li>
|
|
86
115
|
);
|
|
87
116
|
};
|
|
88
117
|
|
|
89
|
-
const getColor = (changeType:
|
|
118
|
+
const getColor = (changeType: FileChangeType) => {
|
|
90
119
|
switch (changeType) {
|
|
91
120
|
case "add":
|
|
92
121
|
return "success";
|
|
@@ -99,7 +128,7 @@ const getColor = (changeType: ChangeType) => {
|
|
|
99
128
|
}
|
|
100
129
|
};
|
|
101
130
|
|
|
102
|
-
const getIcon = (changeType:
|
|
131
|
+
const getIcon = (changeType: FileChangeType) => {
|
|
103
132
|
switch (changeType) {
|
|
104
133
|
case "add":
|
|
105
134
|
case "copy":
|
|
@@ -113,14 +142,22 @@ const getIcon = (changeType: ChangeType) => {
|
|
|
113
142
|
};
|
|
114
143
|
|
|
115
144
|
type FileProps = {
|
|
116
|
-
changeType:
|
|
145
|
+
changeType: FileChangeType;
|
|
117
146
|
path: string;
|
|
118
147
|
parentPath: string;
|
|
119
148
|
currentFile: string;
|
|
120
149
|
setCurrentFile: (path: string) => void;
|
|
150
|
+
FileTreeNodeWrapper: FileTreeNodeWrapper;
|
|
121
151
|
};
|
|
122
152
|
|
|
123
|
-
const TreeFile: FC<FileProps> = ({
|
|
153
|
+
const TreeFile: FC<FileProps> = ({
|
|
154
|
+
changeType,
|
|
155
|
+
path,
|
|
156
|
+
parentPath,
|
|
157
|
+
currentFile,
|
|
158
|
+
setCurrentFile,
|
|
159
|
+
FileTreeNodeWrapper,
|
|
160
|
+
}) => {
|
|
124
161
|
const [t] = useTranslation("repos");
|
|
125
162
|
const completePath = addPath(parentPath, path);
|
|
126
163
|
|
|
@@ -128,35 +165,50 @@ const TreeFile: FC<FileProps> = ({ changeType, path, parentPath, currentFile, se
|
|
|
128
165
|
return currentFile === completePath;
|
|
129
166
|
};
|
|
130
167
|
|
|
168
|
+
const iconName = getIcon(changeType);
|
|
169
|
+
|
|
170
|
+
const icon = (
|
|
171
|
+
<StackedSpan className="fa-stack">
|
|
172
|
+
<StyledIcon
|
|
173
|
+
className={classNames("fa-stack-2x", `has-text-${getColor(changeType)}`)}
|
|
174
|
+
key={completePath + "file"}
|
|
175
|
+
type="fas"
|
|
176
|
+
alt={t("diff.showContent")}
|
|
177
|
+
>
|
|
178
|
+
file
|
|
179
|
+
</StyledIcon>
|
|
180
|
+
<StyledIcon
|
|
181
|
+
className={classNames("fa-stack-1x", "is-relative", "has-text-secondary-least")}
|
|
182
|
+
isSmaller={iconName === "circle"}
|
|
183
|
+
key={changeType}
|
|
184
|
+
alt={t(`diff.changes.${changeType}`)}
|
|
185
|
+
>
|
|
186
|
+
{iconName}
|
|
187
|
+
</StyledIcon>
|
|
188
|
+
</StackedSpan>
|
|
189
|
+
);
|
|
190
|
+
const label = <div className={classNames("ml-1", isCurrentFile() ? "has-text-weight-bold" : "")}>{path}</div>;
|
|
191
|
+
|
|
131
192
|
return (
|
|
132
193
|
<Link
|
|
133
194
|
className="is-flex py-1 pl-3 has-cursor-pointer"
|
|
134
195
|
onClick={() => setCurrentFile(completePath)}
|
|
135
196
|
to={`#diff-${encodeURIComponent(completePath)}`}
|
|
136
197
|
>
|
|
137
|
-
<
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
)}
|
|
152
|
-
isSmaller={getIcon(changeType) === "circle"}
|
|
153
|
-
key={changeType}
|
|
154
|
-
alt={t(`diff.changes.${changeType}`)}
|
|
155
|
-
>
|
|
156
|
-
{getIcon(changeType)}
|
|
157
|
-
</StyledIcon>
|
|
158
|
-
</StackedSpan>
|
|
159
|
-
<div className="ml-1">{path}</div>
|
|
198
|
+
<FileTreeNodeWrapper
|
|
199
|
+
name={path}
|
|
200
|
+
path={completePath}
|
|
201
|
+
changeType={changeType}
|
|
202
|
+
isFile={true}
|
|
203
|
+
iconName={iconName}
|
|
204
|
+
iconColor={getColor(changeType)}
|
|
205
|
+
originalIcon={icon}
|
|
206
|
+
originalLabel={label}
|
|
207
|
+
isCurrentFile={isCurrentFile()}
|
|
208
|
+
>
|
|
209
|
+
{icon}
|
|
210
|
+
{label}
|
|
211
|
+
</FileTreeNodeWrapper>
|
|
160
212
|
</Link>
|
|
161
213
|
);
|
|
162
214
|
};
|