mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-30 00:32:00 +08:00
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:
parent
6a829489a8
commit
694f2562bf
@ -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;
|
||||
|
@ -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 };
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user