import React, { useEffect, useState } from "react"; import { connect, ConnectedProps } from "react-redux"; import Container from "@material-ui/core/Container"; import { makeStyles } from "@material-ui/core/styles"; import Grid from "@material-ui/core/Grid"; import Paper from "@material-ui/core/Paper"; import Typography from "@material-ui/core/Typography"; import InfoIcon from "@material-ui/icons/Info"; import { listQueuesAsync, pauseQueueAsync, resumeQueueAsync, deleteQueueAsync, } from "../actions/queuesActions"; import { listQueueStatsAsync } from "../actions/queueStatsActions"; import { AppState } from "../store"; import QueueSizeChart from "../components/QueueSizeChart"; import ProcessedTasksChart from "../components/ProcessedTasksChart"; import QueuesOverviewTable from "../components/QueuesOverviewTable"; import Tooltip from "../components/Tooltip"; import SplitButton from "../components/SplitButton"; import { usePolling } from "../hooks"; import DailyStatsChart from "../components/DailyStatsChart"; const useStyles = makeStyles((theme) => ({ container: { paddingTop: theme.spacing(4), paddingBottom: theme.spacing(4), }, paper: { padding: theme.spacing(2), display: "flex", overflow: "auto", flexDirection: "column", }, chartHeader: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: theme.spacing(2), }, chartHeaderTitle: { display: "flex", alignItems: "center", }, chartContainer: { width: "100%", height: "300px", }, infoIcon: { marginLeft: theme.spacing(1), color: theme.palette.grey[500], cursor: "pointer", }, tooltipSection: { marginBottom: "4px", }, tableContainer: { marginBottom: theme.spacing(2), }, })); function mapStateToProps(state: AppState) { return { loading: state.queues.loading, queues: state.queues.data.map((q) => ({ ...q.currentStats, requestPending: q.requestPending, })), pollInterval: state.settings.pollInterval, queueStats: state.queueStats.data, }; } const mapDispatchToProps = { listQueuesAsync, pauseQueueAsync, resumeQueueAsync, deleteQueueAsync, listQueueStatsAsync, }; const connector = connect(mapStateToProps, mapDispatchToProps); type Props = ConnectedProps; type DailyStatsKey = "today" | "last-7d" | "last-30d" | "last-90d"; const initialStatsKey = "last-7d"; function DashboardView(props: Props) { const { pollInterval, listQueuesAsync, queues, listQueueStatsAsync } = props; const classes = useStyles(); const [dailyStatsKey, setDailyStatsKey] = useState( initialStatsKey ); usePolling(listQueuesAsync, pollInterval); // Refetch queue stats if a queue is added or deleted. const qnames = queues .map((q) => q.queue) .sort() .join(","); useEffect(() => { listQueueStatsAsync(); }, [listQueueStatsAsync, qnames]); const processedStats = queues.map((q) => ({ queue: q.queue, succeeded: q.processed - q.failed, failed: q.failed, })); return (
Queue Size
Total number of tasks in the queue
Active: number of tasks currently being processed
Pending: number of tasks ready to be processed
Scheduled: number of tasks scheduled to be processed in the future
Retry: number of tasks scheduled to be retried in the future
Dead: number of tasks exhausted their retries
} >
Tasks Processed
Total number of tasks processed in a given day (UTC)
Succeeded: number of tasks successfully processed
Failed: number of tasks failed to be processed
} >
setDailyStatsKey(key as DailyStatsKey)} />
{dailyStatsKey === "today" && ( )} {dailyStatsKey === "last-7d" && ( )} {dailyStatsKey === "last-30d" && ( )} {dailyStatsKey === "last-90d" && ( )}
{/* TODO: Add loading indicator */}
); } export default connector(DashboardView);