mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-16 14:35:58 +08:00
feat: revamp integration flow (#4832)
* feat: revamp integration flow * feat: final design changes * feat: make test connection button grey
This commit is contained in:
parent
872ed9e963
commit
59c242961f
@ -13,12 +13,18 @@ interface IntegrationDetailContentProps {
|
||||
activeDetailTab: string;
|
||||
integrationData: IntegrationDetailedProps;
|
||||
integrationId: string;
|
||||
setActiveDetailTab: React.Dispatch<React.SetStateAction<string | null>>;
|
||||
}
|
||||
|
||||
function IntegrationDetailContent(
|
||||
props: IntegrationDetailContentProps,
|
||||
): JSX.Element {
|
||||
const { activeDetailTab, integrationData, integrationId } = props;
|
||||
const {
|
||||
activeDetailTab,
|
||||
integrationData,
|
||||
integrationId,
|
||||
setActiveDetailTab,
|
||||
} = props;
|
||||
const items: TabsProps['items'] = [
|
||||
{
|
||||
key: 'overview',
|
||||
@ -78,7 +84,11 @@ function IntegrationDetailContent(
|
||||
];
|
||||
return (
|
||||
<div className="integration-detail-container">
|
||||
<Tabs defaultActiveKey={activeDetailTab} items={items} />
|
||||
<Tabs
|
||||
activeKey={activeDetailTab}
|
||||
items={items}
|
||||
onChange={setActiveDetailTab}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ import './IntegrationDetailPage.styles.scss';
|
||||
|
||||
import { Button, Modal, Tooltip, Typography } from 'antd';
|
||||
import installIntegration from 'api/Integrations/installIntegration';
|
||||
import ConfigureIcon from 'assets/Integrations/ConfigureIcon';
|
||||
import cx from 'classnames';
|
||||
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
||||
import dayjs from 'dayjs';
|
||||
import useAnalytics from 'hooks/analytics/useAnalytics';
|
||||
@ -23,6 +25,7 @@ interface IntegrationDetailHeaderProps {
|
||||
refetchIntegrationDetails: () => void;
|
||||
connectionState: ConnectionStates;
|
||||
connectionData: IntegrationConnectionStatus;
|
||||
setActiveDetailTab: React.Dispatch<React.SetStateAction<string | null>>;
|
||||
}
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
function IntegrationDetailHeader(
|
||||
@ -36,6 +39,7 @@ function IntegrationDetailHeader(
|
||||
connectionState,
|
||||
connectionData,
|
||||
refetchIntegrationDetails,
|
||||
setActiveDetailTab,
|
||||
} = props;
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
@ -106,6 +110,12 @@ function IntegrationDetailHeader(
|
||||
last_received_from: connectionData.metrics.last_received_from,
|
||||
};
|
||||
}
|
||||
const isConnectionStatePending =
|
||||
connectionState === ConnectionStates.NotInstalled ||
|
||||
connectionState === ConnectionStates.TestingConnection;
|
||||
|
||||
const isConnectionStateNotInstalled =
|
||||
connectionState === ConnectionStates.NotInstalled;
|
||||
return (
|
||||
<div className="integration-connection-header">
|
||||
<div className="integration-detail-header" key={id}>
|
||||
@ -119,7 +129,10 @@ function IntegrationDetailHeader(
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
className="configure-btn"
|
||||
className={cx(
|
||||
'configure-btn',
|
||||
!isConnectionStateNotInstalled && 'test-connection',
|
||||
)}
|
||||
icon={<ArrowLeftRight size={14} />}
|
||||
disabled={isInstallLoading}
|
||||
onClick={(): void => {
|
||||
@ -127,7 +140,6 @@ function IntegrationDetailHeader(
|
||||
trackEvent(INTEGRATION_TELEMETRY_EVENTS.INTEGRATIONS_DETAIL_CONNECT, {
|
||||
integration: id,
|
||||
});
|
||||
mutate({ integration_id: id, config: {} });
|
||||
} else {
|
||||
trackEvent(
|
||||
INTEGRATION_TELEMETRY_EVENTS.INTEGRATIONS_DETAIL_TEST_CONNECTION,
|
||||
@ -136,13 +148,11 @@ function IntegrationDetailHeader(
|
||||
connectionStatus: connectionState,
|
||||
},
|
||||
);
|
||||
showModal();
|
||||
}
|
||||
showModal();
|
||||
}}
|
||||
>
|
||||
{connectionState === ConnectionStates.NotInstalled
|
||||
? `Connect ${title}`
|
||||
: `Test Connection`}
|
||||
{isConnectionStateNotInstalled ? `Connect ${title}` : `Test Connection`}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@ -153,15 +163,67 @@ function IntegrationDetailHeader(
|
||||
<Modal
|
||||
className="test-connection-modal"
|
||||
open={isModalOpen}
|
||||
title="Test Connection"
|
||||
onOk={handleOk}
|
||||
title={
|
||||
isConnectionStateNotInstalled
|
||||
? `Connect ${title}`
|
||||
: `Test ${title} Connection`
|
||||
}
|
||||
onCancel={handleCancel}
|
||||
okText="I understand"
|
||||
okButtonProps={{ className: 'understandBtn', icon: <Check size={14} /> }}
|
||||
cancelButtonProps={{ style: { display: 'none' } }}
|
||||
footer={
|
||||
<div
|
||||
className={cx(
|
||||
'connection-footer',
|
||||
!isConnectionStatePending && 'not-pending',
|
||||
)}
|
||||
>
|
||||
<Button
|
||||
type="text"
|
||||
icon={
|
||||
isConnectionStateNotInstalled ? <ConfigureIcon /> : <Check size={14} />
|
||||
}
|
||||
onClick={(): void => {
|
||||
if (isConnectionStateNotInstalled) {
|
||||
setActiveDetailTab('configuration');
|
||||
}
|
||||
handleOk();
|
||||
}}
|
||||
className="understandBtn"
|
||||
>
|
||||
{isConnectionStatePending
|
||||
? isConnectionStateNotInstalled
|
||||
? 'Show Configuration Steps'
|
||||
: 'I have already configured'
|
||||
: 'I understand'}
|
||||
</Button>
|
||||
{isConnectionStatePending && (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={
|
||||
isConnectionStateNotInstalled ? <Check size={14} /> : <ConfigureIcon />
|
||||
}
|
||||
onClick={(): void => {
|
||||
if (isConnectionStateNotInstalled) {
|
||||
mutate({ integration_id: id, config: {} });
|
||||
} else {
|
||||
setActiveDetailTab('configuration');
|
||||
}
|
||||
|
||||
handleOk();
|
||||
}}
|
||||
className="configureBtn"
|
||||
>
|
||||
{isConnectionStateNotInstalled
|
||||
? 'I have already configured'
|
||||
: 'Show Configuration Steps'}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="connection-content">
|
||||
<TestConnection connectionState={connectionState} />
|
||||
{!isConnectionStateNotInstalled && (
|
||||
<TestConnection connectionState={connectionState} />
|
||||
)}
|
||||
{connectionState === ConnectionStates.Connected ||
|
||||
connectionState === ConnectionStates.NoDataSinceLong ? (
|
||||
<>
|
||||
@ -210,12 +272,26 @@ function IntegrationDetailHeader(
|
||||
) : connectionState === ConnectionStates.TestingConnection ? (
|
||||
<div className="data-test-connection">
|
||||
<div className="last-data">
|
||||
After adding the {title} integration, you need to manually configure
|
||||
your Redis data source to start sending data to SigNoz.
|
||||
We have not received data from your {title} Instance yet. You need to
|
||||
manually configure your {title} instance to start sending data to
|
||||
SigNoz.
|
||||
</div>
|
||||
<div className="last-data">
|
||||
The status bar above would turn green if we are successfully receiving
|
||||
the data.
|
||||
If you have already configured your resources to send data, sit tight
|
||||
and wait for the data to flow in, Or else, see the steps to configure
|
||||
your resources to start sending data.
|
||||
</div>
|
||||
</div>
|
||||
) : isConnectionStateNotInstalled ? (
|
||||
<div className="data-test-connection">
|
||||
<div className="last-data">
|
||||
You would need to manually configure your {title} instance to start
|
||||
sending data to SigNoz.
|
||||
</div>
|
||||
<div className="last-data">
|
||||
If you have already configured your resources to send data, sit tight
|
||||
and wait for the data to flow in, Or else, see the steps to configure
|
||||
your resources to start sending data.
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
@ -160,6 +160,14 @@
|
||||
font-weight: 500;
|
||||
line-height: 10px; /* 83.333% */
|
||||
letter-spacing: 0.12px;
|
||||
box-shadow: none;
|
||||
|
||||
&.test-connection {
|
||||
border-radius: 2px;
|
||||
border: 1px solid var(--bg-slate-400);
|
||||
background: var(--bg-ink-300);
|
||||
color: var(--bg-vanilla-400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,25 +388,56 @@
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.understandBtn {
|
||||
border-radius: 2px;
|
||||
border: 1px solid var(--bg-slate-400);
|
||||
background: var(--bg-ink-300);
|
||||
box-shadow: none;
|
||||
color: var(--bg-vanilla-400);
|
||||
font-family: Inter;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 10px; /* 83.333% */
|
||||
letter-spacing: 0.12px;
|
||||
.connection-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 131px;
|
||||
height: 30px;
|
||||
padding: 6px;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
.understandBtn {
|
||||
width: 50%;
|
||||
border-radius: 2px;
|
||||
border: 1px solid var(--bg-slate-400);
|
||||
background: var(--bg-ink-300);
|
||||
box-shadow: none;
|
||||
color: var(--bg-vanilla-400);
|
||||
font-family: Inter;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 10px; /* 83.333% */
|
||||
letter-spacing: 0.12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 34px;
|
||||
padding: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.configureBtn {
|
||||
width: 50%;
|
||||
color: var(--bg-vanilla-100);
|
||||
font-family: Inter;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 10px; /* 83.333% */
|
||||
letter-spacing: 0.12px;
|
||||
border-radius: 2px;
|
||||
background: var(--bg-robin-500);
|
||||
display: flex;
|
||||
height: 34px;
|
||||
padding: 6px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex: 1 0 0;
|
||||
}
|
||||
|
||||
&.not-pending {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.understandBtn {
|
||||
width: 131px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,6 +583,13 @@
|
||||
color: var(--bg-slate-200);
|
||||
}
|
||||
}
|
||||
.configure-btn {
|
||||
&.test-connection {
|
||||
border: 1px solid rgba(53, 59, 76, 0.2);
|
||||
background: var(--bg-vanilla-200);
|
||||
color: var(--bg-slate-200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.testingConnection {
|
||||
|
@ -22,10 +22,16 @@ interface IntegrationDetailPageProps {
|
||||
selectedIntegration: string;
|
||||
setSelectedIntegration: (id: string | null) => void;
|
||||
activeDetailTab: string;
|
||||
setActiveDetailTab: React.Dispatch<React.SetStateAction<string | null>>;
|
||||
}
|
||||
|
||||
function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
|
||||
const { selectedIntegration, setSelectedIntegration, activeDetailTab } = props;
|
||||
const {
|
||||
selectedIntegration,
|
||||
setSelectedIntegration,
|
||||
activeDetailTab,
|
||||
setActiveDetailTab,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
data,
|
||||
@ -119,11 +125,13 @@ function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
|
||||
metrics: null,
|
||||
})}
|
||||
refetchIntegrationDetails={refetch}
|
||||
setActiveDetailTab={setActiveDetailTab}
|
||||
/>
|
||||
<IntegrationDetailContent
|
||||
activeDetailTab={activeDetailTab}
|
||||
integrationData={integrationData}
|
||||
integrationId={selectedIntegration}
|
||||
setActiveDetailTab={setActiveDetailTab}
|
||||
/>
|
||||
|
||||
{connectionStatus !== ConnectionStates.NotInstalled && (
|
||||
|
@ -55,6 +55,7 @@ function Integrations(): JSX.Element {
|
||||
selectedIntegration={selectedIntegration}
|
||||
setSelectedIntegration={setSelectedIntegration}
|
||||
activeDetailTab={activeDetailTab}
|
||||
setActiveDetailTab={setActiveDetailTab}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
|
Loading…
x
Reference in New Issue
Block a user