ListItem.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import React from 'react';
  2. import cx from 'classnames';
  3. import { FullConnectorInfo } from 'generated-sources';
  4. import { clusterConnectConnectorPath, clusterTopicPath } from 'lib/paths';
  5. import { ClusterName } from 'redux/interfaces';
  6. import { Link, NavLink } 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 ConnectorStatusTag from 'components/Connect/ConnectorStatusTag';
  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">
  49. <NavLink
  50. exact
  51. to={clusterConnectConnectorPath(clusterName, connect, name)}
  52. activeClassName="is-active"
  53. className="title is-6"
  54. >
  55. {name}
  56. </NavLink>
  57. </td>
  58. <td>{connect}</td>
  59. <td>{type}</td>
  60. <td>{connectorClass}</td>
  61. <td>
  62. <div className="is-flex is-flex-wrap-wrap">
  63. {topics?.map((t) => (
  64. <span key={t} className="tag is-info is-light mr-1 mb-1">
  65. <Link to={clusterTopicPath(clusterName, t)}>{t}</Link>
  66. </span>
  67. ))}
  68. </div>
  69. </td>
  70. <td>{status && <ConnectorStatusTag status={status.state} />}</td>
  71. <td>
  72. {runningTasks && (
  73. <span
  74. className={cx(
  75. failedTasksCount ? 'has-text-danger' : 'has-text-success'
  76. )}
  77. >
  78. {runningTasks} of {tasksCount}
  79. </span>
  80. )}
  81. </td>
  82. <td>
  83. <div className="has-text-right">
  84. <Dropdown
  85. label={
  86. <span className="icon">
  87. <i className="fas fa-cog" />
  88. </span>
  89. }
  90. right
  91. >
  92. <DropdownDivider />
  93. <DropdownItem
  94. onClick={() => setDeleteConnectorConfirmationVisible(true)}
  95. >
  96. <span className="has-text-danger">Remove Connector</span>
  97. </DropdownItem>
  98. </Dropdown>
  99. </div>
  100. <ConfirmationModal
  101. isOpen={isDeleteConnectorConfirmationVisible}
  102. onCancel={() => setDeleteConnectorConfirmationVisible(false)}
  103. onConfirm={handleDelete}
  104. >
  105. Are you sure want to remove <b>{name}</b> connector?
  106. </ConfirmationModal>
  107. </td>
  108. </tr>
  109. );
  110. };
  111. export default ListItem;