mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-31 07:22:02 +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 './CodeCopyBtn.scss';
|
||||||
|
|
||||||
import { CheckOutlined, CopyOutlined } from '@ant-design/icons';
|
import { CheckOutlined, CopyOutlined } from '@ant-design/icons';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
export default function CodeCopyBtn({
|
function CodeCopyBtn({
|
||||||
children,
|
children,
|
||||||
|
onCopyClick,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
onCopyClick?: (additionalInfo?: Record<string, unknown>) => void;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [isSnippetCopied, setIsSnippetCopied] = useState(false);
|
const [isSnippetCopied, setIsSnippetCopied] = useState(false);
|
||||||
|
|
||||||
const handleClick = (): void => {
|
const handleClick = (): void => {
|
||||||
|
let copiedText = '';
|
||||||
if (children && Array.isArray(children)) {
|
if (children && Array.isArray(children)) {
|
||||||
setIsSnippetCopied(true);
|
setIsSnippetCopied(true);
|
||||||
navigator.clipboard.writeText(children[0].props.children[0]).finally(() => {
|
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(() => {
|
setTimeout(() => {
|
||||||
setIsSnippetCopied(false);
|
setIsSnippetCopied(false);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
copiedText = (children[0].props.children[0] as string).slice(0, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCopyClick?.({ copiedText });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -30,3 +38,9 @@ export default function CodeCopyBtn({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeCopyBtn.defaultProps = {
|
||||||
|
onCopyClick: (): void => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CodeCopyBtn;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
/* eslint-disable react/jsx-props-no-spreading */
|
/* eslint-disable react/jsx-props-no-spreading */
|
||||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
/* 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 ReactMarkdown from 'react-markdown';
|
||||||
import { CodeProps } from 'react-markdown/lib/ast-to-react';
|
import { CodeProps } from 'react-markdown/lib/ast-to-react';
|
||||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||||
@ -15,10 +17,28 @@ interface LinkProps {
|
|||||||
children: React.ReactElement;
|
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 (
|
return (
|
||||||
<pre className="code-snippet-container">
|
<pre className="code-snippet-container">
|
||||||
<CodeCopyBtn>{children}</CodeCopyBtn>
|
<CodeCopyBtn onCopyClick={handleClick}>{children}</CodeCopyBtn>
|
||||||
{children}
|
{children}
|
||||||
</pre>
|
</pre>
|
||||||
);
|
);
|
||||||
@ -83,9 +103,13 @@ function CustomTag({ color }: { color: string }): JSX.Element {
|
|||||||
function MarkdownRenderer({
|
function MarkdownRenderer({
|
||||||
markdownContent,
|
markdownContent,
|
||||||
variables,
|
variables,
|
||||||
|
trackCopyAction,
|
||||||
|
elementDetails,
|
||||||
}: {
|
}: {
|
||||||
markdownContent: any;
|
markdownContent: any;
|
||||||
variables: any;
|
variables: any;
|
||||||
|
trackCopyAction?: boolean;
|
||||||
|
elementDetails?: Record<string, unknown>;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const interpolatedMarkdown = interpolateMarkdown(markdownContent, variables);
|
const interpolatedMarkdown = interpolateMarkdown(markdownContent, variables);
|
||||||
|
|
||||||
@ -96,7 +120,12 @@ function MarkdownRenderer({
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
a: Link,
|
a: Link,
|
||||||
pre: Pre,
|
pre: ({ children }) =>
|
||||||
|
Pre({
|
||||||
|
children,
|
||||||
|
elementDetails: elementDetails ?? {},
|
||||||
|
trackCopyAction: !!trackCopyAction,
|
||||||
|
}),
|
||||||
code: Code,
|
code: Code,
|
||||||
customtag: CustomTag,
|
customtag: CustomTag,
|
||||||
}}
|
}}
|
||||||
@ -106,4 +135,9 @@ function MarkdownRenderer({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MarkdownRenderer.defaultProps = {
|
||||||
|
elementDetails: {},
|
||||||
|
trackCopyAction: false,
|
||||||
|
};
|
||||||
|
|
||||||
export { Code, Link, MarkdownRenderer, Pre };
|
export { Code, Link, MarkdownRenderer, Pre };
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import './IntegrationDetailContentTabs.styles.scss';
|
import './IntegrationDetailContentTabs.styles.scss';
|
||||||
|
|
||||||
import { Button, Typography } from 'antd';
|
import { Button, Typography } from 'antd';
|
||||||
|
import logEvent from 'api/common/logEvent';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
|
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import useAnalytics from 'hooks/analytics/useAnalytics';
|
import useAnalytics from 'hooks/analytics/useAnalytics';
|
||||||
@ -17,12 +18,16 @@ function Configure(props: ConfigurationProps): JSX.Element {
|
|||||||
const { configuration, integrationId } = props;
|
const { configuration, integrationId } = props;
|
||||||
const [selectedConfigStep, setSelectedConfigStep] = useState(0);
|
const [selectedConfigStep, setSelectedConfigStep] = useState(0);
|
||||||
|
|
||||||
const handleMenuClick = (index: number): void => {
|
|
||||||
setSelectedConfigStep(index);
|
|
||||||
};
|
|
||||||
|
|
||||||
const { trackEvent } = useAnalytics();
|
const { trackEvent } = useAnalytics();
|
||||||
|
|
||||||
|
const handleMenuClick = (index: number, config: any): void => {
|
||||||
|
setSelectedConfigStep(index);
|
||||||
|
logEvent('Integrations Detail Page: Configure tab', {
|
||||||
|
sectionName: config?.title,
|
||||||
|
integrationId,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
trackEvent(
|
trackEvent(
|
||||||
INTEGRATION_TELEMETRY_EVENTS.INTEGRATIONS_DETAIL_CONFIGURE_INSTRUCTION,
|
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
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const markdownDetailsForTracking = {
|
||||||
|
trackingTitle: `Integrations Detail Page: Copy button`,
|
||||||
|
sectionName: configuration[selectedConfigStep].title,
|
||||||
|
integrationId,
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="integration-detail-configure">
|
<div className="integration-detail-configure">
|
||||||
<div className="configure-menu">
|
<div className="configure-menu">
|
||||||
@ -43,7 +54,7 @@ function Configure(props: ConfigurationProps): JSX.Element {
|
|||||||
className={cx('configure-menu-item', {
|
className={cx('configure-menu-item', {
|
||||||
active: selectedConfigStep === index,
|
active: selectedConfigStep === index,
|
||||||
})}
|
})}
|
||||||
onClick={(): void => handleMenuClick(index)}
|
onClick={(): void => handleMenuClick(index, config)}
|
||||||
>
|
>
|
||||||
<Typography.Text className="configure-text">
|
<Typography.Text className="configure-text">
|
||||||
{config.title}
|
{config.title}
|
||||||
@ -55,6 +66,8 @@ function Configure(props: ConfigurationProps): JSX.Element {
|
|||||||
<MarkdownRenderer
|
<MarkdownRenderer
|
||||||
variables={{}}
|
variables={{}}
|
||||||
markdownContent={configuration[selectedConfigStep].instructions}
|
markdownContent={configuration[selectedConfigStep].instructions}
|
||||||
|
elementDetails={markdownDetailsForTracking}
|
||||||
|
trackCopyAction
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -24,6 +24,7 @@ function Overview(props: OverviewProps): JSX.Element {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const assetLabelMap = ['Pipelines', 'Dashboards', 'Alerts'];
|
const assetLabelMap = ['Pipelines', 'Dashboards', 'Alerts'];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="integration-detail-overview">
|
<div className="integration-detail-overview">
|
||||||
<div className="integration-detail-overview-left-container">
|
<div className="integration-detail-overview-left-container">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user