ListItem.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import React from 'react';
  2. import cx from 'classnames';
  3. import { FullConnectorInfo } from 'generated-sources';
  4. import { clusterTopicPath } from 'lib/paths';
  5. import { ClusterName } from 'redux/interfaces';
  6. import { Link } from 'react-router-dom';
  7. import { useDispatch } from 'react-redux';
  8. import { deleteConnector } from 'redux/actions';
  9. import Dropdown from 'components/common/Dropdown/Dropdown';
  10. import DropdownDivider from 'components/common/Dropdown/DropdownDivider';
  11. import DropdownItem from 'components/common/Dropdown/DropdownItem';
  12. import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
  13. import StatusTag from '../StatusTag';
  14. export interface ListItemProps {
  15. clusterName: ClusterName;
  16. connector: FullConnectorInfo;
  17. }
  18. const ListItem: React.FC<ListItemProps> = ({
  19. clusterName,
  20. connector: {
  21. name,
  22. connect,
  23. type,
  24. connectorClass,
  25. topics,
  26. status,
  27. tasksCount,
  28. failedTasksCount,
  29. },
  30. }) => {
  31. const dispatch = useDispatch();
  32. const [
  33. isDeleteConnectorConfirmationVisible,
  34. setDeleteConnectorConfirmationVisible,
  35. ] = React.useState(false);
  36. const handleDelete = React.useCallback(() => {
  37. if (clusterName && connect && name) {
  38. dispatch(deleteConnector(clusterName, connect, name));
  39. }
  40. setDeleteConnectorConfirmationVisible(false);
  41. }, [clusterName, connect, name]);
  42. const runningTasks = React.useMemo(() => {
  43. if (!tasksCount) return null;
  44. return tasksCount - (failedTasksCount || 0);
  45. }, [tasksCount, failedTasksCount]);
  46. return (
  47. <tr>
  48. <td className="has-text-overflow-ellipsis">{name}</td>
  49. <td>{connect}</td>
  50. <td>{type}</td>
  51. <td>{connectorClass}</td>
  52. <td>
  53. {topics?.map((t) => (
  54. <Link className="mr-1" key={t} to={clusterTopicPath(clusterName, t)}>
  55. {t}
  56. </Link>
  57. ))}
  58. </td>
  59. <td>{status && <StatusTag status={status} />}</td>
  60. <td>
  61. {runningTasks && (
  62. <span
  63. className={cx(
  64. failedTasksCount ? 'has-text-danger' : 'has-text-success'
  65. )}
  66. >
  67. {runningTasks} of {tasksCount}
  68. </span>
  69. )}
  70. </td>
  71. <td>
  72. <div className="has-text-right">
  73. <Dropdown
  74. label={
  75. <span className="icon">
  76. <i className="fas fa-cog" />
  77. </span>
  78. }
  79. right
  80. >
  81. <DropdownDivider />
  82. <DropdownItem
  83. onClick={() => setDeleteConnectorConfirmationVisible(true)}
  84. >
  85. <span className="has-text-danger">Remove Connector</span>
  86. </DropdownItem>
  87. </Dropdown>
  88. </div>
  89. <ConfirmationModal
  90. isOpen={isDeleteConnectorConfirmationVisible}
  91. onCancel={() => setDeleteConnectorConfirmationVisible(false)}
  92. onConfirm={handleDelete}
  93. >
  94. Are you sure want to remove <b>{name}</b> connector?
  95. </ConfirmationModal>
  96. </td>
  97. </tr>
  98. );
  99. };
  100. export default ListItem;