@scm-manager/ui-core 4.0.0-REACT19-20250825-073633 → 4.0.0-REACT19-20250910-124634

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.
Files changed (60) hide show
  1. package/.turbo/turbo-test.log +174 -0
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/package.json +4 -4
  4. package/src/base/buttons/Button.tsx +74 -60
  5. package/src/base/buttons/Icon.tsx +4 -3
  6. package/src/base/forms/ConfigurationForm.tsx +7 -7
  7. package/src/base/forms/FormRow.tsx +9 -9
  8. package/src/base/forms/base/Control.tsx +7 -3
  9. package/src/base/forms/base/ExpandableText.tsx +11 -12
  10. package/src/base/forms/checkbox/Checkbox.tsx +63 -65
  11. package/src/base/forms/checkbox/CheckboxField.tsx +4 -4
  12. package/src/base/forms/chip-input/ChipInputField.tsx +28 -30
  13. package/src/base/forms/chip-input/ControlledChipInputField.tsx +20 -22
  14. package/src/base/forms/combobox/Combobox.tsx +3 -13
  15. package/src/base/forms/combobox/ComboboxField.tsx +11 -14
  16. package/src/base/forms/headless-chip-input/ChipInput.tsx +49 -46
  17. package/src/base/forms/helpers.ts +3 -7
  18. package/src/base/forms/input/Input.tsx +4 -3
  19. package/src/base/forms/input/InputField.tsx +55 -43
  20. package/src/base/forms/input/Textarea.tsx +4 -3
  21. package/src/base/forms/radio-button/RadioButton.tsx +37 -27
  22. package/src/base/forms/radio-button/RadioGroup.tsx +4 -3
  23. package/src/base/forms/radio-button/RadioGroupField.tsx +15 -16
  24. package/src/base/forms/select/Select.tsx +15 -16
  25. package/src/base/forms/select/SelectField.tsx +19 -19
  26. package/src/base/layout/_helpers/with-classes.tsx +15 -12
  27. package/src/base/layout/card/Card.tsx +28 -21
  28. package/src/base/layout/card/CardDetail.tsx +65 -76
  29. package/src/base/layout/card/CardRow.tsx +9 -9
  30. package/src/base/layout/card/CardTitle.tsx +5 -5
  31. package/src/base/layout/card-list/CardList.tsx +9 -9
  32. package/src/base/layout/collapsible/Collapsible.tsx +42 -35
  33. package/src/base/layout/tabs/TabTrigger.tsx +5 -4
  34. package/src/base/layout/tabs/Tabs.tsx +4 -4
  35. package/src/base/layout/tabs/TabsList.tsx +5 -3
  36. package/src/base/layout/templates/data-page/DataPageHeader.tsx +10 -11
  37. package/src/base/misc/Image.tsx +5 -5
  38. package/src/base/misc/Level.tsx +4 -3
  39. package/src/base/misc/Loading.tsx +25 -25
  40. package/src/base/misc/SubSubtitle.tsx +9 -9
  41. package/src/base/misc/Subtitle.tsx +10 -10
  42. package/src/base/misc/Title.tsx +22 -14
  43. package/src/base/notifications/Notification.tsx +12 -13
  44. package/src/base/overlays/dialog/Dialog.tsx +39 -40
  45. package/src/base/overlays/menu/Menu.tsx +49 -52
  46. package/src/base/overlays/menu/MenuTrigger.tsx +6 -6
  47. package/src/base/overlays/popover/Popover.tsx +4 -6
  48. package/src/base/overlays/tooltip/ExpandableHint.tsx +7 -8
  49. package/src/base/overlays/tooltip/Tooltip.tsx +5 -3
  50. package/src/base/status/StatusIcon.tsx +46 -39
  51. package/src/index.ts +1 -0
  52. package/src/routing/admin.ts +38 -0
  53. package/src/routing/group.ts +22 -0
  54. package/src/routing/help.ts +21 -0
  55. package/src/routing/import.ts +17 -0
  56. package/src/routing/index.ts +24 -0
  57. package/src/routing/me.ts +26 -0
  58. package/src/routing/namespace.ts +39 -0
  59. package/src/routing/repository.ts +91 -0
  60. package/src/routing/user.ts +22 -0
@@ -14,7 +14,7 @@
14
14
  * along with this program. If not, see https://www.gnu.org/licenses/.
15
15
  */
16
16
 
17
- import React from "react";
17
+ import React, { FC, Ref } from "react";
18
18
  import classNames from "classnames";
19
19
  import { Icon } from "../buttons";
20
20
 
@@ -47,6 +47,7 @@ type IconProps = React.HTMLProps<HTMLElement> & {
47
47
  color?: string;
48
48
  iconSize?: StatusIconSizeVariant;
49
49
  invert?: boolean;
50
+ ref?: Ref<HTMLElement>;
50
51
  };
51
52
 
52
53
  /**
@@ -54,51 +55,57 @@ type IconProps = React.HTMLProps<HTMLElement> & {
54
55
  * @beta
55
56
  * @since 3.9.0
56
57
  */
57
- const StatusIcon = React.forwardRef<HTMLElement, IconProps>(
58
- ({ color, className, iconSize = StatusIconSizeVariants.MEDIUM, variant, invert = false, children }, ref) => {
59
- const icon = classNames({
60
- "exclamation-triangle": variant === StatusVariants.DANGER,
61
- "check-circle": variant === StatusVariants.SUCCESS,
62
- "hourglass-start": variant === StatusVariants.IN_PROGRESS,
63
- "circle-notch": variant === StatusVariants.UNDEFINED,
64
- });
65
- if (!color) {
66
- if (invert) {
67
- color = classNames({
68
- "icon-color-inverted": variant === StatusVariants.DANGER || StatusVariants.SUCCESS,
69
- "icon-warning-inverted": variant === StatusVariants.WARNING,
70
- "icon-color-inverted-secondary":
71
- variant === StatusVariants.IN_PROGRESS || variant === StatusVariants.UNDEFINED,
72
- });
73
- } else {
74
- color = classNames({
75
- "has-text-danger": variant === StatusVariants.DANGER,
76
- "has-text-success": variant === StatusVariants.SUCCESS,
77
- "has-text-warning": variant === StatusVariants.WARNING,
78
- "icon-color-secondary": variant === StatusVariants.IN_PROGRESS || variant === StatusVariants.UNDEFINED,
79
- });
80
- }
58
+ const StatusIcon: FC<IconProps> = ({
59
+ color,
60
+ className,
61
+ iconSize = StatusIconSizeVariants.MEDIUM,
62
+ variant,
63
+ invert = false,
64
+ children,
65
+ ref,
66
+ }) => {
67
+ const icon = classNames({
68
+ "exclamation-triangle": variant === StatusVariants.DANGER,
69
+ "check-circle": variant === StatusVariants.SUCCESS,
70
+ "hourglass-start": variant === StatusVariants.IN_PROGRESS,
71
+ "circle-notch": variant === StatusVariants.UNDEFINED,
72
+ });
73
+ if (!color) {
74
+ if (invert) {
75
+ color = classNames({
76
+ "icon-color-inverted": variant === StatusVariants.DANGER || StatusVariants.SUCCESS,
77
+ "icon-warning-inverted": variant === StatusVariants.WARNING,
78
+ "icon-color-inverted-secondary": variant === StatusVariants.IN_PROGRESS || variant === StatusVariants.UNDEFINED,
79
+ });
80
+ } else {
81
+ color = classNames({
82
+ "has-text-danger": variant === StatusVariants.DANGER,
83
+ "has-text-success": variant === StatusVariants.SUCCESS,
84
+ "has-text-warning": variant === StatusVariants.WARNING,
85
+ "icon-color-secondary": variant === StatusVariants.IN_PROGRESS || variant === StatusVariants.UNDEFINED,
86
+ });
81
87
  }
82
-
83
- return (
84
- <div className="is-flex is-align-items-center">
85
- {variant === "warning" ? (
86
- <WarningIcon color={color} iconSize={iconSize} className={className}>{`${icon}`}</WarningIcon>
87
- ) : (
88
- <Icon className={className}>{`${icon} ${color} fa-${iconSize}`}</Icon>
89
- )}
90
- {children && <span className="ml-2">{children}</span>}
91
- </div>
92
- );
93
88
  }
94
- );
89
+
90
+ return (
91
+ <div className="is-flex is-align-items-center">
92
+ {variant === "warning" ? (
93
+ <WarningIcon color={color} iconSize={iconSize} className={className} ref={ref}>{`${icon}`}</WarningIcon>
94
+ ) : (
95
+ <Icon className={className} ref={ref}>{`${icon} ${color} fa-${iconSize}`}</Icon>
96
+ )}
97
+ {children && <span className="ml-2">{children}</span>}
98
+ </div>
99
+ );
100
+ };
95
101
 
96
102
  type WarningIconProps = React.HTMLProps<HTMLElement> & {
97
103
  color?: string;
98
104
  iconSize?: string;
105
+ ref?: Ref<HTMLElement>;
99
106
  };
100
107
 
101
- const WarningIcon = React.forwardRef<HTMLElement, WarningIconProps>(({ color, className, iconSize }, ref) => {
108
+ const WarningIcon: FC<WarningIconProps> = ({ color, className, iconSize, ref }) => {
102
109
  return (
103
110
  <span className={classNames(className, "icon", color)} aria-hidden="true" ref={ref}>
104
111
  <svg
@@ -130,6 +137,6 @@ const WarningIcon = React.forwardRef<HTMLElement, WarningIconProps>(({ color, cl
130
137
  </svg>
131
138
  </span>
132
139
  );
133
- });
140
+ };
134
141
 
135
142
  export default StatusIcon;
package/src/index.ts CHANGED
@@ -15,3 +15,4 @@
15
15
  */
16
16
 
17
17
  export * from "./base";
18
+ export * from "./routing";
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ export const ADMIN_BASE_ROUTE = "admin";
18
+
19
+ export const ADMIN_SUB_ROUTES = {
20
+ INFO: "info",
21
+ PLUGINS: "plugins",
22
+ ROLES: "roles",
23
+ ROLE: "role",
24
+ SETTINGS: "settings",
25
+ } as const;
26
+
27
+ export const ADMIN_SETTINGS_SUB_ROUTES = {
28
+ GENERAL: "general",
29
+ } as const;
30
+
31
+ export const ADMIN_ROLES_SUB_ROUTES = {
32
+ CREATE: "create",
33
+ } as const;
34
+
35
+ export const ADMIN_PLUGINS_SUB_ROUTES = {
36
+ INSTALLED: "installed",
37
+ AVAILABLE: "available",
38
+ } as const;
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ export const GROUP_COLLECTION_BASE_ROUTE = "groups";
18
+ export const SINGLE_GROUP_BASE_ROUTE = "group";
19
+
20
+ export const GROUP_COLLECTION_SUB_ROUTES = {
21
+ CREATE: "create",
22
+ } as const;
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ export const HELP_BASE_ROUTE = "help";
18
+
19
+ export const HELP_SUB_ROUTES = {
20
+ SEARCH_SYNTAX: "search-syntax",
21
+ } as const;
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ export const IMPORT_LOG_BASE_ROUTE = "importlog";
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ export * from "./repository";
18
+ export * from "./namespace";
19
+ export * from "./group";
20
+ export * from "./user";
21
+ export * from "./me";
22
+ export * from "./help";
23
+ export * from "./admin";
24
+ export * from "./import";
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ export const ME_BASE_ROUTE = "me";
18
+
19
+ export const ME_SUB_ROUTES = {
20
+ INFO: "info",
21
+ THEME: "settings/theme",
22
+ ACCESSIBILITY: "settings/accessibility",
23
+ PASSWORD: "settings/password",
24
+ PUBLIC_KEYS: "settings/publicKeys",
25
+ API_KEYS: "settings/apiKeys",
26
+ } as const;
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ import { useParams } from "react-router-dom";
18
+ import { useNamespace } from "@scm-manager/ui-api";
19
+
20
+ export const SINGLE_NAMESPACE_BASE_ROUTE = "namespace";
21
+ export const NAMESPACE_SUB_ROUTES = {
22
+ INFO: "info",
23
+ SETTINGS: "settings",
24
+ };
25
+ export const NAMESPACE_SETTINGS_SUB_ROUTES = {
26
+ PERMISSIONS: "permissions",
27
+ };
28
+
29
+ export const useNamespaceFromParams = () => {
30
+ const { namespace: namespaceName } = useParams<{ namespace: string }>();
31
+ if (!namespaceName) {
32
+ throw new Error("No namespace in url");
33
+ }
34
+ const { data: namespace } = useNamespace(namespaceName);
35
+ if (!namespace) {
36
+ throw new Error(`Namespace ${namespace} not found`);
37
+ }
38
+ return namespace;
39
+ };
@@ -0,0 +1,91 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ import { useLocation, useParams } from "react-router-dom";
18
+ import { useRepository } from "@scm-manager/ui-api";
19
+ import { Repository } from "@scm-manager/ui-types";
20
+
21
+ export const REPOSITORY_COLLECTION_BASE_ROUTE = "repos";
22
+ export const SINGLE_REPOSITORY_BASE_ROUTE = "repo";
23
+
24
+ export const REPOSITORY_COLLECTION_SUB_ROUTES = {
25
+ IMPORT: "import",
26
+ CREATE: "create",
27
+ } as const;
28
+
29
+ export const REPOSITORY_SUB_ROUTES = {
30
+ INFO: "info",
31
+ CODE: "code",
32
+ CHANGES: "changes",
33
+ BRANCHES: "branches",
34
+ BRANCH: "branch",
35
+ TAGS: "tags",
36
+ TAG: "tag",
37
+ COMPARE: "compare",
38
+ SEARCH: "search",
39
+ SETTINGS: "settings",
40
+ SOURCEEXT: "sourceext",
41
+ } as const;
42
+
43
+ export const REPOSITORY_CODE_SUB_ROUTES = {
44
+ SOURCES: "sources",
45
+ CHANGESETS: "changesets",
46
+ CHANGESET: "changeset",
47
+ } as const;
48
+
49
+ export const REPOSITORY_BRANCHES_SUB_ROUTES = {
50
+ CREATE: "create",
51
+ } as const;
52
+
53
+ export const REPOSITORY_SETTINGS_SUB_ROUTES = {
54
+ GENERAL: "general",
55
+ PERMISSIONS: "permissions",
56
+ } as const;
57
+
58
+ export const useRepositoryFromParams = () => {
59
+ const { namespace, name } = useParams<{ namespace: string; name: string }>();
60
+ if (!namespace || !name) {
61
+ throw new Error("No namespace or name in url");
62
+ }
63
+ const { data: repository } = useRepository(namespace, name);
64
+ if (!repository) {
65
+ throw new Error(`No repository found for namespace ${namespace} and name ${name}`);
66
+ }
67
+ return repository;
68
+ };
69
+
70
+ export const useBranchFromParams = () => {
71
+ const location = useLocation();
72
+ const branchFromURL =
73
+ !location.pathname.includes("/code/changesets/") && decodeURIComponent(location.pathname.split("/")[6]);
74
+ return branchFromURL && branchFromURL !== "undefined" ? branchFromURL : "";
75
+ };
76
+
77
+ export const useCurrentRepositoryBaseUrl = () => {
78
+ const repository = useRepositoryFromParams();
79
+ return getRepositoryBaseUrl(repository.namespace, repository.name);
80
+ };
81
+
82
+ export function getRepositoryBaseUrl(namespace: string, name: string): string;
83
+ export function getRepositoryBaseUrl(repository: Repository): string;
84
+ export function getRepositoryBaseUrl(arg1: string | Repository, arg2?: string): string {
85
+ if (typeof arg1 === "string" && arg2) {
86
+ return `/repo/${arg1}/${arg2}`;
87
+ } else {
88
+ const repository = arg1 as Repository;
89
+ return `/repo/${repository.namespace}/${repository.name}`;
90
+ }
91
+ }
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright (c) 2020 - present Cloudogu GmbH
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under
5
+ * the terms of the GNU Affero General Public License as published by the Free
6
+ * Software Foundation, version 3.
7
+ *
8
+ * This program is distributed in the hope that it will be useful, but WITHOUT
9
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
+ * details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program. If not, see https://www.gnu.org/licenses/.
15
+ */
16
+
17
+ export const USER_COLLECTION_BASE_ROUTE = "users";
18
+ export const SINGLE_USER_BASE_ROUTE = "user";
19
+
20
+ export const USER_COLLECTION_SUB_ROUTES = {
21
+ CREATE: "create",
22
+ } as const;