import React from 'react'; import { useNavigate } from 'react-router-dom'; import useAppParams from 'lib/hooks/useAppParams'; import { TopicWithDetailedInfo, ClusterName, TopicName, } from 'redux/interfaces'; import { ClusterNameRoute, clusterTopicCopyRelativePath, clusterTopicNewRelativePath, } from 'lib/paths'; import usePagination from 'lib/hooks/usePagination'; import ClusterContext from 'components/contexts/ClusterContext'; import PageLoader from 'components/common/PageLoader/PageLoader'; import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal'; import { GetTopicsRequest, SortOrder, TopicColumnsToSort, } from 'generated-sources'; import Search from 'components/common/Search/Search'; import { PER_PAGE } from 'lib/constants'; import { Button } from 'components/common/Button/Button'; import PageHeading from 'components/common/PageHeading/PageHeading'; import { ControlPanelWrapper } from 'components/common/ControlPanel/ControlPanel.styled'; import Switch from 'components/common/Switch/Switch'; import { SmartTable } from 'components/common/SmartTable/SmartTable'; import { TableColumn } from 'components/common/SmartTable/TableColumn'; import { useTableState } from 'lib/hooks/useTableState'; import PlusIcon from 'components/common/Icons/PlusIcon'; import { MessagesCell, OutOfSyncReplicasCell, TitleCell, TopicSizeCell, } from './TopicsTableCells'; import * as S from './List.styled'; import ActionsCell from './ActionsCell/ActionsCell'; export interface TopicsListProps { areTopicsFetching: boolean; topics: TopicWithDetailedInfo[]; totalPages: number; fetchTopicsList(payload: GetTopicsRequest): void; deleteTopics(payload: { clusterName: ClusterName; topicNames: TopicName[]; }): void; clearTopicsMessages(payload: { clusterName: ClusterName; topicNames: TopicName[]; }): void; clearTopicMessages(payload: { topicName: TopicName; clusterName: ClusterName; partitions?: number[]; }): void; search: string; orderBy: string | null; sortOrder: SortOrder; setTopicsSearch(search: string): void; setTopicsOrderBy(orderBy: string | null): void; } const List: React.FC = ({ areTopicsFetching, topics, totalPages, fetchTopicsList, deleteTopics, clearTopicsMessages, search, orderBy, sortOrder, setTopicsSearch, setTopicsOrderBy, }) => { const { isReadOnly } = React.useContext(ClusterContext); const { clusterName } = useAppParams(); const { page, perPage } = usePagination(); const [showInternal, setShowInternal] = React.useState( !localStorage.getItem('hideInternalTopics') && true ); const [cachedPage, setCachedPage] = React.useState( page || null ); const navigate = useNavigate(); const topicsListParams = React.useMemo( () => ({ clusterName, page, perPage, orderBy: (orderBy as TopicColumnsToSort) || undefined, sortOrder, search, showInternal, }), [clusterName, page, perPage, orderBy, sortOrder, search, showInternal] ); React.useEffect(() => { fetchTopicsList(topicsListParams); }, [fetchTopicsList, topicsListParams]); const tableState = useTableState( topics, { idSelector: (topic) => topic.name, totalPages, isRowSelectable: (topic) => !topic.internal, }, { handleOrderBy: setTopicsOrderBy, orderBy, sortOrder, } ); const getSelectedTopic = (): string => { const name = Array.from(tableState.selectedIds)[0]; const selectedTopic = tableState.data.find( (topic: TopicWithDetailedInfo) => topic.name === name ) || {}; return Object.keys(selectedTopic) .map((x: string) => { const value = selectedTopic[x as keyof typeof selectedTopic]; return value && x !== 'partitions' ? `${x}=${value}` : null; }) .join('&'); }; const handleSwitch = () => { if (showInternal) { localStorage.setItem('hideInternalTopics', 'true'); } else { localStorage.removeItem('hideInternalTopics'); } setShowInternal(!showInternal); navigate({ search: `?page=1&perPage=${perPage || PER_PAGE}`, }); }; const [confirmationModal, setConfirmationModal] = React.useState< '' | 'deleteTopics' | 'purgeMessages' >(''); const [confirmationModalText, setConfirmationModalText] = React.useState(''); const closeConfirmationModal = () => { setConfirmationModal(''); }; const clearSelectedTopics = () => tableState.toggleSelection(false); const searchHandler = (searchString: string) => { setTopicsSearch(searchString); setCachedPage(page || null); const newPageQuery = !searchString && cachedPage ? cachedPage : 1; navigate({ search: `?page=${newPageQuery}&perPage=${perPage || PER_PAGE}`, }); }; const deleteOrPurgeConfirmationHandler = () => { const selectedIds = Array.from(tableState.selectedIds); if (confirmationModal === 'deleteTopics') { deleteTopics({ clusterName, topicNames: selectedIds }); } else { clearTopicsMessages({ clusterName, topicNames: selectedIds }); } closeConfirmationModal(); clearSelectedTopics(); fetchTopicsList(topicsListParams); }; return (
{!isReadOnly && ( )}
{areTopicsFetching ? ( ) : (
{tableState.selectedCount > 0 && ( <> {tableState.selectedCount === 1 && ( )} {confirmationModalText} )}
)}
); }; export default List;