Skip to content

FE: Messages: Implement messages export #740

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

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Changes from 2 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
102 changes: 102 additions & 0 deletions frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
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';

Check failure on line 11 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

'components/common/Select/Select' imported multiple times
import { SelectOption } from 'components/common/Select/Select';

Check failure on line 12 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

'components/common/Select/Select' imported multiple times

import PreviewModal from './PreviewModal';
import Message, { PreviewFilter } from './Message';
Expand All @@ -16,6 +19,33 @@
isFetching: boolean;
}

interface MessageData {
Value: string | undefined;
Offset: number;
Key: string | undefined;
Partition: number;
Headers: { [key: string]: string | undefined; } | undefined;

Check warning on line 27 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Delete `;`
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}`;
}


Check warning on line 48 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Delete `⏎`
const MessagesTable: React.FC<MessagesTableProps> = ({
messages,
isFetching,
Expand All @@ -28,8 +58,80 @@
const nextCursor = useMessageFiltersStore((state) => state.nextCursor);
const isLive = useIsLiveMode();

const [selectedFormat, setSelectedFormat] = useState<DownloadFormat>('json');

const formatOptions: SelectOption<DownloadFormat>[] = [
{ label: 'JSON', value: 'json' },
{ label: 'CSV', value: 'csv' }

Check warning on line 65 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Insert `,`
];

const handleFormatSelect = (format: DownloadFormat) => {
setSelectedFormat(format);
};

const handleDownload = () => {

Check warning on line 73 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Replace `⏎··const·savedMessagesJson:·MessageData[]·=·messages.map(message` with `····const·savedMessagesJson:·MessageData[]·=·messages.map((message)`
const savedMessagesJson: MessageData[] = messages.map(message => ({
Value: message.content,

Check warning on line 75 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Replace `····` with `······`
Offset: message.offset,

Check warning on line 76 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Insert `··`
Key: message.key,

Check warning on line 77 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Replace `····` with `······`
Partition: message.partition,

Check warning on line 78 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Insert `··`
Headers: message.headers,

Check warning on line 79 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Replace `····` with `······`
Timestamp: message.timestamp,

Check warning on line 80 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Insert `··`
}));

const convertToCSV = (messages: MessageData[]) => {

Check failure on line 83 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

'messages' is already declared in the upper scope on line 50 column 3
const headers = ['Value', 'Offset', 'Key', 'Partition', 'Headers', 'Timestamp'] as const;
type Header = typeof headers[number];

Check failure on line 85 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

'Header' is defined but never used

Check failure on line 85 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

'Header' is defined but never used

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();

Check failure on line 100 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Unexpected string concatenation
const jsonSaver = useDataSaver(baseFileName+'.json', JSON.stringify(savedMessagesJson, null, '\t'));

Check failure on line 101 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

React Hook "useDataSaver" is called in function "handleDownload" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use"

Check failure on line 101 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Unexpected string concatenation
const csvSaver = useDataSaver(baseFileName+'.csv', convertToCSV(savedMessagesJson));

Check failure on line 102 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

React Hook "useDataSaver" is called in function "handleDownload" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use"

Check failure on line 102 in frontend/src/components/Topics/Topic/Messages/MessagesTable.tsx

View workflow job for this annotation

GitHub Actions / build / build-and-test

Unexpected string concatenation

if (selectedFormat === 'json') {
jsonSaver.saveFile();
} else {
csvSaver.saveFile();
}
};

return (
<div style={{ position: 'relative' }}>
<div style={{ display: 'flex', gap: '8px', marginLeft: '1rem', marginBottom: '1rem' }}>
<Select<DownloadFormat>
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}
/>
<Button
disabled={isFetching || messages.length === 0}
buttonType="secondary"
buttonSize="M"
onClick={handleDownload}
>
Download All Messages
</Button>
</div>

{previewFor !== null && (
<PreviewModal
values={previewFor === 'key' ? keyFilters : contentFilters}
Expand Down
Loading