@camunda/camunda-composite-components 0.20.0 → 0.20.2
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 +3 -3
- package/lib/esm/src/api/api.d.ts +1 -0
- package/lib/esm/src/api/api.js +1 -0
- package/lib/esm/src/api/help-center.d.ts +2 -1
- package/lib/esm/src/api/help-center.js +10 -6
- package/lib/esm/src/components/c3-data-table/c3-data-table.js +5 -1
- package/lib/esm/src/components/c3-empty-state/c3-empty-state.js +13 -2
- package/lib/esm/src/components/c3-help-center/c3-help-center-provider.d.ts +17 -0
- package/lib/esm/src/components/c3-help-center/c3-help-center-provider.js +118 -2
- package/lib/esm/src/components/c3-help-center/c3-help-center.d.ts +0 -2
- package/lib/esm/src/components/c3-help-center/c3-help-center.js +33 -68
- package/lib/esm/src/components/c3-help-center/help-center.js +81 -80
- package/lib/esm/src/components/c3-help-center/styles.js +3 -0
- package/lib/esm/src/components/c3-help-center/tile.js +41 -35
- package/lib/esm/src/components/c3-navigation/c3-navigation-appbar/c3-navigation-appbar.js +14 -0
- package/lib/esm/src/components/c3-navigation/c3-navigation.js +12 -7
- package/lib/esm/src/components/c3-navigation/c3-org-name.js +0 -1
- package/lib/esm/src/components/c3-onboarding-survey/c3-onboarding-survey.js +8 -36
- package/lib/esm/src/components/c3-onboarding-survey/elements/dropdownSelect.js +2 -1
- package/lib/esm/src/components/c3-user-configuration/c3-user-configuration-provider.js +5 -12
- package/package.json +3 -3
package/lib/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camunda/camunda-composite-components",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"peerDependencies": {
|
|
105
105
|
"@carbon/react": "1.x",
|
|
106
106
|
"event-source-polyfill": "1.0.x",
|
|
107
|
-
"react": "18.x",
|
|
108
|
-
"react-dom": "18.x",
|
|
107
|
+
"react": "18.x || 19.x",
|
|
108
|
+
"react-dom": "18.x || 19.x",
|
|
109
109
|
"styled-components": "5.x || 6.x"
|
|
110
110
|
},
|
|
111
111
|
"description": "Camunda Composite Components",
|
package/lib/esm/src/api/api.d.ts
CHANGED
package/lib/esm/src/api/api.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Persona, TileConfig, WpCardType } from "../components/c3-help-center/c3
|
|
|
3
3
|
import { OnboardingConfig } from "../components/c3-onboarding-survey/defaultOnboardingConfig";
|
|
4
4
|
import { RequestPayload, RequestResponse } from "./api";
|
|
5
5
|
export declare const getConfig: (accessToken: string, audience: string, orgId: string) => Promise<RequestResponse<HelpCenterConfig | null>>;
|
|
6
|
-
export declare const getTiles: ({ accessToken, tileConfig, salesPlanType, clusterIds, persona, flags, cloudAudience, }: {
|
|
6
|
+
export declare const getTiles: ({ accessToken, tileConfig, salesPlanType, clusterIds, persona, flags, cloudAudience, signal, }: {
|
|
7
7
|
accessToken: string;
|
|
8
8
|
tileConfig: TileConfig[];
|
|
9
9
|
cloudAudience: string;
|
|
@@ -13,6 +13,7 @@ export declare const getTiles: ({ accessToken, tileConfig, salesPlanType, cluste
|
|
|
13
13
|
clusterIds: string[];
|
|
14
14
|
salesPlanType: string;
|
|
15
15
|
flags: string[];
|
|
16
|
+
signal?: AbortSignal | undefined;
|
|
16
17
|
}) => Promise<RequestResponse<WpCardType[]>>;
|
|
17
18
|
export declare const getOnboardingConfig: ({ camundaAuth, audience, orgId, }: {
|
|
18
19
|
audience: string;
|
|
@@ -8,13 +8,17 @@ export const getConfig = async (accessToken, audience, orgId) => {
|
|
|
8
8
|
},
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
export const getTiles = async ({ accessToken, tileConfig, salesPlanType, clusterIds, persona, flags, cloudAudience, }) => {
|
|
11
|
+
export const getTiles = async ({ accessToken, tileConfig, salesPlanType, clusterIds, persona, flags, cloudAudience, signal, }) => {
|
|
12
12
|
const availableTileTypes = recommendations(persona, flags, tileConfig, salesPlanType, clusterIds?.length > 0);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
if (availableTileTypes.length) {
|
|
14
|
+
return await request({
|
|
15
|
+
url: `https://helpcenter.${cloudAudience}/cards?card_id=${availableTileTypes.join(",")}`,
|
|
16
|
+
responseType: "json",
|
|
17
|
+
camundaAuth: { token: accessToken },
|
|
18
|
+
signal,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return { success: true };
|
|
18
22
|
};
|
|
19
23
|
export const getOnboardingConfig = ({ camundaAuth, audience, orgId, }) => request({
|
|
20
24
|
url: `https://helpcenter.${audience}/survey/config/${orgId}`,
|
|
@@ -444,7 +444,11 @@ export const C3DataTable = ({ data, headers, options, toolbar: singleToolbar, to
|
|
|
444
444
|
headerKeys.map((key) => {
|
|
445
445
|
return rowCell(key);
|
|
446
446
|
}),
|
|
447
|
-
hasActions && (React.createElement(TableCell, { style: { textAlign: "right" } },
|
|
447
|
+
hasActions && (React.createElement(TableCell, { style: { textAlign: "right" } },
|
|
448
|
+
React.createElement("div", { style: {
|
|
449
|
+
display: "flex",
|
|
450
|
+
alignItems: "center",
|
|
451
|
+
} }, renderActions(row))))));
|
|
448
452
|
if (row.expansion) {
|
|
449
453
|
rowComponent = (React.createElement(React.Fragment, { key: row.id },
|
|
450
454
|
React.createElement(TableExpandRow, { key: row.id, isExpanded: isRowExpanded(row), "aria-label": `row ${row.id}`, onExpand: () => {
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { Stack, Tile, Button, Link, MenuButton, MenuItem } from "@carbon/react";
|
|
2
|
+
import styled from "styled-components";
|
|
2
3
|
import React from "react";
|
|
4
|
+
const ResponsiveStack = styled.div `
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: ${({ orientation }) => `${orientation === "vertical" ? "column" : "row"}`};
|
|
7
|
+
gap: ${({ gap }) => `${typeof gap === "string" ? gap : `${gap ?? 0 * 16}px`}`};
|
|
8
|
+
|
|
9
|
+
@media (max-width: 768px) {
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
3
13
|
export const C3EmptyState = ({ icon, heading, description, button, link, }) => (React.createElement(Tile, { style: {
|
|
4
14
|
paddingLeft: "5rem",
|
|
5
15
|
paddingTop: "3rem",
|
|
6
16
|
paddingBottom: "3rem",
|
|
7
17
|
} },
|
|
8
|
-
React.createElement(
|
|
9
|
-
icon && React.createElement("
|
|
18
|
+
React.createElement(ResponsiveStack, { orientation: "horizontal", gap: "1.5rem" },
|
|
19
|
+
icon && (React.createElement("div", { style: { maxWidth: "80px" } },
|
|
20
|
+
React.createElement("img", { src: icon.path, alt: icon.altText, style: { width: "100%" } }))),
|
|
10
21
|
React.createElement(Stack, { gap: 3 },
|
|
11
22
|
React.createElement("h2", null, heading),
|
|
12
23
|
React.createElement(Stack, { gap: 6 },
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import React, { FC, PropsWithChildren } from "react";
|
|
2
|
+
import { HelpCenterConfig } from "./defaultHelpCenterConfig";
|
|
3
|
+
import { Persona, WpCardType } from "./c3-help-center.types";
|
|
4
|
+
import { OnboardingConfig } from "../c3-onboarding-survey/defaultOnboardingConfig";
|
|
2
5
|
export declare enum HelpCenterHintType {
|
|
3
6
|
HelpCenter = "help-center",
|
|
4
7
|
Onboarding = "onboarding"
|
|
@@ -13,6 +16,20 @@ export type C3HelpCenterContextValue = {
|
|
|
13
16
|
setShowHintOnClose: (showHintOnClose: boolean) => void;
|
|
14
17
|
hintType: HelpCenterHintType;
|
|
15
18
|
setHintType: (hintType: HelpCenterHintType) => void;
|
|
19
|
+
helpCenterConfig: HelpCenterConfig;
|
|
20
|
+
persona: Persona | undefined;
|
|
21
|
+
setPersona: (persona: Persona | undefined) => void;
|
|
22
|
+
rawTabTiles: {
|
|
23
|
+
[id: string]: WpCardType[];
|
|
24
|
+
};
|
|
25
|
+
isLoadingTiles: boolean;
|
|
26
|
+
updateFlags: (flags: string[]) => void;
|
|
27
|
+
updateAutoStartSurvey: (autoStart: boolean) => void;
|
|
28
|
+
showSurvey: boolean;
|
|
29
|
+
setShowSurvey: (showSurvey: boolean) => void;
|
|
30
|
+
onboadingConfig: OnboardingConfig;
|
|
31
|
+
isLoadingOnboardingConfig: boolean;
|
|
32
|
+
getOnboadingSurveyConfig: (audience: string) => Promise<void>;
|
|
16
33
|
};
|
|
17
34
|
export declare const C3HelpCenterContext: React.Context<C3HelpCenterContextValue>;
|
|
18
35
|
export declare const C3HelpCenterProvider: FC<PropsWithChildren>;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState, } from "react";
|
|
2
|
+
import { getConfig, getOnboardingConfig, getTiles } from "../../api/help-center";
|
|
3
|
+
import { useC3UserConfiguration } from "../c3-user-configuration/c3-user-configuration-provider";
|
|
4
|
+
import { defaultHelpCenterConfig, } from "./defaultHelpCenterConfig";
|
|
5
|
+
import { useC3Profile } from "../c3-user-configuration/c3-profile-provider/c3-profile-provider";
|
|
6
|
+
import { defaultOnboardingConfig, } from "../c3-onboarding-survey/defaultOnboardingConfig";
|
|
2
7
|
export var HelpCenterHintType;
|
|
3
8
|
(function (HelpCenterHintType) {
|
|
4
9
|
HelpCenterHintType["HelpCenter"] = "help-center";
|
|
@@ -13,6 +18,18 @@ export const C3HelpCenterContext = React.createContext({
|
|
|
13
18
|
setShowHintOnClose: () => undefined,
|
|
14
19
|
hintType: HelpCenterHintType.Onboarding,
|
|
15
20
|
setHintType: () => undefined,
|
|
21
|
+
helpCenterConfig: defaultHelpCenterConfig,
|
|
22
|
+
persona: undefined,
|
|
23
|
+
setPersona: () => undefined,
|
|
24
|
+
rawTabTiles: {},
|
|
25
|
+
isLoadingTiles: false,
|
|
26
|
+
updateFlags: () => undefined,
|
|
27
|
+
updateAutoStartSurvey: () => undefined,
|
|
28
|
+
showSurvey: false,
|
|
29
|
+
setShowSurvey: () => undefined,
|
|
30
|
+
onboadingConfig: defaultOnboardingConfig,
|
|
31
|
+
isLoadingOnboardingConfig: false,
|
|
32
|
+
getOnboadingSurveyConfig: () => undefined,
|
|
16
33
|
});
|
|
17
34
|
export const C3HelpCenterProvider = ({ children }) => {
|
|
18
35
|
const [isHelpCenterOpen, setIsHelpCenterOpen] = useState(false);
|
|
@@ -20,10 +37,97 @@ export const C3HelpCenterProvider = ({ children }) => {
|
|
|
20
37
|
const [showHint, setShowHint] = useState(false);
|
|
21
38
|
const [showHintOnClose, setShowHintOnClose] = useState(false);
|
|
22
39
|
const [hintType, setHintType] = useState(HelpCenterHintType.Onboarding);
|
|
23
|
-
const
|
|
40
|
+
const [helpCenterConfig, setHelpCenterConfig] = useState(defaultHelpCenterConfig);
|
|
41
|
+
const [showSurvey, setShowSurvey] = useState(false);
|
|
42
|
+
const [onboadingConfig, setOnboardConfig] = useState(defaultOnboardingConfig);
|
|
43
|
+
const [isLoadingOnboardingConfig, setIsLoadingOnboardingConfig] = useState(false);
|
|
44
|
+
const { activeOrg: organization, clusters } = useC3Profile();
|
|
45
|
+
const clusterIds = (clusters || []).map((cluster) => cluster.uuid);
|
|
46
|
+
const [rawTabTiles, setRawTabTiles] = useState({});
|
|
47
|
+
const [isLoadingTiles, setIsLoadingTiles] = useState(true);
|
|
48
|
+
const [persona, setPersona] = useState(undefined);
|
|
49
|
+
const tabCache = useRef(new Map());
|
|
50
|
+
const flags = useRef([]);
|
|
51
|
+
const updateFlags = (updatedFlags) => {
|
|
52
|
+
flags.current = updatedFlags;
|
|
53
|
+
};
|
|
54
|
+
const autoStartSurvey = useRef(false);
|
|
55
|
+
const updateAutoStartSurvey = (autoStart) => {
|
|
56
|
+
autoStartSurvey.current = autoStart;
|
|
57
|
+
};
|
|
58
|
+
const { userToken, activeOrganizationId, decodedAudience, decodedToken } = useC3UserConfiguration();
|
|
59
|
+
const getTileData = async (tabs) => {
|
|
60
|
+
if (!decodedAudience) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const { persona: tokenPersona } = decodedToken ?? {};
|
|
64
|
+
const tiles = {};
|
|
65
|
+
setIsLoadingTiles(true);
|
|
66
|
+
for (const singleTab of tabs) {
|
|
67
|
+
if (userToken) {
|
|
68
|
+
if (tabCache.current.has(singleTab.id)) {
|
|
69
|
+
tiles[singleTab.id] = tabCache.current.get(singleTab.id);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const { result } = await getTiles({
|
|
73
|
+
tileConfig: singleTab.tiles,
|
|
74
|
+
cloudAudience: decodedAudience,
|
|
75
|
+
persona: tokenPersona ?? {},
|
|
76
|
+
clusterIds,
|
|
77
|
+
salesPlanType: organization?.salesPlan?.type ?? "",
|
|
78
|
+
flags: flags.current,
|
|
79
|
+
accessToken: userToken,
|
|
80
|
+
});
|
|
81
|
+
if (result) {
|
|
82
|
+
tiles[singleTab.id] = result;
|
|
83
|
+
tabCache.current.set(singleTab.id, result);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
setIsLoadingTiles(false);
|
|
88
|
+
setRawTabTiles(tiles);
|
|
89
|
+
};
|
|
90
|
+
const getOnboadingSurveyConfig = useCallback(async (decodedAudience) => {
|
|
91
|
+
setIsLoadingOnboardingConfig(true);
|
|
92
|
+
const { result: config } = await getOnboardingConfig({
|
|
93
|
+
audience: decodedAudience,
|
|
94
|
+
camundaAuth: { token: userToken },
|
|
95
|
+
orgId: activeOrganizationId,
|
|
96
|
+
});
|
|
97
|
+
if (config) {
|
|
98
|
+
setOnboardConfig(config);
|
|
99
|
+
}
|
|
100
|
+
setIsLoadingOnboardingConfig(false);
|
|
101
|
+
}, [activeOrganizationId, userToken]);
|
|
102
|
+
const openHelpCenter = async (showTabId) => {
|
|
24
103
|
if (!isHelpCenterOpen) {
|
|
25
104
|
setIsHelpCenterOpen(true);
|
|
26
105
|
setShowHint(false);
|
|
106
|
+
if (decodedAudience) {
|
|
107
|
+
const { persona: tokenPersona } = decodedToken ?? {};
|
|
108
|
+
if (showSurvey || autoStartSurvey.current || !tokenPersona?.wasShown) {
|
|
109
|
+
setIsLoadingTiles(false);
|
|
110
|
+
await getOnboadingSurveyConfig(decodedAudience);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const { result } = await getConfig(userToken, decodedAudience, activeOrganizationId);
|
|
114
|
+
const config = result || defaultHelpCenterConfig;
|
|
115
|
+
await getTileData(config?.tabs);
|
|
116
|
+
setHelpCenterConfig(config);
|
|
117
|
+
}
|
|
118
|
+
if (tokenPersona !== undefined) {
|
|
119
|
+
setPersona(tokenPersona);
|
|
120
|
+
if (tokenPersona.wasShown) {
|
|
121
|
+
setShowSurvey(false);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
setPersona({ wasShown: false });
|
|
126
|
+
}
|
|
127
|
+
if (autoStartSurvey.current && !tokenPersona?.wasShown) {
|
|
128
|
+
setIsHelpCenterOpen(true);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
27
131
|
}
|
|
28
132
|
if (showTabId)
|
|
29
133
|
setActiveTabId(showTabId);
|
|
@@ -47,6 +151,18 @@ export const C3HelpCenterProvider = ({ children }) => {
|
|
|
47
151
|
setShowHintOnClose,
|
|
48
152
|
hintType,
|
|
49
153
|
setHintType,
|
|
154
|
+
helpCenterConfig,
|
|
155
|
+
persona,
|
|
156
|
+
setPersona,
|
|
157
|
+
rawTabTiles,
|
|
158
|
+
isLoadingTiles,
|
|
159
|
+
updateFlags,
|
|
160
|
+
showSurvey,
|
|
161
|
+
setShowSurvey,
|
|
162
|
+
onboadingConfig,
|
|
163
|
+
isLoadingOnboardingConfig,
|
|
164
|
+
updateAutoStartSurvey,
|
|
165
|
+
getOnboadingSurveyConfig,
|
|
50
166
|
} }, children));
|
|
51
167
|
};
|
|
52
168
|
export const useC3HelpCenter = () => React.useContext(C3HelpCenterContext);
|
|
@@ -9,8 +9,6 @@ export interface C3HelpCenterProps {
|
|
|
9
9
|
activeTab?: string;
|
|
10
10
|
autoStartSurvey?: boolean;
|
|
11
11
|
onPersonaChange?: (persona: Persona) => void;
|
|
12
|
-
onRequestClose?: () => void;
|
|
13
|
-
onRequestOpen?: () => void;
|
|
14
12
|
mixpanelTrack?: (event: string, data: Dict | undefined) => void;
|
|
15
13
|
}
|
|
16
14
|
export declare const C3HelpCenter: FC<C3HelpCenterProps>;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ActionableNotification, ComposedModal, Layer, ModalBody, ModalHeader, } from "@carbon/react";
|
|
2
|
-
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { HelpCenter } from "./help-center";
|
|
4
|
-
import { defaultHelpCenterConfig } from "./defaultHelpCenterConfig";
|
|
5
4
|
import { C3OnboardingSurvey } from "../c3-onboarding-survey/c3-onboarding-survey";
|
|
6
|
-
import {
|
|
5
|
+
import { updatePersona } from "../../api/help-center";
|
|
7
6
|
import { useC3UserConfiguration } from "../c3-user-configuration/c3-user-configuration-provider";
|
|
8
7
|
import { defaultTheme, useC3Profile, } from "../c3-user-configuration/c3-profile-provider/c3-profile-provider";
|
|
9
8
|
import { resolveTheme, } from "../c3-user-configuration/c3-profile-provider/carbon-theme-provider";
|
|
@@ -15,29 +14,26 @@ const StyledComposedModal = styled(ComposedModal) `
|
|
|
15
14
|
mask-image: none;
|
|
16
15
|
}
|
|
17
16
|
`;
|
|
18
|
-
export const C3HelpCenter = ({ autoStartSurvey, origin, flags,
|
|
19
|
-
const { isHelpCenterOpen: isOpen, setIsHelpCenterOpen, setShowHintOnClose, } = useC3HelpCenter();
|
|
17
|
+
export const C3HelpCenter = ({ autoStartSurvey, origin, flags, mixpanelTrack: customMixpanelTrack, theme, onPersonaChange, activeTab, }) => {
|
|
18
|
+
const { isHelpCenterOpen: isOpen, setIsHelpCenterOpen, setShowHintOnClose, helpCenterConfig, persona, setPersona, showSurvey, setShowSurvey, updateAutoStartSurvey, getOnboadingSurveyConfig, } = useC3HelpCenter();
|
|
20
19
|
const { userToken, decodedToken, activeOrganizationId, handleTheme, decodedAudience, analyticsTrack, currentApp, } = useC3UserConfiguration();
|
|
21
|
-
const { theme: themeConfig, isEnabled
|
|
20
|
+
const { theme: themeConfig, isEnabled } = useC3Profile();
|
|
22
21
|
const themeHandlingEnabled = isEnabled && !!handleTheme && !!themeConfig;
|
|
23
22
|
const themeRef = useRef();
|
|
24
23
|
const [resolvedTheme, setResolvedTheme] = useState(defaultTheme);
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const [helpCenterConfig, setHelpCenterConfig] = useState(defaultHelpCenterConfig);
|
|
28
|
-
const [email, setEmail] = useState("");
|
|
29
|
-
const [showSurvey, setShowSurvey] = useState(autoStartSurvey);
|
|
24
|
+
const userId = decodedToken?.userId ?? "";
|
|
25
|
+
const email = decodedToken?.meta?.email ?? "";
|
|
30
26
|
if (!origin && !currentApp)
|
|
31
27
|
console.warn("No app provided to the help center. Please provide the `currentApp` prop to the `C3UserConfigurationProvider`.");
|
|
32
28
|
const hostApp = origin || currentApp === "modeler" ? "webmodeler" : currentApp || "console";
|
|
33
|
-
const mixpanelTrack = (event, data) => {
|
|
29
|
+
const mixpanelTrack = useCallback((event, data) => {
|
|
34
30
|
if (customMixpanelTrack) {
|
|
35
31
|
customMixpanelTrack(event, data);
|
|
36
32
|
}
|
|
37
33
|
else if (analyticsTrack) {
|
|
38
34
|
analyticsTrack(event, data);
|
|
39
35
|
}
|
|
40
|
-
};
|
|
36
|
+
}, []);
|
|
41
37
|
useEffect(() => {
|
|
42
38
|
const updateResolvedTheme = ({ matches }) => {
|
|
43
39
|
if (themeRef.current === "system") {
|
|
@@ -57,56 +53,13 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
|
|
|
57
53
|
const newTheme = themeHandlingEnabled ? themeConfig : theme;
|
|
58
54
|
themeRef.current = newTheme;
|
|
59
55
|
setResolvedTheme(resolveTheme(newTheme || "light"));
|
|
60
|
-
}, [theme, themeConfig, isOpen]);
|
|
61
|
-
const fetchConfig = async () => {
|
|
62
|
-
if (!userToken || !decodedAudience)
|
|
63
|
-
return;
|
|
64
|
-
const { result: config } = await getConfig(userToken, decodedAudience, activeOrganizationId);
|
|
65
|
-
setHelpCenterConfig(config || defaultHelpCenterConfig);
|
|
66
|
-
};
|
|
67
|
-
const isFirstLoad = useRef(true);
|
|
68
|
-
const fetchData = async () => {
|
|
69
|
-
if (!userToken || !decodedToken || !decodedAudience)
|
|
70
|
-
return;
|
|
71
|
-
const { userId, meta, persona: tokenPersona } = decodedToken;
|
|
72
|
-
if (tokenPersona !== undefined) {
|
|
73
|
-
setPersona(tokenPersona);
|
|
74
|
-
if (tokenPersona.wasShown) {
|
|
75
|
-
setShowSurvey(false);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
setPersona({ wasShown: false });
|
|
80
|
-
}
|
|
81
|
-
if (meta)
|
|
82
|
-
setEmail(meta.email);
|
|
83
|
-
if (userId)
|
|
84
|
-
setUserId(userId);
|
|
85
|
-
if (autoStartSurvey && !tokenPersona?.wasShown) {
|
|
86
|
-
setIsHelpCenterOpen(true);
|
|
87
|
-
onRequestOpen?.();
|
|
88
|
-
}
|
|
89
|
-
await fetchConfig();
|
|
90
|
-
isFirstLoad.current = false;
|
|
91
|
-
};
|
|
92
|
-
React.useEffect(() => {
|
|
93
|
-
fetchData();
|
|
94
|
-
}, [JSON.stringify(decodedToken), decodedAudience]);
|
|
56
|
+
}, [theme, themeConfig, isOpen, themeHandlingEnabled]);
|
|
95
57
|
useEffect(() => {
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
fetchConfig();
|
|
102
|
-
reloadClusters();
|
|
103
|
-
}, [persona?.complete]);
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
if (isFirstLoad.current || !activeOrganizationId)
|
|
106
|
-
return;
|
|
107
|
-
fetchConfig();
|
|
108
|
-
reloadClusters();
|
|
109
|
-
}, [activeOrganizationId]);
|
|
58
|
+
if (autoStartSurvey) {
|
|
59
|
+
setShowSurvey(autoStartSurvey);
|
|
60
|
+
}
|
|
61
|
+
}, [autoStartSurvey, setShowSurvey]);
|
|
62
|
+
updateAutoStartSurvey(autoStartSurvey ?? false);
|
|
110
63
|
React.useEffect(() => {
|
|
111
64
|
const tabs = helpCenterConfig.tabs;
|
|
112
65
|
const firstTab = tabs[0]?.id;
|
|
@@ -129,7 +82,21 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
|
|
|
129
82
|
from: origin,
|
|
130
83
|
});
|
|
131
84
|
}
|
|
132
|
-
}, [
|
|
85
|
+
}, [
|
|
86
|
+
activeOrganizationId,
|
|
87
|
+
activeTab,
|
|
88
|
+
autoStartSurvey,
|
|
89
|
+
decodedAudience,
|
|
90
|
+
helpCenterConfig.tabs,
|
|
91
|
+
isOpen,
|
|
92
|
+
mixpanelTrack,
|
|
93
|
+
origin,
|
|
94
|
+
persona,
|
|
95
|
+
setPersona,
|
|
96
|
+
setShowHintOnClose,
|
|
97
|
+
userId,
|
|
98
|
+
userToken,
|
|
99
|
+
]);
|
|
133
100
|
const onRequestRetakeSurvey = () => {
|
|
134
101
|
if (!userToken || !activeOrganizationId || !decodedAudience)
|
|
135
102
|
return;
|
|
@@ -148,9 +115,10 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
|
|
|
148
115
|
onPersonaChange?.(newPersona);
|
|
149
116
|
setShowSurvey(true);
|
|
150
117
|
};
|
|
151
|
-
const onRequestResumeSurvey = () => {
|
|
118
|
+
const onRequestResumeSurvey = async () => {
|
|
152
119
|
if (!userToken || !activeOrganizationId || !decodedAudience)
|
|
153
120
|
return;
|
|
121
|
+
await getOnboadingSurveyConfig(decodedAudience);
|
|
154
122
|
const newPersona = { ...persona, ...{ complete: false, wasShown: true } };
|
|
155
123
|
setPersona(newPersona);
|
|
156
124
|
updatePersona({
|
|
@@ -196,9 +164,6 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
|
|
|
196
164
|
userId,
|
|
197
165
|
});
|
|
198
166
|
}
|
|
199
|
-
onRequestClose?.();
|
|
200
|
-
fetchConfig();
|
|
201
|
-
reloadClusters();
|
|
202
167
|
// wait for modal transition
|
|
203
168
|
setTimeout(() => {
|
|
204
169
|
setShowSurvey(false);
|
|
@@ -211,5 +176,5 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
|
|
|
211
176
|
React.createElement(ErrorBoundary, { fallbackRender: () => (React.createElement(React.Fragment, null,
|
|
212
177
|
React.createElement(ModalHeader, { title: "Help Center", closeModal: closeFn }),
|
|
213
178
|
React.createElement(ModalBody, null,
|
|
214
|
-
React.createElement(ActionableNotification, { inline: true, hideCloseButton: true, lowContrast: true, kind: "error", title: "Something went wrong.", subtitle: "Try reloading the page.", actionButtonLabel: "Reload", onActionButtonClick: () => window.location.reload() })))) }, showSurvey || !persona?.wasShown ? (React.createElement(C3OnboardingSurvey, { personaCallback: personaCallback, persona: persona, mixpanelTrack: mixpanelTrack, onRequestClose: closeFn, onRequestSkip: onRequestSkipSurvey, theme: resolvedTheme, origin: hostApp, modal: true })) : (React.createElement(HelpCenter, { configuration: helpCenterConfig, persona: persona, audience: decodedAudience || "", flags: flags, onRequestResumeSurvey: onRequestResumeSurvey, onRequestRetakeSurvey: onRequestRetakeSurvey, onRequestClose: closeFn, mixpanelTrack: mixpanelTrack, email: email, theme: resolvedTheme, origin: hostApp, initialTab: activeTab }))))));
|
|
179
|
+
React.createElement(ActionableNotification, { inline: true, hideCloseButton: true, lowContrast: true, kind: "error", title: "Something went wrong.", subtitle: "Try reloading the page.", actionButtonLabel: "Reload", onActionButtonClick: () => window.location.reload() })))) }, showSurvey || (persona && !persona?.wasShown) ? (React.createElement(C3OnboardingSurvey, { personaCallback: personaCallback, persona: persona, mixpanelTrack: mixpanelTrack, onRequestClose: closeFn, onRequestSkip: onRequestSkipSurvey, theme: resolvedTheme, origin: hostApp, modal: true })) : (React.createElement(HelpCenter, { configuration: helpCenterConfig, persona: persona ?? {}, audience: decodedAudience || "", flags: flags, onRequestResumeSurvey: onRequestResumeSurvey, onRequestRetakeSurvey: onRequestRetakeSurvey, onRequestClose: closeFn, mixpanelTrack: mixpanelTrack, email: email, theme: resolvedTheme, origin: hostApp, initialTab: activeTab }))))));
|
|
215
180
|
};
|
|
@@ -3,13 +3,13 @@ import { Undo } from "@carbon/react/icons";
|
|
|
3
3
|
import React, { useEffect, useState } from "react";
|
|
4
4
|
import { Feedback } from "./tabs/feedback";
|
|
5
5
|
import { TabContent } from "./tabs/tabContent";
|
|
6
|
-
import { getTiles } from "../../api/help-center";
|
|
7
6
|
import { useC3UserConfiguration } from "../c3-user-configuration/c3-user-configuration-provider";
|
|
8
7
|
import { useC3HelpCenter } from "./c3-help-center-provider";
|
|
9
8
|
import { useC3Profile } from "../c3-user-configuration/c3-profile-provider/c3-profile-provider";
|
|
10
9
|
import { TabContentSkeleton } from "./tabs/tabContentSkeleton";
|
|
11
10
|
import { StyledModalBody, StyledModalHeader } from "./styles";
|
|
12
11
|
import styled from "styled-components";
|
|
12
|
+
import { C3Tabs } from "../c3-page/c3-tabs/c3-tabs";
|
|
13
13
|
const StyledModalFooter = styled(ModalFooter) `
|
|
14
14
|
height: 62px;
|
|
15
15
|
padding-right: 16px;
|
|
@@ -20,53 +20,33 @@ const StyledModalFooter = styled(ModalFooter) `
|
|
|
20
20
|
border-color: ${({ $hcTheme }) => $hcTheme === "light" ? "#E0E0E0" : "#727272"};
|
|
21
21
|
background-color: ${({ $hcTheme }) => $hcTheme === "light" ? "#FFFFFF" : "#161616"};
|
|
22
22
|
`;
|
|
23
|
+
const SideNavWrapper = styled.div `
|
|
24
|
+
@media (max-width: 768px) {
|
|
25
|
+
display: none;
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
const SideNavMobileWrapper = styled.div `
|
|
29
|
+
display: none;
|
|
30
|
+
@media (max-width: 768px) {
|
|
31
|
+
display: block;
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
const StyledHeading = styled.h4 `
|
|
35
|
+
margin-left: 16rem;
|
|
36
|
+
@media (max-width: 768px) {
|
|
37
|
+
margin-left: 0rem;
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
23
40
|
export const HelpCenter = ({ configuration, persona, email, audience, flags = [], onRequestResumeSurvey, onRequestRetakeSurvey, onRequestClose, mixpanelTrack, theme, origin, initialTab, }) => {
|
|
24
41
|
const { tabs } = configuration;
|
|
25
42
|
const firstTab = tabs[0].id;
|
|
26
|
-
const {
|
|
43
|
+
const { activeOrganizationId, domain } = useC3UserConfiguration();
|
|
27
44
|
const { activeOrg: organization, clusters } = useC3Profile();
|
|
28
45
|
const clusterIds = (clusters || []).map((cluster) => cluster.uuid);
|
|
29
|
-
const { showTabId } = useC3HelpCenter();
|
|
46
|
+
const { showTabId, rawTabTiles, isLoadingTiles, updateFlags } = useC3HelpCenter();
|
|
30
47
|
const [activeTab, setActiveTab] = useState(firstTab);
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
const [isLoadingTiles, setIsLoadingTiles] = useState(false);
|
|
34
|
-
let header = "";
|
|
35
|
-
let content = React.createElement(React.Fragment, null);
|
|
36
|
-
React.useEffect(() => {
|
|
37
|
-
;
|
|
38
|
-
(async () => {
|
|
39
|
-
const tiles = {};
|
|
40
|
-
setIsLoadingTiles(true);
|
|
41
|
-
for (const singleTab of tabs) {
|
|
42
|
-
if (token) {
|
|
43
|
-
const { result } = await getTiles({
|
|
44
|
-
tileConfig: singleTab.tiles,
|
|
45
|
-
cloudAudience: audience,
|
|
46
|
-
persona,
|
|
47
|
-
clusterIds,
|
|
48
|
-
salesPlanType: organization?.salesPlan?.type ?? "",
|
|
49
|
-
flags,
|
|
50
|
-
accessToken: token,
|
|
51
|
-
});
|
|
52
|
-
if (result)
|
|
53
|
-
tiles[singleTab.id] = result;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
setIsLoadingTiles(false);
|
|
57
|
-
setRawTabTiles(tiles);
|
|
58
|
-
})();
|
|
59
|
-
}, [
|
|
60
|
-
token,
|
|
61
|
-
JSON.stringify(persona),
|
|
62
|
-
audience,
|
|
63
|
-
JSON.stringify(organization),
|
|
64
|
-
JSON.stringify(clusters),
|
|
65
|
-
JSON.stringify(tabs),
|
|
66
|
-
]);
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
if (!tabs || !rawTabTiles)
|
|
69
|
-
return;
|
|
48
|
+
updateFlags(flags);
|
|
49
|
+
const getTabTiles = () => {
|
|
70
50
|
const tiles = {};
|
|
71
51
|
for (const tab of tabs) {
|
|
72
52
|
if (rawTabTiles[tab.id])
|
|
@@ -80,8 +60,11 @@ export const HelpCenter = ({ configuration, persona, email, audience, flags = []
|
|
|
80
60
|
return card;
|
|
81
61
|
}) || [];
|
|
82
62
|
}
|
|
83
|
-
|
|
84
|
-
}
|
|
63
|
+
return tiles;
|
|
64
|
+
};
|
|
65
|
+
const tabTiles = getTabTiles();
|
|
66
|
+
let header = "";
|
|
67
|
+
let content = React.createElement(React.Fragment, null);
|
|
85
68
|
useEffect(() => {
|
|
86
69
|
setActiveTab(initialTab ?? firstTab);
|
|
87
70
|
}, [initialTab]);
|
|
@@ -154,7 +137,7 @@ export const HelpCenter = ({ configuration, persona, email, audience, flags = []
|
|
|
154
137
|
backgroundColor: theme === "light" ? "#FFFFFF" : "#161616",
|
|
155
138
|
marginBottom: "0",
|
|
156
139
|
} },
|
|
157
|
-
React.createElement(
|
|
140
|
+
React.createElement(StyledHeading, null, header)),
|
|
158
141
|
React.createElement(StyledModalBody, { style: {
|
|
159
142
|
backgroundColor: theme === "light" ? "#FFFFFF" : "#161616",
|
|
160
143
|
marginBottom: 0,
|
|
@@ -164,41 +147,59 @@ export const HelpCenter = ({ configuration, persona, email, audience, flags = []
|
|
|
164
147
|
? "634px"
|
|
165
148
|
: "696px",
|
|
166
149
|
} },
|
|
167
|
-
React.createElement(
|
|
168
|
-
React.createElement(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
150
|
+
React.createElement(SideNavMobileWrapper, null,
|
|
151
|
+
React.createElement(C3Tabs, { tabs: tabBar.map((link) => {
|
|
152
|
+
return {
|
|
153
|
+
id: link.id,
|
|
154
|
+
label: link.text,
|
|
155
|
+
content: null,
|
|
156
|
+
};
|
|
157
|
+
}), desiredTabId: activeTab, onTabChange: (tabId) => {
|
|
158
|
+
const link = tabBar.find((item) => item.id === tabId);
|
|
159
|
+
if (link) {
|
|
160
|
+
setActiveTab(link.name);
|
|
161
|
+
mixpanelTrack?.("helpcenter:open", {
|
|
162
|
+
to: link.id,
|
|
163
|
+
from: origin,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
} })),
|
|
167
|
+
React.createElement(SideNavWrapper, null,
|
|
168
|
+
React.createElement(SideNav, { isFixedNav: true, expanded: true, isChildOfHeader: false, "aria-label": "Side nav" },
|
|
169
|
+
React.createElement(SideNavItems, null,
|
|
170
|
+
React.createElement(SideNavMenuItem, null,
|
|
171
|
+
React.createElement("h5", null, "Help Center")),
|
|
172
|
+
React.createElement("li", { style: { marginTop: "4px" } },
|
|
173
|
+
React.createElement(Stack, null,
|
|
174
|
+
React.createElement("ul", null, tabBar.map(({ name, id, text }) => {
|
|
175
|
+
const active = activeTab === name;
|
|
176
|
+
let tabBackgroundColor = theme === "light" ? "#F4F4F4" : "#161616";
|
|
177
|
+
let tabButtonColor = theme === "light" ? "#525252" : "#f4f4f4";
|
|
178
|
+
if (active) {
|
|
179
|
+
tabBackgroundColor =
|
|
180
|
+
theme === "light" ? "#E5E5E5" : "#8D8D8D3D";
|
|
181
|
+
tabButtonColor =
|
|
182
|
+
theme === "light" ? "#161616" : "#f4f4f4";
|
|
183
|
+
}
|
|
184
|
+
return (React.createElement("li", { key: name },
|
|
185
|
+
React.createElement(Button, { className: active ? "active" : "", kind: "secondary", onClick: () => {
|
|
186
|
+
setActiveTab(name);
|
|
187
|
+
mixpanelTrack?.("helpcenter:open", {
|
|
188
|
+
to: id,
|
|
189
|
+
from: origin,
|
|
190
|
+
});
|
|
191
|
+
}, style: {
|
|
192
|
+
width: "100%",
|
|
193
|
+
backgroundColor: tabBackgroundColor,
|
|
194
|
+
color: tabButtonColor,
|
|
195
|
+
}, "aria-label": text }, text)));
|
|
196
|
+
})))),
|
|
197
|
+
React.createElement("li", { style: { position: "absolute", bottom: "20px" } },
|
|
198
|
+
React.createElement("ul", null, configuration.links?.map((link) => (React.createElement(SideNavMenuItem, { key: link.label.split(" ").join("-").toLowerCase(), href: link.link,
|
|
199
|
+
// eslint-disable-next-line
|
|
200
|
+
// @ts-ignore
|
|
201
|
+
target: "_blank" },
|
|
202
|
+
React.createElement("span", { className: "cds--link" }, link.label))))))))),
|
|
202
203
|
content,
|
|
203
204
|
React.createElement("div", { style: { display: activeTab === "feedback" ? "block" : "none" } },
|
|
204
205
|
React.createElement(Feedback, { audience: audience, theme: theme, mixpanelTrack: mixpanelTrack, setHeader: (head) => {
|
|
@@ -18,45 +18,51 @@ const TileStack = styled.div `
|
|
|
18
18
|
display: flex;
|
|
19
19
|
flex-direction: column;
|
|
20
20
|
`;
|
|
21
|
+
const TileWrapper = styled.div `
|
|
22
|
+
width: ${({ $width }) => `${$width}px`};
|
|
23
|
+
@media (max-width: 768px) {
|
|
24
|
+
width: auto;
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
21
27
|
export const HelpCenterTile = ({ tile, tabType, origin, mixpanelTrack }) => {
|
|
22
28
|
const { title, description, timeToComplete, cta, image, link, card_id } = tile;
|
|
23
29
|
if (tabType === TAB_TYPES.Grid) {
|
|
24
|
-
return (React.createElement(
|
|
30
|
+
return (React.createElement(TileWrapper, { "$width": 300 },
|
|
31
|
+
React.createElement(Tile, { style: {
|
|
32
|
+
justifySelf: "start",
|
|
33
|
+
}, className: "cds--layer-two" },
|
|
34
|
+
React.createElement(Stack, { orientation: "vertical", gap: 3 },
|
|
35
|
+
React.createElement("img", { src: image, alt: title }),
|
|
36
|
+
React.createElement(TileStack, null,
|
|
37
|
+
React.createElement(TileHeading, null, title),
|
|
38
|
+
React.createElement(TileDescription, null, description),
|
|
39
|
+
React.createElement("div", { style: { marginLeft: "-4px", marginTop: "12px" } }, (() => {
|
|
40
|
+
let content = React.createElement("div", { style: { height: "32px" } });
|
|
41
|
+
if (timeToComplete) {
|
|
42
|
+
content = (React.createElement(Tag, { type: "warm-gray", size: "sm", title: timeToComplete }, timeToComplete));
|
|
43
|
+
}
|
|
44
|
+
return content;
|
|
45
|
+
})()))),
|
|
46
|
+
React.createElement(Button, { size: "sm", as: "a", href: link, target: "_blank", onClick: () => {
|
|
47
|
+
mixpanelTrack?.(`helpcenter:click`, {
|
|
48
|
+
from: origin,
|
|
49
|
+
to: card_id,
|
|
50
|
+
});
|
|
51
|
+
}, renderIcon: ArrowRight, kind: "tertiary", className: "cds--switcher__item", style: { alignSelf: "end", marginTop: "10px", maxWidth: "100%" } }, cta))));
|
|
52
|
+
}
|
|
53
|
+
return (React.createElement(TileWrapper, { "$width": 214 },
|
|
54
|
+
React.createElement(Tile, { style: {
|
|
25
55
|
justifySelf: "start",
|
|
26
|
-
|
|
27
|
-
}, className: "cds--layer-two"
|
|
56
|
+
height: "initial",
|
|
57
|
+
}, className: "cds--layer-two", onClick: () => {
|
|
58
|
+
mixpanelTrack?.(`helpcenter:click`, {
|
|
59
|
+
to: card_id,
|
|
60
|
+
from: origin,
|
|
61
|
+
});
|
|
62
|
+
} },
|
|
28
63
|
React.createElement(Stack, { orientation: "vertical", gap: 3 },
|
|
29
64
|
React.createElement("img", { src: image, alt: title }),
|
|
30
|
-
React.createElement(
|
|
31
|
-
React.createElement(
|
|
32
|
-
React.createElement(
|
|
33
|
-
React.createElement("div", { style: { marginLeft: "-4px", marginTop: "12px" } }, (() => {
|
|
34
|
-
let content = React.createElement("div", { style: { height: "32px" } });
|
|
35
|
-
if (timeToComplete) {
|
|
36
|
-
content = (React.createElement(Tag, { type: "warm-gray", size: "sm", title: timeToComplete }, timeToComplete));
|
|
37
|
-
}
|
|
38
|
-
return content;
|
|
39
|
-
})()))),
|
|
40
|
-
React.createElement(Button, { size: "sm", as: "a", href: link, target: "_blank", onClick: () => {
|
|
41
|
-
mixpanelTrack?.(`helpcenter:click`, {
|
|
42
|
-
from: origin,
|
|
43
|
-
to: card_id,
|
|
44
|
-
});
|
|
45
|
-
}, renderIcon: ArrowRight, kind: "tertiary", className: "cds--switcher__item", style: { alignSelf: "end", marginTop: "10px", maxWidth: "100%" } }, cta)));
|
|
46
|
-
}
|
|
47
|
-
return (React.createElement(Tile, { style: {
|
|
48
|
-
justifySelf: "start",
|
|
49
|
-
width: "214px",
|
|
50
|
-
height: "initial",
|
|
51
|
-
}, className: "cds--layer-two", onClick: () => {
|
|
52
|
-
mixpanelTrack?.(`helpcenter:click`, {
|
|
53
|
-
to: card_id,
|
|
54
|
-
from: origin,
|
|
55
|
-
});
|
|
56
|
-
} },
|
|
57
|
-
React.createElement(Stack, { orientation: "vertical", gap: 3 },
|
|
58
|
-
React.createElement("img", { src: image, alt: title }),
|
|
59
|
-
React.createElement(Stack, null,
|
|
60
|
-
React.createElement("h5", null, title),
|
|
61
|
-
React.createElement(ReactMarkdown, { linkTarget: "_blank" }, description)))));
|
|
65
|
+
React.createElement(Stack, null,
|
|
66
|
+
React.createElement("h5", null, title),
|
|
67
|
+
React.createElement(ReactMarkdown, { linkTarget: "_blank" }, description))))));
|
|
62
68
|
};
|
|
@@ -9,6 +9,7 @@ import { useC3UserConfiguration } from "../../c3-user-configuration/c3-user-conf
|
|
|
9
9
|
import { APPS } from "../../../utils/camunda";
|
|
10
10
|
import { NavWrapper, SideNav } from "./components";
|
|
11
11
|
import { useClusterUpdate } from "../../../contexts/c3-cluster-update-manager";
|
|
12
|
+
import { ActiveOrgName } from "../c3-org-sidebar/components";
|
|
12
13
|
const getOrgLink = (app, orgId, domain) => {
|
|
13
14
|
switch (app) {
|
|
14
15
|
case "console": {
|
|
@@ -31,6 +32,13 @@ const getClustersToRender = (clusters, activeOrg, appToNavigateTo) => {
|
|
|
31
32
|
// OR this is a 8.8+ cluster - in this case we also allow rendering this item
|
|
32
33
|
[1, 2, 3, 4, 5, 6, 7].every((pre8Minor) => !generation.versions?.zeebe?.includes(`8.${pre8Minor}`))));
|
|
33
34
|
};
|
|
35
|
+
const OrgNameWrapper = styled.div `
|
|
36
|
+
margin-bottom: 1rem;
|
|
37
|
+
padding: 0px 16px;
|
|
38
|
+
@media (min-width: 768px) {
|
|
39
|
+
display: none;
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
34
42
|
const OrgPickerModal = ({ isOpen, onCancel, orgs, activeOrg, loadingStatus, appToNavigateTo, domain, }) => {
|
|
35
43
|
const hasNoTeams = Object.values(orgs ?? {})?.every(({ org }) => {
|
|
36
44
|
return !org?.name;
|
|
@@ -133,6 +141,7 @@ export const C3NavigationAppBar = ({ app: appProps, appBar, forwardRef, navbar,
|
|
|
133
141
|
}
|
|
134
142
|
return clusters;
|
|
135
143
|
});
|
|
144
|
+
break;
|
|
136
145
|
}
|
|
137
146
|
case "created": {
|
|
138
147
|
setClusters((clusters) => {
|
|
@@ -284,6 +293,7 @@ export const C3NavigationAppBar = ({ app: appProps, appBar, forwardRef, navbar,
|
|
|
284
293
|
}, [clusters, currentApp, domain, handleSuperOrg]);
|
|
285
294
|
const appBarElements = appBar.elements || (clusters || clustersByOrgId ? appElements : null);
|
|
286
295
|
const [isOrgPickerModalOpen, setIsOrgPickerModalOpen] = useState(false);
|
|
296
|
+
const orgName = activeOrg?.name || navbar.orgName;
|
|
287
297
|
return (React.createElement(React.Fragment, null,
|
|
288
298
|
React.createElement(HeaderGlobalAction
|
|
289
299
|
// eslint-disable-next-line
|
|
@@ -303,6 +313,10 @@ export const C3NavigationAppBar = ({ app: appProps, appBar, forwardRef, navbar,
|
|
|
303
313
|
React.createElement(NavWrapper, null,
|
|
304
314
|
React.createElement(SideNav, { ref: panelRef, "aria-label": appBar.ariaLabel || "Side Navigation", expanded: appBar.isOpen, isPersistent: false },
|
|
305
315
|
React.createElement(SideNavItems, null,
|
|
316
|
+
orgName && (React.createElement("li", null,
|
|
317
|
+
React.createElement(OrgNameWrapper, null,
|
|
318
|
+
React.createElement(FormLabel, null, "Organization"),
|
|
319
|
+
React.createElement(ActiveOrgName, { className: "textPrimary", title: orgName }, orgName)))),
|
|
306
320
|
React.createElement("li", null, navbar.elements.length > 0 && (React.createElement(HeaderSideNavItems, { hasDivider: true }, navbar.elements.map((element) => (React.createElement(HeaderMenuItem, { key: element.key, as: element.routeProps && forwardRef, isActive: element.isCurrentPage, ...element.routeProps, onClick: () => {
|
|
307
321
|
if (element.routeProps.onClick) {
|
|
308
322
|
element.routeProps.onClick();
|
|
@@ -44,6 +44,16 @@ const ClusterTagWrapper = styled.div `
|
|
|
44
44
|
padding: 0 1rem;
|
|
45
45
|
}
|
|
46
46
|
`;
|
|
47
|
+
const ResponsiveNavbarElementsWrapper = styled.div `
|
|
48
|
+
display: grid;
|
|
49
|
+
grid-auto-flow: column;
|
|
50
|
+
gap: 0.5rem;
|
|
51
|
+
paddingright: 0.5rem;
|
|
52
|
+
|
|
53
|
+
@media (max-width: 768px) {
|
|
54
|
+
display: none;
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
47
57
|
const NON_PRODUCTION_TERMS_LINK = "https://legal.camunda.com/#self-managed-non-production-terms";
|
|
48
58
|
const SALES_CONTACT_LINK = "https://camunda.com/contact/";
|
|
49
59
|
export const SECOND = 1000;
|
|
@@ -73,7 +83,7 @@ export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, info
|
|
|
73
83
|
}
|
|
74
84
|
const [camundaStatus, setCamundaStatus] = useState({ error: false, description: "", endpoint: "" });
|
|
75
85
|
const fetchStatus = async (audience) => {
|
|
76
|
-
|
|
86
|
+
const status = await StatusService.camundaStatus(audience);
|
|
77
87
|
setCamundaStatus(status);
|
|
78
88
|
};
|
|
79
89
|
React.useEffect(() => {
|
|
@@ -176,12 +186,7 @@ export const C3Navigation = ({ app, appBar, forwardRef, navbar, orgSideBar, info
|
|
|
176
186
|
React.createElement(HeaderNavigation, { "aria-label": app.ariaLabel }, navbar.elements.map((element) => (React.createElement(HeaderMenuItem, { key: element.key, as: element.routeProps && forwardRef, isActive: element.isCurrentPage, ...element.routeProps },
|
|
177
187
|
React.createElement("span", null, element.label))))),
|
|
178
188
|
React.createElement(HeaderGlobalBar, null,
|
|
179
|
-
React.createElement(
|
|
180
|
-
display: "grid",
|
|
181
|
-
gridAutoFlow: "column",
|
|
182
|
-
gap: ".5rem",
|
|
183
|
-
paddingRight: ".5rem",
|
|
184
|
-
} },
|
|
189
|
+
React.createElement(ResponsiveNavbarElementsWrapper, null,
|
|
185
190
|
tags &&
|
|
186
191
|
tags.length > 0 &&
|
|
187
192
|
tags.map((tag) => {
|
|
@@ -1,42 +1,14 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { OnboardingSurvey } from "./onboardingSurvey";
|
|
3
|
-
import {
|
|
4
|
-
import { getOnboardingConfig, submitSurvey, updatePersona, } from "../../api/help-center";
|
|
3
|
+
import { submitSurvey, updatePersona } from "../../api/help-center";
|
|
5
4
|
import { useC3UserConfiguration, } from "../c3-user-configuration/c3-user-configuration-provider";
|
|
5
|
+
import { useC3HelpCenter } from "../c3-help-center/c3-help-center-provider";
|
|
6
6
|
export const C3OnboardingSurvey = (props) => {
|
|
7
7
|
const { userToken, decodedToken, activeOrganizationId, decodedAudience } = useC3UserConfiguration();
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const [givenName, setGivenName] = useState("");
|
|
13
|
-
const [email, setEmail] = useState("");
|
|
14
|
-
React.useEffect(() => {
|
|
15
|
-
if (!decodedToken || !decodedAudience)
|
|
16
|
-
return;
|
|
17
|
-
(async () => {
|
|
18
|
-
const { userId, meta, persona } = decodedToken;
|
|
19
|
-
if (props.persona === undefined && persona) {
|
|
20
|
-
setPersona(persona);
|
|
21
|
-
}
|
|
22
|
-
if (meta) {
|
|
23
|
-
setGivenName(meta.given_name);
|
|
24
|
-
setEmail(meta.email);
|
|
25
|
-
}
|
|
26
|
-
if (userId)
|
|
27
|
-
setUserId(userId);
|
|
28
|
-
setOnboardConfig(defaultOnboardingConfig);
|
|
29
|
-
setIsLoadingConfig(true);
|
|
30
|
-
const { result: config } = await getOnboardingConfig({
|
|
31
|
-
audience: decodedAudience,
|
|
32
|
-
camundaAuth: { token: userToken },
|
|
33
|
-
orgId: activeOrganizationId,
|
|
34
|
-
});
|
|
35
|
-
if (config)
|
|
36
|
-
setOnboardConfig(config);
|
|
37
|
-
setIsLoadingConfig(false);
|
|
38
|
-
})();
|
|
39
|
-
}, [JSON.stringify(decodedToken), decodedAudience]);
|
|
8
|
+
const { persona, setPersona, onboadingConfig, isLoadingOnboardingConfig } = useC3HelpCenter();
|
|
9
|
+
const userId = decodedToken?.userId ?? "";
|
|
10
|
+
const email = decodedToken?.meta?.email ?? "";
|
|
11
|
+
const givenName = decodedToken?.meta?.given_name ?? "";
|
|
40
12
|
React.useEffect(() => {
|
|
41
13
|
setPersona(props.persona);
|
|
42
14
|
}, [props.persona]);
|
|
@@ -84,5 +56,5 @@ export const C3OnboardingSurvey = (props) => {
|
|
|
84
56
|
setPersona(newPersona);
|
|
85
57
|
props.personaCallback(newPersona);
|
|
86
58
|
};
|
|
87
|
-
return (React.createElement(OnboardingSurvey, { appTheme: props.theme, userFirstName: givenName, persona: persona, syncPersona: syncPersona, setPersona: setPersona, mixpanelTrack: props.mixpanelTrack, onRequestClose: closeFn, onboardingConfiguration:
|
|
59
|
+
return (React.createElement(OnboardingSurvey, { appTheme: props.theme, userFirstName: givenName, persona: persona, syncPersona: syncPersona, setPersona: setPersona, mixpanelTrack: props.mixpanelTrack, onRequestClose: closeFn, onboardingConfiguration: onboadingConfig, isLoadingConfig: isLoadingOnboardingConfig, modal: props.modal, origin: props.origin }));
|
|
88
60
|
};
|
|
@@ -48,7 +48,8 @@ export const DropdownSelect = ({ title, label, elements, selectedElement, setSel
|
|
|
48
48
|
setElement(element.value, "");
|
|
49
49
|
}, value: elementWithoutSuggestion() }, elements.map((e) => (React.createElement(SelectItem, { key: `selectItem-${Math.random() * 10000}`, id: `selectItem-${Math.random() * 10000}`, value: e.value, text: e.label })))),
|
|
50
50
|
(() => {
|
|
51
|
-
if (
|
|
51
|
+
if (exceptionValue &&
|
|
52
|
+
elementWithoutSuggestion() === exceptionValue) {
|
|
52
53
|
return (React.createElement(React.Fragment, null,
|
|
53
54
|
React.createElement("div", { style: { marginTop: "24px" } }),
|
|
54
55
|
React.createElement("div", { style: { marginTop: "24px" } }),
|
|
@@ -16,9 +16,12 @@ export const C3UserConfigurationContext = React.createContext({
|
|
|
16
16
|
});
|
|
17
17
|
const C3UserConfigurationProvider = ({ children, activeOrganizationId, ...config }) => {
|
|
18
18
|
const [decodedToken, setDecodedToken] = useState(null);
|
|
19
|
-
const [decodedAudience, setDecodedAudience] = useState(null);
|
|
20
|
-
const [domain, setDomain] = useState(null);
|
|
21
19
|
const [activeOrgId, setActiveOrgId] = useState(activeOrganizationId);
|
|
20
|
+
const { audience } = decodedToken || {};
|
|
21
|
+
const decodedAudience = (typeof audience === "string" ? audience : audience?.[0]) || null;
|
|
22
|
+
const domain = config.noCloudInUrl
|
|
23
|
+
? (decodedAudience?.replace("cloud.", "") ?? null)
|
|
24
|
+
: decodedAudience;
|
|
22
25
|
useEffect(() => {
|
|
23
26
|
if (config.userToken)
|
|
24
27
|
setDecodedToken(decodeJWT(config.userToken));
|
|
@@ -26,16 +29,6 @@ const C3UserConfigurationProvider = ({ children, activeOrganizationId, ...config
|
|
|
26
29
|
useEffect(() => {
|
|
27
30
|
setActiveOrgId(activeOrganizationId);
|
|
28
31
|
}, [activeOrganizationId]);
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
const { audience } = decodedToken || {};
|
|
31
|
-
setDecodedAudience((typeof audience === "string" ? audience : audience?.[0]) || null);
|
|
32
|
-
}, [decodedToken]);
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
if (decodedAudience)
|
|
35
|
-
setDomain(config.noCloudInUrl
|
|
36
|
-
? decodedAudience.replace("cloud.", "")
|
|
37
|
-
: decodedAudience);
|
|
38
|
-
}, [decodedAudience, config.noCloudInUrl]);
|
|
39
32
|
return (React.createElement(C3UserConfigurationContext.Provider, { value: {
|
|
40
33
|
...config,
|
|
41
34
|
activeOrganizationId: activeOrgId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camunda/camunda-composite-components",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"peerDependencies": {
|
|
80
80
|
"@carbon/react": "1.x",
|
|
81
81
|
"event-source-polyfill": "1.0.x",
|
|
82
|
-
"react": "18.x",
|
|
83
|
-
"react-dom": "18.x",
|
|
82
|
+
"react": "18.x || 19.x",
|
|
83
|
+
"react-dom": "18.x || 19.x",
|
|
84
84
|
"styled-components": "5.x || 6.x"
|
|
85
85
|
},
|
|
86
86
|
"description": "Camunda Composite Components",
|