mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 15:35:57 +08:00
feat: added facing issues and requestIntegration section in integration pages (#5147)
* feat: added facing issues and requestIntegration section in integration pages * feat: changed text in integration facing issue button * feat: fixed facing-issue tooltip styles * feat: code cleanup * feat: added margin bottom to request more component
This commit is contained in:
parent
bc8a235915
commit
4c7f90dad8
@ -7,3 +7,10 @@
|
|||||||
border-color: var(--bg-amber-300) !important;
|
border-color: var(--bg-amber-300) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip-overlay {
|
||||||
|
text-wrap: nowrap;
|
||||||
|
.ant-tooltip-inner {
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -39,7 +39,12 @@ function FacingIssueBtn({
|
|||||||
|
|
||||||
return isCloudUserVal && isChatSupportEnabled ? ( // Note: we would need to move this condition to license based in future
|
return isCloudUserVal && isChatSupportEnabled ? ( // Note: we would need to move this condition to license based in future
|
||||||
<div className="facing-issue-button">
|
<div className="facing-issue-button">
|
||||||
<Tooltip title={onHoverText} autoAdjustOverflow>
|
<Tooltip
|
||||||
|
title={onHoverText}
|
||||||
|
autoAdjustOverflow
|
||||||
|
style={{ padding: 8 }}
|
||||||
|
overlayClassName="tooltip-overlay"
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
className={cx('periscope-btn', 'facing-issue-button', className)}
|
className={cx('periscope-btn', 'facing-issue-button', className)}
|
||||||
onClick={handleFacingIssuesClick}
|
onClick={handleFacingIssuesClick}
|
||||||
|
@ -55,3 +55,20 @@ State: ${(alertDef as any)?.state || ''}
|
|||||||
Alert Id: ${ruleId}
|
Alert Id: ${ruleId}
|
||||||
|
|
||||||
Thanks`;
|
Thanks`;
|
||||||
|
|
||||||
|
export const integrationsListMessage = `Hi Team,
|
||||||
|
|
||||||
|
I need help with Integrations.
|
||||||
|
|
||||||
|
Thanks`;
|
||||||
|
|
||||||
|
export const integrationDetailMessage = (
|
||||||
|
selectedIntegration: string,
|
||||||
|
): string => `
|
||||||
|
Hi Team,
|
||||||
|
|
||||||
|
I need help in configuring this integration.
|
||||||
|
|
||||||
|
Integration Id: ${selectedIntegration}
|
||||||
|
|
||||||
|
Thanks`;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import './Integrations.styles.scss';
|
import './Integrations.styles.scss';
|
||||||
|
|
||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Input, Typography } from 'antd';
|
import { Flex, Input, Typography } from 'antd';
|
||||||
|
import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn';
|
||||||
|
import { integrationsListMessage } from 'components/facingIssueBtn/util';
|
||||||
import { Search } from 'lucide-react';
|
import { Search } from 'lucide-react';
|
||||||
import { Dispatch, SetStateAction } from 'react';
|
import { Dispatch, SetStateAction } from 'react';
|
||||||
|
|
||||||
@ -19,9 +21,18 @@ function Header(props: HeaderProps): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<div className="integrations-header">
|
<div className="integrations-header">
|
||||||
<Typography.Title className="title">Integrations</Typography.Title>
|
<Typography.Title className="title">Integrations</Typography.Title>
|
||||||
|
<Flex justify="space-between" align="center">
|
||||||
<Typography.Text className="subtitle">
|
<Typography.Text className="subtitle">
|
||||||
Manage Integrations for this workspace
|
Manage Integrations for this workspace
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
|
<FacingIssueBtn
|
||||||
|
attributes={{ screen: 'Integrations list page' }}
|
||||||
|
eventName="Integrations: Facing issues in integrations"
|
||||||
|
buttonText="Facing issues with integrations"
|
||||||
|
message={integrationsListMessage}
|
||||||
|
onHoverText="Click here to get help with integrations"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
placeholder="Search for an integration..."
|
placeholder="Search for an integration..."
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
import './IntegrationDetailPage.styles.scss';
|
import './IntegrationDetailPage.styles.scss';
|
||||||
|
|
||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Button, Skeleton, Typography } from 'antd';
|
import { Button, Flex, Skeleton, Typography } from 'antd';
|
||||||
|
import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn';
|
||||||
|
import { integrationDetailMessage } from 'components/facingIssueBtn/util';
|
||||||
import { useGetIntegration } from 'hooks/Integrations/useGetIntegration';
|
import { useGetIntegration } from 'hooks/Integrations/useGetIntegration';
|
||||||
import { useGetIntegrationStatus } from 'hooks/Integrations/useGetIntegrationStatus';
|
import { useGetIntegrationStatus } from 'hooks/Integrations/useGetIntegrationStatus';
|
||||||
import { defaultTo } from 'lodash-es';
|
import { defaultTo } from 'lodash-es';
|
||||||
@ -64,6 +66,7 @@ function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="integration-detail-content">
|
<div className="integration-detail-content">
|
||||||
|
<Flex justify="space-between" align="center">
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
icon={<ArrowLeft size={14} />}
|
icon={<ArrowLeft size={14} />}
|
||||||
@ -74,6 +77,19 @@ function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
|
|||||||
>
|
>
|
||||||
All Integrations
|
All Integrations
|
||||||
</Button>
|
</Button>
|
||||||
|
<FacingIssueBtn
|
||||||
|
attributes={{
|
||||||
|
screen: 'Integrations detail page',
|
||||||
|
activeTab: activeDetailTab,
|
||||||
|
integrationTitle: integrationData?.title || '',
|
||||||
|
integrationId: selectedIntegration,
|
||||||
|
}}
|
||||||
|
eventName="Integrations: Facing issues in integrations"
|
||||||
|
buttonText="Facing issues with integration"
|
||||||
|
message={integrationDetailMessage(selectedIntegration)}
|
||||||
|
onHoverText="Click here to get help with this integration"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="loading-integration-details">
|
<div className="loading-integration-details">
|
||||||
|
@ -172,6 +172,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.request-entity-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 0.5px solid rgba(78, 116, 248, 0.2);
|
||||||
|
background: rgba(69, 104, 220, 0.1);
|
||||||
|
padding: 12px;
|
||||||
|
margin: 24px 0;
|
||||||
|
margin-bottom: 80px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import { useHistory, useLocation } from 'react-router-dom';
|
|||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
import IntegrationDetailPage from './IntegrationDetailPage/IntegrationDetailPage';
|
import IntegrationDetailPage from './IntegrationDetailPage/IntegrationDetailPage';
|
||||||
import IntegrationsList from './IntegrationsList';
|
import IntegrationsList from './IntegrationsList';
|
||||||
|
import { RequestIntegrationBtn } from './RequestIntegrationBtn';
|
||||||
import { INTEGRATION_TELEMETRY_EVENTS } from './utils';
|
import { INTEGRATION_TELEMETRY_EVENTS } from './utils';
|
||||||
|
|
||||||
function Integrations(): JSX.Element {
|
function Integrations(): JSX.Element {
|
||||||
@ -65,6 +66,7 @@ function Integrations(): JSX.Element {
|
|||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
setActiveDetailTab={setActiveDetailTab}
|
setActiveDetailTab={setActiveDetailTab}
|
||||||
/>
|
/>
|
||||||
|
<RequestIntegrationBtn />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
95
frontend/src/pages/Integrations/RequestIntegrationBtn.tsx
Normal file
95
frontend/src/pages/Integrations/RequestIntegrationBtn.tsx
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import './Integrations.styles.scss';
|
||||||
|
|
||||||
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Input, Space, Typography } from 'antd';
|
||||||
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
|
import { Check } from 'lucide-react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export function RequestIntegrationBtn(): JSX.Element {
|
||||||
|
const [
|
||||||
|
isSubmittingRequestForIntegration,
|
||||||
|
setIsSubmittingRequestForIntegration,
|
||||||
|
] = useState(false);
|
||||||
|
|
||||||
|
const [requestedIntegrationName, setRequestedIntegrationName] = useState('');
|
||||||
|
|
||||||
|
const { notifications } = useNotifications();
|
||||||
|
const { t } = useTranslation(['common']);
|
||||||
|
|
||||||
|
const handleRequestIntegrationSubmit = async (): Promise<void> => {
|
||||||
|
try {
|
||||||
|
setIsSubmittingRequestForIntegration(true);
|
||||||
|
const response = await logEvent('Integration Requested', {
|
||||||
|
screen: 'Integration list page',
|
||||||
|
integration: requestedIntegrationName,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.statusCode === 200) {
|
||||||
|
notifications.success({
|
||||||
|
message: 'Integration Request Submitted',
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsSubmittingRequestForIntegration(false);
|
||||||
|
} else {
|
||||||
|
notifications.error({
|
||||||
|
message:
|
||||||
|
response.error ||
|
||||||
|
t('something_went_wrong', {
|
||||||
|
ns: 'common',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsSubmittingRequestForIntegration(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error({
|
||||||
|
message: t('something_went_wrong', {
|
||||||
|
ns: 'common',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsSubmittingRequestForIntegration(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="request-entity-container">
|
||||||
|
<Typography.Text>
|
||||||
|
Cannot find what you’re looking for? Request more integrations
|
||||||
|
</Typography.Text>
|
||||||
|
|
||||||
|
<div className="form-section">
|
||||||
|
<Space.Compact style={{ width: '100%' }}>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter integration name..."
|
||||||
|
style={{ width: 300, marginBottom: 0 }}
|
||||||
|
value={requestedIntegrationName}
|
||||||
|
onChange={(e): void => setRequestedIntegrationName(e.target.value)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="periscope-btn primary"
|
||||||
|
icon={
|
||||||
|
isSubmittingRequestForIntegration ? (
|
||||||
|
<LoadingOutlined />
|
||||||
|
) : (
|
||||||
|
<Check size={12} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
type="primary"
|
||||||
|
onClick={handleRequestIntegrationSubmit}
|
||||||
|
disabled={
|
||||||
|
isSubmittingRequestForIntegration ||
|
||||||
|
!requestedIntegrationName ||
|
||||||
|
requestedIntegrationName?.trim().length === 0
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Space.Compact>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user