Implement topic deletion
This commit is contained in:
parent
a8ed4ff37f
commit
3fee2214a0
6 changed files with 93 additions and 3 deletions
|
@ -4,7 +4,7 @@ import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { clusterTopicNewPath } from 'lib/paths';
|
import { clusterTopicNewPath } from 'lib/paths';
|
||||||
import ClusterContext from 'components/contexts/ClusterContext';
|
import ClusterContext from 'components/contexts/ClusterContext';
|
||||||
import ListItem from './ListItem';
|
import ListItemContainer from './ListItemContainer';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
clusterName: ClusterName;
|
clusterName: ClusterName;
|
||||||
|
@ -58,11 +58,12 @@ const List: React.FC<Props> = ({ clusterName, topics, externalTopics }) => {
|
||||||
<th>Total Partitions</th>
|
<th>Total Partitions</th>
|
||||||
<th>Out of sync replicas</th>
|
<th>Out of sync replicas</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
|
<th> </th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{items.map((topic) => (
|
{items.map((topic) => (
|
||||||
<ListItem key={topic.id} topic={topic} />
|
<ListItemContainer key={topic.id} topic={topic} />
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,14 +1,22 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { TopicWithDetailedInfo } from 'redux/interfaces';
|
import {
|
||||||
|
ClusterName,
|
||||||
|
TopicName,
|
||||||
|
TopicWithDetailedInfo,
|
||||||
|
} from 'redux/interfaces';
|
||||||
|
|
||||||
interface ListItemProps {
|
interface ListItemProps {
|
||||||
topic: TopicWithDetailedInfo;
|
topic: TopicWithDetailedInfo;
|
||||||
|
deleteTopic: (clusterName: ClusterName, topicName: TopicName) => void;
|
||||||
|
clusterName: ClusterName;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListItem: React.FC<ListItemProps> = ({
|
const ListItem: React.FC<ListItemProps> = ({
|
||||||
topic: { name, internal, partitions },
|
topic: { name, internal, partitions },
|
||||||
|
deleteTopic,
|
||||||
|
clusterName,
|
||||||
}) => {
|
}) => {
|
||||||
const outOfSyncReplicas = React.useMemo(() => {
|
const outOfSyncReplicas = React.useMemo(() => {
|
||||||
if (partitions === undefined || partitions.length === 0) {
|
if (partitions === undefined || partitions.length === 0) {
|
||||||
|
@ -21,6 +29,10 @@ const ListItem: React.FC<ListItemProps> = ({
|
||||||
}, 0);
|
}, 0);
|
||||||
}, [partitions]);
|
}, [partitions]);
|
||||||
|
|
||||||
|
const deleteTopicHandler = () => {
|
||||||
|
deleteTopic(clusterName, name);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
@ -42,6 +54,17 @@ const ListItem: React.FC<ListItemProps> = ({
|
||||||
{internal ? 'Internal' : 'External'}
|
{internal ? 'Internal' : 'External'}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="is-small button is-danger"
|
||||||
|
onClick={deleteTopicHandler}
|
||||||
|
>
|
||||||
|
<span className="icon is-small">
|
||||||
|
<i className="far fa-trash-alt" />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { RootState, ClusterName, TopicName, Action } from 'redux/interfaces';
|
||||||
|
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||||
|
import { ThunkDispatch } from 'redux-thunk';
|
||||||
|
import { deleteTopic } from 'redux/actions';
|
||||||
|
import ListItem from './ListItem';
|
||||||
|
|
||||||
|
interface RouteProps {
|
||||||
|
clusterName: ClusterName;
|
||||||
|
}
|
||||||
|
|
||||||
|
type OwnProps = RouteComponentProps<RouteProps>;
|
||||||
|
|
||||||
|
const mapStateToProps = (
|
||||||
|
state: RootState,
|
||||||
|
{
|
||||||
|
match: {
|
||||||
|
params: { clusterName },
|
||||||
|
},
|
||||||
|
}: OwnProps
|
||||||
|
) => ({
|
||||||
|
clusterName,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (
|
||||||
|
dispatch: ThunkDispatch<RootState, undefined, Action>
|
||||||
|
) => ({
|
||||||
|
deleteTopic: (clusterName: ClusterName, topicName: TopicName) => {
|
||||||
|
dispatch(deleteTopic(clusterName, topicName));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default withRouter(
|
||||||
|
connect(mapStateToProps, mapDispatchToProps)(ListItem)
|
||||||
|
);
|
|
@ -82,6 +82,12 @@ export const updateTopicAction = createAsyncAction(
|
||||||
'PATCH_TOPIC__FAILURE'
|
'PATCH_TOPIC__FAILURE'
|
||||||
)<undefined, Topic, undefined>();
|
)<undefined, Topic, undefined>();
|
||||||
|
|
||||||
|
export const deleteTopicAction = createAsyncAction(
|
||||||
|
'DELETE_TOPIC__REQUEST',
|
||||||
|
'DELETE_TOPIC__SUCCESS',
|
||||||
|
'DELETE_TOPIC__FAILURE'
|
||||||
|
)<undefined, TopicName, undefined>();
|
||||||
|
|
||||||
export const fetchConsumerGroupsAction = createAsyncAction(
|
export const fetchConsumerGroupsAction = createAsyncAction(
|
||||||
'GET_CONSUMER_GROUPS__REQUEST',
|
'GET_CONSUMER_GROUPS__REQUEST',
|
||||||
'GET_CONSUMER_GROUPS__SUCCESS',
|
'GET_CONSUMER_GROUPS__SUCCESS',
|
||||||
|
|
|
@ -234,6 +234,22 @@ export const updateTopic = (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteTopic = (
|
||||||
|
clusterName: ClusterName,
|
||||||
|
topicName: TopicName
|
||||||
|
): PromiseThunkResult => async (dispatch) => {
|
||||||
|
dispatch(actions.deleteTopicAction.request());
|
||||||
|
try {
|
||||||
|
await topicsApiClient.deleteTopic({
|
||||||
|
clusterName,
|
||||||
|
topicName,
|
||||||
|
});
|
||||||
|
dispatch(actions.deleteTopicAction.success(topicName));
|
||||||
|
} catch (e) {
|
||||||
|
dispatch(actions.deleteTopicAction.failure());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const fetchConsumerGroupsList = (
|
export const fetchConsumerGroupsList = (
|
||||||
clusterName: ClusterName
|
clusterName: ClusterName
|
||||||
): PromiseThunkResult => async (dispatch) => {
|
): PromiseThunkResult => async (dispatch) => {
|
||||||
|
|
|
@ -100,6 +100,15 @@ const reducer = (state = initialState, action: Action): TopicsState => {
|
||||||
};
|
};
|
||||||
case getType(actions.createTopicAction.success):
|
case getType(actions.createTopicAction.success):
|
||||||
return addToTopicList(state, action.payload);
|
return addToTopicList(state, action.payload);
|
||||||
|
case getType(actions.deleteTopicAction.success): {
|
||||||
|
const newState: TopicsState = { ...state };
|
||||||
|
delete newState.byName[action.payload];
|
||||||
|
newState.allNames = newState.allNames.filter(
|
||||||
|
(name) => name !== action.payload
|
||||||
|
);
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue