use cluster name instead of cluster id
This commit is contained in:
parent
01c2c8b20b
commit
8b64575bd5
34 changed files with 224 additions and 234 deletions
|
@ -16,11 +16,8 @@ public class ClustersProperties {
|
|||
|
||||
@Data
|
||||
public static class Cluster {
|
||||
String id;
|
||||
String name;
|
||||
String bootstrapServers;
|
||||
String jmxHost;
|
||||
String jmxPort;
|
||||
String zookeeper;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,13 @@ import org.mapstruct.factory.Mappers;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ClustersStorage {
|
||||
|
||||
private final List<KafkaCluster> kafkaClusters = new ArrayList<>();
|
||||
private final Map<String, KafkaCluster> kafkaClusters = new HashMap<>();
|
||||
|
||||
private final ClustersProperties clusterProperties;
|
||||
|
||||
|
@ -23,18 +22,18 @@ public class ClustersStorage {
|
|||
@PostConstruct
|
||||
public void init() {
|
||||
for (ClustersProperties.Cluster clusterProperties : clusterProperties.getClusters()) {
|
||||
kafkaClusters.add(clusterMapper.toKafkaCluster(clusterProperties));
|
||||
if (kafkaClusters.get(clusterProperties.getName()) != null) {
|
||||
throw new IllegalStateException("Application config isn't correct. Two clusters can't have the same name");
|
||||
}
|
||||
kafkaClusters.put(clusterProperties.getName(), clusterMapper.toKafkaCluster(clusterProperties));
|
||||
}
|
||||
}
|
||||
|
||||
public List<KafkaCluster> getKafkaClusters() {
|
||||
return kafkaClusters;
|
||||
public Collection<KafkaCluster> getKafkaClusters() {
|
||||
return kafkaClusters.values();
|
||||
}
|
||||
|
||||
public KafkaCluster getClusterById(String clusterId) {
|
||||
return kafkaClusters.stream()
|
||||
.filter(cluster -> cluster.getId() != null && cluster.getId().equals(clusterId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
public KafkaCluster getClusterByName(String clusterName) {
|
||||
return kafkaClusters.get(clusterName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,32 +29,32 @@ public class ClusterService {
|
|||
return Mono.just(ResponseEntity.ok(Flux.fromIterable(clusters)));
|
||||
}
|
||||
|
||||
public Mono<ResponseEntity<BrokersMetrics>> getBrokersMetrics(String clusterId) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterById(clusterId);
|
||||
public Mono<ResponseEntity<BrokersMetrics>> getBrokersMetrics(String name) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterByName(name);
|
||||
if (cluster == null) return null;
|
||||
return Mono.just(ResponseEntity.ok(cluster.getBrokersMetrics()));
|
||||
}
|
||||
|
||||
public Mono<ResponseEntity<Flux<Topic>>> getTopics(String clusterId) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterById(clusterId);
|
||||
public Mono<ResponseEntity<Flux<Topic>>> getTopics(String name) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterByName(name);
|
||||
if (cluster == null) return null;
|
||||
return Mono.just(ResponseEntity.ok(Flux.fromIterable(cluster.getTopics())));
|
||||
}
|
||||
|
||||
public Mono<ResponseEntity<TopicDetails>> getTopicDetails(String clusterId, String topicName) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterById(clusterId);
|
||||
public Mono<ResponseEntity<TopicDetails>> getTopicDetails(String name, String topicName) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterByName(name);
|
||||
if (cluster == null) return null;
|
||||
return Mono.just(ResponseEntity.ok(cluster.getOrCreateTopicDetails(topicName)));
|
||||
}
|
||||
|
||||
public Mono<ResponseEntity<Flux<TopicConfig>>> getTopicConfigs(String clusterId, String topicName) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterById(clusterId);
|
||||
public Mono<ResponseEntity<Flux<TopicConfig>>> getTopicConfigs(String name, String topicName) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterByName(name);
|
||||
if (cluster == null) return null;
|
||||
return Mono.just(ResponseEntity.ok(Flux.fromIterable(cluster.getTopicConfigsMap().get(topicName))));
|
||||
}
|
||||
|
||||
public Mono<ResponseEntity<Topic>> createTopic(String clusterId, Mono<TopicFormData> topicFormData) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterById(clusterId);
|
||||
public Mono<ResponseEntity<Topic>> createTopic(String name, Mono<TopicFormData> topicFormData) {
|
||||
KafkaCluster cluster = clustersStorage.getClusterByName(name);
|
||||
if (cluster == null) return null;
|
||||
return kafkaService.createTopic(cluster, topicFormData);
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ public class KafkaService {
|
|||
}
|
||||
|
||||
private Topic collectTopicData(KafkaCluster kafkaCluster, TopicDescription topicDescription) {
|
||||
var topic = new Topic().clusterId(kafkaCluster.getId());
|
||||
var topic = new Topic();
|
||||
topic.setInternal(topicDescription.isInternal());
|
||||
topic.setName(topicDescription.name());
|
||||
|
||||
|
|
|
@ -30,14 +30,14 @@ paths:
|
|||
items:
|
||||
$ref: '#/components/schemas/Cluster'
|
||||
|
||||
/api/clusters/{clusterId}/brokers:
|
||||
/api/clusters/{clusterName}/brokers:
|
||||
get:
|
||||
tags:
|
||||
- /api/clusters
|
||||
summary: getBrokers
|
||||
operationId: getBrokers
|
||||
parameters:
|
||||
- name: clusterId
|
||||
- name: clusterName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -52,14 +52,14 @@ paths:
|
|||
items:
|
||||
$ref: '#/components/schemas/Broker'
|
||||
|
||||
/api/clusters/{clusterId}/metrics/broker:
|
||||
/api/clusters/{clusterName}/metrics/broker:
|
||||
get:
|
||||
tags:
|
||||
- /api/clusters
|
||||
summary: getBrokersMetrics
|
||||
operationId: getBrokersMetrics
|
||||
parameters:
|
||||
- name: clusterId
|
||||
- name: clusterName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -72,14 +72,14 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/BrokersMetrics'
|
||||
|
||||
/api/clusters/{clusterId}/topics:
|
||||
/api/clusters/{clusterName}/topics:
|
||||
get:
|
||||
tags:
|
||||
- /api/clusters
|
||||
summary: getTopics
|
||||
operationId: getTopics
|
||||
parameters:
|
||||
- name: clusterId
|
||||
- name: clusterName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -99,7 +99,7 @@ paths:
|
|||
summary: createTopic
|
||||
operationId: createTopic
|
||||
parameters:
|
||||
- name: clusterId
|
||||
- name: clusterName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -117,14 +117,14 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/Topic'
|
||||
|
||||
/api/clusters/{clusterId}/topics/{topicName}:
|
||||
/api/clusters/{clusterName}/topics/{topicName}:
|
||||
get:
|
||||
tags:
|
||||
- /api/clusters
|
||||
summary: getTopicDetails
|
||||
operationId: getTopicDetails
|
||||
parameters:
|
||||
- name: clusterId
|
||||
- name: clusterName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -142,14 +142,14 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/TopicDetails'
|
||||
|
||||
/api/clusters/{clusterId}/topics/{topicName}/config:
|
||||
/api/clusters/{clusterName}/topics/{topicName}/config:
|
||||
get:
|
||||
tags:
|
||||
- /api/clusters
|
||||
summary: getTopicConfigs
|
||||
operationId: getTopicConfigs
|
||||
parameters:
|
||||
- name: clusterId
|
||||
- name: clusterName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -228,8 +228,6 @@ components:
|
|||
Topic:
|
||||
type: object
|
||||
properties:
|
||||
clusterId:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
internal:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const jsonServer = require('json-server');
|
||||
const _ = require('lodash');
|
||||
const clusters = require('./payload/clusters.json');
|
||||
const brokers = require('./payload/brokers.json');
|
||||
const brokerMetrics = require('./payload/brokerMetrics.json');
|
||||
|
@ -8,13 +7,13 @@ const topicDetails = require('./payload/topicDetails.json');
|
|||
const topicConfigs = require('./payload/topicConfigs.json');
|
||||
|
||||
const db = {
|
||||
clusters,
|
||||
brokers,
|
||||
brokerMetrics: brokerMetrics.map(({ clusterId, ...rest }) => ({ ...rest, id: clusterId })),
|
||||
topics: topics.map((topic) => ({ ...topic, id: topic.name })),
|
||||
topicDetails,
|
||||
topicConfigs,
|
||||
}
|
||||
clusters,
|
||||
brokers,
|
||||
brokerMetrics: brokerMetrics.map(({clusterName, ...rest}) => ({...rest, id: clusterName})),
|
||||
topics: topics.map((topic) => ({...topic, id: topic.name})),
|
||||
topicDetails,
|
||||
topicConfigs,
|
||||
};
|
||||
const server = jsonServer.create();
|
||||
const router = jsonServer.router(db);
|
||||
const middlewares = jsonServer.defaults();
|
||||
|
@ -29,11 +28,10 @@ server.use((_req, _res, next) => {
|
|||
|
||||
server.use(
|
||||
jsonServer.rewriter({
|
||||
'/*': '/$1',
|
||||
'/clusters/:clusterId/metrics/broker': '/brokerMetrics/:clusterId',
|
||||
'/clusters/:clusterId/topics/:id': '/topicDetails',
|
||||
'/clusters/:clusterId/topics/:id/config': '/topicDetails',
|
||||
'/clusters/:clusterId/topics/:id/config': '/topicConfigs',
|
||||
'/api/*': '/$1',
|
||||
'/clusters/:clusterName/metrics/broker': '/brokerMetrics/:clusterName',
|
||||
'/clusters/:clusterName/topics/:id': '/topicDetails',
|
||||
'/clusters/:clusterName/topics/:id/config': '/topicConfigs',
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[
|
||||
{
|
||||
"clusterId": "wrYGf-csNgiGdK7B_ADF7Z",
|
||||
"clusterName": "fake.cluster",
|
||||
"bytesInPerSec": 8027,
|
||||
"brokerCount": 1,
|
||||
"zooKeeperStatus": 1,
|
||||
|
@ -20,7 +20,7 @@
|
|||
"diskUsageDistribution": "even"
|
||||
},
|
||||
{
|
||||
"clusterId": "dMMQx-WRh77BKYas_g2ZTz",
|
||||
"clusterName": "kafka-ui.cluster",
|
||||
"bytesInPerSec": 8194,
|
||||
"brokerCount": 1,
|
||||
"zooKeeperStatus": 1,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[
|
||||
{
|
||||
"brokerId": 1,
|
||||
"clusterId": "wrYGf-csNgiGdK7B_ADF7Z",
|
||||
"name": "fake.cluster",
|
||||
"bytesInPerSec": 1234,
|
||||
"bytesOutPerSec": 3567,
|
||||
"segmentSize": 912360707,
|
||||
|
@ -9,7 +9,7 @@
|
|||
},
|
||||
{
|
||||
"brokerId": 2,
|
||||
"clusterId": "dMMQx-WRh77BKYas_g2ZTz",
|
||||
"name": "kafka-ui.cluster",
|
||||
"bytesInPerSec": 9194,
|
||||
"bytesOutPerSec": 7924,
|
||||
"segmentSize": 840060707,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[
|
||||
{
|
||||
"id": "wrYGf-csNgiGdK7B_ADF7Z",
|
||||
"id": "fake.cluster",
|
||||
"name": "fake.cluster",
|
||||
"defaultCluster": true,
|
||||
"status": "online",
|
||||
|
@ -11,7 +11,7 @@
|
|||
"bytesOutPerSec": 4320
|
||||
},
|
||||
{
|
||||
"id": "dMMQx-WRh77BKYas_g2ZTz",
|
||||
"id": "kafka-ui.cluster",
|
||||
"name": "kafka-ui.cluster",
|
||||
"defaultCluster": false,
|
||||
"status": "offline",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[
|
||||
{
|
||||
"clusterId": "wrYGf-csNgiGdK7B_ADF7Z",
|
||||
"clusterId": "fake.cluster",
|
||||
"name": "docker-connect-status",
|
||||
"internal": true,
|
||||
"partitions": [
|
||||
|
@ -62,7 +62,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"clusterId": "wrYGf-csNgiGdK7B_ADF7Z",
|
||||
"clusterId": "fake.cluster",
|
||||
"name": "dsadsda",
|
||||
"internal": false,
|
||||
"partitions": [
|
||||
|
@ -80,7 +80,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"clusterId": "wrYGf-csNgiGdK7B_ADF7Z",
|
||||
"clusterId": "fake.cluster",
|
||||
"name": "my-topic",
|
||||
"internal": false,
|
||||
"partitions": [
|
||||
|
@ -98,7 +98,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"clusterId": "wrYGf-csNgiGdK7B_ADF7Z",
|
||||
"clusterId": "fake.cluster",
|
||||
"name": "docker-connect-offsets",
|
||||
"internal": false,
|
||||
"partitions": [
|
||||
|
@ -171,7 +171,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"clusterId": "dMMQx-WRh77BKYas_g2ZTz",
|
||||
"clusterId": "kafka-ui.cluster",
|
||||
"name": "_schemas",
|
||||
"internal": false,
|
||||
"partitions": [
|
||||
|
@ -189,7 +189,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"clusterId": "dMMQx-WRh77BKYas_g2ZTz",
|
||||
"clusterId": "kafka-ui.cluster",
|
||||
"name": "docker-connect-configs",
|
||||
"internal": false,
|
||||
"partitions": [
|
||||
|
@ -207,7 +207,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"clusterId": "dMMQx-WRh77BKYas_g2ZTz",
|
||||
"clusterId": "kafka-ui.cluster",
|
||||
"name": "_kafka-ui-test-topic-monitoring-message-rekey-store",
|
||||
"internal": false,
|
||||
"partitions": [
|
||||
|
|
|
@ -37,9 +37,9 @@ const App: React.FC<AppProps> = ({
|
|||
<Switch>
|
||||
<Route exact path="/" component={Dashboard} />
|
||||
<Route exact path="/clusters" component={Dashboard} />
|
||||
<Route path="/clusters/:clusterId/topics" component={TopicsContainer} />
|
||||
<Route path="/clusters/:clusterId/brokers" component={BrokersContainer} />
|
||||
<Redirect from="/clusters/:clusterId" to="/clusters/:clusterId/brokers" />
|
||||
<Route path="/clusters/:clusterName/topics" component={TopicsContainer} />
|
||||
<Route path="/clusters/:clusterName/brokers" component={BrokersContainer} />
|
||||
<Redirect from="/clusters/:clusterName" to="/clusters/:clusterName/brokers" />
|
||||
</Switch>
|
||||
) : (
|
||||
<PageLoader />
|
||||
|
@ -48,6 +48,6 @@ const App: React.FC<AppProps> = ({
|
|||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { ClusterId, BrokerMetrics, ZooKeeperStatus } from 'redux/interfaces';
|
||||
import { ClusterName, BrokerMetrics, ZooKeeperStatus } from 'redux/interfaces';
|
||||
import useInterval from 'lib/hooks/useInterval';
|
||||
import formatBytes from 'lib/utils/formatBytes';
|
||||
import cx from 'classnames';
|
||||
|
@ -8,16 +8,16 @@ import Indicator from 'components/common/Dashboard/Indicator';
|
|||
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||
|
||||
interface Props extends BrokerMetrics {
|
||||
clusterId: string;
|
||||
clusterName: ClusterName;
|
||||
isFetched: boolean;
|
||||
minDiskUsage: number;
|
||||
maxDiskUsage: number;
|
||||
fetchBrokers: (clusterId: ClusterId) => void;
|
||||
fetchBrokerMetrics: (clusterId: ClusterId) => void;
|
||||
fetchBrokers: (clusterName: ClusterName) => void;
|
||||
fetchBrokerMetrics: (clusterName: ClusterName) => void;
|
||||
}
|
||||
|
||||
const Topics: React.FC<Props> = ({
|
||||
clusterId,
|
||||
clusterName,
|
||||
isFetched,
|
||||
brokerCount,
|
||||
activeControllers,
|
||||
|
@ -35,13 +35,13 @@ const Topics: React.FC<Props> = ({
|
|||
}) => {
|
||||
React.useEffect(
|
||||
() => {
|
||||
fetchBrokers(clusterId);
|
||||
fetchBrokerMetrics(clusterId);
|
||||
fetchBrokers(clusterName);
|
||||
fetchBrokerMetrics(clusterName);
|
||||
},
|
||||
[fetchBrokers, fetchBrokerMetrics, clusterId],
|
||||
[fetchBrokers, fetchBrokerMetrics, clusterName],
|
||||
);
|
||||
|
||||
useInterval(() => { fetchBrokerMetrics(clusterId); }, 5000);
|
||||
useInterval(() => { fetchBrokerMetrics(clusterName); }, 5000);
|
||||
|
||||
const [minDiskUsageValue, minDiskUsageSize] = formatBytes(minDiskUsage);
|
||||
const [maxDiskUsageValue, maxDiskUsageSize] = formatBytes(maxDiskUsage);
|
||||
|
@ -116,6 +116,6 @@ const Topics: React.FC<Props> = ({
|
|||
</MetricsWrapper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Topics;
|
||||
|
|
|
@ -5,18 +5,18 @@ import {
|
|||
} from 'redux/actions';
|
||||
import Brokers from './Brokers';
|
||||
import * as brokerSelectors from 'redux/reducers/brokers/selectors';
|
||||
import { RootState, ClusterId } from 'redux/interfaces';
|
||||
import { RootState, ClusterName } from 'redux/interfaces';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
clusterName: ClusterName;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterId } }}: OwnProps) => ({
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterName } }}: OwnProps) => ({
|
||||
isFetched: brokerSelectors.getIsBrokerListFetched(state),
|
||||
clusterId,
|
||||
clusterName,
|
||||
brokerCount: brokerSelectors.getBrokerCount(state),
|
||||
zooKeeperStatus: brokerSelectors.getZooKeeperStatus(state),
|
||||
activeControllers: brokerSelectors.getActiveControllers(state),
|
||||
|
@ -31,8 +31,8 @@ const mapStateToProps = (state: RootState, { match: { params: { clusterId } }}:
|
|||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchBrokers: (clusterId: ClusterId) => fetchBrokers(clusterId),
|
||||
fetchBrokerMetrics: (clusterId: ClusterId) => fetchBrokerMetrics(clusterId),
|
||||
}
|
||||
fetchBrokers: (clusterName: ClusterName) => fetchBrokers(clusterName),
|
||||
fetchBrokerMetrics: (clusterName: ClusterName) => fetchBrokerMetrics(clusterName),
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Brokers);
|
||||
|
|
|
@ -5,7 +5,6 @@ import { NavLink } from 'react-router-dom';
|
|||
import { clusterBrokersPath } from 'lib/paths';
|
||||
|
||||
const ClusterWidget: React.FC<Cluster> = ({
|
||||
id,
|
||||
name,
|
||||
status,
|
||||
topicCount,
|
||||
|
@ -14,7 +13,7 @@ const ClusterWidget: React.FC<Cluster> = ({
|
|||
bytesOutPerSec,
|
||||
onlinePartitionCount,
|
||||
}) => (
|
||||
<NavLink to={clusterBrokersPath(id)} className="column is-full-modile is-6">
|
||||
<NavLink to={clusterBrokersPath(name)} className="column is-full-modile is-6">
|
||||
<div className="box is-hoverable">
|
||||
<div
|
||||
className="title is-6 has-text-overflow-ellipsis"
|
||||
|
|
|
@ -21,21 +21,20 @@ const DefaultIcon: React.FC = () => {
|
|||
};
|
||||
|
||||
const ClusterMenu: React.FC<Props> = ({
|
||||
id,
|
||||
name,
|
||||
defaultCluster,
|
||||
}) => (
|
||||
<ul className="menu-list">
|
||||
<li>
|
||||
<NavLink exact to={clusterBrokersPath(id)} title={name} className="has-text-overflow-ellipsis">
|
||||
<NavLink exact to={clusterBrokersPath(name)} title={name} className="has-text-overflow-ellipsis">
|
||||
{defaultCluster && <DefaultIcon />}
|
||||
{name}
|
||||
</NavLink>
|
||||
<ul>
|
||||
<NavLink to={clusterBrokersPath(id)} activeClassName="is-active" title="Brokers">
|
||||
<NavLink to={clusterBrokersPath(name)} activeClassName="is-active" title="Brokers">
|
||||
Brokers
|
||||
</NavLink>
|
||||
<NavLink to={clusterTopicsPath(id)} activeClassName="is-active" title="Topics">
|
||||
<NavLink to={clusterTopicsPath(name)} activeClassName="is-active" title="Topics">
|
||||
Topics
|
||||
</NavLink>
|
||||
</ul>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { ClusterId, Topic, TopicDetails, TopicName } from 'redux/interfaces';
|
||||
import { ClusterName, Topic, TopicDetails, TopicName } from 'redux/interfaces';
|
||||
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||
import { NavLink, Switch, Route } from 'react-router-dom';
|
||||
import { clusterTopicsPath, clusterTopicSettingsPath, clusterTopicPath, clusterTopicMessagesPath } from 'lib/paths';
|
||||
|
@ -8,12 +8,12 @@ import MessagesContainer from './Messages/MessagesContainer';
|
|||
import SettingsContainer from './Settings/SettingsContainer';
|
||||
|
||||
interface Props extends Topic, TopicDetails {
|
||||
clusterId: ClusterId;
|
||||
clusterName: ClusterName;
|
||||
topicName: TopicName;
|
||||
}
|
||||
|
||||
const Details: React.FC<Props> = ({
|
||||
clusterId,
|
||||
clusterName,
|
||||
topicName,
|
||||
}) => {
|
||||
return (
|
||||
|
@ -21,7 +21,7 @@ const Details: React.FC<Props> = ({
|
|||
<div className="level">
|
||||
<div className="level-item level-left">
|
||||
<Breadcrumb links={[
|
||||
{ href: clusterTopicsPath(clusterId), label: 'All Topics' },
|
||||
{ href: clusterTopicsPath(clusterName), label: 'All Topics' },
|
||||
]}>
|
||||
{topicName}
|
||||
</Breadcrumb>
|
||||
|
@ -32,7 +32,7 @@ const Details: React.FC<Props> = ({
|
|||
<nav className="navbar" role="navigation">
|
||||
<NavLink
|
||||
exact
|
||||
to={clusterTopicPath(clusterId, topicName)}
|
||||
to={clusterTopicPath(clusterName, topicName)}
|
||||
className="navbar-item is-tab"
|
||||
activeClassName="is-active is-primary"
|
||||
>
|
||||
|
@ -40,7 +40,7 @@ const Details: React.FC<Props> = ({
|
|||
</NavLink>
|
||||
<NavLink
|
||||
exact
|
||||
to={clusterTopicMessagesPath(clusterId, topicName)}
|
||||
to={clusterTopicMessagesPath(clusterName, topicName)}
|
||||
className="navbar-item is-tab"
|
||||
activeClassName="is-active"
|
||||
>
|
||||
|
@ -48,7 +48,7 @@ const Details: React.FC<Props> = ({
|
|||
</NavLink>
|
||||
<NavLink
|
||||
exact
|
||||
to={clusterTopicSettingsPath(clusterId, topicName)}
|
||||
to={clusterTopicSettingsPath(clusterName, topicName)}
|
||||
className="navbar-item is-tab"
|
||||
activeClassName="is-active"
|
||||
>
|
||||
|
@ -57,13 +57,13 @@ const Details: React.FC<Props> = ({
|
|||
</nav>
|
||||
<br />
|
||||
<Switch>
|
||||
<Route exact path="/clusters/:clusterId/topics/:topicName/messages" component={MessagesContainer} />
|
||||
<Route exact path="/clusters/:clusterId/topics/:topicName/settings" component={SettingsContainer} />
|
||||
<Route exact path="/clusters/:clusterId/topics/:topicName" component={OverviewContainer} />
|
||||
<Route exact path="/clusters/:clusterName/topics/:topicName/messages" component={MessagesContainer} />
|
||||
<Route exact path="/clusters/:clusterName/topics/:topicName/settings" component={SettingsContainer} />
|
||||
<Route exact path="/clusters/:clusterName/topics/:topicName" component={OverviewContainer} />
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Details;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { connect } from 'react-redux';
|
||||
import Details from './Details';
|
||||
import { RootState } from 'redux/interfaces';
|
||||
import {ClusterName, RootState} from 'redux/interfaces';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
clusterName: ClusterName;
|
||||
topicName: string;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterId } } }: OwnProps) => ({
|
||||
clusterId,
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterName } } }: OwnProps) => ({
|
||||
clusterName,
|
||||
topicName,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import React from 'react';
|
||||
import { ClusterId, TopicName } from 'redux/interfaces';
|
||||
import { ClusterName, TopicName } from 'redux/interfaces';
|
||||
|
||||
interface Props {
|
||||
clusterId: ClusterId;
|
||||
clusterName: ClusterName;
|
||||
topicName: TopicName;
|
||||
}
|
||||
|
||||
const Messages: React.FC<Props> = ({
|
||||
clusterId,
|
||||
clusterName,
|
||||
topicName,
|
||||
}) => {
|
||||
return (
|
||||
<h1>
|
||||
Messages from {clusterId}{topicName}
|
||||
Messages from {clusterName}{topicName}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Messages;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { connect } from 'react-redux';
|
||||
import Messages from './Messages';
|
||||
import { RootState } from 'redux/interfaces';
|
||||
import {ClusterName, RootState, TopicName} from 'redux/interfaces';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
topicName: string;
|
||||
clusterName: ClusterName;
|
||||
topicName: TopicName;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterId } } }: OwnProps) => ({
|
||||
clusterId,
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterName } } }: OwnProps) => ({
|
||||
clusterName,
|
||||
topicName,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import React from 'react';
|
||||
import { ClusterId, Topic, TopicDetails, TopicName } from 'redux/interfaces';
|
||||
import { ClusterName, Topic, TopicDetails, TopicName } from 'redux/interfaces';
|
||||
import MetricsWrapper from 'components/common/Dashboard/MetricsWrapper';
|
||||
import Indicator from 'components/common/Dashboard/Indicator';
|
||||
|
||||
interface Props extends Topic, TopicDetails {
|
||||
isFetched: boolean;
|
||||
clusterId: ClusterId;
|
||||
clusterName: ClusterName;
|
||||
topicName: TopicName;
|
||||
fetchTopicDetails: (clusterId: ClusterId, topicName: TopicName) => void;
|
||||
fetchTopicDetails: (clusterName: ClusterName, topicName: TopicName) => void;
|
||||
}
|
||||
|
||||
const Overview: React.FC<Props> = ({
|
||||
isFetched,
|
||||
clusterId,
|
||||
clusterName,
|
||||
topicName,
|
||||
partitions,
|
||||
underReplicatedPartitions,
|
||||
|
@ -24,8 +24,8 @@ const Overview: React.FC<Props> = ({
|
|||
fetchTopicDetails,
|
||||
}) => {
|
||||
React.useEffect(
|
||||
() => { fetchTopicDetails(clusterId, topicName); },
|
||||
[fetchTopicDetails, clusterId, topicName],
|
||||
() => { fetchTopicDetails(clusterName, topicName); },
|
||||
[fetchTopicDetails, clusterName, topicName],
|
||||
);
|
||||
|
||||
if (!isFetched) {
|
||||
|
@ -74,6 +74,6 @@ const Overview: React.FC<Props> = ({
|
|||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Overview;
|
||||
|
|
|
@ -3,27 +3,27 @@ import {
|
|||
fetchTopicDetails,
|
||||
} from 'redux/actions';
|
||||
import Overview from './Overview';
|
||||
import { RootState, TopicName, ClusterId } from 'redux/interfaces';
|
||||
import { RootState, TopicName, ClusterName } from 'redux/interfaces';
|
||||
import { getTopicByName, getIsTopicDetailsFetched } from 'redux/reducers/topics/selectors';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
topicName: string;
|
||||
clusterName: ClusterName;
|
||||
topicName: TopicName;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterId } } }: OwnProps) => ({
|
||||
clusterId,
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterName } } }: OwnProps) => ({
|
||||
clusterName,
|
||||
topicName,
|
||||
isFetched: getIsTopicDetailsFetched(state),
|
||||
...getTopicByName(state, topicName),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchTopicDetails: (clusterId: ClusterId, topicName: TopicName) => fetchTopicDetails(clusterId, topicName),
|
||||
}
|
||||
fetchTopicDetails: (clusterName: ClusterName, topicName: TopicName) => fetchTopicDetails(clusterName, topicName),
|
||||
};
|
||||
|
||||
export default withRouter(
|
||||
connect(mapStateToProps, mapDispatchToProps)(Overview)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import React from 'react';
|
||||
import { ClusterId, TopicName, TopicConfig } from 'redux/interfaces';
|
||||
import { ClusterName, TopicName, TopicConfig } from 'redux/interfaces';
|
||||
|
||||
interface Props {
|
||||
clusterId: ClusterId;
|
||||
clusterName: ClusterName;
|
||||
topicName: TopicName;
|
||||
config?: TopicConfig[];
|
||||
isFetched: boolean;
|
||||
fetchTopicConfig: (clusterId: ClusterId, topicName: TopicName) => void;
|
||||
fetchTopicConfig: (clusterName: ClusterName, topicName: TopicName) => void;
|
||||
}
|
||||
|
||||
const ConfigListItem: React.FC<TopicConfig> = ({
|
||||
|
@ -32,22 +32,22 @@ const ConfigListItem: React.FC<TopicConfig> = ({
|
|||
</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
const Sertings: React.FC<Props> = ({
|
||||
clusterId,
|
||||
clusterName,
|
||||
topicName,
|
||||
isFetched,
|
||||
fetchTopicConfig,
|
||||
config,
|
||||
}) => {
|
||||
React.useEffect(
|
||||
() => { fetchTopicConfig(clusterId, topicName); },
|
||||
[fetchTopicConfig, clusterId, topicName],
|
||||
() => { fetchTopicConfig(clusterName, topicName); },
|
||||
[fetchTopicConfig, clusterName, topicName],
|
||||
);
|
||||
|
||||
if (!isFetched || !config) {
|
||||
return (null);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -66,6 +66,6 @@ const Sertings: React.FC<Props> = ({
|
|||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Sertings;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { RootState, ClusterId, TopicName } from 'redux/interfaces';
|
||||
import { RootState, ClusterName, TopicName } from 'redux/interfaces';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
import {
|
||||
fetchTopicConfig,
|
||||
|
@ -12,22 +12,22 @@ import {
|
|||
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
topicName: string;
|
||||
clusterName: ClusterName;
|
||||
topicName: TopicName;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterId } } }: OwnProps) => ({
|
||||
clusterId,
|
||||
const mapStateToProps = (state: RootState, { match: { params: { topicName, clusterName } } }: OwnProps) => ({
|
||||
clusterName,
|
||||
topicName,
|
||||
config: getTopicConfig(state, topicName),
|
||||
isFetched: getTopicConfigFetched(state),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchTopicConfig: (clusterId: ClusterId, topicName: TopicName) => fetchTopicConfig(clusterId, topicName),
|
||||
}
|
||||
fetchTopicConfig: (clusterName: ClusterName, topicName: TopicName) => fetchTopicConfig(clusterName, topicName),
|
||||
};
|
||||
|
||||
export default withRouter(
|
||||
connect(mapStateToProps, mapDispatchToProps)(Settings)
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import React from 'react';
|
||||
import { TopicWithDetailedInfo, ClusterId } from 'redux/interfaces';
|
||||
import { TopicWithDetailedInfo, ClusterName } from 'redux/interfaces';
|
||||
import ListItem from './ListItem';
|
||||
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { clusterTopicNewPath } from 'lib/paths';
|
||||
|
||||
interface Props {
|
||||
clusterId: ClusterId;
|
||||
clusterName: ClusterName;
|
||||
topics: (TopicWithDetailedInfo)[];
|
||||
externalTopics: (TopicWithDetailedInfo)[];
|
||||
}
|
||||
|
||||
const List: React.FC<Props> = ({
|
||||
clusterId,
|
||||
clusterName,
|
||||
topics,
|
||||
externalTopics,
|
||||
}) => {
|
||||
|
@ -46,7 +46,7 @@ const List: React.FC<Props> = ({
|
|||
<div className="level-item level-right">
|
||||
<NavLink
|
||||
className="button is-primary"
|
||||
to={clusterTopicNewPath(clusterId)}
|
||||
to={clusterTopicNewPath(clusterName)}
|
||||
>
|
||||
Add a Topic
|
||||
</NavLink>
|
||||
|
@ -75,6 +75,6 @@ const List: React.FC<Props> = ({
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default List;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { RootState } from 'redux/interfaces';
|
||||
import {ClusterName, RootState} from 'redux/interfaces';
|
||||
import { getTopicList, getExternalTopicList } from 'redux/reducers/topics/selectors';
|
||||
import List from './List';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
clusterName: ClusterName;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterId } } }: OwnProps) => ({
|
||||
clusterId,
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterName } } }: OwnProps) => ({
|
||||
clusterName,
|
||||
topics: getTopicList(state),
|
||||
externalTopics: getExternalTopicList(state),
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { ClusterId, CleanupPolicy, TopicFormData, TopicName } from 'redux/interfaces';
|
||||
import { ClusterName, CleanupPolicy, TopicFormData, TopicName } from 'redux/interfaces';
|
||||
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||
import { clusterTopicsPath } from 'lib/paths';
|
||||
import { useForm, ErrorMessage } from 'react-hook-form';
|
||||
|
@ -10,15 +10,15 @@ import {
|
|||
} from 'lib/constants';
|
||||
|
||||
interface Props {
|
||||
clusterId: ClusterId;
|
||||
clusterName: ClusterName;
|
||||
isTopicCreated: boolean;
|
||||
createTopic: (clusterId: ClusterId, form: TopicFormData) => void;
|
||||
redirectToTopicPath: (clusterId: ClusterId, topicName: TopicName) => void;
|
||||
createTopic: (clusterName: ClusterName, form: TopicFormData) => void;
|
||||
redirectToTopicPath: (clusterName: ClusterName, topicName: TopicName) => void;
|
||||
resetUploadedState: () => void;
|
||||
}
|
||||
|
||||
const New: React.FC<Props> = ({
|
||||
clusterId,
|
||||
clusterName,
|
||||
isTopicCreated,
|
||||
createTopic,
|
||||
redirectToTopicPath,
|
||||
|
@ -31,10 +31,10 @@ const New: React.FC<Props> = ({
|
|||
() => {
|
||||
if (isSubmitting && isTopicCreated) {
|
||||
const {name} = getValues();
|
||||
redirectToTopicPath(clusterId, name);
|
||||
redirectToTopicPath(clusterName, name);
|
||||
}
|
||||
},
|
||||
[isSubmitting, isTopicCreated, redirectToTopicPath, clusterId, getValues],
|
||||
[isSubmitting, isTopicCreated, redirectToTopicPath, clusterName, getValues],
|
||||
);
|
||||
|
||||
const onSubmit = async (data: TopicFormData) => {
|
||||
|
@ -43,7 +43,7 @@ const New: React.FC<Props> = ({
|
|||
//going to object page on the second creation. Resetting loaded state is workaround, need to tweak loader logic
|
||||
resetUploadedState();
|
||||
setIsSubmitting(true);
|
||||
createTopic(clusterId, data);
|
||||
createTopic(clusterName, data);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -51,7 +51,7 @@ const New: React.FC<Props> = ({
|
|||
<div className="level">
|
||||
<div className="level-item level-left">
|
||||
<Breadcrumb links={[
|
||||
{href: clusterTopicsPath(clusterId), label: 'All Topics'},
|
||||
{href: clusterTopicsPath(clusterName), label: 'All Topics'},
|
||||
]}>
|
||||
New Topic
|
||||
</Breadcrumb>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { RootState, ClusterId, TopicFormData, TopicName, Action } from 'redux/interfaces';
|
||||
import { RootState, ClusterName, TopicFormData, TopicName, Action } from 'redux/interfaces';
|
||||
import New from './New';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
import { createTopic } from 'redux/actions';
|
||||
|
@ -9,22 +9,22 @@ import { ThunkDispatch } from 'redux-thunk';
|
|||
import * as actions from "../../../redux/actions/actions";
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
clusterName: ClusterName;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterId } } }: OwnProps) => ({
|
||||
clusterId,
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterName } } }: OwnProps) => ({
|
||||
clusterName,
|
||||
isTopicCreated: getTopicCreated(state),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: ThunkDispatch<RootState, undefined, Action>, { history }: OwnProps) => ({
|
||||
createTopic: (clusterId: ClusterId, form: TopicFormData) => {
|
||||
dispatch(createTopic(clusterId, form));
|
||||
createTopic: (clusterName: ClusterName, form: TopicFormData) => {
|
||||
dispatch(createTopic(clusterName, form));
|
||||
},
|
||||
redirectToTopicPath: (clusterId: ClusterId, topicName: TopicName) => {
|
||||
history.push(clusterTopicPath(clusterId, topicName));
|
||||
redirectToTopicPath: (clusterName: ClusterName, topicName: TopicName) => {
|
||||
history.push(clusterTopicPath(clusterName, topicName));
|
||||
},
|
||||
resetUploadedState: (() => dispatch(actions.createTopicAction.failure()))
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { ClusterId } from 'redux/interfaces';
|
||||
import { ClusterName } from 'redux/interfaces';
|
||||
import {
|
||||
Switch,
|
||||
Route,
|
||||
|
@ -10,30 +10,30 @@ import PageLoader from 'components/common/PageLoader/PageLoader';
|
|||
import NewContainer from './New/NewContainer';
|
||||
|
||||
interface Props {
|
||||
clusterId: string;
|
||||
clusterName: ClusterName;
|
||||
isFetched: boolean;
|
||||
fetchBrokers: (clusterId: ClusterId) => void;
|
||||
fetchTopicList: (clusterId: ClusterId) => void;
|
||||
fetchBrokers: (clusterName: ClusterName) => void;
|
||||
fetchTopicList: (clusterName: ClusterName) => void;
|
||||
}
|
||||
|
||||
const Topics: React.FC<Props> = ({
|
||||
clusterId,
|
||||
clusterName,
|
||||
isFetched,
|
||||
fetchTopicList,
|
||||
}) => {
|
||||
React.useEffect(() => { fetchTopicList(clusterId); }, [fetchTopicList, clusterId]);
|
||||
React.useEffect(() => { fetchTopicList(clusterName); }, [fetchTopicList, clusterName]);
|
||||
|
||||
if (isFetched) {
|
||||
return (
|
||||
<Switch>
|
||||
<Route exact path="/clusters/:clusterId/topics" component={ListContainer} />
|
||||
<Route exact path="/clusters/:clusterId/topics/new" component={NewContainer} />
|
||||
<Route path="/clusters/:clusterId/topics/:topicName" component={DetailsContainer} />
|
||||
<Route exact path="/clusters/:clusterName/topics" component={ListContainer} />
|
||||
<Route exact path="/clusters/:clusterName/topics/new" component={NewContainer} />
|
||||
<Route path="/clusters/:clusterName/topics/:topicName" component={DetailsContainer} />
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
return (<PageLoader />);
|
||||
}
|
||||
};
|
||||
|
||||
export default Topics;
|
||||
|
|
|
@ -2,22 +2,22 @@ import { connect } from 'react-redux';
|
|||
import { fetchTopicList } from 'redux/actions';
|
||||
import Topics from './Topics';
|
||||
import { getIsTopicListFetched } from 'redux/reducers/topics/selectors';
|
||||
import { RootState, ClusterId } from 'redux/interfaces';
|
||||
import { RootState, ClusterName } from 'redux/interfaces';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
interface RouteProps {
|
||||
clusterId: string;
|
||||
clusterName: ClusterName;
|
||||
}
|
||||
|
||||
interface OwnProps extends RouteComponentProps<RouteProps> { }
|
||||
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterId } }}: OwnProps) => ({
|
||||
const mapStateToProps = (state: RootState, { match: { params: { clusterName } }}: OwnProps) => ({
|
||||
isFetched: getIsTopicListFetched(state),
|
||||
clusterId,
|
||||
clusterName,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchTopicList: (clusterId: ClusterId) => fetchTopicList(clusterId),
|
||||
}
|
||||
fetchTopicList: (clusterName: ClusterName) => fetchTopicList(clusterName),
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Topics);
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import {
|
||||
ClusterId,
|
||||
ClusterName,
|
||||
TopicName,
|
||||
} from 'redux/interfaces';
|
||||
|
||||
const clusterPath = (clusterId: ClusterId) => `/clusters/${clusterId}`;
|
||||
const clusterPath = (clusterName: ClusterName) => `/clusters/${clusterName}`;
|
||||
|
||||
export const clusterBrokersPath = (clusterId: ClusterId) => `${clusterPath(clusterId)}/brokers`;
|
||||
export const clusterBrokersPath = (clusterName: ClusterName) => `${clusterPath(clusterName)}/brokers`;
|
||||
|
||||
export const clusterTopicsPath = (clusterId: ClusterId) => `${clusterPath(clusterId)}/topics`;
|
||||
export const clusterTopicNewPath = (clusterId: ClusterId) => `${clusterPath(clusterId)}/topics/new`;
|
||||
export const clusterTopicsPath = (clusterName: ClusterName) => `${clusterPath(clusterName)}/topics`;
|
||||
export const clusterTopicNewPath = (clusterName: ClusterName) => `${clusterPath(clusterName)}/topics/new`;
|
||||
|
||||
export const clusterTopicPath = (clusterId: ClusterId, topicName: TopicName) => `${clusterTopicsPath(clusterId)}/${topicName}`;
|
||||
export const clusterTopicSettingsPath = (clusterId: ClusterId, topicName: TopicName) => `${clusterTopicsPath(clusterId)}/${topicName}/settings`;
|
||||
export const clusterTopicMessagesPath = (clusterId: ClusterId, topicName: TopicName) => `${clusterTopicsPath(clusterId)}/${topicName}/messages`;
|
||||
export const clusterTopicPath = (clusterName: ClusterName, topicName: TopicName) => `${clusterTopicsPath(clusterName)}/${topicName}`;
|
||||
export const clusterTopicSettingsPath = (clusterName: ClusterName, topicName: TopicName) => `${clusterTopicsPath(clusterName)}/${topicName}/settings`;
|
||||
export const clusterTopicMessagesPath = (clusterName: ClusterName, topicName: TopicName) => `${clusterTopicsPath(clusterName)}/${topicName}/messages`;
|
||||
|
|
|
@ -3,30 +3,30 @@ import * as actions from './actions';
|
|||
import {
|
||||
PromiseThunk,
|
||||
Cluster,
|
||||
ClusterId,
|
||||
ClusterName,
|
||||
TopicFormData,
|
||||
TopicName, Topic,
|
||||
} from 'redux/interfaces';
|
||||
|
||||
export const fetchBrokers = (clusterId: ClusterId): PromiseThunk<void> => async (dispatch) => {
|
||||
export const fetchBrokers = (clusterName: ClusterName): PromiseThunk<void> => async (dispatch) => {
|
||||
dispatch(actions.fetchBrokersAction.request());
|
||||
try {
|
||||
const payload = await api.getBrokers(clusterId);
|
||||
const payload = await api.getBrokers(clusterName);
|
||||
dispatch(actions.fetchBrokersAction.success(payload));
|
||||
} catch (e) {
|
||||
dispatch(actions.fetchBrokersAction.failure());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchBrokerMetrics = (clusterId: ClusterId): PromiseThunk<void> => async (dispatch) => {
|
||||
export const fetchBrokerMetrics = (clusterName: ClusterName): PromiseThunk<void> => async (dispatch) => {
|
||||
dispatch(actions.fetchBrokerMetricsAction.request());
|
||||
try {
|
||||
const payload = await api.getBrokerMetrics(clusterId);
|
||||
const payload = await api.getBrokerMetrics(clusterName);
|
||||
dispatch(actions.fetchBrokerMetricsAction.success(payload));
|
||||
} catch (e) {
|
||||
dispatch(actions.fetchBrokerMetricsAction.failure());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchClustersList = (): PromiseThunk<void> => async (dispatch) => {
|
||||
dispatch(actions.fetchClusterListAction.request());
|
||||
|
@ -36,44 +36,44 @@ export const fetchClustersList = (): PromiseThunk<void> => async (dispatch) => {
|
|||
} catch (e) {
|
||||
dispatch(actions.fetchClusterListAction.failure());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchTopicList = (clusterId: ClusterId): PromiseThunk<void> => async (dispatch) => {
|
||||
export const fetchTopicList = (clusterName: ClusterName): PromiseThunk<void> => async (dispatch) => {
|
||||
dispatch(actions.fetchTopicListAction.request());
|
||||
try {
|
||||
const topics = await api.getTopics(clusterId);
|
||||
const topics = await api.getTopics(clusterName);
|
||||
dispatch(actions.fetchTopicListAction.success(topics));
|
||||
} catch (e) {
|
||||
dispatch(actions.fetchTopicListAction.failure());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchTopicDetails = (clusterId: ClusterId, topicName: TopicName): PromiseThunk<void> => async (dispatch) => {
|
||||
export const fetchTopicDetails = (clusterName: ClusterName, topicName: TopicName): PromiseThunk<void> => async (dispatch) => {
|
||||
dispatch(actions.fetchTopicDetailsAction.request());
|
||||
try {
|
||||
const topicDetails = await api.getTopicDetails(clusterId, topicName);
|
||||
const topicDetails = await api.getTopicDetails(clusterName, topicName);
|
||||
dispatch(actions.fetchTopicDetailsAction.success({ topicName, details: topicDetails }));
|
||||
} catch (e) {
|
||||
dispatch(actions.fetchTopicDetailsAction.failure());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchTopicConfig = (clusterId: ClusterId, topicName: TopicName): PromiseThunk<void> => async (dispatch) => {
|
||||
export const fetchTopicConfig = (clusterName: ClusterName, topicName: TopicName): PromiseThunk<void> => async (dispatch) => {
|
||||
dispatch(actions.fetchTopicConfigAction.request());
|
||||
try {
|
||||
const config = await api.getTopicConfig(clusterId, topicName);
|
||||
const config = await api.getTopicConfig(clusterName, topicName);
|
||||
dispatch(actions.fetchTopicConfigAction.success({ topicName, config }));
|
||||
} catch (e) {
|
||||
dispatch(actions.fetchTopicConfigAction.failure());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const createTopic = (clusterId: ClusterId, form: TopicFormData): PromiseThunk<void> => async (dispatch) => {
|
||||
export const createTopic = (clusterName: ClusterName, form: TopicFormData): PromiseThunk<void> => async (dispatch) => {
|
||||
dispatch(actions.createTopicAction.request());
|
||||
try {
|
||||
const topic: Topic = await api.postTopic(clusterId, form);
|
||||
const topic: Topic = await api.postTopic(clusterName, form);
|
||||
dispatch(actions.createTopicAction.success(topic));
|
||||
} catch (e) {
|
||||
dispatch(actions.createTopicAction.failure());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {
|
||||
Broker,
|
||||
ClusterId,
|
||||
ClusterName,
|
||||
BrokerMetrics,
|
||||
} from 'redux/interfaces';
|
||||
import {
|
||||
|
@ -8,10 +8,10 @@ import {
|
|||
BASE_PARAMS,
|
||||
} from 'lib/constants';
|
||||
|
||||
export const getBrokers = (clusterId: ClusterId): Promise<Broker[]> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterId}/brokers`, { ...BASE_PARAMS })
|
||||
export const getBrokers = (clusterName: ClusterName): Promise<Broker[]> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterName}/brokers`, { ...BASE_PARAMS })
|
||||
.then(res => res.json());
|
||||
|
||||
export const getBrokerMetrics = (clusterId: ClusterId): Promise<BrokerMetrics> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterId}/metrics/broker`, { ...BASE_PARAMS })
|
||||
export const getBrokerMetrics = (clusterName: ClusterName): Promise<BrokerMetrics> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterName}/metrics/broker`, { ...BASE_PARAMS })
|
||||
.then(res => res.json());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
TopicName,
|
||||
Topic,
|
||||
ClusterId,
|
||||
ClusterName,
|
||||
TopicDetails,
|
||||
TopicConfig,
|
||||
TopicFormData,
|
||||
|
@ -11,19 +11,19 @@ import {
|
|||
BASE_PARAMS,
|
||||
} from 'lib/constants';
|
||||
|
||||
export const getTopicConfig = (clusterId: ClusterId, topicName: TopicName): Promise<TopicConfig[]> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterId}/topics/${topicName}/config`, { ...BASE_PARAMS })
|
||||
export const getTopicConfig = (clusterName: ClusterName, topicName: TopicName): Promise<TopicConfig[]> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterName}/topics/${topicName}/config`, { ...BASE_PARAMS })
|
||||
.then(res => res.json());
|
||||
|
||||
export const getTopicDetails = (clusterId: ClusterId, topicName: TopicName): Promise<TopicDetails> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterId}/topics/${topicName}`, { ...BASE_PARAMS })
|
||||
export const getTopicDetails = (clusterName: ClusterName, topicName: TopicName): Promise<TopicDetails> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterName}/topics/${topicName}`, { ...BASE_PARAMS })
|
||||
.then(res => res.json());
|
||||
|
||||
export const getTopics = (clusterId: ClusterId): Promise<Topic[]> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterId}/topics`, { ...BASE_PARAMS })
|
||||
export const getTopics = (clusterName: ClusterName): Promise<Topic[]> =>
|
||||
fetch(`${BASE_URL}/clusters/${clusterName}/topics`, { ...BASE_PARAMS })
|
||||
.then(res => res.json());
|
||||
|
||||
export const postTopic = (clusterId: ClusterId, form: TopicFormData): Promise<Topic> => {
|
||||
export const postTopic = (clusterName: ClusterName, form: TopicFormData): Promise<Topic> => {
|
||||
const {
|
||||
name,
|
||||
partitions,
|
||||
|
@ -46,9 +46,9 @@ export const postTopic = (clusterId: ClusterId, form: TopicFormData): Promise<To
|
|||
'min.insync.replicas': minInSyncReplicas,
|
||||
}
|
||||
});
|
||||
return fetch(`${BASE_URL}/clusters/${clusterId}/topics`, {
|
||||
return fetch(`${BASE_URL}/clusters/${clusterName}/topics`, {
|
||||
...BASE_PARAMS,
|
||||
method: 'POST',
|
||||
body,
|
||||
}).then(res => res.json());
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,11 +3,11 @@ export enum ClusterStatus {
|
|||
Offline = 'offline',
|
||||
}
|
||||
|
||||
export type ClusterId = string;
|
||||
export type ClusterName = string;
|
||||
|
||||
export interface Cluster {
|
||||
id: ClusterId;
|
||||
name: string;
|
||||
id: string;
|
||||
name: ClusterName;
|
||||
defaultCluster: boolean;
|
||||
status: ClusterStatus;
|
||||
brokerCount: number;
|
||||
|
|
Loading…
Add table
Reference in a new issue