Skip to content

Commit

Permalink
feat(ui): download all messages in a topic to a csv file (#1384)
Browse files Browse the repository at this point in the history
close #1183

Co-authored-by: rochelle <[email protected]>
  • Loading branch information
2 people authored and tchiotludo committed Apr 4, 2023
1 parent 07bb5f9 commit 1ac763c
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 4 deletions.
19 changes: 17 additions & 2 deletions client/src/components/Table/Table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class Table extends Component {
};

renderHeader() {
const { has2Headers, firstHeader, columns, actions, data } = this.props;
const { has2Headers, firstHeader, columns, actions, data, loading, updateCheckbox, isChecked } =
this.props;
return (
<>
{has2Headers && (
Expand Down Expand Up @@ -74,7 +75,19 @@ class Table extends Component {
return (
<th className="header-text" key={`secondHead${column.colName}${index}`}>
<div className="header-content">
{column.colName}
{!loading && data && data.length > 0 && column.id === 'checkboxes' ? (
<>
<input
type="checkbox"
checked={isChecked}
onChange={e => {
updateCheckbox(e);
}}
/>
</>
) : (
column.colName
)}
{column.sortable && (
<i
className="fa fa-sort clickable"
Expand Down Expand Up @@ -535,6 +548,7 @@ class Table extends Component {
Table.propTypes = {
title: PropTypes.string,
has2Headers: PropTypes.bool,
isChecked: PropTypes.bool,
firstHeader: PropTypes.arrayOf(
PropTypes.shape({
colName: PropTypes.string,
Expand Down Expand Up @@ -562,6 +576,7 @@ Table.propTypes = {
onRestart: PropTypes.func,
onShare: PropTypes.func,
onDownload: PropTypes.func,
updateCheckbox: PropTypes.func,
onCopy: PropTypes.func,

idCol: PropTypes.string,
Expand Down
74 changes: 72 additions & 2 deletions client/src/containers/Topic/Topic/Topic.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import Header from '../../Header';
import Dropdown from 'react-bootstrap/Dropdown';
import TopicData from './TopicData';
import TopicPartitions from './TopicPartitions';
import TopicGroups from './TopicGroups';
Expand All @@ -24,14 +25,19 @@ class Topic extends Root {
compactMessageToDelete: '',
roles: JSON.parse(sessionStorage.getItem('roles')),
topicInternal: false,
configs: []
configs: [],
isAllTopicDataSelected: false,
downloadFormat: 'Select',
downloadOptions: ['Select', 'csv', 'json'],
messages: []
};

tabs = ['data', 'partitions', 'groups', 'configs', 'acls', 'logs'];

constructor(props) {
super(props);
this.topicData = React.createRef();
this._handleSelectAllCheckboxChange = this._handleSelectAllCheckboxChange.bind(this);
}

static getDerivedStateFromProps(props, state) {
Expand Down Expand Up @@ -73,6 +79,51 @@ class Topic extends Root {
});
}

_handleSelectAllCheckboxChange = (isAllTopicDataSelected, messages) => {
this.setState({ isAllTopicDataSelected: isAllTopicDataSelected, messages: messages });
};

_renderDownloadFormat = isChecked => {
const { downloadOptions } = this.state;

let renderedOptions = [];
for (let option of downloadOptions) {
renderedOptions.push(
<Dropdown.Item
key={option}
se
disabled={isChecked === false}
onClick={() =>
this.setState({ downloadFormat: option }, () => {
this._handleDownloadAll(option);
})
}
>
<i className="fa fa-fw pull-left" aria-hidden="true" /> {option}
</Dropdown.Item>
);
}
return renderedOptions;
};

_handleDownloadAll(option) {
let messages = this.state.messages;
if (this.state.isAllTopicDataSelected && option !== 'Select') {
let allData = [];
messages.map(tableData => {
allData.push(tableData.value);
allData.push('\n');
});
const a = document.createElement('a');
const type = 'text/' + option;
a.href = URL.createObjectURL(new Blob([allData], { type: type }));
a.download = `file.${option}`;

a.click();
a.remove();
}
}

showDeleteModal = deleteMessage => {
this.setState({ showDeleteModal: true, deleteMessage });
};
Expand Down Expand Up @@ -136,7 +187,14 @@ class Topic extends Root {
switch (selectedTab) {
case 'data':
return (
<TopicData ref={this.topicData} history={history} match={match} location={location} />
<TopicData
ref={this.topicData}
history={history}
match={match}
location={location}
isAllTopicDataSelected={this.state.isAllTopicDataSelected}
onSelectAllCheckboxChange={this._handleSelectAllCheckboxChange}
/>
);
case 'partitions':
return <TopicPartitions clusterId={clusterId} topic={topicId} history={history} />;
Expand Down Expand Up @@ -236,6 +294,18 @@ class Topic extends Root {
{selectedTab !== 'configs' && roles.topic && roles.topic['topic/data/insert'] && (
<aside>
<li className="aside-button">
{this.state.isAllTopicDataSelected && (
<div className="btn mr-2">
<Dropdown>
<Dropdown.Toggle>
<strong>Download Format:</strong> ({this.state.downloadFormat})
</Dropdown.Toggle>
<Dropdown.Menu>
<div>{this._renderDownloadFormat(this.state.isAllTopicDataSelected)}</div>
</Dropdown.Menu>
</Dropdown>
</div>
)}
{this.canEmptyTopic() ? (
<div
onClick={() => {
Expand Down
26 changes: 26 additions & 0 deletions client/src/containers/Topic/Topic/TopicData/TopicData.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ class TopicData extends Root {

eventSource;

constructor(props) {
super(props);
this._handleCheckbox = this._handleCheckbox.bind(this);
}

componentDidMount = () => {
this._checkProps();
};
Expand Down Expand Up @@ -405,6 +410,10 @@ class TopicData extends Root {
a.remove();
}

_handleCheckbox(e) {
this.props.onSelectAllCheckboxChange(e.target.checked, this.state.messages);
}

async _handleOnDateTimeFormatChanged(newDateTimeFormat) {
const { clusterId } = this.props.match.params;
this.setState({
Expand Down Expand Up @@ -949,7 +958,21 @@ class TopicData extends Root {
history={history}
reduce={true}
firstHeader={firstColumns}
isChecked={this.props.isAllTopicDataSelected}
columns={[
{
id: 'checkboxes',
accessor: 'checkboxes',
colName: 'Download all',
type: 'checkbox',
expand: true,
cell: () => {
return (
<input type="checkbox" checked={this.props.isAllTopicDataSelected} readOnly />
);
},
readOnly: true
},
{
id: 'key',
accessor: 'key',
Expand Down Expand Up @@ -1093,6 +1116,9 @@ class TopicData extends Root {
updateData={data => {
this.setState({ messages: data });
}}
updateCheckbox={e => {
this._handleCheckbox(e);
}}
onDelete={row => {
this._handleOnDelete(row);
}}
Expand Down

0 comments on commit 1ac763c

Please sign in to comment.