diff --git a/frontend/src/components/Connect/List/ConnectorsTable/ConnectorsTable.tsx b/frontend/src/components/Connect/List/ConnectorsTable/ConnectorsTable.tsx
index 44014c2b2..4a2e45382 100644
--- a/frontend/src/components/Connect/List/ConnectorsTable/ConnectorsTable.tsx
+++ b/frontend/src/components/Connect/List/ConnectorsTable/ConnectorsTable.tsx
@@ -1,9 +1,10 @@
-import React from 'react';
+import React, { useCallback } from 'react';
import { FullConnectorInfo } from 'generated-sources';
import Table from 'components/common/NewTable';
import { useLocalStoragePersister } from 'components/common/NewTable/ColumnResizer/lib';
import { useQueryPersister } from 'components/common/NewTable/ColumnFilter';
import { VisibilityState } from '@tanstack/react-table';
+import { useFilteredConnectorsDispatch } from 'components/Connect/model/FilteredConnectorsProvider';
import { connectorsColumns } from './connectorsColumns/columns';
@@ -21,11 +22,16 @@ export const ConnectorsTable = ({
columnSizingPersistKey = 'KafkaConnect',
columnVisibility,
}: ConnectorsTableProps) => {
+ const dispath = useFilteredConnectorsDispatch();
const filterPersister = useQueryPersister(connectorsColumns);
const columnSizingPersister = useLocalStoragePersister(
columnSizingPersistKey
);
+ const onFilterRows = useCallback((rows: FullConnectorInfo[]) => {
+ dispath({ type: 'updated', connectors: rows });
+ }, []);
+
return (
);
};
diff --git a/frontend/src/components/Connect/List/ListPage.tsx b/frontend/src/components/Connect/List/ListPage.tsx
index 39d87e1de..dab3fe3f1 100644
--- a/frontend/src/components/Connect/List/ListPage.tsx
+++ b/frontend/src/components/Connect/List/ListPage.tsx
@@ -8,6 +8,7 @@ import { useSearchParams } from 'react-router-dom';
import useFts from 'components/common/Fts/useFts';
import Fts from 'components/common/Fts/Fts';
import { FullConnectorInfo } from 'generated-sources';
+import { FilteredConnectorsProvider } from 'components/Connect/model/FilteredConnectorsProvider';
import * as S from './ListPage.styled';
import List from './List';
@@ -26,8 +27,8 @@ const ListPage: React.FC = () => {
);
return (
- <>
-
+
+
{
}>
- >
+
);
};
diff --git a/frontend/src/components/Connect/List/Statistics/Statistics.tsx b/frontend/src/components/Connect/List/Statistics/Statistics.tsx
index f6b58bcb1..13463d6d0 100644
--- a/frontend/src/components/Connect/List/Statistics/Statistics.tsx
+++ b/frontend/src/components/Connect/List/Statistics/Statistics.tsx
@@ -1,18 +1,18 @@
import React, { FC, useMemo } from 'react';
import * as Statistics from 'components/common/Statistics';
-import { FullConnectorInfo } from 'generated-sources';
+import { useFilteredConnectors } from 'components/Connect/model/FilteredConnectorsProvider';
import { computeStatistics } from './models/computeStatistics';
interface ConnectorsStatisticsProps {
- connectors: FullConnectorInfo[];
isLoading: boolean;
}
-const ConnectorsStatistics: FC = ({
- connectors,
- isLoading,
-}) => {
- const statistics = useMemo(() => computeStatistics(connectors), [connectors]);
+const ConnectorsStatistics: FC = ({ isLoading }) => {
+ const connectors = useFilteredConnectors();
+
+ const statistics = useMemo(() => {
+ return computeStatistics(connectors);
+ }, [connectors]);
return (
diff --git a/frontend/src/components/Connect/List/Statistics/__tests__/Statistics.spec.tsx b/frontend/src/components/Connect/List/Statistics/__tests__/Statistics.spec.tsx
index b4056d7e4..a98b7a160 100644
--- a/frontend/src/components/Connect/List/Statistics/__tests__/Statistics.spec.tsx
+++ b/frontend/src/components/Connect/List/Statistics/__tests__/Statistics.spec.tsx
@@ -5,6 +5,7 @@ import ConnectorsStatistics from 'components/Connect/List/Statistics/Statistics'
import { useConnectors } from 'lib/hooks/api/kafkaConnect';
import { connectors } from 'lib/fixtures/kafkaConnect';
import { FullConnectorInfo } from 'generated-sources';
+import { FilteredConnectorsProvider } from 'components/Connect/model/FilteredConnectorsProvider';
jest.mock('lib/hooks/api/kafkaConnect');
jest.mock('lib/hooks/useAppParams', () => ({
@@ -25,7 +26,11 @@ describe('Kafka Connect Connectors Statistics', () => {
function renderComponent({ data = [], isLoading }: RenderComponentProps) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
useConnectorsMock.mockReturnValue({ data, isLoading } as any);
- render();
+ render(
+
+
+
+ );
}
describe('when data loading', () => {
diff --git a/frontend/src/components/Connect/List/Statistics/models/computeStatistics.ts b/frontend/src/components/Connect/List/Statistics/models/computeStatistics.ts
index ad3b85a1d..0311994bf 100644
--- a/frontend/src/components/Connect/List/Statistics/models/computeStatistics.ts
+++ b/frontend/src/components/Connect/List/Statistics/models/computeStatistics.ts
@@ -1,6 +1,6 @@
import { ConnectorState, FullConnectorInfo } from 'generated-sources';
-interface Statistic {
+export interface Statistic {
connectorsCount: number;
failedConnectorsCount: number;
tasksCount: number;
diff --git a/frontend/src/components/Connect/List/__tests__/List.spec.tsx b/frontend/src/components/Connect/List/__tests__/List.spec.tsx
index 679c4299e..a489f2fb7 100644
--- a/frontend/src/components/Connect/List/__tests__/List.spec.tsx
+++ b/frontend/src/components/Connect/List/__tests__/List.spec.tsx
@@ -16,6 +16,7 @@ import {
useUpdateConnectorState,
} from 'lib/hooks/api/kafkaConnect';
import { FullConnectorInfo } from 'generated-sources';
+import { FilteredConnectorsProvider } from 'components/Connect/model/FilteredConnectorsProvider';
const mockedUsedNavigate = jest.fn();
const mockDelete = jest.fn();
@@ -42,7 +43,9 @@ const renderComponent = (
render(
-
+
+
+
,
{ initialEntries: [clusterConnectorsPath(clusterName)] }
diff --git a/frontend/src/components/Connect/model/FilteredConnectorsProvider.tsx b/frontend/src/components/Connect/model/FilteredConnectorsProvider.tsx
new file mode 100644
index 000000000..1952e9ab1
--- /dev/null
+++ b/frontend/src/components/Connect/model/FilteredConnectorsProvider.tsx
@@ -0,0 +1,58 @@
+import { FullConnectorInfo } from 'generated-sources';
+import React, {
+ createContext,
+ Dispatch,
+ FC,
+ PropsWithChildren,
+ useContext,
+ useReducer,
+} from 'react';
+
+const initialConnectors: FullConnectorInfo[] = [];
+type Action = { type: 'updated'; connectors: FullConnectorInfo[] };
+
+function reducer(connectors: FullConnectorInfo[], action: Action) {
+ switch (action.type) {
+ case 'updated': {
+ return action.connectors;
+ }
+ default: {
+ throw Error(`Unknown action: ${action.type}`);
+ }
+ }
+}
+
+const ConnectorsContext = createContext(null);
+const ConnectorsDispatchContext = createContext | null>(null);
+
+export const FilteredConnectorsProvider: FC<
+ PropsWithChildren<{ initialData?: FullConnectorInfo[] }>
+> = ({ children, initialData }) => {
+ const [connectors, dispatch] = useReducer(
+ reducer,
+ initialData ?? initialConnectors
+ );
+ return (
+
+
+ {children}
+
+
+ );
+};
+
+export const useFilteredConnectors = () => {
+ const context = useContext(ConnectorsContext);
+ if (!context) {
+ throw new Error('useCounter must be used within a CounterProvider');
+ }
+ return context;
+};
+
+export const useFilteredConnectorsDispatch = () => {
+ const context = useContext(ConnectorsDispatchContext);
+ if (!context) {
+ throw new Error('useCounter must be used within a CounterProvider');
+ }
+ return context;
+};
diff --git a/frontend/src/components/common/NewTable/Table.tsx b/frontend/src/components/common/NewTable/Table.tsx
index b77b0e758..665f141c6 100644
--- a/frontend/src/components/common/NewTable/Table.tsx
+++ b/frontend/src/components/common/NewTable/Table.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import type {
ColumnDef,
ColumnFiltersState,
@@ -77,6 +77,8 @@ export interface TableProps {
onMouseLeave?: () => void;
setRowId?: (originalRow: TData) => string;
+
+ onFilterRows?: (rows: TData[]) => void;
}
type UpdaterFn = (previousState: T) => T;
@@ -163,6 +165,7 @@ function Table({
filterPersister,
resetPaginationOnFilter = true,
columnVisibility,
+ onFilterRows,
}: TableProps) {
const [searchParams, setSearchParams] = useSearchParams();
const location = useLocation();
@@ -273,6 +276,14 @@ function Table({
return colSizes;
}, [table.getState().columnSizingInfo, table.getState().columnSizing]);
+ useEffect(() => {
+ if (onFilterRows) {
+ const filteredRows = table.getFilteredRowModel().rows;
+ const filteredData = filteredRows.map((row) => row.original);
+ onFilterRows(filteredData);
+ }
+ }, [table.getState().columnFilters]);
+
const handleRowClick = (row: Row) => (e: React.MouseEvent) => {
// If row selection is enabled do not handle row click.
if (enableRowSelection) return undefined;