From bd0c4beeee9853aa5987398e0848eacb43592835 Mon Sep 17 00:00:00 2001 From: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com> Date: Mon, 27 Jan 2025 10:56:01 +0530 Subject: [PATCH] feat: celery overview page (#6918) * feat: added celery task feature - with task garphs and details * feat: added celery bar graph toggle states UI * feat: added histogram charts and right panel * feat: added task latency graph with different states * feat: added right panel trace navigation * feat: added dynamic stepinterval based on timerange * feat: changed histogram occurences to bar * feat: onclick right panels for celery state bar graphs * feat: pagesetup and tabs with kafka setup * feat: custom series for bar for color generation * feat: fixed test cases * feat: added new celery overview page * feat: added table feat and column details * feat: improved table style and column configs * feat: added service name filter and common filter logic * feat: code fix * feat: code fix --- frontend/src/AppRoutes/pageComponents.ts | 7 + frontend/src/AppRoutes/routes.ts | 7 + .../celery/getQueueOverview.ts | 53 +++ .../CeleryOverviewConfigOptions.styles.scss | 39 ++ .../CeleryOverviewConfigOptions.tsx | 126 +++++++ .../CeleryOverviewTable.styles.scss | 106 ++++++ .../CeleryOverviewTable.tsx | 349 ++++++++++++++++++ .../useGetCeleryFilters.ts | 4 +- .../CeleryTask/useCeleryFilterOptions.ts | 7 +- frontend/src/constants/localStorage.ts | 1 + frontend/src/constants/query.ts | 2 + frontend/src/constants/routes.ts | 1 + frontend/src/container/AppLayout/index.tsx | 3 +- frontend/src/container/SideNav/config.ts | 1 + .../TopNav/DateTimeSelectionV2/config.ts | 1 + .../CeleryOverview/CeleryOverview.styles.scss | 44 +++ .../Celery/CeleryOverview/CeleryOverview.tsx | 20 + .../MessagingQueuesMainPage.tsx | 14 +- frontend/src/utils/permission/index.ts | 1 + 19 files changed, 776 insertions(+), 10 deletions(-) create mode 100644 frontend/src/api/messagingQueues/celery/getQueueOverview.ts create mode 100644 frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.styles.scss create mode 100644 frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.tsx create mode 100644 frontend/src/components/CeleryOverview/CeleryOverviewTable/CeleryOverviewTable.styles.scss create mode 100644 frontend/src/components/CeleryOverview/CeleryOverviewTable/CeleryOverviewTable.tsx create mode 100644 frontend/src/pages/Celery/CeleryOverview/CeleryOverview.styles.scss create mode 100644 frontend/src/pages/Celery/CeleryOverview/CeleryOverview.tsx diff --git a/frontend/src/AppRoutes/pageComponents.ts b/frontend/src/AppRoutes/pageComponents.ts index 55edfc54a7..cbbcbbed73 100644 --- a/frontend/src/AppRoutes/pageComponents.ts +++ b/frontend/src/AppRoutes/pageComponents.ts @@ -254,3 +254,10 @@ export const CeleryTask = Loadable( /* webpackChunkName: "CeleryTask" */ 'pages/Celery/CeleryTask/CeleryTask' ), ); + +export const CeleryOverview = Loadable( + () => + import( + /* webpackChunkName: "CeleryOverview" */ 'pages/Celery/CeleryOverview/CeleryOverview' + ), +); diff --git a/frontend/src/AppRoutes/routes.ts b/frontend/src/AppRoutes/routes.ts index 5a259e3968..a93fe6263f 100644 --- a/frontend/src/AppRoutes/routes.ts +++ b/frontend/src/AppRoutes/routes.ts @@ -408,6 +408,13 @@ const routes: AppRoutes[] = [ key: 'MESSAGING_QUEUES_CELERY_TASK', isPrivate: true, }, + { + path: ROUTES.MESSAGING_QUEUES_CELERY_OVERVIEW, + exact: true, + component: MessagingQueues, + key: 'MESSAGING_QUEUES_CELERY_OVERVIEW', + isPrivate: true, + }, { path: ROUTES.MESSAGING_QUEUES_DETAIL, exact: true, diff --git a/frontend/src/api/messagingQueues/celery/getQueueOverview.ts b/frontend/src/api/messagingQueues/celery/getQueueOverview.ts new file mode 100644 index 0000000000..2eeb7be82c --- /dev/null +++ b/frontend/src/api/messagingQueues/celery/getQueueOverview.ts @@ -0,0 +1,53 @@ +import axios from 'api'; +import { ErrorResponse, SuccessResponse } from 'types/api'; + +export interface QueueOverviewPayload { + start: number; + end: number; + filters: { + items: { + key: { + key: string; + dataType: string; + }; + op: string; + value: string[]; + }[]; + op: 'AND' | 'OR'; + }; +} + +export interface QueueOverviewResponse { + status: string; + data: { + timestamp?: string; + data: { + destination?: string; + error_percentage?: number; + kind_string?: string; + messaging_system?: string; + p95_latency?: number; + service_name?: string; + span_name?: string; + throughput?: number; + }[]; + }[]; +} + +export const getQueueOverview = async ( + props: QueueOverviewPayload, +): Promise | ErrorResponse> => { + const { start, end, filters } = props; + const response = await axios.post(`messaging-queues/queue-overview`, { + start, + end, + filters, + }); + + return { + statusCode: 200, + error: null, + message: response.data.status, + payload: response.data.data, + }; +}; diff --git a/frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.styles.scss b/frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.styles.scss new file mode 100644 index 0000000000..6d9be3a665 --- /dev/null +++ b/frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.styles.scss @@ -0,0 +1,39 @@ +.celery-overview-filters { + display: flex; + justify-content: space-between; + width: 100%; + + .celery-filters { + display: flex; + align-items: center; + gap: 8px; + + .config-select-option { + width: 100%; + .ant-select-selector { + display: flex; + min-height: 32px; + align-items: center; + gap: 16px; + min-width: 164px; + + border-radius: 2px; + border: 1px solid var(--bg-slate-400); + background: var(--bg-ink-300); + } + } + } +} + +.lightMode { + .celery-overview-filters { + .celery-filters { + .config-select-option { + .ant-select-selector { + border: 1px solid var(--bg-vanilla-300); + background: var(--bg-vanilla-100); + } + } + } + } +} diff --git a/frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.tsx b/frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.tsx new file mode 100644 index 0000000000..22f2743410 --- /dev/null +++ b/frontend/src/components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions.tsx @@ -0,0 +1,126 @@ +import './CeleryOverviewConfigOptions.styles.scss'; + +import { Color } from '@signozhq/design-tokens'; +import { Button, Select, Spin, Tooltip } from 'antd'; +import { + getValuesFromQueryParams, + setQueryParamsFromOptions, +} from 'components/CeleryTask/CeleryUtils'; +import { useCeleryFilterOptions } from 'components/CeleryTask/useCeleryFilterOptions'; +import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon'; +import { QueryParams } from 'constants/query'; +import useUrlQuery from 'hooks/useUrlQuery'; +import { Check, Share2 } from 'lucide-react'; +import { useState } from 'react'; +import { useHistory, useLocation } from 'react-router-dom'; +import { useCopyToClipboard } from 'react-use'; + +interface SelectOptionConfig { + placeholder: string; + queryParam: QueryParams; + filterType: 'serviceName' | 'spanName' | 'msgSystem'; +} + +function FilterSelect({ + placeholder, + queryParam, + filterType, +}: SelectOptionConfig): JSX.Element { + const { handleSearch, isFetching, options } = useCeleryFilterOptions( + filterType, + ); + const urlQuery = useUrlQuery(); + const history = useHistory(); + const location = useLocation(); + + return ( +