From c55f8c0a503cfb729b0c72d2726489f4db023c14 Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Mon, 30 Dec 2024 19:20:46 +0000 Subject: [PATCH 01/18] add an option to save all messages as csv/json, Issue #688 --- .../Topics/Topic/Messages/MessagesTable.tsx | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index 813cabcfa..dfd3c294f 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -7,6 +7,9 @@ import { Button } from 'components/common/Button/Button'; import * as S from 'components/common/NewTable/Table.styled'; import { usePaginateTopics, useIsLiveMode } from 'lib/hooks/useMessagesFilters'; import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; +import useDataSaver from 'lib/hooks/useDataSaver'; +import Select from 'components/common/Select/Select'; +import { SelectOption } from 'components/common/Select/Select'; import PreviewModal from './PreviewModal'; import Message, { PreviewFilter } from './Message'; @@ -16,6 +19,33 @@ export interface MessagesTableProps { isFetching: boolean; } +interface MessageData { + Value: string | undefined; + Offset: number; + Key: string | undefined; + Partition: number; + Headers: { [key: string]: string | undefined; } | undefined; + Timestamp: Date; +} + +type DownloadFormat = 'json' | 'csv'; + +function padCurrentDateTimeString(): string { + const now: Date = new Date(); + + const year: string = now.getFullYear().toString(); + const month: string = (now.getMonth() + 1).toString().padStart(2, '0'); + const day: string = now.getDate().toString().padStart(2, '0'); + const hours: string = now.getHours().toString().padStart(2, '0'); + const minutes: string = now.getMinutes().toString().padStart(2, '0'); + const seconds: string = now.getSeconds().toString().padStart(2, '0'); + + const dateTimeString: string = `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`; + + return `_${dateTimeString}`; +} + + const MessagesTable: React.FC = ({ messages, isFetching, @@ -28,8 +58,80 @@ const MessagesTable: React.FC = ({ const nextCursor = useMessageFiltersStore((state) => state.nextCursor); const isLive = useIsLiveMode(); + const [selectedFormat, setSelectedFormat] = useState('json'); + + const formatOptions: SelectOption[] = [ + { label: 'JSON', value: 'json' }, + { label: 'CSV', value: 'csv' } + ]; + + const handleFormatSelect = (format: DownloadFormat) => { + setSelectedFormat(format); + }; + + const handleDownload = () => { + + const savedMessagesJson: MessageData[] = messages.map(message => ({ + Value: message.content, + Offset: message.offset, + Key: message.key, + Partition: message.partition, + Headers: message.headers, + Timestamp: message.timestamp, + })); + + const convertToCSV = (messages: MessageData[]) => { + const headers = ['Value', 'Offset', 'Key', 'Partition', 'Headers', 'Timestamp'] as const; + type Header = typeof headers[number]; + + const rows = messages.map(msg => + headers.map(header => { + const value = msg[header]; + if (header === 'Headers') { + return JSON.stringify(value || {}); + } + return String(value ?? ''); + }).join(',') + ); + + return [headers.join(','), ...rows].join('\n'); + }; + + const baseFileName = 'topic-messages'+padCurrentDateTimeString(); + const jsonSaver = useDataSaver(baseFileName+'.json', JSON.stringify(savedMessagesJson, null, '\t')); + const csvSaver = useDataSaver(baseFileName+'.csv', convertToCSV(savedMessagesJson)); + + if (selectedFormat === 'json') { + jsonSaver.saveFile(); + } else { + csvSaver.saveFile(); + } + }; + return (
+
+ + id="download-format" + name="download-format" + onChange={handleFormatSelect} + options={formatOptions} + value={selectedFormat} + minWidth="70px" + selectSize="M" + placeholder="Select format to download" + disabled={isFetching || messages.length === 0} + /> + +
+ {previewFor !== null && ( Date: Mon, 30 Dec 2024 20:29:17 +0000 Subject: [PATCH 02/18] linter issues fix --- .../components/Topics/Topic/Messages/MessagesTable.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index dfd3c294f..5980eff97 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -8,8 +8,7 @@ import * as S from 'components/common/NewTable/Table.styled'; import { usePaginateTopics, useIsLiveMode } from 'lib/hooks/useMessagesFilters'; import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; import useDataSaver from 'lib/hooks/useDataSaver'; -import Select from 'components/common/Select/Select'; -import { SelectOption } from 'components/common/Select/Select'; +import { Select, SelectOption } from 'components/common/Select/Select'; import PreviewModal from './PreviewModal'; import Message, { PreviewFilter } from './Message'; @@ -82,7 +81,6 @@ const MessagesTable: React.FC = ({ const convertToCSV = (messages: MessageData[]) => { const headers = ['Value', 'Offset', 'Key', 'Partition', 'Headers', 'Timestamp'] as const; - type Header = typeof headers[number]; const rows = messages.map(msg => headers.map(header => { @@ -98,8 +96,8 @@ const MessagesTable: React.FC = ({ }; const baseFileName = 'topic-messages'+padCurrentDateTimeString(); - const jsonSaver = useDataSaver(baseFileName+'.json', JSON.stringify(savedMessagesJson, null, '\t')); - const csvSaver = useDataSaver(baseFileName+'.csv', convertToCSV(savedMessagesJson)); + const jsonSaver = useDataSaver(`${baseFileName}.json`, JSON.stringify(savedMessagesJson, null, '\t')); + const csvSaver = useDataSaver(`${baseFileName}.csv`, convertToCSV(savedMessagesJson)); if (selectedFormat === 'json') { jsonSaver.saveFile(); From 1aab310ed37b83e577b0d3819d9f7b6f6d55f702 Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Mon, 30 Dec 2024 20:39:00 +0000 Subject: [PATCH 03/18] lint fixes --- frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index 5980eff97..9b8463a3a 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -8,7 +8,7 @@ import * as S from 'components/common/NewTable/Table.styled'; import { usePaginateTopics, useIsLiveMode } from 'lib/hooks/useMessagesFilters'; import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; import useDataSaver from 'lib/hooks/useDataSaver'; -import { Select, SelectOption } from 'components/common/Select/Select'; +import Select, { SelectOption } from 'components/common/Select/Select'; import PreviewModal from './PreviewModal'; import Message, { PreviewFilter } from './Message'; From 9817ee5b01f758d1d1d541987738ab8f303e82aa Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Sun, 5 Jan 2025 16:26:48 +0000 Subject: [PATCH 04/18] linter fixes + comments --- .../Topics/Topic/Messages/MessagesTable.tsx | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index 9b8463a3a..94384a19f 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -2,7 +2,8 @@ import PageLoader from 'components/common/PageLoader/PageLoader'; import { Table } from 'components/common/table/Table/Table.styled'; import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell'; import { TopicMessage } from 'generated-sources'; -import React, { useState } from 'react'; +import React, { useState, useMemo } from 'react'; +import { format } from 'date-fns'; import { Button } from 'components/common/Button/Button'; import * as S from 'components/common/NewTable/Table.styled'; import { usePaginateTopics, useIsLiveMode } from 'lib/hooks/useMessagesFilters'; @@ -31,15 +32,7 @@ type DownloadFormat = 'json' | 'csv'; function padCurrentDateTimeString(): string { const now: Date = new Date(); - - const year: string = now.getFullYear().toString(); - const month: string = (now.getMonth() + 1).toString().padStart(2, '0'); - const day: string = now.getDate().toString().padStart(2, '0'); - const hours: string = now.getHours().toString().padStart(2, '0'); - const minutes: string = now.getMinutes().toString().padStart(2, '0'); - const seconds: string = now.getSeconds().toString().padStart(2, '0'); - - const dateTimeString: string = `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`; + const dateTimeString:string = format(now, 'yyyy-MM-dd HH:mm:ss'); return `_${dateTimeString}`; } @@ -64,11 +57,7 @@ const MessagesTable: React.FC = ({ { label: 'CSV', value: 'csv' } ]; - const handleFormatSelect = (format: DownloadFormat) => { - setSelectedFormat(format); - }; - - const handleDownload = () => { + const baseFileName = `topic-messages${padCurrentDateTimeString()}`; const savedMessagesJson: MessageData[] = messages.map(message => ({ Value: message.content, @@ -79,26 +68,31 @@ const MessagesTable: React.FC = ({ Timestamp: message.timestamp, })); - const convertToCSV = (messages: MessageData[]) => { - const headers = ['Value', 'Offset', 'Key', 'Partition', 'Headers', 'Timestamp'] as const; + const convertToCSV = useMemo(() => { + return (messagesData: MessageData[]) => { + const headers = ['Value', 'Offset', 'Key', 'Partition', 'Headers', 'Timestamp'] as const; + const rows = messagesData.map(msg => + headers.map(header => { + const value = msg[header]; + if (header === 'Headers') { + return JSON.stringify(value || {}); + } + return String(value ?? ''); + }).join(',') + ); + return [headers.join(','), ...rows].join('\n'); + }; + }, []); - const rows = messages.map(msg => - headers.map(header => { - const value = msg[header]; - if (header === 'Headers') { - return JSON.stringify(value || {}); - } - return String(value ?? ''); - }).join(',') - ); + const jsonSaver = useDataSaver(`${baseFileName}.json`, JSON.stringify(savedMessagesJson, null, '\t')); + const csvSaver = useDataSaver(`${baseFileName}.csv`, convertToCSV(savedMessagesJson)); - return [headers.join(','), ...rows].join('\n'); - }; - const baseFileName = 'topic-messages'+padCurrentDateTimeString(); - const jsonSaver = useDataSaver(`${baseFileName}.json`, JSON.stringify(savedMessagesJson, null, '\t')); - const csvSaver = useDataSaver(`${baseFileName}.csv`, convertToCSV(savedMessagesJson)); + const handleFormatSelect = (format: DownloadFormat) => { + setSelectedFormat(format); + }; + const handleDownload = () => { if (selectedFormat === 'json') { jsonSaver.saveFile(); } else { @@ -126,7 +120,7 @@ const MessagesTable: React.FC = ({ buttonSize="M" onClick={handleDownload} > - Download All Messages + Download Current Messages
From 628ecf15b04cfe26a66833fcfa64aeac0e39776f Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Sun, 5 Jan 2025 16:34:50 +0000 Subject: [PATCH 05/18] forgot missing date-fns in package.json --- frontend/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/package.json b/frontend/package.json index 249c91a8f..c1a1c571b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "ace-builds": "1.33.0", "ajv": "8.8.2", "ajv-formats": "2.1.1", + "date-fns": "4.1.0", "json-schema-faker": "0.5.6", "jsonpath-plus": "10.0.7", "lossless-json": "2.0.11", From b393c2d425accbdd9f4f299618ba3735442a149e Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Sun, 5 Jan 2025 16:49:05 +0000 Subject: [PATCH 06/18] forgot missing date-fns in pnpm --- frontend/pnpm-lock.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 29518a5cf..fa0d8ed96 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -53,6 +53,9 @@ importers: ajv-formats: specifier: 2.1.1 version: 2.1.1(ajv@8.8.2) + date-fns: + specifier: 4.1.0 + version: 4.1.0 json-schema-faker: specifier: 0.5.6 version: 0.5.6 @@ -1805,6 +1808,9 @@ packages: date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -5958,6 +5964,8 @@ snapshots: date-fns@3.6.0: {} + date-fns@4.1.0: {} + debug@3.2.7: dependencies: ms: 2.1.3 From d841a957ee066b2d842276854c423b5e194e6522 Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Sun, 5 Jan 2025 18:59:34 +0000 Subject: [PATCH 07/18] linter --- .../src/components/Topics/Topic/Messages/MessagesTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index 94384a19f..c49eb6a67 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -88,8 +88,8 @@ const MessagesTable: React.FC = ({ const csvSaver = useDataSaver(`${baseFileName}.csv`, convertToCSV(savedMessagesJson)); - const handleFormatSelect = (format: DownloadFormat) => { - setSelectedFormat(format); + const handleFormatSelect = (downloadFormat: DownloadFormat) => { + setSelectedFormat(downloadFormat); }; const handleDownload = () => { From eef61073a4ccd4843671f3cf0f5cf227ea80ce90 Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Sun, 5 Jan 2025 19:12:38 +0000 Subject: [PATCH 08/18] linter warnings fix --- .../Topics/Topic/Messages/MessagesTable.tsx | 117 +++++++++++------- 1 file changed, 69 insertions(+), 48 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index c49eb6a67..d4a463818 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -1,18 +1,18 @@ -import PageLoader from 'components/common/PageLoader/PageLoader'; -import { Table } from 'components/common/table/Table/Table.styled'; -import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell'; -import { TopicMessage } from 'generated-sources'; -import React, { useState, useMemo } from 'react'; -import { format } from 'date-fns'; -import { Button } from 'components/common/Button/Button'; -import * as S from 'components/common/NewTable/Table.styled'; -import { usePaginateTopics, useIsLiveMode } from 'lib/hooks/useMessagesFilters'; -import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; -import useDataSaver from 'lib/hooks/useDataSaver'; -import Select, { SelectOption } from 'components/common/Select/Select'; - -import PreviewModal from './PreviewModal'; -import Message, { PreviewFilter } from './Message'; +import PageLoader from "components/common/PageLoader/PageLoader"; +import { Table } from "components/common/table/Table/Table.styled"; +import TableHeaderCell from "components/common/table/TableHeaderCell/TableHeaderCell"; +import { TopicMessage } from "generated-sources"; +import React, { useState, useMemo } from "react"; +import { format } from "date-fns"; +import { Button } from "components/common/Button/Button"; +import * as S from "components/common/NewTable/Table.styled"; +import { usePaginateTopics, useIsLiveMode } from "lib/hooks/useMessagesFilters"; +import { useMessageFiltersStore } from "lib/hooks/useMessageFiltersStore"; +import useDataSaver from "lib/hooks/useDataSaver"; +import Select, { SelectOption } from "components/common/Select/Select"; + +import PreviewModal from "./PreviewModal"; +import Message, { PreviewFilter } from "./Message"; export interface MessagesTableProps { messages: TopicMessage[]; @@ -24,20 +24,19 @@ interface MessageData { Offset: number; Key: string | undefined; Partition: number; - Headers: { [key: string]: string | undefined; } | undefined; + Headers: { [key: string]: string | undefined } | undefined; Timestamp: Date; } -type DownloadFormat = 'json' | 'csv'; +type DownloadFormat = "json" | "csv"; function padCurrentDateTimeString(): string { const now: Date = new Date(); - const dateTimeString:string = format(now, 'yyyy-MM-dd HH:mm:ss'); + const dateTimeString: string = format(now, "yyyy-MM-dd HH:mm:ss"); return `_${dateTimeString}`; } - const MessagesTable: React.FC = ({ messages, isFetching, @@ -50,16 +49,16 @@ const MessagesTable: React.FC = ({ const nextCursor = useMessageFiltersStore((state) => state.nextCursor); const isLive = useIsLiveMode(); - const [selectedFormat, setSelectedFormat] = useState('json'); + const [selectedFormat, setSelectedFormat] = useState("json"); const formatOptions: SelectOption[] = [ - { label: 'JSON', value: 'json' }, - { label: 'CSV', value: 'csv' } + { label: "JSON", value: "json" }, + { label: "CSV", value: "csv" }, ]; const baseFileName = `topic-messages${padCurrentDateTimeString()}`; - const savedMessagesJson: MessageData[] = messages.map(message => ({ + const savedMessagesJson: MessageData[] = messages.map((message) => ({ Value: message.content, Offset: message.offset, Key: message.key, @@ -70,30 +69,44 @@ const MessagesTable: React.FC = ({ const convertToCSV = useMemo(() => { return (messagesData: MessageData[]) => { - const headers = ['Value', 'Offset', 'Key', 'Partition', 'Headers', 'Timestamp'] as const; - const rows = messagesData.map(msg => - headers.map(header => { - const value = msg[header]; - if (header === 'Headers') { - return JSON.stringify(value || {}); - } - return String(value ?? ''); - }).join(',') + const headers = [ + "Value", + "Offset", + "Key", + "Partition", + "Headers", + "Timestamp", + ] as const; + const rows = messagesData.map((msg) => + headers + .map((header) => { + const value = msg[header]; + if (header === "Headers") { + return JSON.stringify(value || {}); + } + return String(value ?? ""); + }) + .join(","), ); - return [headers.join(','), ...rows].join('\n'); + return [headers.join(","), ...rows].join("\n"); }; }, []); - const jsonSaver = useDataSaver(`${baseFileName}.json`, JSON.stringify(savedMessagesJson, null, '\t')); - const csvSaver = useDataSaver(`${baseFileName}.csv`, convertToCSV(savedMessagesJson)); - + const jsonSaver = useDataSaver( + `${baseFileName}.json`, + JSON.stringify(savedMessagesJson, null, "\t"), + ); + const csvSaver = useDataSaver( + `${baseFileName}.csv`, + convertToCSV(savedMessagesJson), + ); const handleFormatSelect = (downloadFormat: DownloadFormat) => { setSelectedFormat(downloadFormat); }; const handleDownload = () => { - if (selectedFormat === 'json') { + if (selectedFormat === "json") { jsonSaver.saveFile(); } else { csvSaver.saveFile(); @@ -101,16 +114,23 @@ const MessagesTable: React.FC = ({ }; return ( -
-
+
+
id="download-format" name="download-format" onChange={handleFormatSelect} options={formatOptions} value={selectedFormat} - minWidth="70px" - selectSize="M" + minWidth="70px" + selectSize="M" placeholder="Select format to download" disabled={isFetching || messages.length === 0} /> @@ -126,10 +146,10 @@ const MessagesTable: React.FC = ({ {previewFor !== null && ( setPreviewFor(null)} setFilters={(payload: PreviewFilter[]) => - previewFor === 'key' + previewFor === "key" ? setKeyFilters(payload) : setContentFilters(payload) } @@ -145,18 +165,18 @@ const MessagesTable: React.FC = ({ setPreviewFor('key')} + onPreview={() => setPreviewFor("key")} /> setPreviewFor('content')} + onPreview={() => setPreviewFor("content")} /> @@ -169,7 +189,7 @@ const MessagesTable: React.FC = ({ message.timestamp, message.key, message.partition, - ].join('-')} + ].join("-")} message={message} keyFilters={keyFilters} contentFilters={contentFilters} @@ -206,3 +226,4 @@ const MessagesTable: React.FC = ({ }; export default MessagesTable; + From cc31f8096da6893eefb684a04b20aa5dd22f6c20 Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Sun, 5 Jan 2025 19:20:54 +0000 Subject: [PATCH 09/18] linter warnings fix ->> single-quote --- .../Topics/Topic/Messages/MessagesTable.tsx | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index d4a463818..d7acaa371 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -1,18 +1,18 @@ -import PageLoader from "components/common/PageLoader/PageLoader"; -import { Table } from "components/common/table/Table/Table.styled"; -import TableHeaderCell from "components/common/table/TableHeaderCell/TableHeaderCell"; -import { TopicMessage } from "generated-sources"; -import React, { useState, useMemo } from "react"; -import { format } from "date-fns"; -import { Button } from "components/common/Button/Button"; -import * as S from "components/common/NewTable/Table.styled"; -import { usePaginateTopics, useIsLiveMode } from "lib/hooks/useMessagesFilters"; -import { useMessageFiltersStore } from "lib/hooks/useMessageFiltersStore"; -import useDataSaver from "lib/hooks/useDataSaver"; -import Select, { SelectOption } from "components/common/Select/Select"; - -import PreviewModal from "./PreviewModal"; -import Message, { PreviewFilter } from "./Message"; +import PageLoader from 'components/common/PageLoader/PageLoader'; +import { Table } from 'components/common/table/Table/Table.styled'; +import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell'; +import { TopicMessage } from 'generated-sources'; +import React, { useState, useMemo } from 'react'; +import { format } from 'date-fns'; +import { Button } from 'components/common/Button/Button'; +import * as S from 'components/common/NewTable/Table.styled'; +import { usePaginateTopics, useIsLiveMode } from 'lib/hooks/useMessagesFilters'; +import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; +import useDataSaver from 'lib/hooks/useDataSaver'; +import Select, { SelectOption } from 'components/common/Select/Select'; + +import PreviewModal from './PreviewModal'; +import Message, { PreviewFilter } from './Message'; export interface MessagesTableProps { messages: TopicMessage[]; @@ -28,11 +28,11 @@ interface MessageData { Timestamp: Date; } -type DownloadFormat = "json" | "csv"; +type DownloadFormat = 'json' | 'csv'; function padCurrentDateTimeString(): string { const now: Date = new Date(); - const dateTimeString: string = format(now, "yyyy-MM-dd HH:mm:ss"); + const dateTimeString: string = format(now, 'yyyy-MM-dd HH:mm:ss'); return `_${dateTimeString}`; } @@ -49,11 +49,11 @@ const MessagesTable: React.FC = ({ const nextCursor = useMessageFiltersStore((state) => state.nextCursor); const isLive = useIsLiveMode(); - const [selectedFormat, setSelectedFormat] = useState("json"); + const [selectedFormat, setSelectedFormat] = useState('json'); const formatOptions: SelectOption[] = [ - { label: "JSON", value: "json" }, - { label: "CSV", value: "csv" }, + { label: 'JSON', value: 'json' }, + { label: 'CSV', value: 'csv' }, ]; const baseFileName = `topic-messages${padCurrentDateTimeString()}`; @@ -70,31 +70,31 @@ const MessagesTable: React.FC = ({ const convertToCSV = useMemo(() => { return (messagesData: MessageData[]) => { const headers = [ - "Value", - "Offset", - "Key", - "Partition", - "Headers", - "Timestamp", + 'Value', + 'Offset', + 'Key', + 'Partition', + 'Headers', + 'Timestamp', ] as const; const rows = messagesData.map((msg) => headers .map((header) => { const value = msg[header]; - if (header === "Headers") { + if (header === 'Headers') { return JSON.stringify(value || {}); } - return String(value ?? ""); + return String(value ?? ''); }) - .join(","), + .join(','), ); - return [headers.join(","), ...rows].join("\n"); + return [headers.join(','), ...rows].join('\n'); }; }, []); const jsonSaver = useDataSaver( `${baseFileName}.json`, - JSON.stringify(savedMessagesJson, null, "\t"), + JSON.stringify(savedMessagesJson, null, '\t'), ); const csvSaver = useDataSaver( `${baseFileName}.csv`, @@ -106,7 +106,7 @@ const MessagesTable: React.FC = ({ }; const handleDownload = () => { - if (selectedFormat === "json") { + if (selectedFormat === 'json') { jsonSaver.saveFile(); } else { csvSaver.saveFile(); @@ -114,13 +114,13 @@ const MessagesTable: React.FC = ({ }; return ( -
+
@@ -146,10 +146,10 @@ const MessagesTable: React.FC = ({ {previewFor !== null && ( setPreviewFor(null)} setFilters={(payload: PreviewFilter[]) => - previewFor === "key" + previewFor === 'key' ? setKeyFilters(payload) : setContentFilters(payload) } @@ -165,18 +165,18 @@ const MessagesTable: React.FC = ({ setPreviewFor("key")} + onPreview={() => setPreviewFor('key')} /> setPreviewFor("content")} + onPreview={() => setPreviewFor('content')} /> @@ -189,7 +189,7 @@ const MessagesTable: React.FC = ({ message.timestamp, message.key, message.partition, - ].join("-")} + ].join('-')} message={message} keyFilters={keyFilters} contentFilters={contentFilters} From 578982d86de30f38d2f5a3a47f8d7fecb70638a4 Mon Sep 17 00:00:00 2001 From: alexanderlz Date: Sun, 5 Jan 2025 19:25:27 +0000 Subject: [PATCH 10/18] linter warnings fix (hopefully last) --- .../src/components/Topics/Topic/Messages/MessagesTable.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index d7acaa371..a3ee79623 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -86,7 +86,7 @@ const MessagesTable: React.FC = ({ } return String(value ?? ''); }) - .join(','), + .join(',') ); return [headers.join(','), ...rows].join('\n'); }; @@ -94,11 +94,11 @@ const MessagesTable: React.FC = ({ const jsonSaver = useDataSaver( `${baseFileName}.json`, - JSON.stringify(savedMessagesJson, null, '\t'), + JSON.stringify(savedMessagesJson, null, '\t') ); const csvSaver = useDataSaver( `${baseFileName}.csv`, - convertToCSV(savedMessagesJson), + convertToCSV(savedMessagesJson) ); const handleFormatSelect = (downloadFormat: DownloadFormat) => { @@ -226,4 +226,3 @@ const MessagesTable: React.FC = ({ }; export default MessagesTable; - From a5f925bcadf0be8a4411d5c7036ba2164ca42411 Mon Sep 17 00:00:00 2001 From: Alexander Leibzon Date: Wed, 12 Feb 2025 13:29:19 +0200 Subject: [PATCH 11/18] Update MessagesTable.tsx post merge syntax fix --- frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index 612274fd0..9482b4bd3 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -38,7 +38,7 @@ function padCurrentDateTimeString(): string { const dateTimeString: string = format(now, 'yyyy-MM-dd HH:mm:ss'); return `_${dateTimeString}`; - +} interface MessagePreviewProps { [key: string]: { keyFilters: PreviewFilter[]; From bff1aa02e8c072dd155d258e8b51796761a2da5b Mon Sep 17 00:00:00 2001 From: Alexander Leibzon Date: Wed, 12 Feb 2025 13:34:29 +0200 Subject: [PATCH 12/18] Update MessagesTable.tsx linter :-( --- .../src/components/Topics/Topic/Messages/MessagesTable.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index 9482b4bd3..98c0843b7 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -39,7 +39,8 @@ function padCurrentDateTimeString(): string { return `_${dateTimeString}`; } - interface MessagePreviewProps { + +interface MessagePreviewProps { [key: string]: { keyFilters: PreviewFilter[]; contentFilters: PreviewFilter[]; From f8aa58225084753096d50c3f1903a04a93a70bc5 Mon Sep 17 00:00:00 2001 From: Alexander Leibzon Date: Sun, 13 Jul 2025 18:58:57 +0000 Subject: [PATCH 13/18] redesign the export messages button look and feel --- .../Topics/Topic/Messages/Filters/Filters.tsx | 163 +++++++++++++++++- .../Topics/Topic/Messages/Messages.tsx | 2 + .../Topics/Topic/Messages/MessagesTable.tsx | 117 +------------ 3 files changed, 166 insertions(+), 116 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx index 926a38e35..64eab2f56 100644 --- a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx +++ b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx @@ -2,6 +2,7 @@ import 'react-datepicker/dist/react-datepicker.css'; import { SerdeUsage, TopicMessageConsuming } from 'generated-sources'; import React, { ChangeEvent, useMemo, useState } from 'react'; +import { format } from 'date-fns'; import MultiSelect from 'components/common/MultiSelect/MultiSelect.styled'; import Select from 'components/common/Select/Select'; import { Button } from 'components/common/Button/Button'; @@ -18,6 +19,7 @@ import EditIcon from 'components/common/Icons/EditIcon'; import CloseIcon from 'components/common/Icons/CloseIcon'; import FlexBox from 'components/common/FlexBox/FlexBox'; import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; +import useDataSaver from 'lib/hooks/useDataSaver'; import * as S from './Filters.styled'; import { @@ -30,11 +32,29 @@ import { import FiltersSideBar from './FiltersSideBar'; import FiltersMetrics from './FiltersMetrics'; +interface MessageData { + Value: string | undefined; + Offset: number; + Key: string | undefined; + Partition: number; + Headers: { [key: string]: string | undefined } | undefined; + Timestamp: Date; +} + +type DownloadFormat = 'json' | 'csv'; + +function padCurrentDateTimeString(): string { + const now: Date = new Date(); + const dateTimeString: string = format(now, 'yyyy-MM-dd HH:mm:ss'); + return `_${dateTimeString}`; +} + export interface FiltersProps { phaseMessage?: string; consumptionStats?: TopicMessageConsuming; isFetching: boolean; abortFetchData: () => void; + messages?: any[]; // Add messages prop for download functionality } const Filters: React.FC = ({ @@ -42,6 +62,7 @@ const Filters: React.FC = ({ isFetching, abortFetchData, phaseMessage, + messages = [], }) => { const { clusterName, topicName } = useAppParams(); @@ -69,6 +90,76 @@ const Filters: React.FC = ({ const [createdEditedSmartId, setCreatedEditedSmartId] = useState(); const remove = useMessageFiltersStore((state) => state.remove); + // Download functionality + const [selectedFormat, setSelectedFormat] = useState('json'); + const [showFormatSelector, setShowFormatSelector] = useState(false); + + const formatOptions = [ + { label: 'Export JSON', value: 'json' as DownloadFormat }, + { label: 'Export CSV', value: 'csv' as DownloadFormat }, + ]; + + const baseFileName = `topic-messages${padCurrentDateTimeString()}`; + + const savedMessagesJson: MessageData[] = messages.map((message) => ({ + Value: message.content, + Offset: message.offset, + Key: message.key, + Partition: message.partition, + Headers: message.headers, + Timestamp: message.timestamp, + })); + + const convertToCSV = useMemo(() => { + return (messagesData: MessageData[]) => { + const headers = [ + 'Value', + 'Offset', + 'Key', + 'Partition', + 'Headers', + 'Timestamp', + ] as const; + const rows = messagesData.map((msg) => + headers + .map((header) => { + const value = msg[header]; + if (header === 'Headers') { + return JSON.stringify(value || {}); + } + return String(value ?? ''); + }) + .join(',') + ); + return [headers.join(','), ...rows].join('\n'); + }; + }, []); + + const jsonSaver = useDataSaver( + `${baseFileName}.json`, + JSON.stringify(savedMessagesJson, null, '\t') + ); + const csvSaver = useDataSaver( + `${baseFileName}.csv`, + convertToCSV(savedMessagesJson) + ); + + const handleFormatSelect = (downloadFormat: DownloadFormat) => { + setSelectedFormat(downloadFormat); + setShowFormatSelector(false); + + // Automatically download after format selection + if (downloadFormat === 'json') { + jsonSaver.saveFile(); + } else { + csvSaver.saveFile(); + } + }; + + const handleDownloadClick = () => { + setShowFormatSelector(!showFormatSelector); + }; + const partitions = useMemo(() => { return (topic?.partitions || []).reduce<{ dict: Record; @@ -187,7 +278,76 @@ const Filters: React.FC = ({ - + + +
+ + {showFormatSelector && ( +
+ {formatOptions.map((option) => ( +
handleFormatSelect(option.value)} + style={{ + padding: '8px 12px', + cursor: 'pointer', + borderRadius: '4px', + fontSize: '12px', + }} + onMouseEnter={(e) => { + e.currentTarget.style.backgroundColor = '#f5f5f5'; + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = 'transparent'; + }} + > + {option.label} +
+ ))} +
+ )} +
+
= ({ }; export default Filters; + diff --git a/frontend/src/components/Topics/Topic/Messages/Messages.tsx b/frontend/src/components/Topics/Topic/Messages/Messages.tsx index cfa4b16bd..832d7748b 100644 --- a/frontend/src/components/Topics/Topic/Messages/Messages.tsx +++ b/frontend/src/components/Topics/Topic/Messages/Messages.tsx @@ -21,6 +21,7 @@ const Messages: React.FC = () => { isFetching={isFetching} phaseMessage={phase} abortFetchData={abortFetchData} + messages={messages} /> @@ -28,3 +29,4 @@ const Messages: React.FC = () => { }; export default Messages; + diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index 98c0843b7..f2737f15d 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -2,14 +2,11 @@ import PageLoader from 'components/common/PageLoader/PageLoader'; import { Table } from 'components/common/table/Table/Table.styled'; import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell'; import { TopicMessage } from 'generated-sources'; -import { format } from 'date-fns'; -import React, { useCallback, useEffect, useState, useMemo } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { Button } from 'components/common/Button/Button'; import * as S from 'components/common/NewTable/Table.styled'; import { usePaginateTopics, useIsLiveMode } from 'lib/hooks/useMessagesFilters'; import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; -import useDataSaver from 'lib/hooks/useDataSaver'; -import Select, { SelectOption } from 'components/common/Select/Select'; import useAppParams from 'lib/hooks/useAppParams'; import { RouteParamsClusterTopic } from 'lib/paths'; import { useLocalStorage } from 'lib/hooks/useLocalStorage'; @@ -22,24 +19,6 @@ export interface MessagesTableProps { isFetching: boolean; } -interface MessageData { - Value: string | undefined; - Offset: number; - Key: string | undefined; - Partition: number; - Headers: { [key: string]: string | undefined } | undefined; - Timestamp: Date; -} - -type DownloadFormat = 'json' | 'csv'; - -function padCurrentDateTimeString(): string { - const now: Date = new Date(); - const dateTimeString: string = format(now, 'yyyy-MM-dd HH:mm:ss'); - - return `_${dateTimeString}`; -} - interface MessagePreviewProps { [key: string]: { keyFilters: PreviewFilter[]; @@ -96,101 +75,8 @@ const MessagesTable: React.FC = ({ [previewFor, messagesPreview, topicName] ); - const [selectedFormat, setSelectedFormat] = useState('json'); - - const formatOptions: SelectOption[] = [ - { label: 'JSON', value: 'json' }, - { label: 'CSV', value: 'csv' }, - ]; - - const baseFileName = `topic-messages${padCurrentDateTimeString()}`; - - const savedMessagesJson: MessageData[] = messages.map((message) => ({ - Value: message.content, - Offset: message.offset, - Key: message.key, - Partition: message.partition, - Headers: message.headers, - Timestamp: message.timestamp, - })); - - const convertToCSV = useMemo(() => { - return (messagesData: MessageData[]) => { - const headers = [ - 'Value', - 'Offset', - 'Key', - 'Partition', - 'Headers', - 'Timestamp', - ] as const; - const rows = messagesData.map((msg) => - headers - .map((header) => { - const value = msg[header]; - if (header === 'Headers') { - return JSON.stringify(value || {}); - } - return String(value ?? ''); - }) - .join(',') - ); - return [headers.join(','), ...rows].join('\n'); - }; - }, []); - - const jsonSaver = useDataSaver( - `${baseFileName}.json`, - JSON.stringify(savedMessagesJson, null, '\t') - ); - const csvSaver = useDataSaver( - `${baseFileName}.csv`, - convertToCSV(savedMessagesJson) - ); - - const handleFormatSelect = (downloadFormat: DownloadFormat) => { - setSelectedFormat(downloadFormat); - }; - - const handleDownload = () => { - if (selectedFormat === 'json') { - jsonSaver.saveFile(); - } else { - csvSaver.saveFile(); - } - }; - return (
-
- - id="download-format" - name="download-format" - onChange={handleFormatSelect} - options={formatOptions} - value={selectedFormat} - minWidth="70px" - selectSize="M" - placeholder="Select format to download" - disabled={isFetching || messages.length === 0} - /> - -
- {previewFor !== null && ( = ({ }; export default MessagesTable; + From 38abcd0d62b14f7be21a7ab5c8496a4ad0b1250f Mon Sep 17 00:00:00 2001 From: Alexander Leibzon Date: Sun, 13 Jul 2025 19:15:43 +0000 Subject: [PATCH 14/18] redesign the export messages button look and feel, linter errors --- .../Topics/Topic/Messages/Filters/Filters.tsx | 32 ++++++++++++------- .../Topics/Topic/Messages/Messages.tsx | 1 - .../Topics/Topic/Messages/MessagesTable.tsx | 1 - 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx index 64eab2f56..1800ae68b 100644 --- a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx +++ b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx @@ -1,6 +1,6 @@ import 'react-datepicker/dist/react-datepicker.css'; -import { SerdeUsage, TopicMessageConsuming } from 'generated-sources'; +import { SerdeUsage, TopicMessageConsuming, TopicMessage } from 'generated-sources'; import React, { ChangeEvent, useMemo, useState } from 'react'; import { format } from 'date-fns'; import MultiSelect from 'components/common/MultiSelect/MultiSelect.styled'; @@ -54,7 +54,7 @@ export interface FiltersProps { consumptionStats?: TopicMessageConsuming; isFetching: boolean; abortFetchData: () => void; - messages?: any[]; // Add messages prop for download functionality + messages?: TopicMessage[]; } const Filters: React.FC = ({ @@ -88,10 +88,9 @@ const Filters: React.FC = ({ const { data: topic } = useTopicDetails({ clusterName, topicName }); const [createdEditedSmartId, setCreatedEditedSmartId] = useState(); - const remove = useMessageFiltersStore((state) => state.remove); + const remove = useMessageFiltersStore((state: { remove: (id: string) => void }) => state.remove); // Download functionality - const [selectedFormat, setSelectedFormat] = useState('json'); const [showFormatSelector, setShowFormatSelector] = useState(false); const formatOptions = [ @@ -101,7 +100,7 @@ const Filters: React.FC = ({ const baseFileName = `topic-messages${padCurrentDateTimeString()}`; - const savedMessagesJson: MessageData[] = messages.map((message) => ({ + const savedMessagesJson: MessageData[] = messages.map((message: TopicMessage) => ({ Value: message.content, Offset: message.offset, Key: message.key, @@ -145,9 +144,8 @@ const Filters: React.FC = ({ ); const handleFormatSelect = (downloadFormat: DownloadFormat) => { - setSelectedFormat(downloadFormat); setShowFormatSelector(false); - + // Automatically download after format selection if (downloadFormat === 'json') { jsonSaver.saveFile(); @@ -325,24 +323,35 @@ const Filters: React.FC = ({ }} > {formatOptions.map((option) => ( -
handleFormatSelect(option.value)} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + handleFormatSelect(option.value); + } + }} style={{ padding: '8px 12px', cursor: 'pointer', borderRadius: '4px', fontSize: '12px', + border: 'none', + background: 'transparent', + width: '100%', + textAlign: 'left', }} onMouseEnter={(e) => { - e.currentTarget.style.backgroundColor = '#f5f5f5'; + const target = e.currentTarget; + target.style.backgroundColor = '#f5f5f5'; }} onMouseLeave={(e) => { - e.currentTarget.style.backgroundColor = 'transparent'; + const target = e.currentTarget; + target.style.backgroundColor = 'transparent'; }} > {option.label} -
+ ))}
)} @@ -405,4 +414,3 @@ const Filters: React.FC = ({ }; export default Filters; - diff --git a/frontend/src/components/Topics/Topic/Messages/Messages.tsx b/frontend/src/components/Topics/Topic/Messages/Messages.tsx index 832d7748b..7affea841 100644 --- a/frontend/src/components/Topics/Topic/Messages/Messages.tsx +++ b/frontend/src/components/Topics/Topic/Messages/Messages.tsx @@ -29,4 +29,3 @@ const Messages: React.FC = () => { }; export default Messages; - diff --git a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx index f2737f15d..1751a0e56 100644 --- a/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx +++ b/frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx @@ -155,4 +155,3 @@ const MessagesTable: React.FC = ({ }; export default MessagesTable; - From 66c67ee8d912b3f9ef7e9cf2b5eb1f82d333dcdf Mon Sep 17 00:00:00 2001 From: Alexander Leibzon Date: Sun, 13 Jul 2025 19:28:16 +0000 Subject: [PATCH 15/18] redesign the export messages button look and feel, linter errors #2 --- .../Topics/Topic/Messages/Filters/Filters.tsx | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx index 1800ae68b..502025d34 100644 --- a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx +++ b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx @@ -1,6 +1,10 @@ import 'react-datepicker/dist/react-datepicker.css'; -import { SerdeUsage, TopicMessageConsuming, TopicMessage } from 'generated-sources'; +import { + SerdeUsage, + TopicMessageConsuming, + TopicMessage, +} from 'generated-sources'; import React, { ChangeEvent, useMemo, useState } from 'react'; import { format } from 'date-fns'; import MultiSelect from 'components/common/MultiSelect/MultiSelect.styled'; @@ -54,7 +58,7 @@ export interface FiltersProps { consumptionStats?: TopicMessageConsuming; isFetching: boolean; abortFetchData: () => void; - messages?: TopicMessage[]; + messages?: TopicMessage[]; } const Filters: React.FC = ({ @@ -88,7 +92,9 @@ const Filters: React.FC = ({ const { data: topic } = useTopicDetails({ clusterName, topicName }); const [createdEditedSmartId, setCreatedEditedSmartId] = useState(); - const remove = useMessageFiltersStore((state: { remove: (id: string) => void }) => state.remove); + const remove = useMessageFiltersStore( + (state: { remove: (id: string) => void }) => state.remove + ); // Download functionality const [showFormatSelector, setShowFormatSelector] = useState(false); @@ -100,14 +106,16 @@ const Filters: React.FC = ({ const baseFileName = `topic-messages${padCurrentDateTimeString()}`; - const savedMessagesJson: MessageData[] = messages.map((message: TopicMessage) => ({ - Value: message.content, - Offset: message.offset, - Key: message.key, - Partition: message.partition, - Headers: message.headers, - Timestamp: message.timestamp, - })); + const savedMessagesJson: MessageData[] = messages.map( + (message: TopicMessage) => ({ + Value: message.content, + Offset: message.offset, + Key: message.key, + Partition: message.partition, + Headers: message.headers, + Timestamp: message.timestamp, + }) + ); const convertToCSV = useMemo(() => { return (messagesData: MessageData[]) => { @@ -305,7 +313,8 @@ const Filters: React.FC = ({ - Export + {' '} + Export {showFormatSelector && (
= ({ {formatOptions.map((option) => ( From 72cc645d79cc0922492c14973b0c467e0b9aedce Mon Sep 17 00:00:00 2001 From: Alexander Leibzon Date: Sat, 2 Aug 2025 17:40:00 +0300 Subject: [PATCH 18/18] linter warning --- .../Topics/Topic/Messages/Filters/Filters.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx index c6009c0e3..b01d88b0c 100644 --- a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx +++ b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx @@ -303,14 +303,11 @@ const Filters: React.FC = ({ - + + {' '} Export