Skip to content

Commit

Permalink
feat: handle error states for list and details api
Browse files Browse the repository at this point in the history
  • Loading branch information
vikrantgupta25 committed Mar 4, 2024
1 parent 4c9ab52 commit f664536
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,53 @@
gap: 16px;
margin: 12px 0px 20px 0px;

.error-container {
display: flex;
border-radius: 6px;
border: 1px solid var(--bg-slate-500);
background: var(--bg-ink-400);
align-items: center;
justify-content: center;
flex-direction: column;

.error-content {
display: flex;
flex-direction: column;
justify-content: center;
height: 300px;
gap: 15px;

.error-btns {
display: flex;
flex-direction: row;
gap: 16px;
align-items: center;

.retry-btn {
display: flex;
align-items: center;
}

.contact-support {
display: flex;
align-items: center;
gap: 4px;
cursor: pointer;

.text {
color: var(--text-robin-400);
font-weight: 500;
}
}
}

.error-state-svg {
height: 40px;
width: 40px;
}
}
}

.loading-integration-details {
display: flex;
height: 400px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable no-nested-ternary */
import './IntegrationDetailPage.styles.scss';

import { Button } from 'antd';
import { Color } from '@signozhq/design-tokens';
import { Button, Typography } from 'antd';
import { useGetIntegration } from 'hooks/Integrations/useGetIntegration';
import history from 'lib/history';
import { defaultTo } from 'lodash-es';
import { ArrowLeft } from 'lucide-react';
import { ArrowLeft, MoveUpRight, RotateCw } from 'lucide-react';
import { isCloudUser } from 'utils/app';

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

const { data, isLoading, isFetching, refetch } = useGetIntegration({
const handleContactSupport = (): void => {
if (isCloudUser()) {
history.push('/support');
} else {
window.open('https://signoz.io/slack', '_blank');
}
};
const {
data,
isLoading,
isFetching,
refetch,
isRefetching,
isError,
} = useGetIntegration({
integrationId: selectedIntegration,
});

const loading = isLoading || isFetching;
const loading = isLoading || isFetching || isRefetching;
const integrationData = data?.data.data;
return (
<div className="integration-detail-content">
Expand All @@ -43,6 +63,34 @@ function IntegrationDetailPage(props: IntegrationDetailPageProps): JSX.Element {
<div className="loading-integration-details">
Please wait.. While we load the integration details
</div>
) : isError ? (
<div className="error-container">
<div className="error-content">
<img
src="/Icons/awwSnap.svg"
alt="error-emoji"
className="error-state-svg"
/>
<Typography.Text>
Something went wrong :/ Refresh the page or contact support.
</Typography.Text>
<div className="error-btns">
<Button
type="primary"
className="retry-btn"
onClick={(): Promise<any> => refetch()}
icon={<RotateCw size={14} />}
>
Retry
</Button>
<div className="contact-support" onClick={handleContactSupport}>
<Typography.Link className="text">Contact Support </Typography.Link>

<MoveUpRight size={14} color={Color.BG_ROBIN_400} />
</div>
</div>
</div>
</div>
) : (
integrationData && (
<>
Expand Down
47 changes: 47 additions & 0 deletions frontend/src/pages/Integrations/Integrations.styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,53 @@
.integrations-list {
margin-top: 16px;

.error-container {
display: flex;
border-radius: 6px;
border: 1px solid var(--bg-slate-500);
background: var(--bg-ink-400);
align-items: center;
justify-content: center;
flex-direction: column;

.error-content {
display: flex;
flex-direction: column;
justify-content: center;
height: 300px;
gap: 15px;

.error-btns {
display: flex;
flex-direction: row;
gap: 16px;
align-items: center;

.retry-btn {
display: flex;
align-items: center;
}

.contact-support {
display: flex;
align-items: center;
gap: 4px;
cursor: pointer;

.text {
color: var(--text-robin-400);
font-weight: 500;
}
}
}

.error-state-svg {
height: 40px;
width: 40px;
}
}
}

.ant-list-items {
gap: 16px;
display: flex;
Expand Down
120 changes: 87 additions & 33 deletions frontend/src/pages/Integrations/IntegrationsList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import './Integrations.styles.scss';

import { Color } from '@signozhq/design-tokens';
import { Button, List, Typography } from 'antd';
import { useGetAllIntegrations } from 'hooks/Integrations/useGetAllIntegrations';
import history from 'lib/history';
import { MoveUpRight, RotateCw } from 'lucide-react';
import { Dispatch, SetStateAction, useMemo } from 'react';
import { isCloudUser } from 'utils/app';

interface IntegrationsListProps {
setSelectedIntegration: (id: string) => void;
Expand All @@ -13,7 +19,14 @@ interface IntegrationsListProps {
function IntegrationsList(props: IntegrationsListProps): JSX.Element {
const { setSelectedIntegration, searchTerm, setActiveDetailTab } = props;

const { data, isFetching, isLoading } = useGetAllIntegrations();
const {
data,
isFetching,
isLoading,
isRefetching,
isError,
refetch,
} = useGetAllIntegrations();

const filteredDataList = useMemo(() => {
if (data?.data.data.integrations) {
Expand All @@ -24,45 +37,86 @@ function IntegrationsList(props: IntegrationsListProps): JSX.Element {
return [];
}, [data?.data.data.integrations, searchTerm]);

const loading = isLoading || isFetching || isRefetching;

const handleContactSupport = (): void => {
if (isCloudUser()) {
history.push('/support');
} else {
window.open('https://signoz.io/slack', '_blank');
}
};

return (
<div className="integrations-list">
<List
dataSource={filteredDataList}
loading={isFetching || isLoading}
itemLayout="horizontal"
renderItem={(item): JSX.Element => (
<List.Item
key={item.id}
className="integrations-list-item"
onClick={(): void => {
setSelectedIntegration(item.id);
setActiveDetailTab('overview');
}}
>
<div style={{ display: 'flex', gap: '10px' }}>
<div className="list-item-image-container">
<img src={item.icon} alt={item.title} className="list-item-image" />
</div>
<div className="list-item-details">
<Typography.Text className="heading">{item.title}</Typography.Text>
<Typography.Text className="description">
{item.description}
</Typography.Text>
{!loading && isError && (
<div className="error-container">
<div className="error-content">
<img
src="/Icons/awwSnap.svg"
alt="error-emoji"
className="error-state-svg"
/>
<Typography.Text>
Something went wrong :/ Refresh the page or contact support.
</Typography.Text>
<div className="error-btns">
<Button
type="primary"
className="retry-btn"
onClick={(): Promise<any> => refetch()}
icon={<RotateCw size={14} />}
>
Retry
</Button>
<div className="contact-support" onClick={handleContactSupport}>
<Typography.Link className="text">Contact Support </Typography.Link>

<MoveUpRight size={14} color={Color.BG_ROBIN_400} />
</div>
</div>
<Button
className="configure-btn"
onClick={(event): void => {
event.stopPropagation();
</div>
</div>
)}
{!isError && (
<List
dataSource={filteredDataList}
loading={loading}
itemLayout="horizontal"
renderItem={(item): JSX.Element => (
<List.Item
key={item.id}
className="integrations-list-item"
onClick={(): void => {
setSelectedIntegration(item.id);
setActiveDetailTab('configuration');
setActiveDetailTab('overview');
}}
>
Configure
</Button>
</List.Item>
)}
/>
<div style={{ display: 'flex', gap: '10px' }}>
<div className="list-item-image-container">
<img src={item.icon} alt={item.title} className="list-item-image" />
</div>
<div className="list-item-details">
<Typography.Text className="heading">{item.title}</Typography.Text>
<Typography.Text className="description">
{item.description}
</Typography.Text>
</div>
</div>
<Button
className="configure-btn"
onClick={(event): void => {
event.stopPropagation();
setSelectedIntegration(item.id);
setActiveDetailTab('configuration');
}}
>
Configure
</Button>
</List.Item>
)}
/>
)}
</div>
);
}
Expand Down

0 comments on commit f664536

Please sign in to comment.