Skip to content

Commit

Permalink
feat: integrate the status api calls and polling logic
Browse files Browse the repository at this point in the history
  • Loading branch information
vikrantgupta25 committed Mar 5, 2024
1 parent 0520554 commit 4ef84cc
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 32 deletions.
11 changes: 11 additions & 0 deletions frontend/src/api/Integrations/getIntegrationStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import {
GetIntegrationPayloadProps,
GetIntegrationStatusProps,
} from 'types/api/integrations/types';

export const getIntegrationStatus = (
props: GetIntegrationPayloadProps,
): Promise<AxiosResponse<GetIntegrationStatusProps>> =>
axios.get(`/integrations/${props.integrationId}/connection_status`);
18 changes: 18 additions & 0 deletions frontend/src/hooks/Integrations/useGetIntegrationStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getIntegrationStatus } from 'api/Integrations/getIntegrationStatus';
import { AxiosError, AxiosResponse } from 'axios';
import { useQuery, UseQueryResult } from 'react-query';
import {
GetIntegrationPayloadProps,
GetIntegrationStatusProps,
} from 'types/api/integrations/types';

export const useGetIntegrationStatus = ({
integrationId,
}: GetIntegrationPayloadProps): UseQueryResult<
AxiosResponse<GetIntegrationStatusProps>,
AxiosError
> =>
useQuery<AxiosResponse<GetIntegrationStatusProps>, AxiosError>({
queryKey: ['Integration', integrationId, Date.now()],
queryFn: () => getIntegrationStatus({ integrationId }),
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,14 @@ import { useState } from 'react';
import { useMutation } from 'react-query';

import TestConnection, { ConnectionStates } from './TestConnection';
import { getConnectionStatesFromConnectionStatus } from './utils';

interface IntegrationDetailHeaderProps {
id: string;
title: string;
description: string;
icon: string;
refetchIntegrationDetails: () => void;
connectionStatus:
| {
last_received_ts: number;
last_received_from: string;
}
| undefined;
connectionState: ConnectionStates;
}
function IntegrationDetailHeader(
props: IntegrationDetailHeaderProps,
Expand All @@ -33,16 +27,11 @@ function IntegrationDetailHeader(
title,
icon,
description,
connectionStatus,
connectionState,
refetchIntegrationDetails,
} = props;
const [isModalOpen, setIsModalOpen] = useState(false);

const [connectionState] = useState<ConnectionStates>(
(): ConnectionStates =>
getConnectionStatesFromConnectionStatus(connectionStatus),
);

const { notifications } = useNotifications();

const showModal = (): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import './IntegrationDetailPage.styles.scss';
import { Color } from '@signozhq/design-tokens';
import { Button, Typography } from 'antd';
import { useGetIntegration } from 'hooks/Integrations/useGetIntegration';
import { useGetIntegrationStatus } from 'hooks/Integrations/useGetIntegrationStatus';
import useTabVisibility from 'hooks/useTabFocus';
import history from 'lib/history';
import { defaultTo } from 'lodash-es';
import { ArrowLeft, MoveUpRight, RotateCw } from 'lucide-react';
import { useEffect } from 'react';
import { isCloudUser } from 'utils/app';

import IntegrationDetailContent from './IntegrationDetailContent';
Expand All @@ -26,6 +29,8 @@ interface IntegrationDetailPageProps {
function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
const { selectedIntegration, setSelectedIntegration, activeDetailTab } = props;

const isVisible = useTabVisibility();

const handleContactSupport = (): void => {
if (isCloudUser()) {
history.push('/support');
Expand All @@ -44,8 +49,36 @@ function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
integrationId: selectedIntegration,
});

const {
data: integrationStatus,
refetch: refetchStatus,
} = useGetIntegrationStatus({
integrationId: selectedIntegration,
});

const loading = isLoading || isFetching || isRefetching;
const integrationData = data?.data.data;

const connectionStatus = getConnectionStatesFromConnectionStatus(
integrationData?.installation,
defaultTo(
integrationStatus?.data.data.connection_status,
defaultTo(integrationData?.connection_status, { logs: null, metrics: null }),
),
);

useEffect(() => {
const timer = setTimeout(() => {
if (isVisible) {
refetchStatus();
}
}, 1000);

return (): void => {
clearTimeout(timer);
};
}, [refetchStatus, isVisible]);

return (
<div className="integration-detail-content">
<Button
Expand Down Expand Up @@ -99,17 +132,15 @@ function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
title={defaultTo(integrationData?.title, '')}
description={defaultTo(integrationData?.description, '')}
icon={defaultTo(integrationData?.icon, '')}
connectionStatus={integrationData?.connection_status}
connectionState={connectionStatus}
refetchIntegrationDetails={refetch}
/>
<IntegrationDetailContent
activeDetailTab={activeDetailTab}
integrationData={integrationData}
/>

{getConnectionStatesFromConnectionStatus(
integrationData.connection_status,
) !== ConnectionStates.NotInstalled && (
{connectionStatus !== ConnectionStates.NotInstalled && (
<IntergrationsUninstallBar
integrationTitle={defaultTo(integrationData?.title, '')}
integrationId={selectedIntegration}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ import cx from 'classnames';
export enum ConnectionStates {
Connected = 'connected',
TestingConnection = 'testingConnection',
ConnectionFailed = 'connectionFailed',
NoDataSinceLong = 'noDataSinceLong',
NotInstalled = 'notInstalled',
}

const ConnectionStatesLabelMap = {
[ConnectionStates.Connected]: 'This integration is working properly',
[ConnectionStates.TestingConnection]: 'Listening for data...',
[ConnectionStates.ConnectionFailed]: 'Something went wrong :/',
[ConnectionStates.NoDataSinceLong]:
'This integration has not received data in a while :/',
[ConnectionStates.NotInstalled]: '',
Expand Down
49 changes: 44 additions & 5 deletions frontend/src/pages/Integrations/IntegrationDetailPage/utils.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,56 @@
import { isUndefined } from 'lodash-es';
import dayjs from 'dayjs';
import { isNull, isUndefined } from 'lodash-es';

import { ConnectionStates } from './TestConnection';

export function getConnectionStatesFromConnectionStatus(
connectionStatus:
installation:
| {
last_received_ts: number;
last_received_from: string;
installed_at: string;
}
| null
| undefined,
connection_status: {
logs:
| {
last_received_ts: number;
last_received_from: string;
}
| null
| undefined;
metrics:
| {
last_received_ts: number;
last_received_from: string;
}
| null
| undefined;
},
): ConnectionStates {
if (isUndefined(connectionStatus)) {
console.log(installation, connection_status);
if (isNull(installation) || isUndefined(installation)) {
return ConnectionStates.NotInstalled;
}
if (
(isNull(connection_status.logs) || isUndefined(connection_status.logs)) &&
(isNull(connection_status.metrics) || isUndefined(connection_status.metrics))
) {
const installationDate = dayjs(installation.installed_at);
if (installationDate.isBefore(dayjs().subtract(7, 'days'))) {
return ConnectionStates.NoDataSinceLong;
}
return ConnectionStates.TestingConnection;
}

const logsDate = dayjs(connection_status.logs?.last_received_ts);
const metricsDate = dayjs(connection_status.metrics?.last_received_ts);

if (
logsDate.isBefore(dayjs().subtract(7, 'days')) &&
metricsDate.isBefore(dayjs().subtract(7, 'days'))
) {
return ConnectionStates.NoDataSinceLong;
}

return ConnectionStates.Connected;
}
36 changes: 28 additions & 8 deletions frontend/src/types/api/integrations/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ export interface AllIntegrationsProps {
export interface IntegrationDetailedProps {
description: string;
id: string;
// check for the correct type here
installation: null;
installation: {
installed_at: string;
} | null;
title: string;
author: {
email: string;
Expand All @@ -31,12 +32,16 @@ export interface IntegrationDetailedProps {
};
icon: string;
connection_status: {
last_received_ts: number;
last_received_from: string;
logs: {
last_received_ts: number;
last_received_from: string;
} | null;
metrics: {
last_received_ts: number;
last_received_from: string;
} | null;
};
// check for the correct type here
categories: string[];
// check for the correct type here
assets: {
logs: {
pipelines: [];
Expand All @@ -51,7 +56,6 @@ export interface IntegrationDetailedProps {
instructions: string;
},
];
// check for the correct type heres
data_collected: {
logs: string[];
metrics: string[];
Expand All @@ -61,13 +65,29 @@ export interface GetIntegrationProps {
data: IntegrationDetailedProps;
}

export interface IntegrationStatusProps {
connection_status: {
logs: {
last_received_ts: number;
last_received_from: string;
} | null;
metrics: {
last_received_ts: number;
last_received_from: string;
} | null;
};
}

export interface GetIntegrationStatusProps {
data: IntegrationStatusProps;
}

export interface GetIntegrationPayloadProps {
integrationId: string;
}

export interface InstallIntegrationKeyProps {
integration_id: string;
// TODO exact object for config
config: any;
}

Expand Down

0 comments on commit 4ef84cc

Please sign in to comment.