feat: integration: added copy test tracking, facing issue btn and request more integration section (#5130)

* feat: integration: added copy test tracking, facing issue btn and request more integration section

* feat: removed copy btn tracking from onboarding markdown

* feat: removed copy btn tracking from onboarding markdown

* feat: added track event on Configure option clicks

* feat: code cleanup

* feat: code cleanup

* feat: changed trackEvent to logEvent

* feat: changed text in integration facing issue button

* feat: sliced copied text

* feat: code cleanup
This commit is contained in:
SagarRajput-7 2024-06-05 19:35:03 +05:30 committed by GitHub
parent 6a829489a8
commit 694f2562bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 10 deletions

View File

@ -1,25 +1,33 @@
/* eslint-disable prefer-destructuring */
import './CodeCopyBtn.scss';
import { CheckOutlined, CopyOutlined } from '@ant-design/icons';
import cx from 'classnames';
import { useState } from 'react';
import React, { useState } from 'react';
export default function CodeCopyBtn({
function CodeCopyBtn({
children,
onCopyClick,
}: {
children: React.ReactNode;
onCopyClick?: (additionalInfo?: Record<string, unknown>) => void;
}): JSX.Element {
const [isSnippetCopied, setIsSnippetCopied] = useState(false);
const handleClick = (): void => {
let copiedText = '';
if (children && Array.isArray(children)) {
setIsSnippetCopied(true);
navigator.clipboard.writeText(children[0].props.children[0]).finally(() => {
copiedText = (children[0].props.children[0] as string).slice(0, 200); // slicing is done due to the limitation in accepted char length in attributes
setTimeout(() => {
setIsSnippetCopied(false);
}, 1000);
});
copiedText = (children[0].props.children[0] as string).slice(0, 200);
}
onCopyClick?.({ copiedText });
};
return (
@ -30,3 +38,9 @@ export default function CodeCopyBtn({
</div>
);
}
CodeCopyBtn.defaultProps = {
onCopyClick: (): void => {},
};
export default CodeCopyBtn;

View File

@ -2,6 +2,8 @@
/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import logEvent from 'api/common/logEvent';
import { isEmpty } from 'lodash-es';
import ReactMarkdown from 'react-markdown';
import { CodeProps } from 'react-markdown/lib/ast-to-react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
@ -15,10 +17,28 @@ interface LinkProps {
children: React.ReactElement;
}
function Pre({ children }: { children: React.ReactNode }): JSX.Element {
function Pre({
children,
elementDetails,
trackCopyAction,
}: {
children: React.ReactNode;
trackCopyAction: boolean;
elementDetails: Record<string, unknown>;
}): JSX.Element {
const { trackingTitle = '', ...rest } = elementDetails;
const handleClick = (additionalInfo?: Record<string, unknown>): void => {
const trackingData = { ...rest, copiedContent: additionalInfo };
if (trackCopyAction && !isEmpty(trackingTitle)) {
logEvent(trackingTitle as string, trackingData);
}
};
return (
<pre className="code-snippet-container">
<CodeCopyBtn>{children}</CodeCopyBtn>
<CodeCopyBtn onCopyClick={handleClick}>{children}</CodeCopyBtn>
{children}
</pre>
);
@ -83,9 +103,13 @@ function CustomTag({ color }: { color: string }): JSX.Element {
function MarkdownRenderer({
markdownContent,
variables,
trackCopyAction,
elementDetails,
}: {
markdownContent: any;
variables: any;
trackCopyAction?: boolean;
elementDetails?: Record<string, unknown>;
}): JSX.Element {
const interpolatedMarkdown = interpolateMarkdown(markdownContent, variables);
@ -96,7 +120,12 @@ function MarkdownRenderer({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
a: Link,
pre: Pre,
pre: ({ children }) =>
Pre({
children,
elementDetails: elementDetails ?? {},
trackCopyAction: !!trackCopyAction,
}),
code: Code,
customtag: CustomTag,
}}
@ -106,4 +135,9 @@ function MarkdownRenderer({
);
}
MarkdownRenderer.defaultProps = {
elementDetails: {},
trackCopyAction: false,
};
export { Code, Link, MarkdownRenderer, Pre };

View File

@ -1,6 +1,7 @@
import './IntegrationDetailContentTabs.styles.scss';
import { Button, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import cx from 'classnames';
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
import useAnalytics from 'hooks/analytics/useAnalytics';
@ -17,12 +18,16 @@ function Configure(props: ConfigurationProps): JSX.Element {
const { configuration, integrationId } = props;
const [selectedConfigStep, setSelectedConfigStep] = useState(0);
const handleMenuClick = (index: number): void => {
setSelectedConfigStep(index);
};
const { trackEvent } = useAnalytics();
const handleMenuClick = (index: number, config: any): void => {
setSelectedConfigStep(index);
logEvent('Integrations Detail Page: Configure tab', {
sectionName: config?.title,
integrationId,
});
};
useEffect(() => {
trackEvent(
INTEGRATION_TELEMETRY_EVENTS.INTEGRATIONS_DETAIL_CONFIGURE_INSTRUCTION,
@ -33,6 +38,12 @@ function Configure(props: ConfigurationProps): JSX.Element {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const markdownDetailsForTracking = {
trackingTitle: `Integrations Detail Page: Copy button`,
sectionName: configuration[selectedConfigStep].title,
integrationId,
};
return (
<div className="integration-detail-configure">
<div className="configure-menu">
@ -43,7 +54,7 @@ function Configure(props: ConfigurationProps): JSX.Element {
className={cx('configure-menu-item', {
active: selectedConfigStep === index,
})}
onClick={(): void => handleMenuClick(index)}
onClick={(): void => handleMenuClick(index, config)}
>
<Typography.Text className="configure-text">
{config.title}
@ -55,6 +66,8 @@ function Configure(props: ConfigurationProps): JSX.Element {
<MarkdownRenderer
variables={{}}
markdownContent={configuration[selectedConfigStep].instructions}
elementDetails={markdownDetailsForTracking}
trackCopyAction
/>
</div>
</div>

View File

@ -24,6 +24,7 @@ function Overview(props: OverviewProps): JSX.Element {
];
const assetLabelMap = ['Pipelines', 'Dashboards', 'Alerts'];
return (
<div className="integration-detail-overview">
<div className="integration-detail-overview-left-container">