import { Table } from 'components/common/table/Table/Table.styled'; import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell'; import { ConsumerGroupTopicPartition, SortOrder } from 'generated-sources'; import React from 'react'; import { ContentBox, TopicContentWrapper } from './TopicContent.styled'; interface Props { consumers: ConsumerGroupTopicPartition[]; } type OrderByKey = keyof ConsumerGroupTopicPartition; interface Headers { title: string; orderBy: OrderByKey | undefined; } const TABLE_HEADERS_MAP: Headers[] = [ { title: 'Partition', orderBy: 'partition' }, { title: 'Consumer ID', orderBy: 'consumerId' }, { title: 'Host', orderBy: 'host' }, { title: 'Messages Behind', orderBy: 'messagesBehind' }, { title: 'Current Offset', orderBy: 'currentOffset' }, { title: 'End offset', orderBy: 'endOffset' }, ]; const ipV4ToNum = (ip?: string) => { if (typeof ip === 'string' && ip.length !== 0) { const withoutSlash = ip.indexOf('/') !== -1 ? ip.slice(1) : ip; return Number( withoutSlash .split('.') .map((octet) => `000${octet}`.slice(-3)) .join('') ); } return 0; }; type ComparatorFunction = ( valueA: T, valueB: T, order: SortOrder, property?: keyof T ) => number; const numberComparator: ComparatorFunction = ( valueA, valueB, order, property ) => { if (property !== undefined) { return order === SortOrder.ASC ? Number(valueA[property]) - Number(valueB[property]) : Number(valueB[property]) - Number(valueA[property]); } return 0; }; const ipComparator: ComparatorFunction = ( valueA, valueB, order ) => order === SortOrder.ASC ? ipV4ToNum(valueA.host) - ipV4ToNum(valueB.host) : ipV4ToNum(valueB.host) - ipV4ToNum(valueA.host); const consumerIdComparator: ComparatorFunction = ( valueA, valueB, order ) => { if (valueA.consumerId && valueB.consumerId) { if (order === SortOrder.ASC) { if (valueA.consumerId?.toLowerCase() > valueB.consumerId?.toLowerCase()) { return 1; } } if (order === SortOrder.DESC) { if (valueB.consumerId?.toLowerCase() > valueA.consumerId?.toLowerCase()) { return -1; } } } return 0; }; const TopicContents: React.FC = ({ consumers }) => { const [orderBy, setOrderBy] = React.useState('partition'); const [sortOrder, setSortOrder] = React.useState(SortOrder.DESC); const handleOrder = React.useCallback((columnName: string | null) => { if (typeof columnName === 'string') { setOrderBy(columnName as OrderByKey); setSortOrder((prevOrder) => prevOrder === SortOrder.DESC ? SortOrder.ASC : SortOrder.DESC ); } }, []); const sortedConsumers = React.useMemo(() => { if (orderBy && sortOrder) { const isNumberProperty = orderBy === 'partition' || orderBy === 'currentOffset' || orderBy === 'endOffset' || orderBy === 'messagesBehind'; let comparator: ComparatorFunction; if (isNumberProperty) { comparator = numberComparator; } if (orderBy === 'host') { comparator = ipComparator; } if (orderBy === 'consumerId') { comparator = consumerIdComparator; } return consumers.sort((a, b) => comparator(a, b, sortOrder, orderBy)); } return consumers; }, [orderBy, sortOrder, consumers]); return ( {TABLE_HEADERS_MAP.map((header) => ( ))} {sortedConsumers.map((consumer) => ( ))}
{consumer.partition} {consumer.consumerId} {consumer.host} {consumer.messagesBehind} {consumer.currentOffset} {consumer.endOffset}
); }; export default TopicContents;