import {Fragment} from 'react'; import styled from '@emotion/styled'; import type {Location} from 'history'; import qs from 'qs'; import GridEditable, { COL_WIDTH_UNDEFINED, type GridColumnHeader, } from 'sentry/components/gridEditable'; import Link from 'sentry/components/links/link'; import type {CursorHandler} from 'sentry/components/pagination'; import Pagination from 'sentry/components/pagination'; import {t} from 'sentry/locale'; import type {Organization} from 'sentry/types'; import {browserHistory} from 'sentry/utils/browserHistory'; import type {EventsMetaType} from 'sentry/utils/discover/eventView'; import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers'; import {formatAbbreviatedNumber, formatPercentage} from 'sentry/utils/formatters'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; import {normalizeUrl} from 'sentry/utils/withDomainRequired'; import {useQueuesByDestinationQuery} from 'sentry/views/performance/queues/queries/useQueuesByDestinationQuery'; import {renderHeadCell} from 'sentry/views/starfish/components/tableCells/renderHeadCell'; import type {MetricsResponse} from 'sentry/views/starfish/types'; import {QueryParameterNames} from 'sentry/views/starfish/views/queryParameters'; type Row = Pick< MetricsResponse, | 'avg_if(span.self_time,span.op,queue.task.celery)' | 'count_op(queue.submit.celery)' | 'count_op(queue.task.celery)' | 'sum(span.self_time)' | 'transaction' >; type Column = GridColumnHeader; const COLUMN_ORDER: Column[] = [ // TODO: Needs to be updated to display an actual destination, not transaction { key: 'transaction', name: t('Destination'), width: COL_WIDTH_UNDEFINED, }, { key: '', // TODO name: t('Avg Time in Queue'), width: COL_WIDTH_UNDEFINED, }, { key: 'avg_if(span.self_time,span.op,queue.task.celery)', name: t('Avg Processing Time'), width: COL_WIDTH_UNDEFINED, }, { key: 'failure_rate()', name: t('Error Rate'), width: COL_WIDTH_UNDEFINED, }, { key: 'count_op(queue.submit.celery)', name: t('Published'), width: COL_WIDTH_UNDEFINED, }, { key: 'count_op(queue.task.celery)', name: t('Processed'), width: COL_WIDTH_UNDEFINED, }, { key: 'sum(span.self_time)', name: t('Time Spent'), width: COL_WIDTH_UNDEFINED, }, ]; interface Props { domain?: string; error?: Error | null; meta?: EventsMetaType; } export function QueuesTable({error}: Props) { const location = useLocation(); const organization = useOrganization(); const {data, isLoading, meta, pageLinks} = useQueuesByDestinationQuery({}); const handleCursor: CursorHandler = (newCursor, pathname, query) => { browserHistory.push({ pathname, query: {...query, [QueryParameterNames.DESTINATIONS_CURSOR]: newCursor}, }); }; return ( renderHeadCell({ column: col, location, }), renderBodyCell: (column, row) => renderBodyCell(column, row, meta, location, organization), }} location={location} /> ); } function renderBodyCell( column: Column, row: Row, meta: EventsMetaType | undefined, location: Location, organization: Organization ) { const key = column.key; if (row[key] === undefined) { return ( {' \u2014 '} ); } if (key === 'transaction') { return ; } if (key.startsWith('count')) { return {formatAbbreviatedNumber(row[key])}; } if (key === 'failure_rate()') { return {formatPercentage(row[key])}; } if (!meta?.fields) { return row[column.key]; } const renderer = getFieldRenderer(column.key, meta.fields, false); return renderer(row, { location, organization, unit: meta.units?.[column.key], }); } function DestinationCell({destination}: {destination: string}) { const organization = useOrganization(); const {query} = useLocation(); const queryString = { ...query, destination, }; return ( {destination} ); } const NoOverflow = styled('span')` overflow: hidden; `; const AlignRight = styled('span')` text-align: right; `; const NoValue = styled('span')` color: ${p => p.theme.gray300}; `;