|
@@ -1,4 +1,4 @@
|
|
-import React, { useEffect, useRef } from 'react';
|
|
|
|
|
|
+import React, { useCallback, useEffect, useRef } from 'react';
|
|
import {
|
|
import {
|
|
ClusterName,
|
|
ClusterName,
|
|
SeekTypes,
|
|
SeekTypes,
|
|
@@ -15,6 +15,8 @@ import CustomParamButton, {
|
|
CustomParamButtonType,
|
|
CustomParamButtonType,
|
|
} from 'components/Topics/shared/Form/CustomParams/CustomParamButton';
|
|
} from 'components/Topics/shared/Form/CustomParams/CustomParamButton';
|
|
|
|
|
|
|
|
+import { debounce } from 'lodash';
|
|
|
|
+
|
|
interface Props {
|
|
interface Props {
|
|
clusterName: ClusterName;
|
|
clusterName: ClusterName;
|
|
topicName: TopicName;
|
|
topicName: TopicName;
|
|
@@ -58,7 +60,7 @@ const Messages: React.FC<Props> = ({
|
|
|
|
|
|
const prevSearchTimestamp = usePrevious(searchTimestamp);
|
|
const prevSearchTimestamp = usePrevious(searchTimestamp);
|
|
|
|
|
|
- const getUniqueDataForEachPartition = () => {
|
|
|
|
|
|
+ const getUniqueDataForEachPartition: FilterProps[] = React.useMemo(() => {
|
|
const map = messages.map((message) => [
|
|
const map = messages.map((message) => [
|
|
message.partition,
|
|
message.partition,
|
|
{
|
|
{
|
|
@@ -68,7 +70,7 @@ const Messages: React.FC<Props> = ({
|
|
]);
|
|
]);
|
|
// @ts-ignore
|
|
// @ts-ignore
|
|
return [...new Map(map).values()];
|
|
return [...new Map(map).values()];
|
|
- };
|
|
|
|
|
|
+ }, [messages]);
|
|
|
|
|
|
React.useEffect(() => {
|
|
React.useEffect(() => {
|
|
fetchTopicMessages(clusterName, topicName, queryParams);
|
|
fetchTopicMessages(clusterName, topicName, queryParams);
|
|
@@ -78,11 +80,18 @@ const Messages: React.FC<Props> = ({
|
|
setFilterProps(getUniqueDataForEachPartition);
|
|
setFilterProps(getUniqueDataForEachPartition);
|
|
}, [messages]);
|
|
}, [messages]);
|
|
|
|
|
|
|
|
+ const handleDelayedQuery = useCallback(
|
|
|
|
+ debounce(
|
|
|
|
+ (query: string) => setQueryParams({ ...queryParams, q: query }),
|
|
|
|
+ 1000
|
|
|
|
+ ),
|
|
|
|
+ []
|
|
|
|
+ );
|
|
const handleQueryChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
const handleQueryChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
const query = event.target.value;
|
|
const query = event.target.value;
|
|
|
|
|
|
setSearchQuery(query);
|
|
setSearchQuery(query);
|
|
- setQueryParams({ ...queryParams, q: query });
|
|
|
|
|
|
+ handleDelayedQuery(query);
|
|
};
|
|
};
|
|
|
|
|
|
const handleDateTimeChange = () => {
|
|
const handleDateTimeChange = () => {
|
|
@@ -108,7 +117,7 @@ const Messages: React.FC<Props> = ({
|
|
return format(new Date(timestamp * 1000), 'MM.dd.yyyy HH:mm:ss');
|
|
return format(new Date(timestamp * 1000), 'MM.dd.yyyy HH:mm:ss');
|
|
};
|
|
};
|
|
|
|
|
|
- const getMessageContentHeaders = () => {
|
|
|
|
|
|
+ const getMessageContentHeaders = React.useMemo(() => {
|
|
const message = messages[0];
|
|
const message = messages[0];
|
|
const headers: JSX.Element[] = [];
|
|
const headers: JSX.Element[] = [];
|
|
try {
|
|
try {
|
|
@@ -117,19 +126,21 @@ const Messages: React.FC<Props> = ({
|
|
? JSON.parse(message.content)
|
|
? JSON.parse(message.content)
|
|
: message.content;
|
|
: message.content;
|
|
Object.keys(content).forEach((k) =>
|
|
Object.keys(content).forEach((k) =>
|
|
- headers.push(<th>{`content.${k}`}</th>)
|
|
|
|
|
|
+ headers.push(<th key={Math.random()}>{`content.${k}`}</th>)
|
|
);
|
|
);
|
|
} catch (e) {
|
|
} catch (e) {
|
|
headers.push(<th>Content</th>);
|
|
headers.push(<th>Content</th>);
|
|
}
|
|
}
|
|
return headers;
|
|
return headers;
|
|
- };
|
|
|
|
|
|
+ }, [messages]);
|
|
|
|
|
|
const getMessageContentBody = (content: any) => {
|
|
const getMessageContentBody = (content: any) => {
|
|
const columns: JSX.Element[] = [];
|
|
const columns: JSX.Element[] = [];
|
|
try {
|
|
try {
|
|
const c = typeof content !== 'object' ? JSON.parse(content) : content;
|
|
const c = typeof content !== 'object' ? JSON.parse(content) : content;
|
|
- Object.values(c).map((v) => columns.push(<td>{JSON.stringify(v)}</td>));
|
|
|
|
|
|
+ Object.values(c).map((v) =>
|
|
|
|
+ columns.push(<td key={Math.random()}>{JSON.stringify(v)}</td>)
|
|
|
|
+ );
|
|
} catch (e) {
|
|
} catch (e) {
|
|
columns.push(<td>{content}</td>);
|
|
columns.push(<td>{content}</td>);
|
|
}
|
|
}
|
|
@@ -158,12 +169,12 @@ const Messages: React.FC<Props> = ({
|
|
<th>Timestamp</th>
|
|
<th>Timestamp</th>
|
|
<th>Offset</th>
|
|
<th>Offset</th>
|
|
<th>Partition</th>
|
|
<th>Partition</th>
|
|
- {getMessageContentHeaders()}
|
|
|
|
|
|
+ {getMessageContentHeaders}
|
|
</tr>
|
|
</tr>
|
|
</thead>
|
|
</thead>
|
|
<tbody>
|
|
<tbody>
|
|
{messages.map((message) => (
|
|
{messages.map((message) => (
|
|
- <tr key={message.timestamp}>
|
|
|
|
|
|
+ <tr key={`${message.timestamp}${Math.random()}`}>
|
|
<td>{getTimestampDate(message.timestamp)}</td>
|
|
<td>{getTimestampDate(message.timestamp)}</td>
|
|
<td>{message.offset}</td>
|
|
<td>{message.offset}</td>
|
|
<td>{message.partition}</td>
|
|
<td>{message.partition}</td>
|