@camunda/camunda-composite-components 0.0.28 → 0.0.29-np-rc1

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 (37) hide show
  1. package/lib/esm/api/api.d.ts +21 -0
  2. package/lib/esm/api/api.js +59 -0
  3. package/lib/esm/api/endpoints.const.d.ts +9 -0
  4. package/lib/esm/api/endpoints.const.js +18 -0
  5. package/lib/esm/api/jwt.utils.d.ts +5 -0
  6. package/lib/esm/api/jwt.utils.js +23 -0
  7. package/lib/esm/api/notifications.d.ts +30 -0
  8. package/lib/esm/api/notifications.js +70 -0
  9. package/lib/esm/components/c3-empty-state/c3-empty-state.types.d.ts +2 -1
  10. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-info-sidebar.d.ts +6 -0
  11. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-info-sidebar.js +39 -0
  12. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar-element.d.ts +11 -0
  13. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar-element.js +16 -0
  14. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.d.ts +9 -0
  15. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.js +41 -0
  16. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.types.d.ts +56 -0
  17. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-navigation-sidebar.types.js +1 -0
  18. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-notification-sidebar.d.ts +5 -0
  19. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-notification-sidebar.js +55 -0
  20. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-org-sidebar.d.ts +6 -0
  21. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-org-sidebar.js +51 -0
  22. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-user-sidebar.d.ts +6 -0
  23. package/lib/esm/components/c3-navigation/c3-navigation-sidebar/c3-user-sidebar.js +43 -0
  24. package/lib/esm/components/c3-navigation/c3-navigation.d.ts +1 -1
  25. package/lib/esm/components/c3-navigation/c3-navigation.js +15 -204
  26. package/lib/esm/components/c3-navigation/c3-navigation.types.d.ts +15 -40
  27. package/lib/esm/components/c3-navigation/c3-notification-provider/c3-notification-container.d.ts +10 -0
  28. package/lib/esm/components/c3-navigation/c3-notification-provider/c3-notification-container.js +86 -0
  29. package/lib/esm/components/c3-navigation/c3-notification-provider/c3-notification-provider.d.ts +37 -0
  30. package/lib/esm/components/c3-navigation/c3-notification-provider/c3-notification-provider.js +43 -0
  31. package/lib/esm/components/c3-navigation/helpers.d.ts +5 -0
  32. package/lib/esm/components/c3-navigation/helpers.js +47 -0
  33. package/lib/esm/icons/c3-icons.d.ts +2 -0
  34. package/lib/esm/icons/c3-icons.js +6 -1
  35. package/lib/esm/index.d.ts +4 -1
  36. package/lib/esm/index.js +1 -0
  37. package/package.json +23 -3
@@ -0,0 +1,21 @@
1
+ import { Stage } from "./endpoints.const";
2
+ export declare class HttpError extends Error {
3
+ status: number;
4
+ constructor(message: string, status: number);
5
+ }
6
+ export interface RequestPayload {
7
+ base?: "notifications";
8
+ stage?: Stage;
9
+ url: string;
10
+ method: "get" | "post" | "put" | "delete" | "patch";
11
+ headers?: {
12
+ [key: string]: string;
13
+ };
14
+ type?: "json" | "text" | "none";
15
+ responseType?: "json" | "text" | "none";
16
+ camundaAuth?: {
17
+ token: string;
18
+ };
19
+ body?: any;
20
+ }
21
+ export declare function request(payload: RequestPayload): Promise<any>;
@@ -0,0 +1,59 @@
1
+ import { getEndpoint, NOTIFICATIONS } from "./endpoints.const";
2
+ export class HttpError extends Error {
3
+ status;
4
+ constructor(message, status) {
5
+ super(message);
6
+ this.status = status;
7
+ }
8
+ }
9
+ export async function request(payload) {
10
+ const headers = {};
11
+ if (payload.camundaAuth) {
12
+ headers.Authorization = `Bearer ${payload.camundaAuth.token}`;
13
+ }
14
+ const type = payload.type ?? "json";
15
+ if (type) {
16
+ switch (type) {
17
+ case "json":
18
+ headers["Content-Type"] = "application/json";
19
+ break;
20
+ case "text":
21
+ headers["Content-Type"] = "text/plain";
22
+ break;
23
+ }
24
+ }
25
+ const body = payload.body ? JSON.stringify(payload.body) : undefined;
26
+ let base;
27
+ if (payload.base && payload.stage) {
28
+ switch (payload.base) {
29
+ case "notifications":
30
+ base = getEndpoint(payload.stage, NOTIFICATIONS);
31
+ break;
32
+ }
33
+ }
34
+ const url = base ? `${base}/${payload.url}` : payload.url;
35
+ const response = await fetch(url, {
36
+ method: payload.method.toUpperCase(),
37
+ headers,
38
+ body,
39
+ });
40
+ let success = true;
41
+ if (response.status >= 400 && response.status < 500) {
42
+ success = false;
43
+ }
44
+ if (response.status >= 500) {
45
+ success = false;
46
+ }
47
+ if (!success) {
48
+ throw new HttpError(response.statusText, response.status);
49
+ }
50
+ const responseType = payload.responseType ?? type;
51
+ switch (responseType) {
52
+ case "json":
53
+ return response.json();
54
+ case "text":
55
+ return response.text();
56
+ default:
57
+ return response;
58
+ }
59
+ }
@@ -0,0 +1,9 @@
1
+ export interface Endpoint {
2
+ id: string;
3
+ dev: string;
4
+ int: string;
5
+ prod: string;
6
+ }
7
+ export declare const NOTIFICATIONS: Endpoint;
8
+ export declare type Stage = "dev" | "int" | "prod";
9
+ export declare function getEndpoint(stage: Stage, endpoint: Endpoint): string;
@@ -0,0 +1,18 @@
1
+ export const NOTIFICATIONS = {
2
+ id: "notifications",
3
+ dev: "https://notifications.cloud.dev.ultrawombat.com",
4
+ int: "todo",
5
+ prod: "todo",
6
+ };
7
+ export function getEndpoint(stage, endpoint) {
8
+ switch (stage) {
9
+ case "dev":
10
+ return endpoint.dev;
11
+ case "int":
12
+ return endpoint.int;
13
+ case "prod":
14
+ return endpoint.prod;
15
+ default:
16
+ throw new Error(`Unknown stage: ${stage}`);
17
+ }
18
+ }
@@ -0,0 +1,5 @@
1
+ export declare class JWTUtils {
2
+ static decode(token: string): any;
3
+ static getExpiration(token: string): number;
4
+ static isExpired(token: string): boolean;
5
+ }
@@ -0,0 +1,23 @@
1
+ export class JWTUtils {
2
+ static decode(token) {
3
+ const base64Url = token.split(".")[1];
4
+ const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
5
+ const jsonPayload = decodeURIComponent(window
6
+ .atob(base64)
7
+ .split("")
8
+ .map(function (c) {
9
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
10
+ })
11
+ .join(""));
12
+ return JSON.parse(jsonPayload);
13
+ }
14
+ static getExpiration(token) {
15
+ const decoded = JWTUtils.decode(token);
16
+ return decoded.exp;
17
+ }
18
+ static isExpired(token) {
19
+ const expiration = JWTUtils.getExpiration(token);
20
+ const now = new Date().getTime() / 1000;
21
+ return expiration < now;
22
+ }
23
+ }
@@ -0,0 +1,30 @@
1
+ import { C3NotificationsProps } from "../components/c3-navigation/c3-navigation.types";
2
+ export interface Notification {
3
+ uuid: string;
4
+ userId?: string;
5
+ orgId?: string;
6
+ timestamp: number;
7
+ source: string;
8
+ type: string;
9
+ title: string;
10
+ description: string;
11
+ state: string;
12
+ meta?: {
13
+ href?: string;
14
+ label?: string;
15
+ entity?: {
16
+ id: string;
17
+ type: string;
18
+ };
19
+ parentEntity?: {
20
+ id: string;
21
+ type: string;
22
+ };
23
+ };
24
+ }
25
+ export declare class NotificationService {
26
+ static getNotifications(options: C3NotificationsProps): Promise<Notification[]>;
27
+ static changeState(options: C3NotificationsProps, notificationId: string, operation: "read" | "dismiss"): void;
28
+ static notificationsStream(options: C3NotificationsProps, handler: (notification: Notification) => void): void;
29
+ static updateNotifications(allNotifications: Notification[], newNotification: Notification): Notification[];
30
+ }
@@ -0,0 +1,70 @@
1
+ import { EventSourcePolyfill } from "event-source-polyfill";
2
+ import { request } from "./api";
3
+ import { getEndpoint, NOTIFICATIONS } from "./endpoints.const";
4
+ export class NotificationService {
5
+ static async getNotifications(options) {
6
+ let notifications = [];
7
+ try {
8
+ notifications = await request({
9
+ method: "get",
10
+ base: "notifications",
11
+ stage: options.stage,
12
+ camundaAuth: {
13
+ token: options.userToken,
14
+ },
15
+ url: `notifications/orgs/${options.activeOrganizationId}`,
16
+ });
17
+ return notifications;
18
+ }
19
+ catch (error) {
20
+ console.error(error);
21
+ }
22
+ return notifications;
23
+ }
24
+ static changeState(options, notificationId, operation) {
25
+ request({
26
+ method: "patch",
27
+ base: "notifications",
28
+ stage: options.stage,
29
+ camundaAuth: {
30
+ token: options.userToken,
31
+ },
32
+ url: `notifications/${notificationId}/${operation}`,
33
+ })
34
+ .then(() => {
35
+ // do nothing
36
+ })
37
+ .catch((error) => {
38
+ console.error(error);
39
+ });
40
+ }
41
+ static notificationsStream(options, handler) {
42
+ const source = new EventSourcePolyfill(`${getEndpoint(options.stage, NOTIFICATIONS)}/notifications/events`, {
43
+ headers: {
44
+ authorization: `Bearer ${options.userToken}`,
45
+ },
46
+ });
47
+ source.onmessage = function (event) {
48
+ try {
49
+ const notification = JSON.parse(event.data);
50
+ handler(notification);
51
+ }
52
+ catch (error) {
53
+ console.error(`Failed to handle SSE event`, { error });
54
+ }
55
+ };
56
+ }
57
+ // updates <allNotifications> with <newNotification>
58
+ // if <newNotification> is read or new, it will be added to <allNotifications>
59
+ // if <newNotification> is dismissed, it will be removed from <allNotifications>
60
+ static updateNotifications(allNotifications, newNotification) {
61
+ const updatedNotifications = allNotifications
62
+ .slice()
63
+ .filter((currentNotification) => currentNotification.uuid !== newNotification.uuid);
64
+ if (newNotification.state === "read" || newNotification.state === "new") {
65
+ updatedNotifications.push(newNotification);
66
+ }
67
+ updatedNotifications.sort((a, b) => b.timestamp - a.timestamp);
68
+ return updatedNotifications;
69
+ }
70
+ }
@@ -1,6 +1,7 @@
1
+ import { ReactElement } from "react";
1
2
  export interface C3EmptyStateProps {
2
3
  heading: string;
3
- description: any;
4
+ description: string | ReactElement;
4
5
  icon?: {
5
6
  path: string;
6
7
  altText: string;
@@ -0,0 +1,6 @@
1
+ import { FC } from "react";
2
+ import { C3NavigationInfoSideBarProps } from "./c3-navigation-sidebar.types";
3
+ declare const C3InfoSidebar: FC<{
4
+ sideBar: C3NavigationInfoSideBarProps;
5
+ }>;
6
+ export default C3InfoSidebar;
@@ -0,0 +1,39 @@
1
+ import React, { useState } from "react";
2
+ import { SwitcherDivider } from "@carbon/react";
3
+ import { Help } from "@carbon/react/icons";
4
+ import C3NavigationSideBar from "./c3-navigation-sidebar";
5
+ const C3InfoSidebar = ({ sideBar, }) => {
6
+ const { version, isOpen, ...sideBarProps } = sideBar;
7
+ const [isSidebarOpen, setIsSidebarOpen] = useState(isOpen);
8
+ return (React.createElement(C3NavigationSideBar, { sideBar: {
9
+ ...sideBarProps,
10
+ isOpen: isSidebarOpen,
11
+ setIsOpen: setIsSidebarOpen,
12
+ }, icon: React.createElement(Help, { size: 20 }), bottomChildren: version !== undefined && (React.createElement(React.Fragment, null,
13
+ React.createElement(SwitcherDivider, null),
14
+ React.createElement("span", { className: "cds--switcher__item", style: {
15
+ padding: "var(--cds-spacing-05)",
16
+ paddingTop: "var(--cds-spacing-03)",
17
+ paddingBottom: 0,
18
+ color: "var(--cds-text-primary)",
19
+ fontSize: "var(--cds-body-01-font-size)",
20
+ fontWeight: "var(--cds-body-01-font-weight)",
21
+ lineHeight: "var(--cds-body-01-line-height)",
22
+ letterSpacing: "var(--cds-body-01-letter-spacing)",
23
+ } },
24
+ "Version ",
25
+ version),
26
+ React.createElement("span", { className: "cds--switcher__item", style: {
27
+ paddingRight: "var(--cds-spacing-05)",
28
+ paddingLeft: "var(--cds-spacing-05)",
29
+ color: "var(--cds-text-secondary)",
30
+ fontSize: "var(--cds-label-01-font-size)",
31
+ fontWeight: "var(--cds-label-01-font-weight)",
32
+ lineHeight: "var(--cds-label-01-line-height)",
33
+ letterSpacing: "var(--cds-label-01-letter-spacing)",
34
+ } },
35
+ `© Camunda Services GmbH ${new Date().getFullYear()}`,
36
+ React.createElement("br", null),
37
+ " All rights reserved."))) }));
38
+ };
39
+ export default C3InfoSidebar;
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ import { C3NavigationElementProps } from "../c3-navigation.types";
3
+ import { C3NavigationSideBarProps } from "./c3-navigation-sidebar.types";
4
+ declare const C3NavigationSidebarElement: (props: {
5
+ element: C3NavigationElementProps;
6
+ index: number;
7
+ itemTabIndex?: number | undefined;
8
+ sideBar: C3NavigationSideBarProps;
9
+ setSideBarOpen: (open: boolean) => void;
10
+ }) => JSX.Element;
11
+ export default C3NavigationSidebarElement;
@@ -0,0 +1,16 @@
1
+ import { Button, SwitcherDivider } from "@carbon/react";
2
+ import React from "react";
3
+ const C3NavigationSidebarElement = (props) => (React.createElement(React.Fragment, null,
4
+ props.element.preceedingDivider && React.createElement(SwitcherDivider, null),
5
+ React.createElement(Button, { style: props.index === 0 &&
6
+ (!("elements" in props.sideBar) || !props.sideBar.elements)
7
+ ? { marginTop: "1.5rem", whiteSpace: "nowrap" }
8
+ : { whiteSpace: "nowrap" }, size: "sm", kind: props.element.kind ?? "ghost", className: "cds--switcher__item", onClick: () => {
9
+ if (props.element.onClick) {
10
+ props.element.onClick();
11
+ }
12
+ if (props.sideBar.closeOnClick !== false) {
13
+ props.setSideBarOpen(false);
14
+ }
15
+ }, tabIndex: props.itemTabIndex }, props.element.label)));
16
+ export default C3NavigationSidebarElement;
@@ -0,0 +1,9 @@
1
+ import { ReactElement, ReactNode } from "react";
2
+ import { C3NavigationSideBarProps } from "./c3-navigation-sidebar.types";
3
+ declare const C3NavigationSideBar: (props: {
4
+ sideBar: C3NavigationSideBarProps;
5
+ icon: ReactElement;
6
+ children?: ReactNode;
7
+ bottomChildren?: ReactNode;
8
+ }) => JSX.Element;
9
+ export default C3NavigationSideBar;
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+ import { Button, HeaderGlobalAction, HeaderPanel, Stack, SwitcherDivider, } from "@carbon/react";
3
+ import { useOnClickOutside } from "../helpers";
4
+ import C3NavigationSidebarElement from "./c3-navigation-sidebar-element";
5
+ const C3NavigationSideBar = (props) => {
6
+ const { icon, sideBar, children, bottomChildren } = props;
7
+ const { isOpen, setIsOpen } = sideBar;
8
+ const itemTabIndex = isOpen ? undefined : -1;
9
+ const refPanel = React.createRef();
10
+ const refIcon = React.createRef();
11
+ useOnClickOutside(refPanel, refIcon, () => setIsOpen(false));
12
+ return (React.createElement(React.Fragment, null,
13
+ React.createElement(HeaderGlobalAction, { ref: refIcon, "aria-label": sideBar.ariaLabel, onClick: () => {
14
+ setIsOpen(!isOpen);
15
+ }, isActive: isOpen, tooltipAlignment: sideBar.type === "user" ? "end" : "center" }, icon),
16
+ React.createElement(HeaderPanel, { ref: refPanel, "aria-label": sideBar.ariaLabel, expanded: isOpen, style: {
17
+ display: "grid",
18
+ gridAutoFlow: "row",
19
+ gridAutoRows: "max-content 1fr",
20
+ } },
21
+ React.createElement(Stack, null,
22
+ children,
23
+ sideBar.elements &&
24
+ sideBar.elements.length > 0 &&
25
+ "customElements" in sideBar &&
26
+ sideBar.customElements &&
27
+ "activeOrganization" in sideBar.customElements &&
28
+ !sideBar.customElements?.activeOrganization && React.createElement(SwitcherDivider, null),
29
+ sideBar.elements?.map((element, index) => (React.createElement(C3NavigationSidebarElement, { key: element.key, element: element, index: index, sideBar: sideBar, setSideBarOpen: setIsOpen, itemTabIndex: itemTabIndex }))),
30
+ bottomChildren),
31
+ sideBar.bottomElements &&
32
+ sideBar.bottomElements.map((element) => (React.createElement(Button, { kind: element.kind, key: element.key, className: "cds--switcher__item", renderIcon: element.renderIcon, onClick: () => {
33
+ if (element.onClick) {
34
+ element.onClick();
35
+ }
36
+ if (sideBar.closeOnClick !== false) {
37
+ setIsOpen(false);
38
+ }
39
+ }, style: { alignSelf: "end" }, tabIndex: itemTabIndex }, element.label))))));
40
+ };
41
+ export default C3NavigationSideBar;
@@ -0,0 +1,56 @@
1
+ import { C3NavigationElementProps } from "../c3-navigation.types";
2
+ export declare type C3NavigationSideBarBaseProps = {
3
+ ariaLabel?: string;
4
+ isOpen?: boolean;
5
+ closeOnClick?: boolean;
6
+ elementClicked?: (key: string) => void;
7
+ elements?: C3NavigationElementProps[];
8
+ bottomElements?: C3NavigationElementProps[];
9
+ };
10
+ export declare type C3NavigationOrgSideBarProps = C3NavigationSideBarBaseProps & {
11
+ type: "org";
12
+ customElements?: {
13
+ activeOrganization?: {
14
+ activeLabel: string;
15
+ otherLabel: string;
16
+ orgName: string;
17
+ action: {
18
+ label: string;
19
+ onClick: () => void;
20
+ };
21
+ };
22
+ };
23
+ };
24
+ export declare type C3NavigationInfoSideBarProps = C3NavigationSideBarBaseProps & {
25
+ type: "info";
26
+ version?: string;
27
+ };
28
+ export declare type C3NavigationUserSideBarProps = C3NavigationSideBarBaseProps & {
29
+ type: "user";
30
+ customElements?: {
31
+ profile?: {
32
+ label: string;
33
+ user: {
34
+ name: string;
35
+ email: string;
36
+ };
37
+ };
38
+ themeSelector?: {
39
+ currentTheme: string;
40
+ onChange: (newValue: string) => void;
41
+ };
42
+ stageToggle?: {
43
+ prodFeaturesEnabled: boolean;
44
+ toggle: () => void;
45
+ };
46
+ };
47
+ };
48
+ export declare type C3NavigationNotificationsSideBarProps = C3NavigationSideBarBaseProps & {
49
+ type: "notifications";
50
+ };
51
+ export declare type C3NavigationAppBarProps = C3NavigationSideBarBaseProps & {
52
+ type: "app";
53
+ };
54
+ export declare type C3NavigationSideBarProps = {
55
+ setIsOpen: (isOpen: boolean) => void;
56
+ } & (C3NavigationOrgSideBarProps | C3NavigationInfoSideBarProps | C3NavigationUserSideBarProps | C3NavigationNotificationsSideBarProps | C3NavigationAppBarProps);
@@ -0,0 +1,5 @@
1
+ import { FC } from "react";
2
+ import { C3NavigationNotificationsSideBarProps } from "./c3-navigation-sidebar.types";
3
+ export declare const C3NotificationSidebar: FC<{
4
+ sideBar: C3NavigationNotificationsSideBarProps;
5
+ }>;
@@ -0,0 +1,55 @@
1
+ import { Button } from "@carbon/react";
2
+ import { Notification as NotificationIcon } from "@carbon/react/icons";
3
+ import React, { useContext, useState } from "react";
4
+ import C3NotificationContainer, { NotificationDescription, NotificationTitle, } from "../c3-notification-provider/c3-notification-container";
5
+ import { C3NotificationContext } from "../c3-notification-provider/c3-notification-provider";
6
+ import { C3BellIcon, C3NotificationsUnreadIcon } from "../../../icons/c3-icons";
7
+ import styled from "styled-components";
8
+ import C3NavigationSideBar from "./c3-navigation-sidebar";
9
+ const PanelHeader = styled.div `
10
+ background: var(--cds-layer-01);
11
+ box-shadow: inset 0px -1px 0px var(--cds-border-subtle-01);
12
+ width: 100%;
13
+ height: 60px;
14
+ padding: 24px 16px 13px;
15
+ display: flex;
16
+ flex-direction: row;
17
+ justify-content: space-between;
18
+ align-items: center;
19
+ `;
20
+ const PanelTitle = styled.span `
21
+ color: var(--cds-text-primary);
22
+ font-size: var(--cds-body-01-font-size);
23
+ font-weight: var(--cds-body-01-font-weight);
24
+ line-height: var(--cds-body-01-line-height);
25
+ letter-spacing: var(--cds-body-01-letter-spacing);
26
+ `;
27
+ const EmptyState = styled.div `
28
+ padding: 16px;
29
+ `;
30
+ const EmptyStateTitle = styled(NotificationTitle) `
31
+ margin-top: 24px;
32
+ `;
33
+ const EmptyStateDescription = styled(NotificationDescription) `
34
+ color: var(--cds-text-secondary);
35
+ margin-top: 8px;
36
+ `;
37
+ export const C3NotificationSidebar = ({ sideBar }) => {
38
+ const { isOpen } = sideBar;
39
+ const [isSidebarOpen, setIsSidebarOpen] = useState(isOpen);
40
+ const { notifications, markAsRead, dismiss } = useContext(C3NotificationContext);
41
+ const hasUnreadNotifications = notifications.some(({ state }) => state === "new");
42
+ const dismissAll = () => notifications.forEach((notification) => dismiss(notification));
43
+ return (React.createElement(C3NavigationSideBar, { sideBar: {
44
+ ...sideBar,
45
+ isOpen: isSidebarOpen,
46
+ setIsOpen: setIsSidebarOpen,
47
+ }, icon: hasUnreadNotifications ? (React.createElement(C3NotificationsUnreadIcon, { size: 20 })) : (React.createElement(NotificationIcon, { size: 20 })) },
48
+ React.createElement(PanelHeader, null,
49
+ React.createElement(PanelTitle, null, "Notifications"),
50
+ notifications.length > 0 && (React.createElement(Button, { kind: "ghost", size: "sm", onClick: dismissAll }, "Dismiss all"))),
51
+ notifications.length > 0 ? (notifications.map((notification) => (React.createElement(C3NotificationContainer, { key: notification.uuid, onRead: () => markAsRead(notification), onDismiss: () => dismiss(notification), ...notification })))) : (React.createElement(EmptyState, null,
52
+ React.createElement(C3BellIcon, { size: 56 }),
53
+ React.createElement(EmptyStateTitle, null, "No notifications"),
54
+ React.createElement(EmptyStateDescription, null, "New updates regarding your processes, clusters and more will appear here.")))));
55
+ };
@@ -0,0 +1,6 @@
1
+ import { FC } from "react";
2
+ import { C3NavigationOrgSideBarProps } from "./c3-navigation-sidebar.types";
3
+ declare const C3OrgSidebar: FC<{
4
+ sideBar: C3NavigationOrgSideBarProps;
5
+ }>;
6
+ export default C3OrgSidebar;
@@ -0,0 +1,51 @@
1
+ import React, { useState } from "react";
2
+ import { Button, FormLabel, SwitcherDivider } from "@carbon/react";
3
+ import { Enterprise } from "@carbon/react/icons";
4
+ import C3NavigationSideBar from "./c3-navigation-sidebar";
5
+ const C3OrgSidebar = ({ sideBar }) => {
6
+ const { customElements, isOpen, ...sideBarProps } = sideBar;
7
+ const activeOrganization = sideBar.customElements?.activeOrganization;
8
+ const [isSidebarOpen, setIsSidebarOpen] = useState(isOpen);
9
+ const itemTabIndex = isSidebarOpen ? undefined : -1;
10
+ return (React.createElement(C3NavigationSideBar, { sideBar: {
11
+ ...sideBarProps,
12
+ isOpen: isSidebarOpen,
13
+ setIsOpen: setIsSidebarOpen,
14
+ }, icon: React.createElement(Enterprise, { size: 20 }) }, activeOrganization && (React.createElement(React.Fragment, null,
15
+ React.createElement("div", { style: {
16
+ padding: "1rem",
17
+ paddingTop: "1.5rem",
18
+ paddingBottom: ".5rem",
19
+ display: "grid",
20
+ gridAutoFlow: "column",
21
+ gap: ".25rem",
22
+ } },
23
+ React.createElement("div", { style: {
24
+ overflow: "hidden",
25
+ display: "grid",
26
+ gap: "4px",
27
+ } },
28
+ React.createElement(FormLabel, null, activeOrganization.activeLabel),
29
+ React.createElement("div", { className: "textPrimary", style: {
30
+ height: "20px",
31
+ lineHeight: "20px",
32
+ fontSize: "14px",
33
+ textOverflow: "ellipsis",
34
+ overflow: "hidden",
35
+ whiteSpace: "nowrap",
36
+ }, title: activeOrganization.orgName }, activeOrganization.orgName)),
37
+ React.createElement(Button, { size: "md", kind: "ghost", key: "org-management", onClick: () => {
38
+ activeOrganization.action.onClick();
39
+ if (sideBar.closeOnClick !== false) {
40
+ setIsSidebarOpen(false);
41
+ }
42
+ }, tabIndex: itemTabIndex }, activeOrganization.action.label)),
43
+ sideBar.elements && sideBar.elements.length > 0 && (React.createElement(React.Fragment, null,
44
+ React.createElement(SwitcherDivider, null),
45
+ React.createElement(FormLabel, { style: {
46
+ paddingTop: ".5rem",
47
+ paddingLeft: "1rem",
48
+ paddingBottom: ".25rem",
49
+ } }, activeOrganization.otherLabel)))))));
50
+ };
51
+ export default C3OrgSidebar;
@@ -0,0 +1,6 @@
1
+ import { FC } from "react";
2
+ import { C3NavigationUserSideBarProps } from "./c3-navigation-sidebar.types";
3
+ declare const C3UserSidebar: FC<{
4
+ sideBar: C3NavigationUserSideBarProps;
5
+ }>;
6
+ export default C3UserSidebar;
@@ -0,0 +1,43 @@
1
+ import React, { useState } from "react";
2
+ import C3NavigationSideBar from "./c3-navigation-sidebar";
3
+ import { FormLabel, RadioButton, RadioButtonGroup, Stack, SwitcherDivider, Toggle, } from "@carbon/react";
4
+ import { UserAvatar } from "@carbon/react/icons";
5
+ const C3UserSidebar = ({ sideBar }) => {
6
+ const { customElements, isOpen, ...sideBarProps } = sideBar;
7
+ const profile = sideBar.customElements?.profile;
8
+ const themeSelector = sideBar.customElements?.themeSelector;
9
+ const stageToggle = sideBar.customElements?.stageToggle;
10
+ const [isSidebarOpen, setIsSidebarOpen] = useState(isOpen);
11
+ const itemTabIndex = isSidebarOpen ? undefined : -1;
12
+ return (React.createElement(C3NavigationSideBar, { sideBar: {
13
+ ...sideBarProps,
14
+ isOpen: isSidebarOpen,
15
+ setIsOpen: setIsSidebarOpen,
16
+ }, icon: React.createElement(UserAvatar, { size: 20 }) },
17
+ profile && (React.createElement("div", { style: {
18
+ padding: "1rem",
19
+ paddingTop: "1.5rem",
20
+ paddingBottom: ".5rem",
21
+ } },
22
+ React.createElement(Stack, { gap: 2 },
23
+ React.createElement(FormLabel, null, profile.label),
24
+ React.createElement(Stack, null,
25
+ React.createElement("div", { className: "textPrimary", style: { fontSize: "14px" } }, profile.user.name),
26
+ React.createElement("div", { className: "textPrimary", style: { fontSize: "12px" } }, profile.user.email))))),
27
+ themeSelector && (React.createElement(React.Fragment, null,
28
+ React.createElement(SwitcherDivider, null),
29
+ React.createElement("div", { style: {
30
+ padding: ".5rem 1rem",
31
+ } },
32
+ React.createElement(RadioButtonGroup, { name: "theme-radio-group", defaultSelected: themeSelector.currentTheme, legendText: "Theme", orientation: "vertical", onChange: (newValue) => {
33
+ themeSelector.onChange(newValue);
34
+ } },
35
+ React.createElement(RadioButton, { id: "light", labelText: "Light", value: "light", tabIndex: itemTabIndex }),
36
+ React.createElement(RadioButton, { id: "system", labelText: "System", value: "system", tabIndex: itemTabIndex }),
37
+ React.createElement(RadioButton, { id: "dark", labelText: "Dark", value: "dark", tabIndex: itemTabIndex }))))),
38
+ stageToggle && (React.createElement(React.Fragment, null,
39
+ React.createElement(SwitcherDivider, null),
40
+ React.createElement("div", { style: { padding: ".5rem 1rem" } },
41
+ React.createElement(Toggle, { size: "sm", id: "toggle-productionfeatures", defaultToggled: stageToggle.prodFeaturesEnabled, onClick: stageToggle.toggle, labelText: "Simulate Production Features", tabIndex: itemTabIndex }))))));
42
+ };
43
+ export default C3UserSidebar;
@@ -1,3 +1,3 @@
1
1
  /// <reference types="react" />
2
2
  import { C3NavigationProps } from "./c3-navigation.types";
3
- export declare const C3Navigation: ({ app, appBar, forwardRef, navbar, orgSideBar, infoSideBar, userSideBar, }: C3NavigationProps) => JSX.Element;
3
+ export declare const C3Navigation: ({ app, appBar, forwardRef, navbar, orgSideBar, infoSideBar, userSideBar, notificationSideBar, }: C3NavigationProps) => JSX.Element;