@scm-manager/ui-components 3.10.2 → 3.10.3-20250815-132001
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 +12 -12
- package/src/repos/DiffTypes.ts +14 -2
- package/src/repos/diff/DiffFileTree.tsx +89 -37
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scm-manager/ui-components",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.3-20250815-132001",
|
|
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.
|
|
36
|
-
"@scm-manager/ui-types": "3.10.
|
|
35
|
+
"@scm-manager/ui-tests": "3.10.3-20250815-132001",
|
|
36
|
+
"@scm-manager/ui-types": "3.10.3-20250815-132001",
|
|
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.
|
|
72
|
-
"@scm-manager/ui-shortcuts": "3.10.
|
|
73
|
-
"@scm-manager/ui-text": "3.10.
|
|
71
|
+
"@scm-manager/ui-syntaxhighlighting": "3.10.3-20250815-132001",
|
|
72
|
+
"@scm-manager/ui-shortcuts": "3.10.3-20250815-132001",
|
|
73
|
+
"@scm-manager/ui-text": "3.10.3-20250815-132001"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@scm-manager/ui-core": "3.10.
|
|
77
|
-
"@scm-manager/ui-overlays": "3.10.
|
|
78
|
-
"@scm-manager/ui-layout": "3.10.
|
|
79
|
-
"@scm-manager/ui-buttons": "3.10.
|
|
80
|
-
"@scm-manager/ui-api": "3.10.
|
|
81
|
-
"@scm-manager/ui-extensions": "3.10.
|
|
76
|
+
"@scm-manager/ui-core": "3.10.3-20250815-132001",
|
|
77
|
+
"@scm-manager/ui-overlays": "3.10.3-20250815-132001",
|
|
78
|
+
"@scm-manager/ui-layout": "3.10.3-20250815-132001",
|
|
79
|
+
"@scm-manager/ui-buttons": "3.10.3-20250815-132001",
|
|
80
|
+
"@scm-manager/ui-api": "3.10.3-20250815-132001",
|
|
81
|
+
"@scm-manager/ui-extensions": "3.10.3-20250815-132001",
|
|
82
82
|
"deepmerge": "^4.2.2",
|
|
83
83
|
"hast-util-sanitize": "^3.0.2",
|
|
84
84
|
"react-diff-view": "^2.4.10",
|
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;
|
|
@@ -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
|
};
|