@camunda/camunda-composite-components 0.1.5-rc.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/lib/esm/api/api.d.ts +5 -5
  2. package/lib/esm/api/api.js +8 -4
  3. package/lib/esm/api/help-center.d.ts +44 -0
  4. package/lib/esm/api/help-center.js +95 -0
  5. package/lib/esm/api/notifications.js +2 -0
  6. package/lib/esm/api/profile.js +1 -0
  7. package/lib/esm/components/c3-help-center/c3-help-center.d.ts +16 -0
  8. package/lib/esm/components/c3-help-center/c3-help-center.js +137 -0
  9. package/lib/esm/components/c3-help-center/c3-help-center.types.d.ts +54 -0
  10. package/lib/esm/components/c3-help-center/c3-help-center.types.js +1 -0
  11. package/lib/esm/components/c3-help-center/defaultHelpCenterConfig.d.ts +10 -0
  12. package/lib/esm/components/c3-help-center/defaultHelpCenterConfig.js +12 -0
  13. package/lib/esm/components/c3-help-center/help-center.d.ts +23 -0
  14. package/lib/esm/components/c3-help-center/help-center.js +173 -0
  15. package/lib/esm/components/c3-help-center/recommendations.d.ts +4 -0
  16. package/lib/esm/components/c3-help-center/recommendations.js +53 -0
  17. package/lib/esm/components/c3-help-center/tabs/feedback.d.ts +8 -0
  18. package/lib/esm/components/c3-help-center/tabs/feedback.js +183 -0
  19. package/lib/esm/components/c3-help-center/tabs/tabContent.d.ts +19 -0
  20. package/lib/esm/components/c3-help-center/tabs/tabContent.js +18 -0
  21. package/lib/esm/components/c3-help-center/tile.d.ts +10 -0
  22. package/lib/esm/components/c3-help-center/tile.js +51 -0
  23. package/lib/esm/components/c3-navigation/c3-navigation-appbar.js +2 -2
  24. package/lib/esm/components/c3-navigation/c3-navigation.d.ts +1 -1
  25. package/lib/esm/components/c3-navigation/c3-navigation.js +12 -4
  26. package/lib/esm/components/c3-navigation/c3-navigation.types.d.ts +3 -0
  27. package/lib/esm/components/c3-navigation/story-helpers.js +1 -0
  28. package/lib/esm/components/c3-onboarding-survey/c3-onboarding-survey.d.ts +14 -0
  29. package/lib/esm/components/c3-onboarding-survey/c3-onboarding-survey.js +96 -0
  30. package/lib/esm/components/c3-onboarding-survey/defaultOnboardingConfig.d.ts +12 -0
  31. package/lib/esm/components/c3-onboarding-survey/defaultOnboardingConfig.js +3 -0
  32. package/lib/esm/components/c3-onboarding-survey/elements/dropdownSelect.d.ts +15 -0
  33. package/lib/esm/components/c3-onboarding-survey/elements/dropdownSelect.js +61 -0
  34. package/lib/esm/components/c3-onboarding-survey/elements/radioGroupMulti.d.ts +7 -0
  35. package/lib/esm/components/c3-onboarding-survey/elements/radioGroupMulti.js +62 -0
  36. package/lib/esm/components/c3-onboarding-survey/elements/radioGroupSingle.d.ts +7 -0
  37. package/lib/esm/components/c3-onboarding-survey/elements/radioGroupSingle.js +42 -0
  38. package/lib/esm/components/c3-onboarding-survey/elements/textField.d.ts +6 -0
  39. package/lib/esm/components/c3-onboarding-survey/elements/textField.js +10 -0
  40. package/lib/esm/components/c3-onboarding-survey/onboarding.types.d.ts +33 -0
  41. package/lib/esm/components/c3-onboarding-survey/onboarding.types.js +8 -0
  42. package/lib/esm/components/c3-onboarding-survey/onboardingModal.d.ts +24 -0
  43. package/lib/esm/components/c3-onboarding-survey/onboardingModal.js +52 -0
  44. package/lib/esm/components/c3-onboarding-survey/onboardingPage.d.ts +20 -0
  45. package/lib/esm/components/c3-onboarding-survey/onboardingPage.js +42 -0
  46. package/lib/esm/components/c3-onboarding-survey/onboardingSurvey.d.ts +16 -0
  47. package/lib/esm/components/c3-onboarding-survey/onboardingSurvey.js +135 -0
  48. package/lib/esm/components/c3-onboarding-survey/step.d.ts +6 -0
  49. package/lib/esm/components/c3-onboarding-survey/step.js +36 -0
  50. package/lib/esm/components/c3-user-configuration/authToken.d.ts +29 -0
  51. package/lib/esm/components/c3-user-configuration/authToken.js +25 -0
  52. package/lib/esm/components/c3-user-configuration/c3-profile-provider/carbon-theme-provider.js +28 -6
  53. package/lib/esm/components/styles.d.ts +548 -0
  54. package/lib/esm/components/styles.js +62 -0
  55. package/package.json +6 -3
@@ -4,21 +4,21 @@ export declare class HttpError extends Error {
4
4
  constructor(message: string, status: number);
5
5
  }
6
6
  export interface RequestPayload {
7
+ url: string;
7
8
  base?: "notifications" | "accounts";
8
9
  stage?: Stage;
9
10
  endpoints?: Endpoints;
10
- url: string;
11
- method: "get" | "post" | "put" | "delete" | "patch";
11
+ method?: "get" | "post" | "put" | "delete" | "patch";
12
12
  headers?: {
13
13
  [key: string]: string;
14
14
  };
15
- type?: "json" | "text" | "none";
15
+ type?: "json" | "text" | "form" | "none";
16
16
  responseType?: "json" | "text" | "none";
17
17
  camundaAuth?: {
18
18
  token: string;
19
- refreshTokenMethod: () => Promise<string>;
19
+ refreshTokenMethod?: () => Promise<string>;
20
20
  };
21
- body?: {
21
+ body?: string | FormData | {
22
22
  [key: string]: unknown;
23
23
  };
24
24
  }
@@ -11,7 +11,7 @@ export async function request(payload) {
11
11
  const headers = {};
12
12
  if (payload.camundaAuth) {
13
13
  if (JWTUtils.isExpired(payload.camundaAuth.token)) {
14
- const newToken = await payload.camundaAuth.refreshTokenMethod();
14
+ const newToken = await payload.camundaAuth?.refreshTokenMethod?.();
15
15
  headers.Authorization = `Bearer ${newToken}`;
16
16
  }
17
17
  else {
@@ -29,7 +29,11 @@ export async function request(payload) {
29
29
  break;
30
30
  }
31
31
  }
32
- const body = payload.body ? JSON.stringify(payload.body) : undefined;
32
+ const body = payload.body && type === "json"
33
+ ? JSON.stringify(payload.body)
34
+ : payload.body instanceof FormData
35
+ ? payload.body
36
+ : undefined;
33
37
  let base;
34
38
  if (payload.base) {
35
39
  switch (payload.base) {
@@ -52,7 +56,7 @@ export async function request(payload) {
52
56
  }
53
57
  const url = base ? `${base}/${payload.url}` : payload.url;
54
58
  const response = await fetch(url, {
55
- method: payload.method.toUpperCase(),
59
+ method: payload.method ? payload.method.toUpperCase() : "GET",
56
60
  headers,
57
61
  body,
58
62
  });
@@ -69,7 +73,7 @@ export async function request(payload) {
69
73
  const responseType = payload.responseType ?? type;
70
74
  switch (responseType) {
71
75
  case "json":
72
- return response.text().then((text) => (text ? JSON.parse(text) : {}));
76
+ return response.json();
73
77
  case "text":
74
78
  return response.text();
75
79
  default:
@@ -0,0 +1,44 @@
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";
3
+ import { OnboardingConfig } from "../components/c3-onboarding-survey/defaultOnboardingConfig";
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
+ export declare const getConfig: (accessToken: string, audience: string) => Promise<HelpCenterConfig | null>;
8
+ export declare const getTiles: ({ accessToken, tileConfig, salesPlanType, clusterIds, currentOrgId, persona, flags, email, cloudAudience, }: {
9
+ accessToken: string;
10
+ tileConfig: TileConfig[];
11
+ cloudAudience: string;
12
+ persona: {
13
+ [id: string]: unknown;
14
+ };
15
+ clusterIds: string[];
16
+ email: string;
17
+ currentOrgId: string;
18
+ salesPlanType: string;
19
+ flags: string[];
20
+ }) => Promise<WpCardType[]>;
21
+ export declare const getOnboardingConfig: ({ camundaAuth, audience, }: {
22
+ audience: string;
23
+ camundaAuth: RequestPayload["camundaAuth"];
24
+ }) => Promise<OnboardingConfig>;
25
+ export declare const updatePersona: ({ newPersona, audience, accessToken, orgId, userId, }: {
26
+ newPersona: Persona;
27
+ audience: string;
28
+ orgId: string;
29
+ userId: string;
30
+ accessToken: string;
31
+ }) => Promise<void>;
32
+ export declare const submitSurvey: ({ audience, token, data, }: {
33
+ audience: string;
34
+ token: string;
35
+ data: Persona & {
36
+ email: string;
37
+ orgUuid: string;
38
+ };
39
+ }) => Promise<void>;
40
+ export declare const submitFeedback: ({ token, audience, formData, }: {
41
+ token: string;
42
+ audience: string;
43
+ formData: FormData;
44
+ }) => Promise<any>;
@@ -0,0 +1,95 @@
1
+ import { recommendations } from "../components/c3-help-center/recommendations";
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}/api/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}/api/orgs/${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
+ export const getConfig = async (accessToken, audience) => {
37
+ try {
38
+ const response = await fetch(`https://helpcenter.${audience}/helpcenter/config`, {
39
+ headers: {
40
+ authorization: `Bearer ${accessToken}`,
41
+ "Content-Type": "application/json",
42
+ },
43
+ });
44
+ return response.json();
45
+ }
46
+ catch (error) {
47
+ console.error(error);
48
+ }
49
+ return null;
50
+ };
51
+ export const getTiles = async ({ accessToken, tileConfig, salesPlanType, clusterIds, currentOrgId, persona, flags, email, cloudAudience, }) => {
52
+ const availableTileTypes = recommendations(persona, flags, tileConfig, salesPlanType, clusterIds?.length > 0);
53
+ let cards = await request({
54
+ url: `https://helpcenter.${cloudAudience}/cards?card_id=${availableTileTypes.join(",")}`,
55
+ responseType: "json",
56
+ camundaAuth: { token: accessToken },
57
+ });
58
+ cards = cards.map((card) => {
59
+ card.link = card.link?.replaceAll("{cloudAudience}", cloudAudience);
60
+ card.link = card.link?.replaceAll("{currentOrgId}", currentOrgId);
61
+ card.link = card.link?.replaceAll("{clusterId}", clusterIds[0]);
62
+ card.link = card.link?.replaceAll("{email}", email);
63
+ return card;
64
+ });
65
+ return cards;
66
+ };
67
+ export const getOnboardingConfig = ({ camundaAuth, audience, }) => request({
68
+ url: `https://helpcenter.${audience}/survey/config`,
69
+ camundaAuth,
70
+ type: "json",
71
+ });
72
+ export const updatePersona = async ({ newPersona, audience, accessToken, orgId, userId, }) => request({
73
+ url: `https://helpcenter.${audience}/persona`,
74
+ method: "patch",
75
+ camundaAuth: { token: accessToken },
76
+ type: "json",
77
+ body: { persona: newPersona, userId, orgId },
78
+ responseType: "text",
79
+ });
80
+ export const submitSurvey = async ({ audience, token, data, }) => request({
81
+ method: "post",
82
+ url: `https://helpcenter.${audience}/survey/submit`,
83
+ camundaAuth: { token },
84
+ type: "json",
85
+ body: { data },
86
+ responseType: "text",
87
+ });
88
+ export const submitFeedback = async ({ token, audience, formData, }) => request({
89
+ method: "post",
90
+ url: `https://feedback.${audience}/submit`,
91
+ camundaAuth: { token },
92
+ body: formData,
93
+ type: "form",
94
+ responseType: "text",
95
+ });
@@ -37,6 +37,7 @@ export class NotificationService {
37
37
  body: {
38
38
  id: eventOptions.id,
39
39
  },
40
+ type: "json",
40
41
  responseType: "text",
41
42
  })
42
43
  .then(() => {
@@ -82,6 +83,7 @@ export class NotificationService {
82
83
  body: {
83
84
  uuids: notificationIds,
84
85
  },
86
+ type: "json",
85
87
  })
86
88
  .then(() => {
87
89
  // do nothing
@@ -21,6 +21,7 @@ export const updateTheme = async ({ endpoints, stage, userToken, getNewUserToken
21
21
  camundaAuth: { token: userToken, refreshTokenMethod: getNewUserToken },
22
22
  url: `external/user/theme`,
23
23
  body: { theme },
24
+ responseType: "text",
24
25
  });
25
26
  }
26
27
  catch (error) {
@@ -0,0 +1,16 @@
1
+ import { FC } from "react";
2
+ import { Persona } from "./c3-help-center.types";
3
+ import { Dict } from "mixpanel-browser";
4
+ export interface C3HelpCenterProps {
5
+ isOpen: boolean;
6
+ origin: "console" | "webmodeler" | "operate" | "tasklist" | "optimize";
7
+ theme?: "light" | "dark";
8
+ flags?: string[];
9
+ activeTab?: string;
10
+ autoStartSurvey?: boolean;
11
+ onPersonaChange?: (persona: Persona) => void;
12
+ onRequestClose?: () => void;
13
+ onRequestOpen?: () => void;
14
+ mixpanelTrack?: (event: string, data: Dict | undefined) => void;
15
+ }
16
+ export declare const C3HelpCenter: FC<C3HelpCenterProps>;
@@ -0,0 +1,137 @@
1
+ import { ComposedModal, Layer } from "@carbon/react";
2
+ import React, { useState } from "react";
3
+ import { HelpCenter } from "./help-center";
4
+ import { defaultHelpCenterConfig } from "./defaultHelpCenterConfig";
5
+ import { C3OnboardingSurvey } from "../c3-onboarding-survey/c3-onboarding-survey";
6
+ import { getClusters, getConfig, getOrg, updatePersona, } from "../../api/help-center";
7
+ import { decodeJWT } from "../c3-user-configuration/authToken";
8
+ import { useC3UserConfiguration } from "../c3-user-configuration/c3-user-configuration-provider";
9
+ export const C3HelpCenter = ({ autoStartSurvey, origin, flags, isOpen, onRequestClose, mixpanelTrack, onRequestOpen, theme = "light", onPersonaChange, activeTab, }) => {
10
+ const { userToken, activeOrganizationId } = useC3UserConfiguration() || {};
11
+ const [persona, setPersona] = useState(undefined);
12
+ const [userId, setUserId] = useState("");
13
+ const [token, setToken] = useState("");
14
+ const [audience, setAudience] = useState("");
15
+ const [organization, setOrganization] = useState(null);
16
+ const [clusters, setClusters] = useState([]);
17
+ const [helpCenterConfig, setHelpCenterConfig] = useState(defaultHelpCenterConfig);
18
+ const [email, setEmail] = useState("");
19
+ const [showSurvey, setShowSurvey] = useState(autoStartSurvey);
20
+ const fetchData = async () => {
21
+ const decodedToken = decodeJWT(userToken);
22
+ if (!decodedToken)
23
+ return;
24
+ const { userId, meta, audience, persona } = decodedToken;
25
+ if (persona !== undefined) {
26
+ setPersona(persona);
27
+ if (persona.wasShown) {
28
+ setShowSurvey(false);
29
+ }
30
+ }
31
+ if (meta)
32
+ setEmail(meta.email);
33
+ const decodedAudience = typeof audience === "string" ? audience : audience?.[0];
34
+ if (userId)
35
+ setUserId(userId);
36
+ if (decodedAudience && userToken && activeOrganizationId) {
37
+ setAudience(decodedAudience);
38
+ const clusters = await getClusters(decodedAudience, userToken, activeOrganizationId);
39
+ setClusters(clusters);
40
+ const org = await getOrg(decodedAudience, userToken, activeOrganizationId);
41
+ setOrganization(org);
42
+ }
43
+ if (autoStartSurvey && !(persona?.wasShown ?? false)) {
44
+ onRequestOpen?.();
45
+ }
46
+ if (decodedAudience && userToken) {
47
+ const onboardConfig = await getConfig(userToken, decodedAudience);
48
+ setHelpCenterConfig(onboardConfig || defaultHelpCenterConfig);
49
+ }
50
+ };
51
+ React.useEffect(() => {
52
+ if (token !== userToken && !!userToken) {
53
+ setToken(userToken);
54
+ fetchData();
55
+ }
56
+ }, [userToken]);
57
+ React.useEffect(() => {
58
+ const tabs = helpCenterConfig.tabs;
59
+ const firstTab = tabs[0].id;
60
+ if (isOpen) {
61
+ mixpanelTrack?.(`helpcenter:open`, {
62
+ to: activeTab ?? firstTab,
63
+ from: origin,
64
+ });
65
+ }
66
+ else {
67
+ setShowSurvey(false);
68
+ }
69
+ }, [isOpen]);
70
+ const onRequestRetakeSurvey = () => {
71
+ const newPersona = {
72
+ ...persona,
73
+ ...{ nextStep: 0, complete: false },
74
+ };
75
+ setPersona(newPersona);
76
+ updatePersona({
77
+ newPersona,
78
+ audience,
79
+ accessToken: userToken || "",
80
+ orgId: activeOrganizationId || "",
81
+ userId,
82
+ });
83
+ onPersonaChange?.(newPersona);
84
+ setShowSurvey(true);
85
+ };
86
+ const onRequestResumeSurvey = () => {
87
+ if (!userToken || !activeOrganizationId)
88
+ return;
89
+ const newPersona = { ...persona, ...{ complete: false, wasShown: true } };
90
+ setPersona(newPersona);
91
+ updatePersona({
92
+ newPersona,
93
+ audience,
94
+ accessToken: userToken,
95
+ orgId: activeOrganizationId,
96
+ userId,
97
+ });
98
+ onPersonaChange?.(newPersona);
99
+ setShowSurvey(true);
100
+ };
101
+ const onRequestSkipSurvey = () => {
102
+ if (!userToken || !activeOrganizationId)
103
+ return;
104
+ const newPersona = { ...persona, ...{ complete: false, wasShown: true } };
105
+ setPersona(newPersona);
106
+ updatePersona({
107
+ newPersona,
108
+ audience,
109
+ accessToken: userToken,
110
+ orgId: activeOrganizationId,
111
+ userId,
112
+ });
113
+ onPersonaChange?.(newPersona);
114
+ setShowSurvey(false);
115
+ };
116
+ const personaCallback = (newPersona) => {
117
+ setPersona(newPersona);
118
+ onPersonaChange?.(newPersona);
119
+ if (newPersona.complete) {
120
+ setShowSurvey(false);
121
+ }
122
+ };
123
+ const closeFn = () => {
124
+ if (persona && userToken && activeOrganizationId) {
125
+ updatePersona({
126
+ newPersona: persona,
127
+ audience,
128
+ accessToken: userToken,
129
+ orgId: activeOrganizationId,
130
+ userId,
131
+ });
132
+ }
133
+ onRequestClose?.();
134
+ };
135
+ return (React.createElement(Layer, null,
136
+ React.createElement(ComposedModal, { open: isOpen, size: "lg", onClose: closeFn, className: "help-center", "aria-label": "HelpCenter" }, showSurvey || !persona ? (React.createElement(C3OnboardingSurvey, { personaCallback: personaCallback, persona: persona, mixpanelTrack: mixpanelTrack, onRequestClose: closeFn, onRequestSkip: onRequestSkipSurvey, theme: theme, 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: theme, origin: origin, initialTab: activeTab })))));
137
+ };
@@ -0,0 +1,54 @@
1
+ import { TabType } from "./tabs/tabContent";
2
+ export interface Persona {
3
+ role?: string;
4
+ company?: string;
5
+ interestedInExecutingProcess?: boolean;
6
+ goal?: string[];
7
+ orchestrate?: string[];
8
+ client?: string;
9
+ clientToSupport?: string;
10
+ bpmnExperience?: string;
11
+ camunda7Experience?: string;
12
+ nextStep?: number;
13
+ complete?: boolean;
14
+ wasShown?: boolean;
15
+ [attribute: string]: unknown;
16
+ }
17
+ export interface WpCardType {
18
+ image: string;
19
+ title: string;
20
+ description: string;
21
+ timeToComplete?: string;
22
+ cta?: string;
23
+ link?: string;
24
+ card_id: string;
25
+ mixpanelId: string;
26
+ }
27
+ export interface Prerequestite {
28
+ id: string;
29
+ value: string;
30
+ not: boolean;
31
+ }
32
+ export interface TileConfig {
33
+ id: string;
34
+ bool: string;
35
+ prerequestites: Prerequestite[] | boolean;
36
+ }
37
+ export type Cluster = {
38
+ uuid: string;
39
+ };
40
+ export type Tab = {
41
+ id: string;
42
+ label: string;
43
+ title: string;
44
+ tiles: TileConfig[];
45
+ tiletype: TabType;
46
+ };
47
+ export type Organization = {
48
+ uuid: string;
49
+ organizationToSalesPlan?: {
50
+ salesPlan?: {
51
+ salesPlanType: string;
52
+ };
53
+ };
54
+ };
@@ -0,0 +1,10 @@
1
+ import { Tab } from "./c3-help-center.types";
2
+ export type HelpCenterConfig = {
3
+ tabs: Tab[];
4
+ links: {
5
+ label: string;
6
+ link: string;
7
+ id: string;
8
+ }[];
9
+ };
10
+ export declare const defaultHelpCenterConfig: HelpCenterConfig;
@@ -0,0 +1,12 @@
1
+ export const defaultHelpCenterConfig = {
2
+ tabs: [
3
+ {
4
+ id: "recommendations",
5
+ label: "Your recommendations",
6
+ title: "",
7
+ tiletype: "grid",
8
+ tiles: [],
9
+ },
10
+ ],
11
+ links: [],
12
+ };
@@ -0,0 +1,23 @@
1
+ import { ModalBodyProps, ModalHeaderProps } from "@carbon/react";
2
+ import { Dict } from "mixpanel-browser";
3
+ import { FC } from "react";
4
+ import { Cluster, Organization, Persona } from "./c3-help-center.types";
5
+ import { HelpCenterConfig } from "./defaultHelpCenterConfig";
6
+ export declare const StyledModalHeader: FC<ModalHeaderProps>;
7
+ export declare const StyledModalBody: FC<ModalBodyProps>;
8
+ export declare const HelpCenter: FC<{
9
+ configuration: HelpCenterConfig;
10
+ organization: Organization;
11
+ persona: Persona;
12
+ email: string;
13
+ audience: string;
14
+ clusters: Cluster[];
15
+ onRequestResumeSurvey: () => void;
16
+ onRequestRetakeSurvey: () => void;
17
+ onRequestClose: () => void;
18
+ theme: string;
19
+ origin: string;
20
+ initialTab: string | undefined;
21
+ flags?: string[];
22
+ mixpanelTrack?: (event: string, data: Dict | undefined) => void;
23
+ }>;
@@ -0,0 +1,173 @@
1
+ import { Button, Link, ModalBody, ModalFooter, ModalHeader, SideNav, SideNavItems, SideNavMenuItem, Stack, } from "@carbon/react";
2
+ import { Undo } from "@carbon/react/icons";
3
+ import React, { useState } from "react";
4
+ import { Feedback } from "./tabs/feedback";
5
+ import { TabContent } from "./tabs/tabContent";
6
+ import { getTiles } from "../../api/help-center";
7
+ import { useC3UserConfiguration } from "../c3-user-configuration/c3-user-configuration-provider";
8
+ import { body01, headings } from "../styles";
9
+ import styled from "styled-components";
10
+ export const StyledModalHeader = styled(ModalHeader) `
11
+ ${headings}
12
+ `;
13
+ export const StyledModalBody = styled(ModalBody) `
14
+ ${headings}
15
+
16
+ p {
17
+ ${body01}
18
+ }
19
+ `;
20
+ export const HelpCenter = ({ configuration, organization, persona, email, audience, clusters, flags = [], onRequestResumeSurvey, onRequestRetakeSurvey, onRequestClose, mixpanelTrack, theme, origin, initialTab, }) => {
21
+ const { tabs } = configuration;
22
+ const firstTab = tabs[0].id;
23
+ const { userToken: token } = useC3UserConfiguration() || {};
24
+ const [activeTab, setActiveTab] = useState(firstTab);
25
+ const [tabTiles, setTabTiles] = useState({});
26
+ let header = "";
27
+ let content = React.createElement(React.Fragment, null);
28
+ React.useEffect(() => {
29
+ ;
30
+ (async () => {
31
+ const tiles = {};
32
+ for (const singleTab of tabs) {
33
+ if (token) {
34
+ tiles[singleTab.id] = await getTiles({
35
+ tileConfig: singleTab.tiles,
36
+ cloudAudience: audience,
37
+ persona,
38
+ clusterIds: clusters.map((cluster) => cluster.uuid),
39
+ email,
40
+ currentOrgId: organization?.uuid ?? "",
41
+ salesPlanType: organization?.organizationToSalesPlan?.salesPlan?.salesPlanType ??
42
+ "",
43
+ flags,
44
+ accessToken: token,
45
+ });
46
+ }
47
+ }
48
+ setTabTiles(tiles);
49
+ })();
50
+ }, [token, persona, audience, organization, clusters, tabs]);
51
+ React.useEffect(() => {
52
+ setActiveTab(initialTab ?? firstTab);
53
+ }, [initialTab]);
54
+ if (activeTab === "feedback") {
55
+ header = "Share your feedback";
56
+ content = (React.createElement(Feedback, { audience: audience, theme: theme, mixpanelTrack: mixpanelTrack, setHeader: (head) => {
57
+ header = head;
58
+ } }));
59
+ }
60
+ else if (activeTab === "recommendations" &&
61
+ Object.keys(tabTiles).length === 0) {
62
+ header = "";
63
+ content = (React.createElement("div", { style: {
64
+ paddingLeft: "256px",
65
+ height: "100%",
66
+ display: "flex",
67
+ justifyContent: "center",
68
+ alignItems: "center",
69
+ } },
70
+ React.createElement("div", { style: {
71
+ height: "200px",
72
+ width: "450px",
73
+ } },
74
+ React.createElement(Stack, { orientation: "horizontal", gap: 6 },
75
+ React.createElement("svg", { width: "64", height: "64", viewBox: "0 0 64 64", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
76
+ React.createElement("path", { d: "M22.5379 14.9379C22.5379 9.46436 26.9851 5.0171 32.4587 5.0171C37.9322 5.0171 42.3795 9.46436 42.3795 14.9379C42.3795 20.4115 37.9322 24.8587 32.4587 24.8587C26.9851 24.8587 22.5379 20.3944 22.5379 14.9379ZM53.4976 38.7137L51.445 59H13.4723L11.4197 38.7137H20.5024V34.5743L10 26.86V5H16.3288V23.6443L24.5733 29.6994H41.4045L44.415 33.8046V38.7308L53.4976 38.7137ZM36.1704 48.8568C36.1704 46.8042 34.5112 45.1451 32.4587 45.1451C30.4061 45.1451 28.7469 46.8042 28.7469 48.8568C28.7469 50.9094 30.4061 52.5686 32.4587 52.5686C34.5112 52.5686 36.1704 50.9094 36.1704 48.8568Z", fill: "#FC5D0D" })),
77
+ React.createElement(Stack, { gap: 3 },
78
+ React.createElement("h2", null, "Personalize your experience"),
79
+ React.createElement(Stack, { gap: 6 },
80
+ React.createElement("p", { style: { maxWidth: "400px" } }, "Complete a 1-minute survey to access personalized next steps and educational content designed for you"),
81
+ React.createElement(Stack, { gap: 3 },
82
+ React.createElement(Button, { id: "additional-feedback-button", size: "md", onClick: () => {
83
+ onRequestRetakeSurvey();
84
+ } }, "Start now"))))))));
85
+ }
86
+ else {
87
+ const tab = configuration.tabs.find((tab) => tab.id === activeTab);
88
+ header = tab?.title ?? "";
89
+ if (tabTiles[activeTab]) {
90
+ content = (React.createElement(TabContent, { onboarding: (() => {
91
+ if (activeTab === "recommendations") {
92
+ return {
93
+ complete: persona.complete || false,
94
+ resumeSurvey: onRequestResumeSurvey,
95
+ };
96
+ }
97
+ else {
98
+ return undefined;
99
+ }
100
+ })(), origin: origin, type: tab?.tiletype || "grid", tiles: tabTiles[activeTab], mixpanelTrack: mixpanelTrack, salesPlanType: organization?.organizationToSalesPlan?.salesPlan?.salesPlanType ??
101
+ "" }));
102
+ }
103
+ }
104
+ const tabBar = [
105
+ ...configuration.tabs.map(({ id, label }) => ({
106
+ id,
107
+ name: id,
108
+ text: label,
109
+ })),
110
+ { id: "feedback", name: "feedback", text: "Share your feedback" },
111
+ ];
112
+ return (React.createElement(React.Fragment, null,
113
+ React.createElement(StyledModalHeader, { title: "", label: "", closeModal: onRequestClose, style: {
114
+ backgroundColor: theme === "light" ? "#FFFFFF" : "#161616",
115
+ marginBottom: "0",
116
+ } },
117
+ React.createElement("h4", { style: { marginLeft: "16rem" } }, header)),
118
+ React.createElement(StyledModalBody, { style: {
119
+ height: persona.complete && activeTab === "recommendations"
120
+ ? "638px"
121
+ : "700px",
122
+ backgroundColor: theme === "light" ? "#FFFFFF" : "#161616",
123
+ marginBottom: 0,
124
+ } },
125
+ React.createElement(SideNav, { isFixedNav: true, expanded: true, isChildOfHeader: false, "aria-label": "Side nav" },
126
+ React.createElement(SideNavItems, null,
127
+ React.createElement(SideNavMenuItem, null,
128
+ React.createElement("h5", null, "Help Center")),
129
+ React.createElement("div", { style: { marginTop: "4px" } },
130
+ React.createElement(Stack, null, tabBar.map(({ name, id, text }) => {
131
+ const active = activeTab === name;
132
+ let tabBackgroundColor = theme === "light" ? "#F4F4F4" : "#161616";
133
+ let tabButtonColor = theme === "light" ? "#525252" : "#f4f4f4";
134
+ if (active) {
135
+ tabBackgroundColor =
136
+ theme === "light" ? "#E5E5E5" : "#8D8D8D3D";
137
+ tabButtonColor = theme === "light" ? "#161616" : "#f4f4f4";
138
+ }
139
+ return (React.createElement(Button, { className: active ? "active" : "", kind: "secondary", onClick: () => {
140
+ setActiveTab(name);
141
+ mixpanelTrack?.("helpcenter:open", {
142
+ to: id,
143
+ from: origin,
144
+ });
145
+ }, style: {
146
+ width: "100%",
147
+ backgroundColor: tabBackgroundColor,
148
+ color: tabButtonColor,
149
+ }, key: name }, text));
150
+ }))),
151
+ React.createElement("div", { style: { position: "absolute", bottom: "20px" } }, configuration.links.map((link) => (React.createElement(SideNavMenuItem, { key: link.label.split(" ").join("-").toLowerCase() },
152
+ React.createElement(Link, { href: link.link, target: "_blank" }, link.label))))))),
153
+ content),
154
+ persona.complete && activeTab === "recommendations" && (React.createElement(ModalFooter, { style: {
155
+ height: "62px",
156
+ paddingRight: "16px",
157
+ paddingTop: "16px",
158
+ paddingBottom: "16px",
159
+ borderTop: "1px",
160
+ borderStyle: "solid",
161
+ borderColor: theme === "light" ? "#E0E0E0" : "#727272",
162
+ backgroundColor: theme === "light" ? "#FFFFFF" : "#161616",
163
+ } },
164
+ React.createElement("div", null,
165
+ React.createElement(Button, { kind: "tertiary", renderIcon: Undo, onClick: onRequestRetakeSurvey, size: "sm", style: {
166
+ maxWidth: "200px",
167
+ height: "32px",
168
+ alignItems: "center",
169
+ paddingTop: "0px",
170
+ paddingBottom: "0px",
171
+ marginRight: "6px",
172
+ } }, "Retake the survey"))))));
173
+ };
@@ -0,0 +1,4 @@
1
+ import { TileConfig } from "./c3-help-center.types";
2
+ export declare const recommendations: (persona: {
3
+ [id: string]: unknown;
4
+ }, flags: string[], tileConfig: TileConfig[], salesPlanType: string, hasClusters: boolean) => string[];