Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added table column and row logic for the new api response structure for producer overview #6433

Merged
merged 4 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import axios from 'api';
import { ErrorResponse, SuccessResponse } from 'types/api';

import {
MessagingQueueServicePayload,
MessagingQueuesPayloadProps,
} from './getConsumerLagDetails';
} from 'pages/MessagingQueues/MQDetails/MQTables/getConsumerLagDetails';
import { ErrorResponse, SuccessResponse } from 'types/api';

export const getTopicThroughputOverview = async (
props: Omit<MessagingQueueServicePayload, 'variables'>,
Expand Down
7 changes: 0 additions & 7 deletions frontend/src/pages/MessagingQueues/MQDetails/MQDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,6 @@ const checkValidityOfDetailConfigs = (
return false;
}

if (currentTab === MessagingQueueServiceDetailType.ProducerDetails) {
return Boolean(
configDetails?.topic &&
configDetails?.partition &&
configDetails?.service_name,
);
}
return Boolean(configDetails?.topic && configDetails?.service_name);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { RowData } from 'pages/MessagingQueues/MessagingQueuesUtils';

import { MessagingQueuesPayloadProps } from './getConsumerLagDetails';

export function getTableDataForProducerLatencyOverview(
data: MessagingQueuesPayloadProps['payload'],
): RowData[] {
if (data?.result?.length === 0) {
return [];
}

const firstTableData = data.result[0].table.rows || [];
const secondTableData = data.result[1]?.table.rows || [];

// Create a map for quick lookup of byte_rate using service_name and topic
const byteRateMap = new Map(
secondTableData.map((row) => [
`${row.data.service_name}--${row.data.topic}`,
row.data.byte_rate,
]),
);

// Merge the data from both tables
const mergedTableData: RowData[] =
firstTableData.map(
(row, index): RowData => ({
...row.data,
byte_rate:
byteRateMap.get(`${row.data.service_name}--${row.data.topic}`) || 0,
key: index,
}),
) || [];

return mergedTableData;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,32 @@ import {
MessagingQueueServicePayload,
MessagingQueuesPayloadProps,
} from './getConsumerLagDetails';
import { getTableDataForProducerLatencyOverview } from './MQTableUtils';

const INITIAL_PAGE_SIZE = 10;

// eslint-disable-next-line sonarjs/cognitive-complexity
export function getColumns(
data: MessagingQueuesPayloadProps['payload'],
history: History<unknown>,
isProducerOverview?: boolean,
): RowData[] {
if (data?.result?.length === 0) {
return [];
}

const mergedColumns = isProducerOverview
? [
...(data?.result?.[0]?.table?.columns || []),
{ name: 'byte_rate', queryName: 'byte_rate' },
]
: data?.result?.[0]?.table?.columns;

SagarRajput-7 marked this conversation as resolved.
Show resolved Hide resolved
const columns: {
title: string;
dataIndex: string;
key: string;
}[] = data?.result?.[0]?.table?.columns.map((column) => ({
}[] = mergedColumns.map((column) => ({
title: convertToTitleCase(column.name),
dataIndex: column.name,
key: column.name,
Expand All @@ -58,6 +67,8 @@ export function getColumns(
'throughput',
'avg_msg_size',
'error_percentage',
'ingestion_rate',
'byte_rate',
].includes(column.name)
? (value: number | string): string => {
if (!isNumber(value)) return value.toString();
Expand Down Expand Up @@ -172,13 +183,25 @@ function MessagingQueuesTable({
});
};

const isProducerOverview = useMemo(
() =>
type === 'Overview' &&
selectedView === MessagingQueuesViewType.producerLatency.value &&
tableApiPayload?.detailType === 'producer',
[type, selectedView, tableApiPayload],
);

const { mutate: getViewDetails, isLoading, error, isError } = useMutation(
tableApi,
{
onSuccess: (data) => {
if (data.payload) {
setColumns(getColumns(data?.payload, history));
setTableData(getTableData(data?.payload));
setColumns(getColumns(data?.payload, history, isProducerOverview));
setTableData(
isProducerOverview
? getTableDataForProducerLatencyOverview(data?.payload)
: getTableData(data?.payload),
);
}
},
onError: handleConsumerDetailsOnError,
Expand All @@ -199,15 +222,29 @@ function MessagingQueuesTable({
const [, setSelectedRows] = useState<any>();
const location = useLocation();

const onRowClick = (record: { [key: string]: string }): void => {
const selectedKey = record.key;
const selectedRowKeyGenerator = (record: {
[key: string]: string;
}): React.Key => {
if (!isEmpty(tableApiPayload?.detailType)) {
return `${record.key}_${selectedView}_${tableApiPayload?.detailType}`;
}
return `${record.key}_${selectedView}`;
};

useEffect(() => {
if (isEmpty(configDetailQueryData)) {
setSelectedRowKey(undefined);
setSelectedRows({});
}
}, [configDetailQueryData]);

if (`${selectedKey}_${selectedView}` === selectedRowKey) {
const onRowClick = (record: { [key: string]: string }): void => {
if (selectedRowKeyGenerator(record) === selectedRowKey) {
setSelectedRowKey(undefined);
setSelectedRows({});
setConfigDetail(urlQuery, location, history, {});
} else {
setSelectedRowKey(`${selectedKey}_${selectedView}`);
setSelectedRowKey(selectedRowKeyGenerator(record));
setSelectedRows(record);

if (!isEmpty(record)) {
Expand Down Expand Up @@ -267,7 +304,7 @@ function MessagingQueuesTable({
: {}
}
rowClassName={(record): any =>
`${record.key}_${selectedView}` === selectedRowKey
selectedRowKeyGenerator(record) === selectedRowKey
? 'ant-table-row-selected'
: ''
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
import './MQDetails.style.scss';

import { Radio } from 'antd';
import { Dispatch, SetStateAction } from 'react';
import { getTopicThroughputOverview } from 'api/messagingQueues/getTopicThroughputOverview';
import useUrlQuery from 'hooks/useUrlQuery';
import { Dispatch, SetStateAction, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';

import {
MessagingQueuesViewType,
MessagingQueuesViewTypeOptions,
ProducerLatencyOptions,
setConfigDetail,
} from '../MessagingQueuesUtils';
import { MessagingQueueServicePayload } from './MQTables/getConsumerLagDetails';
import { getKafkaSpanEval } from './MQTables/getKafkaSpanEval';
import { getPartitionLatencyOverview } from './MQTables/getPartitionLatencyOverview';
import { getTopicThroughputOverview } from './MQTables/getTopicThroughputOverview';
import MessagingQueuesTable from './MQTables/MQTables';

type SelectedViewType = keyof typeof MessagingQueuesViewType;

function PartitionLatencyTabs({
function ProducerLatencyTabs({
option,
setOption,
}: {
option: ProducerLatencyOptions;
setOption: Dispatch<SetStateAction<ProducerLatencyOptions>>;
}): JSX.Element {
const urlQuery = useUrlQuery();
const location = useLocation();
const history = useHistory();

return (
<Radio.Group
onChange={(e): void => setOption(e.target.value)}
onChange={(e): void => {
setConfigDetail(urlQuery, location, history, {});
setOption(e.target.value);
}}
value={option}
className="mq-details-options"
>
Expand Down Expand Up @@ -71,27 +81,26 @@ function MessagingQueueOverview({
(state) => state.globalTime,
);

const tableApiPayload: MessagingQueueServicePayload = {
variables: {},
start: minTime,
end: maxTime,
detailType:
// eslint-disable-next-line no-nested-ternary
selectedView === MessagingQueuesViewType.producerLatency.value
? option === ProducerLatencyOptions.Producers
? 'producer'
: 'consumer'
: undefined,
evalTime:
selectedView === MessagingQueuesViewType.dropRate.value
? 2363404
: undefined,
};
const tableApiPayload: MessagingQueueServicePayload = useMemo(
() => ({
variables: {},
start: minTime,
end: maxTime,
detailType:
// eslint-disable-next-line no-nested-ternary
selectedView === MessagingQueuesViewType.producerLatency.value
? option === ProducerLatencyOptions.Producers
? 'producer'
: 'consumer'
: undefined,
}),
[minTime, maxTime, selectedView, option],
);

return (
<div className="mq-overview-container">
{selectedView === MessagingQueuesViewType.producerLatency.value ? (
<PartitionLatencyTabs option={option} setOption={setOption} />
<ProducerLatencyTabs option={option} setOption={setOption} />
) : (
<div className="mq-overview-title">
{MessagingQueuesViewType[selectedView as SelectedViewType].label}
Expand Down
Loading