@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.
Files changed (44) hide show
  1. package/lib/esm/package.json +17 -17
  2. package/lib/esm/src/api/api.d.ts +7 -1
  3. package/lib/esm/src/api/api.js +18 -14
  4. package/lib/esm/src/api/help-center.d.ts +7 -7
  5. package/lib/esm/src/api/notifications.d.ts +2 -1
  6. package/lib/esm/src/api/organizations.d.ts +7 -1
  7. package/lib/esm/src/api/organizations.js +5 -0
  8. package/lib/esm/src/api/profile.d.ts +3 -2
  9. package/lib/esm/src/components/c3-app-teaser/c3-app-teaser-page.js +3 -3
  10. package/lib/esm/src/components/c3-empty-state/c3-empty-state.js +1 -1
  11. package/lib/esm/src/components/c3-help-center/c3-help-center.js +1 -1
  12. package/lib/esm/src/components/c3-help-center/help-center.js +19 -12
  13. package/lib/esm/src/components/c3-help-center/styles.d.ts +0 -1
  14. package/lib/esm/src/components/c3-help-center/tabs/feedback.js +7 -9
  15. package/lib/esm/src/components/c3-navigation/c3-navigation-appbar/c3-navigation-appbar.js +8 -2
  16. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar-element.d.ts +1 -0
  17. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar-element.js +50 -22
  18. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.js +37 -7
  19. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.types.d.ts +1 -0
  20. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-notification-sidebar.js +2 -2
  21. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-sidebar-state-provider.d.ts +2 -0
  22. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-sidebar-state-provider.js +24 -3
  23. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/components.d.ts +0 -1
  24. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/components.js +1 -0
  25. package/lib/esm/src/components/c3-navigation/c3-navigation.js +37 -10
  26. package/lib/esm/src/components/c3-navigation/c3-navigation.types.d.ts +5 -2
  27. package/lib/esm/src/components/c3-navigation/c3-notification-provider/c3-notification-provider.js +8 -6
  28. package/lib/esm/src/components/c3-navigation/{c3-navigation-sidebar → c3-org-sidebar}/c3-org-sidebar.d.ts +1 -1
  29. package/lib/esm/src/components/c3-navigation/c3-org-sidebar/c3-org-sidebar.js +125 -0
  30. package/lib/esm/src/components/c3-navigation/c3-org-sidebar/components.d.ts +24 -0
  31. package/lib/esm/src/components/c3-navigation/c3-org-sidebar/components.js +64 -0
  32. package/lib/esm/src/components/c3-navigation/helpers.d.ts +7 -1
  33. package/lib/esm/src/components/c3-navigation/helpers.js +1 -1
  34. package/lib/esm/src/components/c3-navigation/stories/story-helpers.d.ts +3 -1
  35. package/lib/esm/src/components/c3-navigation/stories/story-helpers.js +8 -9
  36. package/lib/esm/src/components/c3-onboarding-survey/c3-onboarding-survey.js +3 -2
  37. package/lib/esm/src/components/c3-onboarding-survey/elements/radioGroupSingle.js +7 -5
  38. package/lib/esm/src/components/c3-onboarding-survey/onboardingModal.d.ts +0 -1
  39. package/lib/esm/src/components/c3-onboarding-survey/onboardingModal.js +4 -3
  40. package/lib/esm/src/components/c3-user-configuration/c3-profile-provider/c3-profile-provider.d.ts +1 -0
  41. package/lib/esm/src/components/c3-user-configuration/c3-profile-provider/c3-profile-provider.js +12 -4
  42. package/lib/esm/src/utils/camunda.types.d.ts +13 -8
  43. package/package.json +17 -17
  44. package/lib/esm/src/components/c3-navigation/c3-navigation-sidebar/c3-org-sidebar.js +0 -85
@@ -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,3 +1,2 @@
1
- /// <reference path="../../../../../../src/carbon.d.ts" />
2
1
  import { SwitcherDivider as CarbonSwitcherDivider } from "@carbon/react";
3
2
  export declare const SwitcherDivider: typeof CarbonSwitcherDivider;
@@ -2,4 +2,5 @@ import { SwitcherDivider as CarbonSwitcherDivider } from "@carbon/react";
2
2
  import styled from "styled-components";
3
3
  export const SwitcherDivider = styled(CarbonSwitcherDivider) `
4
4
  margin: auto;
5
+ width: calc(100% - 30px);
5
6
  `;
@@ -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-navigation-sidebar/c3-org-sidebar";
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
- navbar.tags &&
75
- navbar.tags.length > 0 &&
76
- navbar.tags.map((tag) => {
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.50rem",
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
- padding: "0 1rem",
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 {
@@ -24,8 +24,9 @@ const C3NotificationProvider = ({ children, }) => {
24
24
  setNotifications([]);
25
25
  }
26
26
  if (enabled && !isFetched && config.userToken) {
27
- NotificationService.getNotifications(config).then((response) => {
28
- setNotifications(response);
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((allNotifications) => NotificationService.updateNotifications(allNotifications, notification));
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((response) => {
43
- setNotifications(response);
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((allNotifications) => NotificationService.updateNotificationState(allNotifications, uuid, newState));
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 "./c3-navigation-sidebar.types";
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
- export declare function useOnClickOutside(handler: (e: Event) => void): ((node: unknown) => void)[];
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 [setPanelRef, setIconRef];
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: "abcdefg",
101
+ label: "example tag",
103
102
  color: "teal",
104
103
  },
105
104
  {
106
105
  key: "fooTooltip",
107
- label: "I am a tooltip pill",
108
- color: "cool-gray",
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
- setOnboardConfig(config);
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(RadioTile, { key: `tile-${element.value}-${index}`, style: {
37
- backgroundColor,
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
  };
@@ -1,4 +1,3 @@
1
- /// <reference path="../../../../../src/carbon.d.ts" />
2
1
  import { ModalBodyProps } from "@carbon/react";
3
2
  import React, { FC } from "react";
4
3
  export declare const StyledModalBody: FC<ModalBodyProps>;
@@ -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(ModalFooter, { style: {
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),
@@ -9,6 +9,7 @@ export type C3ProfileContextValue = {
9
9
  orgs: Organization[] | null;
10
10
  activeOrg: Organization | null;
11
11
  reloadOrgs: () => void;
12
+ removeOrg: (orgId: string) => void;
12
13
  clusters: Cluster[] | null;
13
14
  reloadClusters: () => void;
14
15
  resolvedTheme: ResolvedTheme;
@@ -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((res) => {
30
- setClusters(res);
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
  };