From 10a27ba60eb4c2c9569eaec253bb219869bd0ba5 Mon Sep 17 00:00:00 2001 From: Guzel738 <66492070+Guzel738@users.noreply.github.com> Date: Fri, 5 Feb 2021 16:53:41 +0300 Subject: [PATCH] Messages component refactoring (#174) * ISSUE-169 Sort topics (#172) * Messages Table component created * Messages component refactored * MessageItem component fixed * MessageItem component updated * MessageItem component refactored Co-authored-by: German Osin Co-authored-by: Oleg Shuralev --- .../Topics/Details/Messages/MessageItem.tsx | 52 +++++++++++ .../Topics/Details/Messages/Messages.tsx | 90 +------------------ .../Topics/Details/Messages/MessagesTable.tsx | 57 ++++++++++++ .../src/redux/reducers/topics/reducer.ts | 32 +++++-- 4 files changed, 138 insertions(+), 93 deletions(-) create mode 100644 kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx create mode 100644 kafka-ui-react-app/src/components/Topics/Details/Messages/MessagesTable.tsx diff --git a/kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx b/kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx new file mode 100644 index 0000000000..e168ef042a --- /dev/null +++ b/kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { format } from 'date-fns'; +import JSONTree from 'react-json-tree'; +import { TopicMessage } from 'generated-sources'; + +interface MessageItemProp { + partition: TopicMessage['partition']; + offset: TopicMessage['offset']; + timestamp: TopicMessage['timestamp']; + content: TopicMessage['content']; +} + +const MessageItem: React.FC = ({ + partition, + offset, + timestamp, + content, +}) => ( + + + {timestamp ? format(timestamp, 'yyyy-MM-dd HH:mm:ss') : null} + + {offset} + {partition} + + {content && ( + ({ + style: { + ...style, + backgroundColor: undefined, + marginLeft: 0, + marginTop: 0, + }, + }), + value: ({ style }) => ({ + style: { ...style, marginLeft: 0 }, + }), + base0D: '#3273dc', + base0B: '#363636', + }} + /> + )} + + +); + +export default MessageItem; diff --git a/kafka-ui-react-app/src/components/Topics/Details/Messages/Messages.tsx b/kafka-ui-react-app/src/components/Topics/Details/Messages/Messages.tsx index 5a6f639f69..59e8b72112 100644 --- a/kafka-ui-react-app/src/components/Topics/Details/Messages/Messages.tsx +++ b/kafka-ui-react-app/src/components/Topics/Details/Messages/Messages.tsx @@ -6,19 +6,15 @@ import { } from 'redux/interfaces'; import { TopicMessage, Partition, SeekType } from 'generated-sources'; import PageLoader from 'components/common/PageLoader/PageLoader'; -import { format } from 'date-fns'; import DatePicker from 'react-datepicker'; -import JSONTree from 'react-json-tree'; import 'react-datepicker/dist/react-datepicker.css'; -import CustomParamButton, { - CustomParamButtonType, -} from 'components/Topics/shared/Form/CustomParams/CustomParamButton'; import MultiSelect from 'react-multi-select-component'; import * as _ from 'lodash'; import { useDebouncedCallback } from 'use-debounce'; import { Option } from 'react-multi-select-component/dist/lib/interfaces'; +import MessagesTable from './MessagesTable'; export interface Props { clusterName: ClusterName; @@ -174,42 +170,6 @@ const Messages: React.FC = ({ fetchTopicMessages(clusterName, topicName, queryParams); }, [clusterName, topicName, queryParams]); - const getFormattedDate = (date: Date) => { - if (!date) return null; - return format(date, 'yyyy-MM-dd HH:mm:ss'); - }; - - const getMessageContentBody = (content: Record) => { - try { - const contentObj = - typeof content !== 'object' ? JSON.parse(content) : content; - return ( - ({ - style: { - ...style, - backgroundColor: undefined, - marginLeft: 0, - marginTop: 0, - }, - }), - value: ({ style }) => ({ - style: { ...style, marginLeft: 0 }, - }), - base0D: '#3273dc', - base0B: '#363636', - }} - /> - ); - } catch (e) { - return content; - } - }; - const onNext = (event: React.MouseEvent) => { event.preventDefault(); @@ -236,52 +196,6 @@ const Messages: React.FC = ({ ); }; - const getTopicMessagesTable = () => { - return messages.length > 0 ? ( -
- - - - - - - - - - - {messages.map((message) => ( - - - - - - - ))} - -
TimestampOffsetPartitionContent
- {getFormattedDate(message.timestamp)} - {message.offset}{message.partition} - {message.content && - getMessageContentBody( - message.content as Record - )} -
-
-
- -
-
-
- ) : ( -
No messages at selected topic
- ); - }; - if (!isFetched) { return ; } @@ -366,7 +280,7 @@ const Messages: React.FC = ({ /> - {getTopicMessagesTable()} + ); }; diff --git a/kafka-ui-react-app/src/components/Topics/Details/Messages/MessagesTable.tsx b/kafka-ui-react-app/src/components/Topics/Details/Messages/MessagesTable.tsx new file mode 100644 index 0000000000..5073673f86 --- /dev/null +++ b/kafka-ui-react-app/src/components/Topics/Details/Messages/MessagesTable.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { TopicMessage } from 'generated-sources'; +import CustomParamButton, { + CustomParamButtonType, +} from '../../shared/Form/CustomParams/CustomParamButton'; +import MessageItem from './MessageItem'; + +interface MessagesTableProp { + messages: TopicMessage[]; + onNext(event: React.MouseEvent): void; +} + +const MessagesTable: React.FC = ({ messages, onNext }) => { + if (!messages.length) { + return
No messages at selected topic
; + } + + return ( +
+ + + + + + + + + + + {messages.map( + ({ partition, offset, timestamp, content }: TopicMessage) => ( + } + /> + ) + )} + +
TimestampOffsetPartitionContent
+
+
+ +
+
+
+ ); +}; + +export default MessagesTable; diff --git a/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts b/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts index f4d2e1b856..6a11485172 100644 --- a/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts +++ b/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts @@ -1,5 +1,5 @@ import { v4 } from 'uuid'; -import { Topic } from 'generated-sources'; +import { Topic, TopicMessage } from 'generated-sources'; import { Action, TopicsState } from 'redux/interfaces'; import ActionType from 'redux/actionType'; @@ -41,6 +41,31 @@ const addToTopicList = (state: TopicsState, payload: Topic): TopicsState => { return newState; }; +const transformTopicMessages = ( + state: TopicsState, + messages: TopicMessage[] +): TopicsState => ({ + ...state, + messages: messages.map((mes) => { + const { content } = mes; + let parsedContent = content; + + if (content) { + try { + parsedContent = + typeof content !== 'object' ? JSON.parse(content) : content; + } catch (_) { + // do nothing + } + } + + return { + ...mes, + content: parsedContent, + }; + }), +}); + const reducer = (state = initialState, action: Action): TopicsState => { switch (action.type) { case ActionType.GET_TOPICS__SUCCESS: @@ -57,10 +82,7 @@ const reducer = (state = initialState, action: Action): TopicsState => { }, }; case ActionType.GET_TOPIC_MESSAGES__SUCCESS: - return { - ...state, - messages: action.payload, - }; + return transformTopicMessages(state, action.payload); case ActionType.GET_TOPIC_CONFIG__SUCCESS: return { ...state,