@camunda/camunda-composite-components 0.2.13 → 0.2.14

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.
@@ -1,9 +1,7 @@
1
1
  import { HelpCenterConfig } from "../components/c3-help-center/defaultHelpCenterConfig";
2
- import { Cluster, Organization, Persona, TileConfig, WpCardType } from "../components/c3-help-center/c3-help-center.types";
2
+ import { Persona, TileConfig, WpCardType } from "../components/c3-help-center/c3-help-center.types";
3
3
  import { OnboardingConfig } from "../components/c3-onboarding-survey/defaultOnboardingConfig";
4
4
  import { RequestPayload } from "./api";
5
- export declare const getOrg: (stage: string, accessToken: string, orgId: string) => Promise<Organization | null>;
6
- export declare const getClusters: (stage: string, accessToken: string, orgId: string) => Promise<Cluster[] | null>;
7
5
  export declare const getConfig: (accessToken: string, audience: string) => Promise<HelpCenterConfig | null>;
8
6
  export declare const getTiles: ({ accessToken, tileConfig, salesPlanType, clusterIds, currentOrgId, persona, flags, email, cloudAudience, }: {
9
7
  accessToken: string;
@@ -1,38 +1,5 @@
1
1
  import { recommendations } from "../components/c3-help-center/recommendations";
2
2
  import { request } from "./api";
3
- export const getOrg = async (stage, accessToken, orgId) => {
4
- const headers = {};
5
- headers.Authorization = `Bearer ${accessToken}`;
6
- headers["Content-Type"] = "application/json";
7
- try {
8
- const response = await fetch(`https://accounts.${stage}/external/organizations/my`, {
9
- method: "GET",
10
- headers,
11
- });
12
- const orgs = await response.json();
13
- return orgs.find((org) => org.uuid === orgId);
14
- }
15
- catch (error) {
16
- console.log(error);
17
- }
18
- return null;
19
- };
20
- export const getClusters = async (stage, accessToken, orgId) => {
21
- const headers = {};
22
- headers.Authorization = `Bearer ${accessToken}`;
23
- headers["Content-Type"] = "application/json";
24
- try {
25
- const response = await fetch(`https://console.${stage}/external/organizations/${orgId}/clusters`, {
26
- method: "GET",
27
- headers,
28
- });
29
- return response.json();
30
- }
31
- catch (error) {
32
- console.log(error);
33
- }
34
- return null;
35
- };
36
3
  export const getConfig = async (accessToken, audience) => {
37
4
  try {
38
5
  const response = await fetch(`https://helpcenter.${audience}/helpcenter/config`, {
@@ -87,7 +54,7 @@ export const submitSurvey = async ({ audience, token, data, }) => request({
87
54
  });
88
55
  export const submitFeedback = async ({ token, audience, formData, }) => request({
89
56
  method: "post",
90
- url: `https://feedback.${audience}/submit`,
57
+ url: `https://helpcenter.${audience}/feedback/submit`,
91
58
  camundaAuth: { token },
92
59
  body: formData,
93
60
  type: "form",
@@ -1,5 +1,6 @@
1
1
  import { C3NotificationsProps } from "../components/c3-navigation/c3-navigation.types";
2
2
  import { Theme } from "../components/c3-user-configuration/c3-profile-provider/c3-profile-provider";
3
+ import { Cluster, Organization } from "../components/c3-help-center/c3-help-center.types";
3
4
  export type Profile = {
4
5
  theme: Theme;
5
6
  };
@@ -14,3 +15,5 @@ export type UpdateThemeOptions = C3NotificationsProps & {
14
15
  theme: Profile["theme"];
15
16
  };
16
17
  export declare const updateTheme: ({ endpoints, stage, userToken, getNewUserToken, theme, }: UpdateThemeOptions) => Promise<void>;
18
+ export declare const getOrgs: (stage: string, accessToken: string) => Promise<Organization[] | null>;
19
+ export declare const getClusters: (stage: string, accessToken: string, orgId: string) => Promise<Cluster[] | null>;
@@ -28,3 +28,29 @@ export const updateTheme = async ({ endpoints, stage, userToken, getNewUserToken
28
28
  console.error(error);
29
29
  }
30
30
  };
31
+ export const getOrgs = async (stage, accessToken) => {
32
+ try {
33
+ return await request({
34
+ url: `https://accounts.${stage}/external/organizations/my`,
35
+ camundaAuth: { token: accessToken },
36
+ type: "json",
37
+ });
38
+ }
39
+ catch (error) {
40
+ console.log(error);
41
+ }
42
+ return null;
43
+ };
44
+ export const getClusters = async (stage, accessToken, orgId) => {
45
+ try {
46
+ return await request({
47
+ url: `https://console.${stage}/external/organizations/${orgId}/clusters`,
48
+ camundaAuth: { token: accessToken },
49
+ type: "json",
50
+ });
51
+ }
52
+ catch (error) {
53
+ console.log(error);
54
+ }
55
+ return null;
56
+ };
@@ -3,23 +3,20 @@ import React, { useEffect, useRef, useState } from "react";
3
3
  import { HelpCenter } from "./help-center";
4
4
  import { defaultHelpCenterConfig } from "./defaultHelpCenterConfig";
5
5
  import { C3OnboardingSurvey } from "../c3-onboarding-survey/c3-onboarding-survey";
6
- import { getClusters, getConfig, getOrg, updatePersona, } from "../../api/help-center";
6
+ import { getConfig, updatePersona } from "../../api/help-center";
7
7
  import { useC3UserConfiguration } from "../c3-user-configuration/c3-user-configuration-provider";
8
8
  import { defaultTheme, useC3Profile, } from "../c3-user-configuration/c3-profile-provider/c3-profile-provider";
9
9
  import { resolveTheme, } from "../c3-user-configuration/c3-profile-provider/carbon-theme-provider";
10
10
  import { useC3HelpCenter } from "./c3-help-center-provider";
11
11
  export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, mixpanelTrack, onRequestOpen, theme, onPersonaChange, activeTab, }) => {
12
12
  const { isHelpCenterOpen: isOpen, setIsHelpCenterOpen } = useC3HelpCenter();
13
- const { userToken, decodedToken, activeOrganizationId, handleTheme } = useC3UserConfiguration() || {};
14
- const { theme: themeConfig, isEnabled } = useC3Profile();
13
+ const { userToken, decodedToken, activeOrganizationId, handleTheme, decodedAudience, } = useC3UserConfiguration() || {};
14
+ const { theme: themeConfig, isEnabled, activeOrg, clusters } = useC3Profile();
15
15
  const themeHandlingEnabled = isEnabled && !!handleTheme && !!themeConfig;
16
16
  const themeRef = useRef();
17
17
  const [resolvedTheme, setResolvedTheme] = useState(defaultTheme);
18
18
  const [persona, setPersona] = useState(undefined);
19
19
  const [userId, setUserId] = useState("");
20
- const [audience, setAudience] = useState("");
21
- const [organization, setOrganization] = useState(null);
22
- const [clusters, setClusters] = useState([]);
23
20
  const [helpCenterConfig, setHelpCenterConfig] = useState(defaultHelpCenterConfig);
24
21
  const [email, setEmail] = useState("");
25
22
  const [showSurvey, setShowSurvey] = useState(autoStartSurvey);
@@ -44,9 +41,9 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
44
41
  setResolvedTheme(resolveTheme(newTheme || "light"));
45
42
  }, [theme, themeConfig, isOpen]);
46
43
  const fetchData = async () => {
47
- if (!decodedToken)
44
+ if (!userToken || !decodedToken || !decodedAudience)
48
45
  return;
49
- const { userId, meta, audience, persona } = decodedToken;
46
+ const { userId, meta, persona } = decodedToken;
50
47
  if (persona !== undefined) {
51
48
  setPersona(persona);
52
49
  if (persona.wasShown) {
@@ -58,29 +55,19 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
58
55
  }
59
56
  if (meta)
60
57
  setEmail(meta.email);
61
- const decodedAudience = typeof audience === "string" ? audience : audience?.[0];
62
58
  if (userId)
63
59
  setUserId(userId);
64
- if (decodedAudience && userToken && activeOrganizationId) {
65
- setAudience(decodedAudience);
66
- const clusters = await getClusters(decodedAudience, userToken, activeOrganizationId);
67
- setClusters(clusters);
68
- const org = await getOrg(decodedAudience, userToken, activeOrganizationId);
69
- setOrganization(org);
70
- }
71
60
  if (autoStartSurvey && !(persona?.wasShown ?? false)) {
72
61
  setShowSurvey(true);
73
62
  setIsHelpCenterOpen(true);
74
63
  onRequestOpen?.();
75
64
  }
76
- if (decodedAudience && userToken) {
77
- const onboardConfig = await getConfig(userToken, decodedAudience);
78
- setHelpCenterConfig(onboardConfig || defaultHelpCenterConfig);
79
- }
65
+ const onboardConfig = await getConfig(userToken, decodedAudience);
66
+ setHelpCenterConfig(onboardConfig || defaultHelpCenterConfig);
80
67
  };
81
68
  React.useEffect(() => {
82
69
  fetchData();
83
- }, [JSON.stringify(decodedToken), activeOrganizationId]);
70
+ }, [JSON.stringify(decodedToken), decodedAudience]);
84
71
  React.useEffect(() => {
85
72
  const tabs = helpCenterConfig.tabs;
86
73
  const firstTab = tabs[0].id;
@@ -95,6 +82,8 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
95
82
  }
96
83
  }, [isOpen]);
97
84
  const onRequestRetakeSurvey = () => {
85
+ if (!userToken || !activeOrganizationId || !decodedAudience)
86
+ return;
98
87
  const newPersona = {
99
88
  ...persona,
100
89
  ...{ nextStep: 0, complete: false },
@@ -102,22 +91,22 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
102
91
  setPersona(newPersona);
103
92
  updatePersona({
104
93
  newPersona,
105
- audience,
106
- accessToken: userToken || "",
107
- orgId: activeOrganizationId || "",
94
+ audience: decodedAudience,
95
+ accessToken: userToken,
96
+ orgId: activeOrganizationId,
108
97
  userId,
109
98
  });
110
99
  onPersonaChange?.(newPersona);
111
100
  setShowSurvey(true);
112
101
  };
113
102
  const onRequestResumeSurvey = () => {
114
- if (!userToken || !activeOrganizationId)
103
+ if (!userToken || !activeOrganizationId || !decodedAudience)
115
104
  return;
116
105
  const newPersona = { ...persona, ...{ complete: false, wasShown: true } };
117
106
  setPersona(newPersona);
118
107
  updatePersona({
119
108
  newPersona,
120
- audience,
109
+ audience: decodedAudience,
121
110
  accessToken: userToken,
122
111
  orgId: activeOrganizationId,
123
112
  userId,
@@ -126,13 +115,13 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
126
115
  setShowSurvey(true);
127
116
  };
128
117
  const onRequestSkipSurvey = () => {
129
- if (!userToken || !activeOrganizationId)
118
+ if (!userToken || !activeOrganizationId || !decodedAudience)
130
119
  return;
131
120
  const newPersona = { ...persona, ...{ complete: false, wasShown: true } };
132
121
  setPersona(newPersona);
133
122
  updatePersona({
134
123
  newPersona,
135
- audience,
124
+ audience: decodedAudience,
136
125
  accessToken: userToken,
137
126
  orgId: activeOrganizationId,
138
127
  userId,
@@ -148,10 +137,10 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
148
137
  }
149
138
  };
150
139
  const closeFn = () => {
151
- if (persona && userToken && activeOrganizationId) {
140
+ if (persona && userToken && activeOrganizationId && decodedAudience) {
152
141
  updatePersona({
153
142
  newPersona: persona,
154
- audience,
143
+ audience: decodedAudience,
155
144
  accessToken: userToken,
156
145
  orgId: activeOrganizationId,
157
146
  userId,
@@ -161,5 +150,5 @@ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, onRequestClose, m
161
150
  onRequestClose?.();
162
151
  };
163
152
  return (React.createElement(Layer, null,
164
- React.createElement(ComposedModal, { open: isOpen, size: "lg", onClose: closeFn, className: "help-center", "aria-label": "HelpCenter" }, showSurvey || !persona || !persona.wasShown ? (React.createElement(C3OnboardingSurvey, { personaCallback: personaCallback, persona: persona, mixpanelTrack: mixpanelTrack, onRequestClose: closeFn, onRequestSkip: onRequestSkipSurvey, theme: resolvedTheme, origin: origin, modal: true })) : (React.createElement(HelpCenter, { configuration: helpCenterConfig, persona: persona, audience: audience, organization: organization, clusters: clusters || [], flags: flags, onRequestResumeSurvey: onRequestResumeSurvey, onRequestRetakeSurvey: onRequestRetakeSurvey, onRequestClose: closeFn, mixpanelTrack: mixpanelTrack, email: email, theme: resolvedTheme, origin: origin, initialTab: activeTab })))));
153
+ React.createElement(ComposedModal, { open: isOpen, size: "lg", onClose: closeFn, className: "help-center", "aria-label": "HelpCenter" }, showSurvey || !persona || !persona.wasShown ? (React.createElement(C3OnboardingSurvey, { personaCallback: personaCallback, persona: persona, mixpanelTrack: mixpanelTrack, onRequestClose: closeFn, onRequestSkip: onRequestSkipSurvey, theme: resolvedTheme, origin: origin, modal: true })) : (React.createElement(HelpCenter, { configuration: helpCenterConfig, persona: persona, audience: decodedAudience || "", organization: activeOrg, clusters: clusters || [], flags: flags, onRequestResumeSurvey: onRequestResumeSurvey, onRequestRetakeSurvey: onRequestRetakeSurvey, onRequestClose: closeFn, mixpanelTrack: mixpanelTrack, email: email, theme: resolvedTheme, origin: origin, initialTab: activeTab })))));
165
154
  };
@@ -4,19 +4,18 @@ import { defaultOnboardingConfig } from "./defaultOnboardingConfig";
4
4
  import { getOnboardingConfig, submitSurvey, updatePersona, } from "../../api/help-center";
5
5
  import { useC3UserConfiguration } from "../c3-user-configuration/c3-user-configuration-provider";
6
6
  export const C3OnboardingSurvey = (props) => {
7
- const { userToken, decodedToken, activeOrganizationId } = useC3UserConfiguration() || {};
7
+ const { userToken, decodedToken, activeOrganizationId, decodedAudience } = useC3UserConfiguration() || {};
8
8
  const [persona, setPersona] = useState(props.persona);
9
9
  const [userId, setUserId] = useState("");
10
- const [audience, setAudience] = useState("");
11
10
  const [onboardConfig, setOnboardConfig] = useState(defaultOnboardingConfig);
12
11
  const [isLoadingConfig, setIsLoadingConfig] = useState(false);
13
12
  const [givenName, setGivenName] = useState("");
14
13
  const [email, setEmail] = useState("");
15
14
  React.useEffect(() => {
16
- if (!decodedToken)
15
+ if (!decodedToken || !decodedAudience)
17
16
  return;
18
17
  (async () => {
19
- const { userId, meta, audience, persona } = decodedToken;
18
+ const { userId, meta, persona } = decodedToken;
20
19
  if (props.persona === undefined && persona) {
21
20
  setPersona(persona);
22
21
  }
@@ -24,23 +23,18 @@ export const C3OnboardingSurvey = (props) => {
24
23
  setGivenName(meta.given_name);
25
24
  setEmail(meta.email);
26
25
  }
27
- const decodedAudience = typeof audience === "string" ? audience : audience?.[0];
28
- if (decodedAudience)
29
- setAudience(decodedAudience);
30
26
  if (userId)
31
27
  setUserId(userId);
32
28
  setOnboardConfig(defaultOnboardingConfig);
33
- if (decodedAudience) {
34
- setIsLoadingConfig(true);
35
- const config = await getOnboardingConfig({
36
- audience: decodedAudience,
37
- camundaAuth: { token: userToken },
38
- });
39
- setOnboardConfig(config);
40
- setIsLoadingConfig(false);
41
- }
29
+ setIsLoadingConfig(true);
30
+ const config = await getOnboardingConfig({
31
+ audience: decodedAudience,
32
+ camundaAuth: { token: userToken },
33
+ });
34
+ setOnboardConfig(config);
35
+ setIsLoadingConfig(false);
42
36
  })();
43
- }, [JSON.stringify(decodedToken)]);
37
+ }, [JSON.stringify(decodedToken), decodedAudience]);
44
38
  React.useEffect(() => {
45
39
  setPersona(props.persona);
46
40
  }, [props.persona]);
@@ -51,10 +45,10 @@ export const C3OnboardingSurvey = (props) => {
51
45
  from: props.origin,
52
46
  });
53
47
  const newPersona = { ...persona, ...{ complete: skip } };
54
- if (activeOrganizationId && userToken)
48
+ if (activeOrganizationId && userToken && decodedAudience)
55
49
  await updatePersona({
56
50
  newPersona,
57
- audience,
51
+ audience: decodedAudience,
58
52
  orgId: activeOrganizationId,
59
53
  userId,
60
54
  accessToken: userToken,
@@ -69,17 +63,17 @@ export const C3OnboardingSurvey = (props) => {
69
63
  }
70
64
  };
71
65
  const syncPersona = async (newPersona, notifyHubspot) => {
72
- if (activeOrganizationId && userToken) {
66
+ if (activeOrganizationId && userToken && decodedAudience) {
73
67
  await updatePersona({
74
68
  newPersona,
75
- audience,
69
+ audience: decodedAudience,
76
70
  orgId: activeOrganizationId,
77
71
  userId,
78
72
  accessToken: userToken,
79
73
  });
80
74
  if (notifyHubspot) {
81
75
  await submitSurvey({
82
- audience,
76
+ audience: decodedAudience,
83
77
  token: userToken,
84
78
  data: { ...newPersona, ...{ email, orgUuid: activeOrganizationId } },
85
79
  });
@@ -1,11 +1,13 @@
1
1
  import React, { FC, PropsWithChildren } from "react";
2
2
  import { ResolvedTheme } from "./carbon-theme-provider";
3
- import { Cluster } from "../../c3-help-center/c3-help-center.types";
3
+ import { Cluster, Organization } from "../../c3-help-center/c3-help-center.types";
4
4
  export type Theme = "light" | "dark" | "system";
5
5
  export declare const defaultTheme: "light";
6
6
  export type C3ProfileContextValue = {
7
7
  isEnabled: boolean;
8
8
  theme: Theme;
9
+ orgs: Organization[] | null;
10
+ activeOrg: Organization | null;
9
11
  clusters: Cluster[] | null;
10
12
  resolvedTheme: ResolvedTheme;
11
13
  onThemeChange: (newTheme: Theme) => void;
@@ -1,29 +1,34 @@
1
1
  import React, { createContext, useContext, useEffect, useRef, useState, } from "react";
2
2
  import { C3UserConfigurationContext } from "../c3-user-configuration-provider";
3
- import { getUserTheme, updateTheme } from "../../../api/profile";
3
+ import { getUserTheme, updateTheme, getClusters, getOrgs, } from "../../../api/profile";
4
4
  import { CarbonThemeProvider, resolveTheme, } from "./carbon-theme-provider";
5
- import { getClusters } from "../../../api/help-center";
6
5
  export const defaultTheme = "light";
7
6
  export const C3ProfileContext = createContext({
8
7
  isEnabled: false,
9
8
  theme: defaultTheme,
9
+ orgs: null,
10
+ activeOrg: null,
10
11
  clusters: null,
11
12
  resolvedTheme: defaultTheme,
12
13
  onThemeChange: () => undefined,
13
14
  });
14
15
  export const C3ProfileProvider = ({ children }) => {
15
- const { decodedToken, ...config } = useContext(C3UserConfigurationContext);
16
+ const { decodedToken, decodedAudience, ...config } = useContext(C3UserConfigurationContext);
16
17
  const isEnabled = !!config;
17
18
  const themeRef = useRef(getUserTheme(config.userToken) || defaultTheme);
18
19
  const [resolvedTheme, setResolvedTheme] = useState(defaultTheme);
20
+ const [orgs, setOrgs] = useState(null);
21
+ const [activeOrg, setActiveOrg] = useState(null);
19
22
  const [clusters, setClusters] = useState(null);
20
23
  useEffect(() => {
21
24
  if (!decodedToken) {
22
25
  return;
23
26
  }
24
- const { audience } = decodedToken;
25
- const decodedAudience = typeof audience === "string" ? audience : audience?.[0];
26
27
  if (decodedAudience) {
28
+ getOrgs(decodedAudience, config.userToken).then((res) => {
29
+ setOrgs(res);
30
+ setActiveOrg(res?.find((org) => org.uuid === config.activeOrganizationId) || null);
31
+ });
27
32
  getClusters(decodedAudience, config.userToken, config.activeOrganizationId).then((res) => {
28
33
  setClusters(res);
29
34
  });
@@ -65,6 +70,8 @@ export const C3ProfileProvider = ({ children }) => {
65
70
  isEnabled,
66
71
  theme: themeRef.current,
67
72
  resolvedTheme,
73
+ orgs,
74
+ activeOrg,
68
75
  clusters,
69
76
  onThemeChange,
70
77
  } },
@@ -17,6 +17,7 @@ type C3UserConfigurationWithStage = C3UserConfigurationBase & {
17
17
  export type C3UserConfiguration = C3UserConfigurationWithEndpoints | C3UserConfigurationWithStage;
18
18
  export type C3UserConfigurationContextValue = C3UserConfiguration & {
19
19
  decodedToken: DecodedToken | null;
20
+ decodedAudience: string | null;
20
21
  };
21
22
  export declare const C3UserConfigurationContext: React.Context<C3UserConfigurationContextValue>;
22
23
  declare const C3UserConfigurationProvider: FC<C3UserConfiguration & {
@@ -7,15 +7,21 @@ export const C3UserConfigurationContext = React.createContext({
7
7
  activeOrganizationId: "",
8
8
  userToken: "",
9
9
  decodedToken: null,
10
+ decodedAudience: null,
10
11
  getNewUserToken: () => Promise.resolve(""),
11
12
  });
12
13
  const C3UserConfigurationProvider = ({ children, ...config }) => {
13
14
  const [decodedToken, setDecodedToken] = useState(null);
15
+ const [decodedAudience, setDecodedAudience] = useState(null);
14
16
  useEffect(() => {
15
17
  if (config.userToken)
16
18
  setDecodedToken(decodeJWT(config.userToken));
17
19
  }, [config.userToken]);
18
- return (React.createElement(C3UserConfigurationContext.Provider, { value: { ...config, decodedToken } },
20
+ useEffect(() => {
21
+ const { audience } = decodedToken || {};
22
+ setDecodedAudience((typeof audience === "string" ? audience : audience?.[0]) || null);
23
+ }, [decodedToken]);
24
+ return (React.createElement(C3UserConfigurationContext.Provider, { value: { ...config, decodedToken, decodedAudience } },
19
25
  React.createElement(C3ProfileProvider, null,
20
26
  React.createElement(C3HelpCenterProvider, null, children))));
21
27
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/camunda-composite-components",
3
- "version": "0.2.13",
3
+ "version": "0.2.14",
4
4
  "scripts": {
5
5
  "clean": "rimraf lib/",
6
6
  "build": "yarn clean && tsc",
@@ -44,7 +44,7 @@
44
44
  "@storybook/react": "7.4.5",
45
45
  "@storybook/react-webpack5": "7.4.5",
46
46
  "@storybook/test-runner": "0.13.0",
47
- "@storybook/testing-library": "0.2.1",
47
+ "@storybook/testing-library": "0.2.2",
48
48
  "@types/carbon-components-react": "7.55.3",
49
49
  "@types/event-source-polyfill": "1.0.1",
50
50
  "@types/mixpanel-browser": "2.47.1",