refactor + new account sync metrics + isolating health status inside folder admin-panel > health-status (#10314)
closes https://github.com/twentyhq/core-team-issues/issues/444 https://github.com/twentyhq/core-team-issues/issues/443 https://github.com/twentyhq/core-team-issues/issues/442
This commit is contained in:
@ -1,44 +0,0 @@
|
||||
import { Table } from '@/ui/layout/table/components/Table';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
|
||||
export const SettingsAdminHealthMessageSyncCountersTable = ({
|
||||
details,
|
||||
}: {
|
||||
details: string | null | undefined;
|
||||
}) => {
|
||||
const parsedDetails = details ? JSON.parse(details) : null;
|
||||
if (!parsedDetails) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<TableRow>
|
||||
<TableHeader>Status</TableHeader>
|
||||
<TableHeader align="right">Count</TableHeader>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Message Not Synced</TableCell>
|
||||
<TableCell align="right">{parsedDetails.counters.NOT_SYNCED}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Message Sync Ongoing</TableCell>
|
||||
<TableCell align="right">{parsedDetails.counters.ONGOING}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Total Jobs</TableCell>
|
||||
<TableCell align="right">{parsedDetails.totalJobs}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Failed Jobs</TableCell>
|
||||
<TableCell align="right">{parsedDetails.failedJobs}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Failure Rate</TableCell>
|
||||
<TableCell align="right">{parsedDetails.failureRate}%</TableCell>
|
||||
</TableRow>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
@ -1,66 +0,0 @@
|
||||
import { SettingsAdminHealthMessageSyncCountersTable } from '@/settings/admin-panel/components/SettingsAdminHealthMessageSyncCountersTable';
|
||||
import { SettingsHealthStatusListCard } from '@/settings/admin-panel/components/SettingsHealthStatusListCard';
|
||||
import { AdminHealthService } from '@/settings/admin-panel/types/AdminHealthService';
|
||||
import styled from '@emotion/styled';
|
||||
import { H2Title, Section } from 'twenty-ui';
|
||||
import {
|
||||
AdminPanelHealthServiceStatus,
|
||||
useGetSystemHealthStatusQuery,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
const StyledErrorMessage = styled.div`
|
||||
color: ${({ theme }) => theme.color.red};
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
export const SettingsAdminHealthStatus = () => {
|
||||
const { data, loading } = useGetSystemHealthStatusQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
|
||||
const services = [
|
||||
{
|
||||
id: 'DATABASE',
|
||||
name: 'Database Status',
|
||||
...data?.getSystemHealthStatus.database,
|
||||
},
|
||||
{ id: 'REDIS', name: 'Redis Status', ...data?.getSystemHealthStatus.redis },
|
||||
{
|
||||
id: 'WORKER',
|
||||
name: 'Worker Status',
|
||||
status: data?.getSystemHealthStatus.worker.status,
|
||||
queues: data?.getSystemHealthStatus.worker.queues,
|
||||
},
|
||||
].filter((service): service is AdminHealthService => !!service.status);
|
||||
|
||||
const isMessageSyncCounterDown =
|
||||
!data?.getSystemHealthStatus.messageSync.status ||
|
||||
data?.getSystemHealthStatus.messageSync.status ===
|
||||
AdminPanelHealthServiceStatus.OUTAGE;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Section>
|
||||
<H2Title title="Health Status" description="How your system is doing" />
|
||||
<SettingsHealthStatusListCard services={services} loading={loading} />
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Message Sync Status"
|
||||
description="How your message sync is doing"
|
||||
/>
|
||||
{isMessageSyncCounterDown ? (
|
||||
<StyledErrorMessage>
|
||||
{data?.getSystemHealthStatus.messageSync.details ||
|
||||
'Message sync status is unavailable'}
|
||||
</StyledErrorMessage>
|
||||
) : (
|
||||
<SettingsAdminHealthMessageSyncCountersTable
|
||||
details={data?.getSystemHealthStatus.messageSync.details}
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -1,27 +0,0 @@
|
||||
import { AdminHealthService } from '@/settings/admin-panel/types/AdminHealthService';
|
||||
import styled from '@emotion/styled';
|
||||
import { Status } from 'twenty-ui';
|
||||
import { AdminPanelHealthServiceStatus } from '~/generated/graphql';
|
||||
|
||||
const StyledRowRightContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const SettingsAdminHealthStatusRightContainer = ({
|
||||
service,
|
||||
}: {
|
||||
service: AdminHealthService;
|
||||
}) => {
|
||||
return (
|
||||
<StyledRowRightContainer>
|
||||
{service.status === AdminPanelHealthServiceStatus.OPERATIONAL && (
|
||||
<Status color="green" text="Operational" weight="medium" />
|
||||
)}
|
||||
{service.status === AdminPanelHealthServiceStatus.OUTAGE && (
|
||||
<Status color="red" text="Outage" weight="medium" />
|
||||
)}
|
||||
</StyledRowRightContainer>
|
||||
);
|
||||
};
|
||||
@ -1,8 +1,8 @@
|
||||
import { SettingsAdminEnvVariables } from '@/settings/admin-panel/components/SettingsAdminEnvVariables';
|
||||
import { SettingsAdminGeneral } from '@/settings/admin-panel/components/SettingsAdminGeneral';
|
||||
import { SettingsAdminHealthStatus } from '@/settings/admin-panel/components/SettingsAdminHealthStatus';
|
||||
import { SETTINGS_ADMIN_TABS } from '@/settings/admin-panel/constants/SettingsAdminTabs';
|
||||
import { SETTINGS_ADMIN_TABS_ID } from '@/settings/admin-panel/constants/SettingsAdminTabsId';
|
||||
import { SettingsAdminHealthStatus } from '@/settings/admin-panel/health-status/components/SettingsAdminHealthStatus';
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
|
||||
export const SettingsAdminTabContent = () => {
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
import { AdminHealthService } from '@/settings/admin-panel/types/AdminHealthService';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
import { SettingsListCard } from '../../components/SettingsListCard';
|
||||
import { SettingsAdminHealthStatusRightContainer } from './SettingsAdminHealthStatusRightContainer';
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
text-decoration: none;
|
||||
`;
|
||||
|
||||
export const SettingsHealthStatusListCard = ({
|
||||
services,
|
||||
loading,
|
||||
}: {
|
||||
services: Array<AdminHealthService>;
|
||||
loading?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{services.map((service) => (
|
||||
<>
|
||||
<StyledLink
|
||||
to={getSettingsPath(SettingsPath.AdminPanelIndicatorHealthStatus, {
|
||||
indicatorName: service.id,
|
||||
})}
|
||||
>
|
||||
<SettingsListCard
|
||||
items={[service]}
|
||||
getItemLabel={(service) => service.name}
|
||||
isLoading={loading}
|
||||
RowRightComponent={({ item: service }) => (
|
||||
<SettingsAdminHealthStatusRightContainer service={service} />
|
||||
)}
|
||||
/>
|
||||
</StyledLink>
|
||||
</>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -1,36 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_SYSTEM_HEALTH_STATUS = gql`
|
||||
query GetSystemHealthStatus {
|
||||
getSystemHealthStatus {
|
||||
database {
|
||||
status
|
||||
details
|
||||
}
|
||||
redis {
|
||||
status
|
||||
details
|
||||
}
|
||||
worker {
|
||||
status
|
||||
queues {
|
||||
name
|
||||
workers
|
||||
status
|
||||
metrics {
|
||||
failed
|
||||
completed
|
||||
waiting
|
||||
active
|
||||
delayed
|
||||
prioritized
|
||||
}
|
||||
}
|
||||
}
|
||||
messageSync {
|
||||
status
|
||||
details
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -0,0 +1,57 @@
|
||||
import { SettingsAdminHealthAccountSyncCountersTable } from '@/settings/admin-panel/health-status/components/SettingsAdminHealthAccountSyncCountersTable';
|
||||
import { SettingsAdminIndicatorHealthContext } from '@/settings/admin-panel/health-status/contexts/SettingsAdminIndicatorHealthContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext } from 'react';
|
||||
import { AdminPanelHealthServiceStatus } from '~/generated/graphql';
|
||||
|
||||
const StyledErrorMessage = styled.div`
|
||||
color: ${({ theme }) => theme.color.red};
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
export const ConnectedAccountHealthStatus = () => {
|
||||
const { indicatorHealth } = useContext(SettingsAdminIndicatorHealthContext);
|
||||
const details = indicatorHealth.details;
|
||||
if (!details) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parsedDetails = JSON.parse(details);
|
||||
|
||||
const isMessageSyncDown =
|
||||
parsedDetails.messageSync?.status === AdminPanelHealthServiceStatus.OUTAGE;
|
||||
const isCalendarSyncDown =
|
||||
parsedDetails.calendarSync?.status === AdminPanelHealthServiceStatus.OUTAGE;
|
||||
|
||||
const errorMessages = [];
|
||||
if (isMessageSyncDown) {
|
||||
errorMessages.push('Message Sync');
|
||||
}
|
||||
if (isCalendarSyncDown) {
|
||||
errorMessages.push('Calendar Sync');
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{errorMessages.length > 0 && (
|
||||
<StyledErrorMessage>
|
||||
{`${errorMessages.join(' and ')} ${errorMessages.length > 1 ? 'are' : 'is'} not available because the service is down`}
|
||||
</StyledErrorMessage>
|
||||
)}
|
||||
|
||||
{!isMessageSyncDown && parsedDetails.messageSync?.details && (
|
||||
<SettingsAdminHealthAccountSyncCountersTable
|
||||
details={parsedDetails.messageSync.details}
|
||||
title="Message Sync Status"
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isCalendarSyncDown && parsedDetails.calendarSync?.details && (
|
||||
<SettingsAdminHealthAccountSyncCountersTable
|
||||
details={parsedDetails.calendarSync.details}
|
||||
title="Calendar Sync Status"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,45 @@
|
||||
import { SettingsAdminIndicatorHealthContext } from '@/settings/admin-panel/health-status/contexts/SettingsAdminIndicatorHealthContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext } from 'react';
|
||||
import { Section } from 'twenty-ui';
|
||||
import { AdminPanelHealthServiceStatus } from '~/generated/graphql';
|
||||
|
||||
const StyledDetailsContainer = styled.pre`
|
||||
background-color: ${({ theme }) => theme.background.quaternary};
|
||||
padding: ${({ theme }) => theme.spacing(6)};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
white-space: pre-wrap;
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
margin: 0;
|
||||
`;
|
||||
|
||||
const StyledErrorMessage = styled.div`
|
||||
color: ${({ theme }) => theme.color.red};
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
export const DatabaseAndRedisHealthStatus = () => {
|
||||
const { indicatorHealth, loading } = useContext(
|
||||
SettingsAdminIndicatorHealthContext,
|
||||
);
|
||||
|
||||
const formattedDetails = indicatorHealth.details
|
||||
? JSON.stringify(JSON.parse(indicatorHealth.details), null, 2)
|
||||
: null;
|
||||
|
||||
const isDatabaseOrRedisDown =
|
||||
!indicatorHealth.status ||
|
||||
indicatorHealth.status === AdminPanelHealthServiceStatus.OUTAGE;
|
||||
|
||||
return (
|
||||
<Section>
|
||||
{isDatabaseOrRedisDown && !loading ? (
|
||||
<StyledErrorMessage>
|
||||
{`${indicatorHealth.label} information is not available because the service is down`}
|
||||
</StyledErrorMessage>
|
||||
) : (
|
||||
<StyledDetailsContainer>{formattedDetails}</StyledDetailsContainer>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,55 @@
|
||||
import { Table } from '@/ui/layout/table/components/Table';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import styled from '@emotion/styled';
|
||||
import { H2Title } from 'twenty-ui';
|
||||
|
||||
const StyledContainer = styled.div``;
|
||||
|
||||
export const SettingsAdminHealthAccountSyncCountersTable = ({
|
||||
details,
|
||||
title,
|
||||
}: {
|
||||
details: Record<string, any> | null;
|
||||
title: string;
|
||||
}) => {
|
||||
if (!details) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<H2Title
|
||||
title={title}
|
||||
description={`How your ${title.toLowerCase()} is doing`}
|
||||
/>
|
||||
<Table>
|
||||
<TableRow>
|
||||
<TableHeader>Status</TableHeader>
|
||||
<TableHeader align="right">Count</TableHeader>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Not Synced</TableCell>
|
||||
<TableCell align="right">{details.counters.NOT_SYNCED}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Sync Ongoing</TableCell>
|
||||
<TableCell align="right">{details.counters.ONGOING}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Total Jobs</TableCell>
|
||||
<TableCell align="right">{details.totalJobs}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Failed Jobs</TableCell>
|
||||
<TableCell align="right">{details.failedJobs}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Failure Rate</TableCell>
|
||||
<TableCell align="right">{details.failureRate}%</TableCell>
|
||||
</TableRow>
|
||||
</Table>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import { SettingsHealthStatusListCard } from '@/settings/admin-panel/health-status/components/SettingsHealthStatusListCard';
|
||||
import { H2Title, Section } from 'twenty-ui';
|
||||
import { useGetSystemHealthStatusQuery } from '~/generated/graphql';
|
||||
|
||||
export const SettingsAdminHealthStatus = () => {
|
||||
const { data, loading } = useGetSystemHealthStatusQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
|
||||
const services = data?.getSystemHealthStatus.services ?? [];
|
||||
return (
|
||||
<>
|
||||
<Section>
|
||||
<H2Title title="Health Status" description="How your system is doing" />
|
||||
<SettingsHealthStatusListCard services={services} loading={loading} />
|
||||
</Section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import { Status } from 'twenty-ui';
|
||||
import { AdminPanelHealthServiceStatus } from '~/generated/graphql';
|
||||
|
||||
export const SettingsAdminHealthStatusRightContainer = ({
|
||||
status,
|
||||
}: {
|
||||
status: AdminPanelHealthServiceStatus;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{status === AdminPanelHealthServiceStatus.OPERATIONAL && (
|
||||
<Status color="green" text="Operational" weight="medium" />
|
||||
)}
|
||||
{status === AdminPanelHealthServiceStatus.OUTAGE && (
|
||||
<Status color="red" text="Outage" weight="medium" />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,21 @@
|
||||
import { ConnectedAccountHealthStatus } from '@/settings/admin-panel/health-status/components/ConnectedAccountHealthStatus';
|
||||
import { DatabaseAndRedisHealthStatus } from '@/settings/admin-panel/health-status/components/DatabaseAndRedisHealthStatus';
|
||||
import { WorkerHealthStatus } from '@/settings/admin-panel/health-status/components/WorkerHealthStatus';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { HealthIndicatorId } from '~/generated/graphql';
|
||||
|
||||
export const SettingsAdminIndicatorHealthStatusContent = () => {
|
||||
const { indicatorId } = useParams();
|
||||
|
||||
switch (indicatorId) {
|
||||
case HealthIndicatorId.database:
|
||||
case HealthIndicatorId.redis:
|
||||
return <DatabaseAndRedisHealthStatus />;
|
||||
case HealthIndicatorId.worker:
|
||||
return <WorkerHealthStatus />;
|
||||
case HealthIndicatorId.connectedAccount:
|
||||
return <ConnectedAccountHealthStatus />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@ -43,7 +43,7 @@ export const SettingsAdminQueueExpandableContainer = ({
|
||||
selectedQueue: string | null;
|
||||
}) => {
|
||||
const selectedQueueData = queues.find(
|
||||
(queue) => queue.name === selectedQueue,
|
||||
(queue) => queue.queueName === selectedQueue,
|
||||
);
|
||||
|
||||
return (
|
||||
@ -55,10 +55,12 @@ export const SettingsAdminQueueExpandableContainer = ({
|
||||
<>
|
||||
<StyledContainer>
|
||||
<SettingsListCard
|
||||
items={[{ ...selectedQueueData, id: selectedQueueData.name }]}
|
||||
items={[
|
||||
{ ...selectedQueueData, id: selectedQueueData.queueName },
|
||||
]}
|
||||
getItemLabel={(
|
||||
item: AdminPanelWorkerQueueHealth & { id: string },
|
||||
) => item.name}
|
||||
) => item.queueName}
|
||||
isLoading={false}
|
||||
RowRightComponent={({
|
||||
item,
|
||||
@ -39,11 +39,11 @@ export const SettingsAdminQueueHealthButtons = ({
|
||||
<StyledQueueButtonsRow>
|
||||
{queues.map((queue) => (
|
||||
<StyledQueueHealthButton
|
||||
key={queue.name}
|
||||
onClick={() => toggleQueueVisibility(queue.name)}
|
||||
title={queue.name}
|
||||
key={queue.queueName}
|
||||
onClick={() => toggleQueueVisibility(queue.queueName)}
|
||||
title={queue.queueName}
|
||||
variant="secondary"
|
||||
isSelected={selectedQueue === queue.name}
|
||||
isSelected={selectedQueue === queue.queueName}
|
||||
status={queue.status}
|
||||
/>
|
||||
))}
|
||||
@ -0,0 +1,29 @@
|
||||
import { SettingsListCard } from '@/settings/components/SettingsListCard';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { SystemHealthService } from '~/generated/graphql';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
import { SettingsAdminHealthStatusRightContainer } from './SettingsAdminHealthStatusRightContainer';
|
||||
|
||||
export const SettingsHealthStatusListCard = ({
|
||||
services,
|
||||
loading,
|
||||
}: {
|
||||
services: Array<SystemHealthService>;
|
||||
loading?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<SettingsListCard
|
||||
items={services}
|
||||
getItemLabel={(service) => service.label}
|
||||
isLoading={loading}
|
||||
RowRightComponent={({ item: service }) => (
|
||||
<SettingsAdminHealthStatusRightContainer status={service.status} />
|
||||
)}
|
||||
to={(service) =>
|
||||
getSettingsPath(SettingsPath.AdminPanelIndicatorHealthStatus, {
|
||||
indicatorId: service.id,
|
||||
})
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,62 @@
|
||||
import { SettingsAdminQueueExpandableContainer } from '@/settings/admin-panel/health-status/components/SettingsAdminQueueExpandableContainer';
|
||||
import { SettingsAdminQueueHealthButtons } from '@/settings/admin-panel/health-status/components/SettingsAdminQueueHealthButtons';
|
||||
import { SettingsAdminIndicatorHealthContext } from '@/settings/admin-panel/health-status/contexts/SettingsAdminIndicatorHealthContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext, useState } from 'react';
|
||||
import { H2Title, Section } from 'twenty-ui';
|
||||
import { AdminPanelHealthServiceStatus } from '~/generated/graphql';
|
||||
|
||||
const StyledTitleContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
`;
|
||||
|
||||
const StyledErrorMessage = styled.div`
|
||||
color: ${({ theme }) => theme.color.red};
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
export const WorkerHealthStatus = () => {
|
||||
const { indicatorHealth, loading } = useContext(
|
||||
SettingsAdminIndicatorHealthContext,
|
||||
);
|
||||
|
||||
const isWorkerDown =
|
||||
!indicatorHealth.status ||
|
||||
indicatorHealth.status === AdminPanelHealthServiceStatus.OUTAGE;
|
||||
|
||||
const [selectedQueue, setSelectedQueue] = useState<string | null>(null);
|
||||
|
||||
const toggleQueueVisibility = (queueName: string) => {
|
||||
setSelectedQueue(selectedQueue === queueName ? null : queueName);
|
||||
};
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<StyledTitleContainer>
|
||||
<H2Title
|
||||
title="Queue Status"
|
||||
description="Background job processing status and metrics"
|
||||
/>
|
||||
</StyledTitleContainer>
|
||||
{isWorkerDown && !loading ? (
|
||||
<StyledErrorMessage>
|
||||
Queue information is not available because the worker is down
|
||||
</StyledErrorMessage>
|
||||
) : (
|
||||
<>
|
||||
<SettingsAdminQueueHealthButtons
|
||||
queues={indicatorHealth.queues ?? []}
|
||||
selectedQueue={selectedQueue}
|
||||
toggleQueueVisibility={toggleQueueVisibility}
|
||||
/>
|
||||
<SettingsAdminQueueExpandableContainer
|
||||
queues={indicatorHealth.queues ?? []}
|
||||
selectedQueue={selectedQueue}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,23 @@
|
||||
import { createContext } from 'react';
|
||||
import {
|
||||
AdminPanelHealthServiceData,
|
||||
AdminPanelHealthServiceStatus,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
type SettingsAdminIndicatorHealthContextType = {
|
||||
indicatorHealth: AdminPanelHealthServiceData;
|
||||
loading: boolean;
|
||||
};
|
||||
|
||||
export const SettingsAdminIndicatorHealthContext =
|
||||
createContext<SettingsAdminIndicatorHealthContextType>({
|
||||
indicatorHealth: {
|
||||
id: '',
|
||||
label: '',
|
||||
description: '',
|
||||
status: AdminPanelHealthServiceStatus.OPERATIONAL,
|
||||
details: '',
|
||||
queues: [],
|
||||
},
|
||||
loading: false,
|
||||
});
|
||||
@ -1,14 +1,16 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_INDICATOR_HEALTH_STATUS = gql`
|
||||
query GetIndicatorHealthStatus(
|
||||
$indicatorName: AdminPanelIndicatorHealthStatusInputEnum!
|
||||
) {
|
||||
getIndicatorHealthStatus(indicatorName: $indicatorName) {
|
||||
query GetIndicatorHealthStatus($indicatorId: HealthIndicatorId!) {
|
||||
getIndicatorHealthStatus(indicatorId: $indicatorId) {
|
||||
id
|
||||
label
|
||||
description
|
||||
status
|
||||
details
|
||||
queues {
|
||||
name
|
||||
id
|
||||
queueName
|
||||
status
|
||||
workers
|
||||
metrics {
|
||||
@ -0,0 +1,13 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_SYSTEM_HEALTH_STATUS = gql`
|
||||
query GetSystemHealthStatus {
|
||||
getSystemHealthStatus {
|
||||
services {
|
||||
id
|
||||
label
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,12 +0,0 @@
|
||||
import { useGetSystemHealthStatusQuery } from '~/generated/graphql';
|
||||
|
||||
export const useGetUptoDateHealthStatus = () => {
|
||||
const { data, loading } = useGetSystemHealthStatusQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
|
||||
return {
|
||||
healthStatus: data?.getSystemHealthStatus,
|
||||
healthStatusLoading: loading,
|
||||
};
|
||||
};
|
||||
@ -1,12 +0,0 @@
|
||||
import {
|
||||
AdminPanelHealthServiceData,
|
||||
AdminPanelWorkerQueueHealth,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
type AdminWorkerService = AdminPanelHealthServiceData & {
|
||||
id: string;
|
||||
name: string;
|
||||
queues: AdminPanelWorkerQueueHealth[] | null | undefined;
|
||||
};
|
||||
|
||||
export type AdminHealthService = AdminWorkerService;
|
||||
Reference in New Issue
Block a user