Skip to content

Commit

Permalink
Merge pull request #34 from polarising-oss/AKHQ-84-Routing-Not-Working
Browse files Browse the repository at this point in the history
AKHQ-84 - Routing not working
  • Loading branch information
lyudmylatodoriko authored Feb 24, 2020
2 parents 0ab4ae5 + 82c0eda commit d6fcf76
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 6 deletions.
261 changes: 261 additions & 0 deletions client/src/containers/Tab/Tabs/TopicList/TopicList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
import React from 'react';
import { Link } from 'react-router-dom';

import Header from '../../../Header';
import SearchBar from '../../../../components/SearchBar';
import Pagination from '../../../../components/Pagination';
import Tab from '../../Tab';
import ConfirmModal from '../../../../components/Modal/ConfirmModal';
import { getTopics, deleteTopic } from '../../../../utils/FakeTopicService';

// Adaptation of topicList.ftl

class TopicList extends Tab {
state = {
topics: [],
showDeleteModal: false,
deleteMessage: '',
deleteData: {}
};

componentDidMount() {
const topics = getTopics();
this.setState({
topics
});
}

showDeleteModal = (deleteMessage, deleteData) => {
this.setState({ showDeleteModal: true, deleteMessage, deleteData });
};

closeDeleteModal = () => {
this.setState({ showDeleteModal: false, deleteMessage: '', deleteData: {} });
};

deleteTopic = () => {
const { clusterId, topic } = this.state.deleteData;
deleteTopic(clusterId, topic.name);
this.closeDeleteModal();

this.props.history.push({
pathname: `/${clusterId}/topic`,
showSuccessToast: true,
successToastMessage: `Topic '${topic.name}' is deleted`
});
};

renderTopics() {
const { topics } = this.state;
const { clusterId } = this.props.match.params;

if (topics.length === 0) {
return (
<tr>
<td colSpan="9">
<div className="alert alert-info mb-0" role="alert">
No topic available
</div>
</td>
</tr>
);
}

let renderedTopics = [];
for (let topic of topics) {
topic.size = 0;
topic.logDirSize = 0;

renderedTopics.push(
<tr key={topic._id}>
<td>{topic.name}</td>
<td>
<span className="text-nowrap">{topic.size}</span>
</td>
<td>{topic.logDirSize ? 'n/a' : topic.logDirSize}</td>
<td>{topic.partition}</td>
<td>{topic.replication}</td>
<td>
<span
// className="${(topic.getReplicaCount() > topic.getInSyncReplicaCount())?then(" text-warning"
>
{topic.replication}
</span>
</td>
<td></td>
{/*<#if skipConsumerGroups == false>
<td>
<
#list topic.getConsumerGroups() as group>
<
#assign active=group.isActiveTopic(topic.getName()) >
<a href="${basePath}/${clusterId}/group/${group.getId()}" className="btn btn-sm mb-1
btn-${active ? then("success", "warning")} ">
${group.getId()}
<span className="badge badge-light">
Lag: ${group.getOffsetLag(topic.getName())}
</span>
</a>
<br/>
</#list>
</td>
{/#if*/}
<td className="khq-row-action khq-row-action-main">
{/* <a href="${basePath}/${clusterId}/topic/${topic.getName()}${roles?seq_contains("*/}
{/*topic/data/read")?then("", "/partitions")}" */}
<Link to={`/${clusterId}/topic/${topic.name}`}>
<i className="fa fa-search" />
</Link>
</td>
{/*<#if canDelete == true>*/}
<td className="khq-row-action">
{/*<#if topic.isInternal() == false>*/}
<Link
to="#"
onClick={() =>
this.showDeleteModal(`Do you want to delete topic: ${topic.name}`, {
clusterId: clusterId,
topic: topic
})
}
// href="${basePath}/${clusterId}/topic/${topic.getName()}/delete"
//data-confirm="Do you want to delete topic: <code>${topic.getName()}</code> ?"
>
<i className="fa fa-trash" />
</Link>
{/*</#if>*/}
</td>
{/*</#if>*/}
</tr>
);
}

return renderedTopics;
}

render() {
const { topics } = this.state;
const { clusterId } = this.props.match.params;

return (
<div id="content">
<Header title="Topics" />
<SearchBar pagination={true} topicListView={true} />
<div className="table-responsive">
<table className="table table-bordered table-striped table-hover mb-0">
<thead className="thead-dark">
<tr>
<th colSpan="3">Topics</th>
<th colSpan="1">Partitions</th>
<th colSpan="2">Replications</th>
{/*<#if skipConsumerGroups== false>*/}
<th>Consumers Groups</th>
{/*</#if>*/}
<th colSpan="2" className="khq-row-action" />
</tr>
</thead>
<thead className="thead-dark">
<tr>
<th className="text-nowrap">Name</th>
<th className="text-nowrap">Size</th>
<th className="text-nowrap">Weight</th>
<th className="text-nowrap">Total</th>
<th className="text-nowrap">Factor</th>
<th className="text-nowrap">In Sync</th>
{/*<#if skipConsumerGroups== false>*/}
<th className="text-nowrap">Consumer Groups</th>
{/*</#if>*/}
<th className="khq-row-action"></th>
{/*<#if canDelete== true>*/}
<th className="khq-row-action"></th>
{/*</#if>*/}
</tr>
</thead>
<tbody>
{/*#if topics?size == 0*/}
{this.renderTopics()}
{/*</#if>
<#list topics as topic>
<tr>
<td>${topic.getName()}</td>
<td>
<span className="text-nowrap">
≈ ${topic.getSize()}
</span>
</td>
<td>
#if topic.getLogDirSize().isEmpty()
n/a
<#else>
${functions.filesize(topic.getLogDirSize().get())}
</#if>
</td>
<td>${topic.getPartitions() ? size}</td>
<td>${topic.getReplicaCount()}</td>
<td><span className="${(topic.getReplicaCount() > topic.getInSyncReplicaCount())?then("
text-warning", "")}">${topic.getInSyncReplicaCount()}</span></td>
<#if skipConsumerGroups == false>
<td>
<
#list topic.getConsumerGroups() as group>
<
#assign active=group.isActiveTopic(topic.getName()) >
<a href="${basePath}/${clusterId}/group/${group.getId()}" className="btn btn-sm mb-1
btn-${active ? then("success", "warning")} ">
${group.getId()}
<span className="badge badge-light">
Lag: ${group.getOffsetLag(topic.getName())}
</span>
</a>
<br/>
</#list>
</td>
</#if>
<td className="khq-row-action khq-row-action-main">
<a href="${basePath}/${clusterId}/topic/${topic.getName()}${roles?seq_contains("
topic/data/read")?then("", "/partitions")}" ><i className="fa fa-search"></i></a>
</td>
<#if canDelete == true>
<td className="khq-row-action">
<
#if topic.isInternal() == false>
<a
href="${basePath}/${clusterId}/topic/${topic.getName()}/delete"
data-confirm="Do you want to delete topic: <code>${topic.getName()}</code> ?"
><i className="fa fa-trash"></i></a>
</#if>
</td>
</#if>
</tr>
</#list>*/}
</tbody>
</table>
</div>

<Pagination />

{/*#if roles?seq_contains("topic/insert") == true*/}
<aside>
<Link
to={{
pathname: `/${clusterId}/topic/create`
}}
className="btn btn-primary"
>
Create a topic
</Link>
</aside>
{/*</#if>*/}

<ConfirmModal
show={this.state.showDeleteModal}
handleCancel={this.closeDeleteModal}
handleConfirm={this.deleteTopic}
message={this.state.deleteMessage}
/>
</div>
);
}
}

export default TopicList;
10 changes: 4 additions & 6 deletions client/src/containers/TopicList/TopicCreate/TopicCreate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ class TopicCreate extends Form {
state = {
formData: {
name: '',
partition: 0,
replication: 0,
partition: 1,
replication: 1,
cleanup: 'delete',
retention: 0
retention: 86400000
},
errors: {}
};
Expand All @@ -32,9 +32,7 @@ class TopicCreate extends Form {
retention: Joi.number().label('Retention')
};

componentDidMount() {
this.setState({ formData: this.props.location.state.formData });
}
componentDidMount() {}

onCleanupChange = value => {
let { formData } = { ...this.state };
Expand Down
1 change: 1 addition & 0 deletions client/src/utils/endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const uriTopics = (id, view, search) => {
: 'topicsByType?clusterId=' + id + '&view=' + view
} `;
};

export const uriNodesConfigs = (clusterId, nodeId) => {
return (
`${apiUrl}/cluster/nodes/configs${clusterId ? '?clusterId=' + clusterId : ''}` +
Expand Down

0 comments on commit d6fcf76

Please sign in to comment.