@camunda/camunda-composite-components 0.6.4 → 0.7.0
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/lib/esm/package.json +17 -17
- package/lib/esm/src/api/api.d.ts +7 -1
- package/lib/esm/src/api/api.js +18 -14
- package/lib/esm/src/api/help-center.d.ts +7 -7
- package/lib/esm/src/api/notifications.d.ts +2 -1
- package/lib/esm/src/api/organizations.d.ts +7 -1
- package/lib/esm/src/api/organizations.js +5 -0
- package/lib/esm/src/api/profile.d.ts +3 -2
- package/lib/esm/src/components/c3-app-teaser/c3-app-teaser-page.js +3 -3
- package/lib/esm/src/components/c3-empty-state/c3-empty-state.js +1 -1
- package/lib/esm/src/components/c3-help-center/c3-help-center.js +1 -1
- package/lib/esm/src/components/c3-help-center/help-center.js +19 -12
- package/lib/esm/src/components/c3-help-center/styles.d.ts +0 -1
- package/lib/esm/src/components/c3-help-center/tabs/feedback.js +7 -9
- package/lib/esm/src/components/c3-navigation/c3-navigation-appbar/c3-navigation-appbar.js +8 -2
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar-element.d.ts +1 -0
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar-element.js +50 -22
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.js +37 -7
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.types.d.ts +1 -0
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-notification-sidebar.js +2 -2
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-sidebar-state-provider.d.ts +2 -0
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-sidebar-state-provider.js +24 -3
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/components.d.ts +0 -1
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/components.js +1 -0
- package/lib/esm/src/components/c3-navigation/c3-navigation.js +37 -10
- package/lib/esm/src/components/c3-navigation/c3-navigation.types.d.ts +5 -2
- package/lib/esm/src/components/c3-navigation/c3-notification-provider/c3-notification-provider.js +8 -6
- package/lib/esm/src/components/c3-navigation/{c3-navigation-sidebar → c3-org-sidebar}/c3-org-sidebar.d.ts +1 -1
- package/lib/esm/src/components/c3-navigation/c3-org-sidebar/c3-org-sidebar.js +125 -0
- package/lib/esm/src/components/c3-navigation/c3-org-sidebar/components.d.ts +24 -0
- package/lib/esm/src/components/c3-navigation/c3-org-sidebar/components.js +64 -0
- package/lib/esm/src/components/c3-navigation/helpers.d.ts +7 -1
- package/lib/esm/src/components/c3-navigation/helpers.js +1 -1
- package/lib/esm/src/components/c3-navigation/stories/story-helpers.d.ts +3 -1
- package/lib/esm/src/components/c3-navigation/stories/story-helpers.js +8 -9
- package/lib/esm/src/components/c3-onboarding-survey/c3-onboarding-survey.js +3 -2
- package/lib/esm/src/components/c3-onboarding-survey/elements/radioGroupSingle.js +7 -5
- package/lib/esm/src/components/c3-onboarding-survey/onboardingModal.d.ts +0 -1
- package/lib/esm/src/components/c3-onboarding-survey/onboardingModal.js +4 -3
- package/lib/esm/src/components/c3-user-configuration/c3-profile-provider/c3-profile-provider.d.ts +1 -0
- package/lib/esm/src/components/c3-user-configuration/c3-profile-provider/c3-profile-provider.js +12 -4
- package/lib/esm/src/utils/camunda.types.d.ts +13 -8
- package/package.json +17 -17
- package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-org-sidebar.js +0 -85
package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-sidebar-state-provider.js
CHANGED
|
@@ -2,17 +2,38 @@ import React, { useContext, useState } from "react";
|
|
|
2
2
|
export const C3SidebarStateContext = React.createContext(null);
|
|
3
3
|
export const C3SidebarStateProvider = ({ children, ...value }) => {
|
|
4
4
|
const [isNotificationSidebarOpen, setIsNotificationSidebarOpen] = useState(value.isNotificationSidebarOpen || false);
|
|
5
|
+
const [notificationScrollBarWidth, setNotificationScrollBarWidth] = useState(0);
|
|
5
6
|
const [isOrgSidebarOpen, setIsOrgSidebarOpen] = useState(value.isOrgSidebarOpen || false);
|
|
7
|
+
const [orgScrollBarWidth, setOrgScrollBarWidth] = useState(0);
|
|
6
8
|
const [isInfoSidebarOpen, setIsInfoSidebarOpen] = useState(value.isInfoSidebarOpen || false);
|
|
9
|
+
const [infoScrollBarWidth, setInfoScrollBarWidth] = useState(0);
|
|
7
10
|
const [isUserSidebarOpen, setIsUserSidebarOpen] = useState(value.isUserSidebarOpen || false);
|
|
11
|
+
const [userScrollBarWidth, setUserScrollBarWidth] = useState(0);
|
|
8
12
|
return (React.createElement(C3SidebarStateContext.Provider, { value: {
|
|
9
13
|
notifications: {
|
|
10
14
|
isOpen: isNotificationSidebarOpen,
|
|
11
15
|
setIsOpen: setIsNotificationSidebarOpen,
|
|
16
|
+
scrollBarWidth: notificationScrollBarWidth,
|
|
17
|
+
setScrollBarWidth: setNotificationScrollBarWidth,
|
|
18
|
+
},
|
|
19
|
+
org: {
|
|
20
|
+
isOpen: isOrgSidebarOpen,
|
|
21
|
+
setIsOpen: setIsOrgSidebarOpen,
|
|
22
|
+
scrollBarWidth: orgScrollBarWidth,
|
|
23
|
+
setScrollBarWidth: setOrgScrollBarWidth,
|
|
24
|
+
},
|
|
25
|
+
info: {
|
|
26
|
+
isOpen: isInfoSidebarOpen,
|
|
27
|
+
setIsOpen: setIsInfoSidebarOpen,
|
|
28
|
+
scrollBarWidth: infoScrollBarWidth,
|
|
29
|
+
setScrollBarWidth: setInfoScrollBarWidth,
|
|
30
|
+
},
|
|
31
|
+
user: {
|
|
32
|
+
isOpen: isUserSidebarOpen,
|
|
33
|
+
setIsOpen: setIsUserSidebarOpen,
|
|
34
|
+
scrollBarWidth: userScrollBarWidth,
|
|
35
|
+
setScrollBarWidth: setUserScrollBarWidth,
|
|
12
36
|
},
|
|
13
|
-
org: { isOpen: isOrgSidebarOpen, setIsOpen: setIsOrgSidebarOpen },
|
|
14
|
-
info: { isOpen: isInfoSidebarOpen, setIsOpen: setIsInfoSidebarOpen },
|
|
15
|
-
user: { isOpen: isUserSidebarOpen, setIsOpen: setIsUserSidebarOpen },
|
|
16
37
|
} }, children));
|
|
17
38
|
};
|
|
18
39
|
export const useSidebarState = () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Header, HeaderContainer, HeaderGlobalBar, HeaderMenuItem, HeaderName, HeaderNavigation, SkipToContent, Tag, Toggletip, ToggletipButton, ToggletipContent, Stack as CarbonStack, } from "@carbon/react";
|
|
1
|
+
import { Header, HeaderContainer, HeaderGlobalBar, HeaderMenuItem, HeaderName, HeaderNavigation, SkipToContent, Tag, Toggletip, ToggletipButton, ToggletipContent, Stack as CarbonStack, Link, } from "@carbon/react";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import C3InfoSidebar from "./c3-navigation-sidebar/c3-info-sidebar";
|
|
4
4
|
import { C3NotificationSidebar } from "./c3-navigation-sidebar/c3-notification-sidebar";
|
|
5
|
-
import C3OrgSidebar from "./c3-
|
|
5
|
+
import C3OrgSidebar from "./c3-org-sidebar/c3-org-sidebar";
|
|
6
6
|
import C3UserSidebar from "./c3-navigation-sidebar/c3-user-sidebar";
|
|
7
7
|
import { useMediaQuery } from "./helpers";
|
|
8
8
|
import { C3NavigationAppBar } from "./c3-navigation-appbar/c3-navigation-appbar";
|
|
@@ -41,6 +41,8 @@ const ClusterTagWrapper = styled.div `
|
|
|
41
41
|
padding: 0 1rem;
|
|
42
42
|
}
|
|
43
43
|
`;
|
|
44
|
+
const NON_PRODUCTION_TERMS_LINK = "https://legal.camunda.com/#self-managed-non-production-terms";
|
|
45
|
+
const SALES_CONTACT_LINK = "https://camunda.com/contact/";
|
|
44
46
|
export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, infoSideBar, infoButton, helpCenter, actionButtons, userSideBar, notificationSideBar, clusterUuid, options, }) => {
|
|
45
47
|
const { openHelpCenter } = useC3HelpCenter();
|
|
46
48
|
const { currentClusterUuid } = useC3UserConfiguration();
|
|
@@ -51,6 +53,34 @@ export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, info
|
|
|
51
53
|
appBar.appTeaserRouteProps ||
|
|
52
54
|
(!isLargeScreen && navbar.elements.length > 0);
|
|
53
55
|
const orgName = activeOrg?.name || navbar.orgName;
|
|
56
|
+
const tags = [
|
|
57
|
+
...(navbar.tags || []),
|
|
58
|
+
...(navbar.licenseTag?.show
|
|
59
|
+
? [
|
|
60
|
+
{
|
|
61
|
+
key: "license-tag",
|
|
62
|
+
label: navbar.licenseTag.isProductionLicense
|
|
63
|
+
? "Production license"
|
|
64
|
+
: "Non-production license",
|
|
65
|
+
color: "gray",
|
|
66
|
+
tooltip: navbar.licenseTag.isProductionLicense
|
|
67
|
+
? undefined
|
|
68
|
+
: {
|
|
69
|
+
content: (React.createElement("p", null,
|
|
70
|
+
"Non-production license. For production usage details, visit our",
|
|
71
|
+
" ",
|
|
72
|
+
React.createElement(Link, { href: NON_PRODUCTION_TERMS_LINK, target: "_blank", style: { display: "inline" } }, "terms & conditions page"),
|
|
73
|
+
" ",
|
|
74
|
+
"or",
|
|
75
|
+
" ",
|
|
76
|
+
React.createElement(Link, { href: SALES_CONTACT_LINK, target: "_blank", style: { display: "inline" } }, "contact our sales team"),
|
|
77
|
+
".")),
|
|
78
|
+
buttonLabel: "Learn more",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
]
|
|
82
|
+
: []),
|
|
83
|
+
];
|
|
54
84
|
if (app.prefix)
|
|
55
85
|
console.warn("The `prefix` prop is deprecated and will be removed in a future release. It has been replaced with a Camunda icon.");
|
|
56
86
|
return (React.createElement(C3SidebarStateProvider, { isNotificationSidebarOpen: notificationSideBar?.isOpen, isOrgSidebarOpen: orgSideBar?.isOpen, isInfoSidebarOpen: infoSideBar?.isOpen, isUserSidebarOpen: userSideBar?.isOpen },
|
|
@@ -71,21 +101,19 @@ export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, info
|
|
|
71
101
|
gap: ".5rem",
|
|
72
102
|
paddingRight: ".5rem",
|
|
73
103
|
} },
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
tags &&
|
|
105
|
+
tags.length > 0 &&
|
|
106
|
+
tags.map((tag) => {
|
|
77
107
|
if (tag?.tooltip !== undefined) {
|
|
78
108
|
const { content, buttonLabel } = tag.tooltip;
|
|
79
109
|
return (React.createElement("div", { key: tag.key, style: {
|
|
80
110
|
height: "1.5rem",
|
|
81
|
-
marginTop: "0.
|
|
111
|
+
marginTop: "0.75rem",
|
|
82
112
|
} },
|
|
83
113
|
React.createElement(Toggletip, null,
|
|
84
114
|
React.createElement(ToggletipButton, { label: buttonLabel },
|
|
85
115
|
React.createElement(Tag, { type: tag.color, style: {
|
|
86
|
-
|
|
87
|
-
marginRight: 0,
|
|
88
|
-
marginLeft: 0,
|
|
116
|
+
margin: "0",
|
|
89
117
|
cursor: "pointer",
|
|
90
118
|
} }, tag.label)),
|
|
91
119
|
React.createElement(StyledToggletipContent, null, content))));
|
|
@@ -93,7 +121,6 @@ export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, info
|
|
|
93
121
|
return (React.createElement(Tag, { key: tag.key, style: {
|
|
94
122
|
height: "1.5rem",
|
|
95
123
|
marginTop: "0.75rem",
|
|
96
|
-
padding: "0 1rem",
|
|
97
124
|
}, type: tag.color }, tag.label));
|
|
98
125
|
}),
|
|
99
126
|
(clusterUuid || currentClusterUuid) && (React.createElement(ClusterTagWrapper, null,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/// <reference path="../../../../../src/carbon.d.ts" />
|
|
2
|
-
/// <reference types="react" />
|
|
3
1
|
import { Tag } from "@carbon/react";
|
|
4
2
|
import { Endpoints, Stage } from "../../api/endpoints.const";
|
|
5
3
|
import { C3NavigationAppBarProps, C3NavigationInfoSideBarProps, C3NavigationNotificationsSideBarProps, C3NavigationOrgSideBarProps, C3NavigationUserSideBarProps } from "./c3-navigation-sidebar/c3-navigation-sidebar.types";
|
|
@@ -26,6 +24,7 @@ export interface C3NavigationElementProps {
|
|
|
26
24
|
onClick?: () => void;
|
|
27
25
|
subElements?: C3NavigationElementProps[];
|
|
28
26
|
preceedingDivider?: boolean;
|
|
27
|
+
overflowMenu?: React.ReactNode;
|
|
29
28
|
}
|
|
30
29
|
export interface C3NavigationNavBarProps {
|
|
31
30
|
elements: Array<{
|
|
@@ -43,6 +42,10 @@ export interface C3NavigationNavBarProps {
|
|
|
43
42
|
buttonLabel: string;
|
|
44
43
|
};
|
|
45
44
|
}>;
|
|
45
|
+
licenseTag?: {
|
|
46
|
+
show: boolean;
|
|
47
|
+
isProductionLicense: boolean;
|
|
48
|
+
};
|
|
46
49
|
orgName?: string;
|
|
47
50
|
}
|
|
48
51
|
export interface C3NotificationsProps {
|
package/lib/esm/src/components/c3-navigation/c3-notification-provider/c3-notification-provider.js
CHANGED
|
@@ -24,8 +24,9 @@ const C3NotificationProvider = ({ children, }) => {
|
|
|
24
24
|
setNotifications([]);
|
|
25
25
|
}
|
|
26
26
|
if (enabled && !isFetched && config.userToken) {
|
|
27
|
-
NotificationService.getNotifications(config).then((
|
|
28
|
-
|
|
27
|
+
NotificationService.getNotifications(config).then(({ result }) => {
|
|
28
|
+
if (result)
|
|
29
|
+
setNotifications(result);
|
|
29
30
|
setFetched(true);
|
|
30
31
|
});
|
|
31
32
|
}
|
|
@@ -33,21 +34,22 @@ const C3NotificationProvider = ({ children, }) => {
|
|
|
33
34
|
setEventStreamAvailable(true);
|
|
34
35
|
NotificationService.notificationsStream(config, (notification) => {
|
|
35
36
|
if (notification.orgId === activeOrganizationId) {
|
|
36
|
-
setNotifications(
|
|
37
|
+
setNotifications(NotificationService.updateNotifications(notifications, notification));
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
useEffect(() => {
|
|
41
42
|
if (enabled && config.userToken) {
|
|
42
|
-
NotificationService.getNotifications(config).then((
|
|
43
|
-
|
|
43
|
+
NotificationService.getNotifications(config).then(({ result }) => {
|
|
44
|
+
if (result)
|
|
45
|
+
setNotifications(result);
|
|
44
46
|
setFetched(true);
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
49
|
}, [config?.userToken]);
|
|
48
50
|
const changeState = (newState, { uuid, state }) => {
|
|
49
51
|
if (enabled && state !== newState) {
|
|
50
|
-
setNotifications(
|
|
52
|
+
setNotifications(NotificationService.updateNotificationState(notifications, uuid, newState));
|
|
51
53
|
NotificationService.changeState(config, uuid, newState);
|
|
52
54
|
}
|
|
53
55
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FC } from "react";
|
|
2
|
-
import { C3NavigationOrgSideBarProps } from "
|
|
2
|
+
import { C3NavigationOrgSideBarProps } from "../c3-navigation-sidebar/c3-navigation-sidebar.types";
|
|
3
3
|
declare const C3OrgSidebar: FC<{
|
|
4
4
|
sideBar: C3NavigationOrgSideBarProps;
|
|
5
5
|
}>;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { Button, FormLabel } from "@carbon/react";
|
|
3
|
+
import { Enterprise } from "@carbon/react/icons";
|
|
4
|
+
import C3NavigationSideBar from "../c3-navigation-sidebar/c3-navigation-sidebar";
|
|
5
|
+
import { SwitcherDivider } from "../c3-navigation-sidebar/components";
|
|
6
|
+
import { useOrgSidebarState } from "../c3-navigation-sidebar/c3-sidebar-state-provider";
|
|
7
|
+
import { useC3Profile } from "../../c3-user-configuration/c3-profile-provider/c3-profile-provider";
|
|
8
|
+
import { useC3UserConfiguration } from "../../c3-user-configuration/c3-user-configuration-provider";
|
|
9
|
+
import { ActiveOrgName, ActiveOrgNameWrapper, ActiveOrgWrapper, ActiveOrgWrapperCustom, ConfirmLeaveModal, ManageOrgOverflowMenu, } from "./components";
|
|
10
|
+
import { leaveOrganization } from "../../../api/organizations";
|
|
11
|
+
const C3OrgSidebar = ({ sideBar }) => {
|
|
12
|
+
const { customElements, switchToOrg, manageOrg, elements, ...sideBarProps } = sideBar;
|
|
13
|
+
const { isOpen, setIsOpen, scrollBarWidth } = useOrgSidebarState();
|
|
14
|
+
const { userToken, decodedAudience, domain, analyticsTrack, setActiveOrgId } = useC3UserConfiguration();
|
|
15
|
+
const { activeOrg, orgs, removeOrg } = useC3Profile();
|
|
16
|
+
const isCustomized = Boolean(customElements?.activeOrganization);
|
|
17
|
+
const [isConfirmLeaveModalOpen, setIsConfirmLeaveModalOpen] = useState(false);
|
|
18
|
+
const [orgToLeave, setOrgToLeave] = useState(null);
|
|
19
|
+
const [loadingStatus, setLoadingStatus] = useState("inactive");
|
|
20
|
+
const isLastOrg = orgs?.length === 1;
|
|
21
|
+
const canUserLeaveOrg = (orgPermissions) => (!orgPermissions.org?.users?.owner?.update &&
|
|
22
|
+
orgs?.length &&
|
|
23
|
+
orgs.length > 1) ||
|
|
24
|
+
false;
|
|
25
|
+
const canUserManageOrg = (orgPermissions) => orgPermissions.org?.settings?.read || false;
|
|
26
|
+
const onManageCustomOrg = () => {
|
|
27
|
+
if (sideBar.closeOnClick !== false)
|
|
28
|
+
setIsOpen(false);
|
|
29
|
+
};
|
|
30
|
+
const onManageOrg = (orgId) => {
|
|
31
|
+
setIsOpen(false);
|
|
32
|
+
analyticsTrack?.("navBar:orgSettings:click", { orgId: activeOrg?.uuid });
|
|
33
|
+
if (manageOrg) {
|
|
34
|
+
manageOrg(orgId);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
window.location.href = `https://console.${domain}/org/${orgId}/management`;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const activeOrganization = customElements?.activeOrganization || {
|
|
41
|
+
activeLabel: "Active organization",
|
|
42
|
+
orgName: activeOrg?.name || "",
|
|
43
|
+
action: {
|
|
44
|
+
onClick: onManageCustomOrg,
|
|
45
|
+
label: "Manage",
|
|
46
|
+
},
|
|
47
|
+
otherLabel: "Other organizations",
|
|
48
|
+
};
|
|
49
|
+
const switchOrg = (orgId, track) => {
|
|
50
|
+
setActiveOrgId(orgId);
|
|
51
|
+
if (track)
|
|
52
|
+
analyticsTrack?.("navBar:orgSwitch:click", { orgId });
|
|
53
|
+
switchToOrg?.(orgId);
|
|
54
|
+
setIsOpen(false);
|
|
55
|
+
};
|
|
56
|
+
const orgElements = orgs
|
|
57
|
+
?.filter(({ uuid }) => uuid !== activeOrg?.uuid)
|
|
58
|
+
.map((org) => ({
|
|
59
|
+
key: org.uuid,
|
|
60
|
+
label: org.name,
|
|
61
|
+
onClick: () => switchOrg(org.uuid, true),
|
|
62
|
+
overflowMenu: (React.createElement(ManageOrgOverflowMenu, { canManage: canUserManageOrg(org.permissions), canLeave: canUserLeaveOrg(org.permissions), isLastOrg: isLastOrg, onManage: () => onManageOrg(org.uuid), onRequestToLeave: () => {
|
|
63
|
+
setOrgToLeave(org);
|
|
64
|
+
setIsConfirmLeaveModalOpen(true);
|
|
65
|
+
} })),
|
|
66
|
+
}));
|
|
67
|
+
const confirmLeaveOrg = async () => {
|
|
68
|
+
if (orgToLeave && decodedAudience && userToken) {
|
|
69
|
+
setLoadingStatus("active");
|
|
70
|
+
const { success } = await leaveOrganization({
|
|
71
|
+
token: userToken,
|
|
72
|
+
audience: decodedAudience,
|
|
73
|
+
orgId: orgToLeave.uuid,
|
|
74
|
+
});
|
|
75
|
+
setLoadingStatus(success ? "finished" : "error");
|
|
76
|
+
if (success) {
|
|
77
|
+
setIsConfirmLeaveModalOpen(false);
|
|
78
|
+
removeOrg(orgToLeave.uuid);
|
|
79
|
+
}
|
|
80
|
+
if (orgToLeave.uuid === activeOrg?.uuid) {
|
|
81
|
+
const newActiveOrg = orgs?.[0]?.uuid;
|
|
82
|
+
if (newActiveOrg)
|
|
83
|
+
switchOrg(newActiveOrg);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const itemTabIndex = isOpen ? undefined : -1;
|
|
88
|
+
return (React.createElement(C3NavigationSideBar, { sideBar: {
|
|
89
|
+
...sideBarProps,
|
|
90
|
+
elements: elements || orgElements,
|
|
91
|
+
ariaLabel: sideBarProps.ariaLabel || "Organization Sidebars",
|
|
92
|
+
}, icon: React.createElement(Enterprise, { size: 20 }) }, (customElements?.activeOrganization || activeOrg) && (React.createElement(React.Fragment, null,
|
|
93
|
+
isCustomized ? (React.createElement(ActiveOrgWrapperCustom, null,
|
|
94
|
+
React.createElement("div", { style: {
|
|
95
|
+
overflow: "hidden",
|
|
96
|
+
display: "grid",
|
|
97
|
+
gap: "4px",
|
|
98
|
+
} },
|
|
99
|
+
React.createElement(FormLabel, null, activeOrganization.activeLabel),
|
|
100
|
+
React.createElement(ActiveOrgName, { className: "textPrimary", title: activeOrganization.orgName, "$isCustomized": true }, activeOrganization.orgName)),
|
|
101
|
+
React.createElement(Button, { size: "md", kind: "ghost", onClick: () => {
|
|
102
|
+
activeOrganization.action.onClick();
|
|
103
|
+
onManageCustomOrg();
|
|
104
|
+
}, tabIndex: itemTabIndex }, activeOrganization.action?.label))) : (React.createElement(ActiveOrgWrapper, { "$scrollBarWidth": scrollBarWidth },
|
|
105
|
+
React.createElement(FormLabel, null, activeOrganization.activeLabel),
|
|
106
|
+
React.createElement(ActiveOrgNameWrapper, null,
|
|
107
|
+
React.createElement(ActiveOrgName, { className: "textPrimary", title: activeOrganization.orgName }, activeOrganization.orgName),
|
|
108
|
+
activeOrg?.uuid && domain && (React.createElement(ManageOrgOverflowMenu, { canManage: canUserManageOrg(activeOrg?.permissions), canLeave: canUserLeaveOrg(activeOrg?.permissions), isLastOrg: isLastOrg, onManage: () => onManageOrg(activeOrg?.uuid), onRequestToLeave: () => {
|
|
109
|
+
setOrgToLeave(activeOrg);
|
|
110
|
+
setIsConfirmLeaveModalOpen(true);
|
|
111
|
+
} }))),
|
|
112
|
+
React.createElement(ConfirmLeaveModal, { isOpen: isConfirmLeaveModalOpen, orgName: orgToLeave?.name || "", onConfirm: confirmLeaveOrg, onCancel: () => {
|
|
113
|
+
setIsConfirmLeaveModalOpen(false);
|
|
114
|
+
setOrgToLeave(null);
|
|
115
|
+
}, loadingStatus: loadingStatus }))),
|
|
116
|
+
((sideBar.elements && sideBar.elements.length > 0) ||
|
|
117
|
+
(orgElements && orgElements.length > 0)) && (React.createElement(React.Fragment, null,
|
|
118
|
+
React.createElement(SwitcherDivider, null),
|
|
119
|
+
React.createElement(FormLabel, { style: {
|
|
120
|
+
paddingTop: "15px",
|
|
121
|
+
paddingLeft: "1rem",
|
|
122
|
+
paddingBottom: ".25rem",
|
|
123
|
+
} }, activeOrganization.otherLabel)))))));
|
|
124
|
+
};
|
|
125
|
+
export default C3OrgSidebar;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React, { FC } from "react";
|
|
2
|
+
import { ModalProps } from "@carbon/react/es/components/Modal/Modal";
|
|
3
|
+
export declare const ActiveOrgWrapperCustom: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
4
|
+
export declare const ActiveOrgWrapper: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
5
|
+
$scrollBarWidth: number;
|
|
6
|
+
}>>;
|
|
7
|
+
export declare const ActiveOrgNameWrapper: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
8
|
+
export declare const ActiveOrgName: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
9
|
+
$isCustomized?: boolean | undefined;
|
|
10
|
+
}>>;
|
|
11
|
+
export declare const ConfirmLeaveModal: FC<{
|
|
12
|
+
isOpen: boolean;
|
|
13
|
+
orgName: string;
|
|
14
|
+
onConfirm: () => void;
|
|
15
|
+
onCancel: () => void;
|
|
16
|
+
loadingStatus: ModalProps["loadingStatus"];
|
|
17
|
+
}>;
|
|
18
|
+
export declare const ManageOrgOverflowMenu: FC<{
|
|
19
|
+
canManage: boolean;
|
|
20
|
+
canLeave: boolean;
|
|
21
|
+
isLastOrg?: boolean;
|
|
22
|
+
onManage: () => void;
|
|
23
|
+
onRequestToLeave: () => void;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Modal, OverflowMenu, OverflowMenuItem, Popover, PopoverContent, } from "@carbon/react";
|
|
3
|
+
import styled from "styled-components";
|
|
4
|
+
export const ActiveOrgWrapperCustom = styled.div `
|
|
5
|
+
padding: 1.5rem 1rem 15px;
|
|
6
|
+
display: grid;
|
|
7
|
+
grid-auto-flow: column;
|
|
8
|
+
gap: 0.25rem;
|
|
9
|
+
`;
|
|
10
|
+
export const ActiveOrgWrapper = styled.div `
|
|
11
|
+
padding: 15px 0 0.5rem 1rem;
|
|
12
|
+
width: ${({ $scrollBarWidth }) => `calc(16rem - ${$scrollBarWidth}px)`};
|
|
13
|
+
`;
|
|
14
|
+
export const ActiveOrgNameWrapper = styled.div `
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: space-between;
|
|
18
|
+
`;
|
|
19
|
+
export const ActiveOrgName = styled.div `
|
|
20
|
+
height: 20px; // Set minimum height to allow decenders to be rendered
|
|
21
|
+
line-height: 20px;
|
|
22
|
+
font-size: 14px;
|
|
23
|
+
${({ $isCustomized }) => ($isCustomized ? "" : "width: calc(-2px + 13rem)")};
|
|
24
|
+
text-overflow: ellipsis;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
white-space: nowrap;
|
|
27
|
+
`;
|
|
28
|
+
export const ConfirmLeaveModal = ({ isOpen, onConfirm, onCancel, orgName, loadingStatus }) => {
|
|
29
|
+
return (React.createElement(Modal, { danger: true, open: isOpen, modalHeading: "Leave organization", primaryButtonText: "Leave", secondaryButtonText: "Cancel", closeButtonLabel: "Cancel", loadingStatus: loadingStatus, onRequestClose: onCancel, onRequestSubmit: onConfirm, onSecondarySubmit: onCancel, loadingDescription: "Leaving" },
|
|
30
|
+
React.createElement("p", null,
|
|
31
|
+
"Are you sure you want to leave ",
|
|
32
|
+
React.createElement("strong", null, orgName),
|
|
33
|
+
"?"),
|
|
34
|
+
React.createElement("br", null),
|
|
35
|
+
React.createElement("p", null, "Leaving this organization will remove you from all associated teams and projects. To regain access you would need to reach out to the admin/owner of this organization.")));
|
|
36
|
+
};
|
|
37
|
+
const PopoverWrapper = styled(Popover) `
|
|
38
|
+
max-width: 11rem;
|
|
39
|
+
|
|
40
|
+
.cds--popover-content {
|
|
41
|
+
max-width: 176px;
|
|
42
|
+
padding: 0.5rem 1rem;
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
const StyledOverflowMenu = styled(OverflowMenu) `
|
|
46
|
+
.cds--overflow-menu-options {
|
|
47
|
+
width: 165px;
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
export const ManageOrgOverflowMenu = ({ canManage, canLeave, isLastOrg, onManage, onRequestToLeave }) => {
|
|
51
|
+
const [isPopoverShown, setIsPopoverShown] = React.useState(false);
|
|
52
|
+
const leaveMenuItem = (React.createElement(OverflowMenuItem, { itemText: "Leave organization", disabled: !canLeave, onClick: onRequestToLeave, onMouseOver: () => setIsPopoverShown(true), onMouseLeave: () => setIsPopoverShown(false) }));
|
|
53
|
+
const popoverLabel = isLastOrg
|
|
54
|
+
? "You need to be a member of at least one organization. Join a different organization first if you wish to leave."
|
|
55
|
+
: "Owners cannot leave an organization directly. Assign another user as an owner if you wish to leave.";
|
|
56
|
+
return (React.createElement(StyledOverflowMenu, { size: "sm", flipped: true, "aria-label": "Organization options menu",
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
58
|
+
// @ts-expect-error
|
|
59
|
+
align: "top-right", "data-floating-menu-container": "cds--header-panel" },
|
|
60
|
+
canManage && (React.createElement(OverflowMenuItem, { itemText: "Manage organization", onClick: onManage })),
|
|
61
|
+
canLeave ? (leaveMenuItem) : (React.createElement(PopoverWrapper, { open: isPopoverShown, label: popoverLabel, align: "bottom-right" },
|
|
62
|
+
leaveMenuItem,
|
|
63
|
+
React.createElement(PopoverContent, null, popoverLabel)))));
|
|
64
|
+
};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare function useOnClickOutside(handler: (e: Event) => void): {
|
|
3
|
+
panelRef: import("react").MutableRefObject<HTMLElement | null>;
|
|
4
|
+
setPanelRef: (node: unknown) => void;
|
|
5
|
+
iconRef: import("react").MutableRefObject<HTMLElement | null>;
|
|
6
|
+
setIconRef: (node: unknown) => void;
|
|
7
|
+
};
|
|
2
8
|
export declare function executeMediaQuery(mediaQuery: string): MediaQueryList;
|
|
3
9
|
export declare function useMediaQuery(mediaQuery: string): boolean;
|
|
@@ -34,7 +34,7 @@ export function useOnClickOutside(handler) {
|
|
|
34
34
|
setListener();
|
|
35
35
|
}
|
|
36
36
|
}, []);
|
|
37
|
-
return
|
|
37
|
+
return { panelRef, setPanelRef, iconRef, setIconRef };
|
|
38
38
|
}
|
|
39
39
|
export function executeMediaQuery(mediaQuery) {
|
|
40
40
|
return window.matchMedia(mediaQuery);
|
|
@@ -7,9 +7,11 @@ export declare function createAppBarProps(options?: {
|
|
|
7
7
|
elements?: Array<C3NavigationElementProps>;
|
|
8
8
|
useElementsFromConfig?: boolean;
|
|
9
9
|
}): C3NavigationProps["appBar"];
|
|
10
|
-
export declare function createNavBarBarProps({ orgName, elements, }?: {
|
|
10
|
+
export declare function createNavBarBarProps({ orgName, elements, showLicenseTag, showProductionLicense, }?: {
|
|
11
11
|
elements?: C3NavigationNavBarProps["elements"];
|
|
12
12
|
orgName?: string;
|
|
13
|
+
showLicenseTag?: boolean;
|
|
14
|
+
showProductionLicense?: boolean;
|
|
13
15
|
}): C3NavigationNavBarProps;
|
|
14
16
|
export declare function createInfoSideBarProps(options: {
|
|
15
17
|
isOpen: boolean;
|
|
@@ -72,7 +72,7 @@ export function createAppBarProps(options = {}) {
|
|
|
72
72
|
elementClicked: (element) => console.log(`event coming from the appBarProps: ${element} has been clicked`),
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
|
-
export function createNavBarBarProps({ orgName = "Camunda", elements = undefined, } = {}) {
|
|
75
|
+
export function createNavBarBarProps({ orgName = "Camunda", elements = undefined, showLicenseTag, showProductionLicense, } = {}) {
|
|
76
76
|
return {
|
|
77
77
|
elements: elements ?? [
|
|
78
78
|
{
|
|
@@ -91,21 +91,20 @@ export function createNavBarBarProps({ orgName = "Camunda", elements = undefined
|
|
|
91
91
|
},
|
|
92
92
|
],
|
|
93
93
|
orgName,
|
|
94
|
+
licenseTag: {
|
|
95
|
+
show: showLicenseTag || false,
|
|
96
|
+
isProductionLicense: showProductionLicense || false,
|
|
97
|
+
},
|
|
94
98
|
tags: [
|
|
95
|
-
{
|
|
96
|
-
key: "stage",
|
|
97
|
-
label: "Production",
|
|
98
|
-
color: "red",
|
|
99
|
-
},
|
|
100
99
|
{
|
|
101
100
|
key: "githash",
|
|
102
|
-
label: "
|
|
101
|
+
label: "example tag",
|
|
103
102
|
color: "teal",
|
|
104
103
|
},
|
|
105
104
|
{
|
|
106
105
|
key: "fooTooltip",
|
|
107
|
-
label: "
|
|
108
|
-
color: "
|
|
106
|
+
label: "tooltip tag",
|
|
107
|
+
color: "purple",
|
|
109
108
|
tooltip: {
|
|
110
109
|
content: (React.createElement("p", null,
|
|
111
110
|
"tooltip popover with a",
|
|
@@ -27,12 +27,13 @@ export const C3OnboardingSurvey = (props) => {
|
|
|
27
27
|
setUserId(userId);
|
|
28
28
|
setOnboardConfig(defaultOnboardingConfig);
|
|
29
29
|
setIsLoadingConfig(true);
|
|
30
|
-
const config = await getOnboardingConfig({
|
|
30
|
+
const { result: config } = await getOnboardingConfig({
|
|
31
31
|
audience: decodedAudience,
|
|
32
32
|
camundaAuth: { token: userToken },
|
|
33
33
|
orgId: activeOrganizationId,
|
|
34
34
|
});
|
|
35
|
-
|
|
35
|
+
if (config)
|
|
36
|
+
setOnboardConfig(config);
|
|
36
37
|
setIsLoadingConfig(false);
|
|
37
38
|
})();
|
|
38
39
|
}, [JSON.stringify(decodedToken), decodedAudience]);
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { Column, FlexGrid, RadioTile, Row, Stack, Tooltip, Button, } from "@carbon/react";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { Information } from "@carbon/react/icons";
|
|
4
|
+
import styled from "styled-components";
|
|
5
|
+
const StyledRadioTile = styled(RadioTile) `
|
|
6
|
+
background-color: ${({ $backgroundColor }) => $backgroundColor};
|
|
7
|
+
margin-bottom: 24px;
|
|
8
|
+
`;
|
|
4
9
|
export const RadioGroupElementSingle = ({ theme, title, label, elements, columns, tooltip, selectedElement, setSelectedElement, }) => {
|
|
5
10
|
const backgroundColor = theme === "dark" ? "#393939" : "#E5E5E5";
|
|
6
11
|
return (React.createElement(React.Fragment, null,
|
|
@@ -33,10 +38,7 @@ export const RadioGroupElementSingle = ({ theme, title, label, elements, columns
|
|
|
33
38
|
paddingRight: "0",
|
|
34
39
|
} },
|
|
35
40
|
React.createElement(Row, null, row.map((element, index) => (React.createElement(Column, { key: `column-${element.value}-${index}`, style: { maxWidth: `${100 / columns}%` } },
|
|
36
|
-
React.createElement(
|
|
37
|
-
|
|
38
|
-
marginBottom: "24px",
|
|
39
|
-
}, checked: (selectedElement ?? "") === element.value, onClick: () => {
|
|
40
|
-
setSelectedElement(element.value);
|
|
41
|
+
React.createElement(StyledRadioTile, { "$backgroundColor": backgroundColor, key: `tile-${element.value}-${index}`, checked: (selectedElement ?? "") === element.value, onChange: (value) => {
|
|
42
|
+
setSelectedElement(value);
|
|
41
43
|
}, value: element.value }, element.label)))))))))));
|
|
42
44
|
};
|
|
@@ -5,6 +5,9 @@ import { headingStyles } from "../c3-help-center/styles";
|
|
|
5
5
|
export const StyledModalBody = styled(ModalBody) `
|
|
6
6
|
${headingStyles}
|
|
7
7
|
`;
|
|
8
|
+
const StyledModalFooter = styled(ModalFooter) `
|
|
9
|
+
background-color: ${({ $c3Theme }) => $c3Theme === "light" ? "#FFFFFF" : "#161616"};
|
|
10
|
+
`;
|
|
8
11
|
export const OnboardingModal = ({ isDoingAsyncWork, heading, headingLabel, primaryButtonText, primaryButtonDisabled = false, secondaryButtonText = "Cancel", tertiaryButtonText, loadingText, error = { title: "", description: "" }, danger = false, theme, onRequestClose, onSecondary, onPrimary, onTertiary, children, }) => {
|
|
9
12
|
return (React.createElement(React.Fragment, null,
|
|
10
13
|
React.createElement(ModalHeader, { title: heading, label: headingLabel, style: {
|
|
@@ -21,9 +24,7 @@ export const OnboardingModal = ({ isDoingAsyncWork, heading, headingLabel, prima
|
|
|
21
24
|
React.createElement(Stack, { gap: 6 },
|
|
22
25
|
children,
|
|
23
26
|
error.title ? (React.createElement(InlineNotification, { kind: "error", title: error.title, subtitle: error.description, hideCloseButton: true })) : ("")))),
|
|
24
|
-
React.createElement(
|
|
25
|
-
backgroundColor: theme === "light" ? "#FFFFFF" : "#161616",
|
|
26
|
-
} }, (() => {
|
|
27
|
+
React.createElement(StyledModalFooter, { "$c3Theme": theme }, (() => {
|
|
27
28
|
if (tertiaryButtonText && onTertiary !== undefined) {
|
|
28
29
|
return (React.createElement(React.Fragment, null,
|
|
29
30
|
React.createElement(Button, { kind: "ghost", disabled: isDoingAsyncWork, onClick: () => onTertiary() }, tertiaryButtonText),
|
package/lib/esm/src/components/c3-user-configuration/c3-profile-provider/c3-profile-provider.js
CHANGED
|
@@ -9,6 +9,7 @@ export const C3ProfileContext = createContext({
|
|
|
9
9
|
orgs: null,
|
|
10
10
|
activeOrg: null,
|
|
11
11
|
reloadOrgs: () => undefined,
|
|
12
|
+
removeOrg: () => undefined,
|
|
12
13
|
clusters: null,
|
|
13
14
|
reloadClusters: () => undefined,
|
|
14
15
|
resolvedTheme: defaultTheme,
|
|
@@ -26,18 +27,24 @@ export const C3ProfileProvider = ({ children }) => {
|
|
|
26
27
|
const loadClusters = () => {
|
|
27
28
|
if (!isConfigValid)
|
|
28
29
|
return;
|
|
29
|
-
getClusters(decodedAudience, config.userToken, config.activeOrganizationId).then((
|
|
30
|
-
|
|
30
|
+
getClusters(decodedAudience, config.userToken, config.activeOrganizationId).then(({ result }) => {
|
|
31
|
+
if (result)
|
|
32
|
+
setClusters(result);
|
|
31
33
|
});
|
|
32
34
|
};
|
|
33
35
|
const loadOrgs = () => {
|
|
34
36
|
if (!isConfigValid)
|
|
35
37
|
return;
|
|
36
|
-
getOrgs(decodedAudience, config.userToken).then((res) => {
|
|
37
|
-
setOrgs(res);
|
|
38
|
+
getOrgs(decodedAudience, config.userToken).then(({ result: res }) => {
|
|
39
|
+
setOrgs(res?.sort(({ name: a }, { name: b }) => a.localeCompare(b)) || null);
|
|
38
40
|
setActiveOrg(res?.find((org) => org.uuid === config.activeOrganizationId) || null);
|
|
39
41
|
});
|
|
40
42
|
};
|
|
43
|
+
const removeOrg = (orgId) => {
|
|
44
|
+
if (orgs?.length === 1)
|
|
45
|
+
return;
|
|
46
|
+
setOrgs((orgs) => orgs?.filter((org) => org.uuid !== orgId) || null);
|
|
47
|
+
};
|
|
41
48
|
useEffect(() => {
|
|
42
49
|
if (config?.activeOrganizationId) {
|
|
43
50
|
const org = orgs?.find((org) => org.uuid === config.activeOrganizationId);
|
|
@@ -100,6 +107,7 @@ export const C3ProfileProvider = ({ children }) => {
|
|
|
100
107
|
reloadOrgs: loadOrgs,
|
|
101
108
|
clusters,
|
|
102
109
|
reloadClusters: loadClusters,
|
|
110
|
+
removeOrg,
|
|
103
111
|
onThemeChange,
|
|
104
112
|
} }, content));
|
|
105
113
|
};
|