List.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import React from 'react';
  2. import { TopicWithDetailedInfo, ClusterName } from 'redux/interfaces';
  3. import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
  4. import { NavLink, useParams } from 'react-router-dom';
  5. import { clusterTopicNewPath } from 'lib/paths';
  6. import usePagination from 'lib/hooks/usePagination';
  7. import { FetchTopicsListParams } from 'redux/actions';
  8. import ClusterContext from 'components/contexts/ClusterContext';
  9. import PageLoader from 'components/common/PageLoader/PageLoader';
  10. import ListItem from './ListItem';
  11. interface Props {
  12. areTopicsFetching: boolean;
  13. topics: TopicWithDetailedInfo[];
  14. externalTopics: TopicWithDetailedInfo[];
  15. fetchTopicsList(props: FetchTopicsListParams): void;
  16. }
  17. const List: React.FC<Props> = ({
  18. areTopicsFetching,
  19. topics,
  20. externalTopics,
  21. fetchTopicsList,
  22. }) => {
  23. const { isReadOnly } = React.useContext(ClusterContext);
  24. const { clusterName } = useParams<{ clusterName: ClusterName }>();
  25. const { page, perPage } = usePagination();
  26. React.useEffect(() => {
  27. fetchTopicsList({ clusterName, page, perPage });
  28. }, [fetchTopicsList, clusterName, page, perPage]);
  29. const [showInternal, setShowInternal] = React.useState<boolean>(true);
  30. const handleSwitch = React.useCallback(() => {
  31. setShowInternal(!showInternal);
  32. }, [showInternal]);
  33. const items = showInternal ? topics : externalTopics;
  34. return (
  35. <div className="section">
  36. <Breadcrumb>{showInternal ? `All Topics` : `External Topics`}</Breadcrumb>
  37. <div className="box">
  38. <div className="level">
  39. <div className="level-item level-left">
  40. <div className="field">
  41. <input
  42. id="switchRoundedDefault"
  43. type="checkbox"
  44. name="switchRoundedDefault"
  45. className="switch is-rounded"
  46. checked={showInternal}
  47. onChange={handleSwitch}
  48. />
  49. <label htmlFor="switchRoundedDefault">Show Internal Topics</label>
  50. </div>
  51. </div>
  52. <div className="level-item level-right">
  53. {!isReadOnly && (
  54. <NavLink
  55. className="button is-primary"
  56. to={clusterTopicNewPath(clusterName)}
  57. >
  58. Add a Topic
  59. </NavLink>
  60. )}
  61. </div>
  62. </div>
  63. </div>
  64. {areTopicsFetching ? (
  65. <PageLoader />
  66. ) : (
  67. <div className="box">
  68. <table className="table is-striped is-fullwidth">
  69. <thead>
  70. <tr>
  71. <th>Topic Name</th>
  72. <th>Total Partitions</th>
  73. <th>Out of sync replicas</th>
  74. <th>Type</th>
  75. </tr>
  76. </thead>
  77. <tbody>
  78. {items.length > 0 ? (
  79. items.map((topic) => (
  80. <ListItem key={topic.name} topic={topic} />
  81. ))
  82. ) : (
  83. <tr>
  84. <td colSpan={10}>No topics found</td>
  85. </tr>
  86. )}
  87. </tbody>
  88. </table>
  89. </div>
  90. )}
  91. </div>
  92. );
  93. };
  94. export default List;