Details.tsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import React from 'react';
  2. import { ClusterName, TopicName } from 'redux/interfaces';
  3. import { Topic, TopicDetails } from 'generated-sources';
  4. import { NavLink, Switch, Route, useHistory } from 'react-router-dom';
  5. import {
  6. clusterTopicSettingsPath,
  7. clusterTopicPath,
  8. clusterTopicMessagesPath,
  9. clusterTopicsPath,
  10. clusterTopicConsumerGroupsPath,
  11. clusterTopicEditPath,
  12. clusterTopicSendMessagePath,
  13. } from 'lib/paths';
  14. import ClusterContext from 'components/contexts/ClusterContext';
  15. import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
  16. import { useDispatch } from 'react-redux';
  17. import { deleteTopicAction } from 'redux/actions';
  18. import PageHeading from 'components/common/PageHeading/PageHeading';
  19. import { Button } from 'components/common/Button/Button';
  20. import Dropdown from 'components/common/Dropdown/Dropdown';
  21. import VerticalElipsisIcon from 'components/common/Icons/VerticalElipsisIcon';
  22. import DropdownItem from 'components/common/Dropdown/DropdownItem';
  23. import styled from 'styled-components';
  24. import Navbar from 'components/common/Navigation/Navbar.styled';
  25. import OverviewContainer from './Overview/OverviewContainer';
  26. import TopicConsumerGroupsContainer from './ConsumerGroups/TopicConsumerGroupsContainer';
  27. import SettingsContainer from './Settings/SettingsContainer';
  28. import Messages from './Messages/Messages';
  29. interface Props extends Topic, TopicDetails {
  30. clusterName: ClusterName;
  31. topicName: TopicName;
  32. isInternal: boolean;
  33. isDeleted: boolean;
  34. deleteTopic: (clusterName: ClusterName, topicName: TopicName) => void;
  35. clearTopicMessages(clusterName: ClusterName, topicName: TopicName): void;
  36. }
  37. const HeaderControlsWrapper = styled.div`
  38. display: flex;
  39. justify-content: flex-end;
  40. align-self: center;
  41. gap: 26px;
  42. `;
  43. const Details: React.FC<Props> = ({
  44. clusterName,
  45. topicName,
  46. isInternal,
  47. isDeleted,
  48. deleteTopic,
  49. clearTopicMessages,
  50. }) => {
  51. const history = useHistory();
  52. const dispatch = useDispatch();
  53. const { isReadOnly, isTopicDeletionAllowed } =
  54. React.useContext(ClusterContext);
  55. const [isDeleteTopicConfirmationVisible, setDeleteTopicConfirmationVisible] =
  56. React.useState(false);
  57. const [isClearTopicConfirmationVisible, setClearTopicConfirmationVisible] =
  58. React.useState(false);
  59. const deleteTopicHandler = React.useCallback(() => {
  60. deleteTopic(clusterName, topicName);
  61. }, [clusterName, topicName]);
  62. React.useEffect(() => {
  63. if (isDeleted) {
  64. dispatch(deleteTopicAction.cancel());
  65. history.push(clusterTopicsPath(clusterName));
  66. }
  67. }, [isDeleted]);
  68. const clearTopicMessagesHandler = React.useCallback(() => {
  69. clearTopicMessages(clusterName, topicName);
  70. setClearTopicConfirmationVisible(false);
  71. }, [clusterName, topicName]);
  72. return (
  73. <div>
  74. <PageHeading text={topicName}>
  75. <HeaderControlsWrapper>
  76. <Route
  77. exact
  78. path="/ui/clusters/:clusterName/topics/:topicName/messages"
  79. >
  80. <Button
  81. buttonSize="M"
  82. buttonType="primary"
  83. isLink
  84. to={clusterTopicSendMessagePath(clusterName, topicName)}
  85. >
  86. Produce Message
  87. </Button>
  88. </Route>
  89. {!isReadOnly && !isInternal && (
  90. <Route path="/ui/clusters/:clusterName/topics/:topicName">
  91. <Dropdown label={<VerticalElipsisIcon />} right>
  92. <DropdownItem
  93. onClick={() =>
  94. history.push(clusterTopicEditPath(clusterName, topicName))
  95. }
  96. >
  97. Edit settings
  98. </DropdownItem>
  99. <DropdownItem
  100. onClick={() => setClearTopicConfirmationVisible(true)}
  101. danger
  102. >
  103. Clear messages
  104. </DropdownItem>
  105. {isTopicDeletionAllowed && (
  106. <DropdownItem
  107. onClick={() => setDeleteTopicConfirmationVisible(true)}
  108. danger
  109. >
  110. Remove topic
  111. </DropdownItem>
  112. )}
  113. </Dropdown>
  114. </Route>
  115. )}
  116. </HeaderControlsWrapper>
  117. </PageHeading>
  118. <ConfirmationModal
  119. isOpen={isDeleteTopicConfirmationVisible}
  120. onCancel={() => setDeleteTopicConfirmationVisible(false)}
  121. onConfirm={deleteTopicHandler}
  122. >
  123. Are you sure want to remove <b>{topicName}</b> topic?
  124. </ConfirmationModal>
  125. <ConfirmationModal
  126. isOpen={isClearTopicConfirmationVisible}
  127. onCancel={() => setClearTopicConfirmationVisible(false)}
  128. onConfirm={clearTopicMessagesHandler}
  129. >
  130. Are you sure want to clear topic messages?
  131. </ConfirmationModal>
  132. <Navbar role="navigation">
  133. <NavLink
  134. exact
  135. to={clusterTopicPath(clusterName, topicName)}
  136. activeClassName="is-active is-primary"
  137. >
  138. Overview
  139. </NavLink>
  140. <NavLink
  141. exact
  142. to={clusterTopicMessagesPath(clusterName, topicName)}
  143. activeClassName="is-active"
  144. >
  145. Messages
  146. </NavLink>
  147. <NavLink
  148. exact
  149. to={clusterTopicConsumerGroupsPath(clusterName, topicName)}
  150. activeClassName="is-active"
  151. >
  152. Consumers
  153. </NavLink>
  154. <NavLink
  155. exact
  156. to={clusterTopicSettingsPath(clusterName, topicName)}
  157. activeClassName="is-active"
  158. >
  159. Settings
  160. </NavLink>
  161. </Navbar>
  162. <Switch>
  163. <Route
  164. exact
  165. path="/ui/clusters/:clusterName/topics/:topicName/messages"
  166. component={Messages}
  167. />
  168. <Route
  169. exact
  170. path="/ui/clusters/:clusterName/topics/:topicName/settings"
  171. component={SettingsContainer}
  172. />
  173. <Route
  174. exact
  175. path="/ui/clusters/:clusterName/topics/:topicName"
  176. component={OverviewContainer}
  177. />
  178. <Route
  179. exact
  180. path="/ui/clusters/:clusterName/topics/:topicName/consumer-groups"
  181. component={TopicConsumerGroupsContainer}
  182. />
  183. </Switch>
  184. </div>
  185. );
  186. };
  187. export default Details;