Skip to content

Commit aa4a489

Browse files
VixtirHaaroleangermanosin
authored
FE: Optional FTS (#1402)
Co-authored-by: Roman Zabaluev <gpg@haarolean.dev> Co-authored-by: German Osin <german.osin@gmail.com>
1 parent 3c1fd1f commit aa4a489

File tree

32 files changed

+390
-76
lines changed

32 files changed

+390
-76
lines changed

frontend/src/components/ACLPage/List/List.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourceP
2626
import BreakableTextCell from 'components/common/NewTable/BreakableTextCell';
2727
import { useQueryPersister } from 'components/common/NewTable/ColumnFilter';
2828
import { ActionPermissionWrapper } from 'components/common/ActionComponent';
29+
import useFts from 'components/common/Fts/useFts';
30+
import Fts from 'components/common/Fts/Fts';
2931
import ClusterContext from 'components/contexts/ClusterContext';
3032

3133
import * as S from './List.styled';
@@ -34,7 +36,8 @@ const ACList: React.FC = () => {
3436
const { clusterName } = useAppParams<{ clusterName: ClusterName }>();
3537
const [searchParams, setSearchParams] = useSearchParams();
3638
const [search, setSearch] = useState(searchParams.get('q') || '');
37-
const { data: aclList } = useAcls({ clusterName, search });
39+
const { isFtsEnabled } = useFts('acl');
40+
const { data: aclList } = useAcls({ clusterName, search, fts: isFtsEnabled });
3841
const { deleteResource } = useDeleteAcl(clusterName);
3942
const { isReadOnly } = React.useContext(ClusterContext);
4043
const modal = useConfirm(true);
@@ -214,6 +217,7 @@ const ACList: React.FC = () => {
214217
placeholder="Search by Principal Name"
215218
value={search}
216219
onChange={setSearch}
220+
extraActions={<Fts resourceName="acl" />}
217221
/>
218222
</ControlPanelWrapper>
219223
<Table

frontend/src/components/ACLPage/lib/useConsumerGroupsOptions.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
import useFts from 'components/common/Fts/useFts';
12
import { useConsumerGroups } from 'lib/hooks/api/consumers';
23
import { useMemo } from 'react';
34

45
const useConsumerGroupsOptions = (clusterName: string) => {
5-
const { data } = useConsumerGroups({ clusterName, search: '' });
6+
const { isFtsEnabled } = useFts('consumer_groups');
7+
const { data } = useConsumerGroups({
8+
clusterName,
9+
search: '',
10+
fts: isFtsEnabled,
11+
});
612
const consumerGroups = useMemo(() => {
713
return (
814
data?.consumerGroups?.map((cg) => {

frontend/src/components/ClusterPage/ClusterPage.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const ClusterPage: React.FC = () => {
4242
const { clusterName } = useAppParams<ClusterNameRoute>();
4343
const appInfo = React.useContext(GlobalSettingsContext);
4444

45-
const { data } = useClusters();
45+
const { data, isFetched } = useClusters();
4646
const contextValue = React.useMemo(() => {
4747
const cluster = data?.find(({ name }) => name === clusterName);
4848
const features = cluster?.features || [];
@@ -61,9 +61,17 @@ const ClusterPage: React.FC = () => {
6161
hasAclViewConfigured:
6262
features.includes(ClusterFeaturesEnum.KAFKA_ACL_VIEW) ||
6363
features.includes(ClusterFeaturesEnum.KAFKA_ACL_EDIT),
64+
ftsEnabled: features.includes(ClusterFeaturesEnum.FTS_ENABLED),
65+
ftsDefaultEnabled: features.includes(
66+
ClusterFeaturesEnum.FTS_DEFAULT_ENABLED
67+
),
6468
};
6569
}, [clusterName, data]);
6670

71+
if (!isFetched) {
72+
return <PageLoader />;
73+
}
74+
6775
return (
6876
<Suspense fallback={<PageLoader />}>
6977
<ClusterContext.Provider value={contextValue}>

frontend/src/components/ClusterPage/__tests__/ClusterPage.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ describe('ClusterPage', () => {
5252
const renderComponent = async (pathname: string, payload: Cluster[] = []) => {
5353
(useClusters as jest.Mock).mockImplementation(() => ({
5454
data: payload,
55+
isFetched: true,
5556
}));
5657
await render(
5758
<WithRoute path={`${clusterPath()}/*`}>

frontend/src/components/Connect/List/List.tsx

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
import React from 'react';
2-
import useAppParams from 'lib/hooks/useAppParams';
3-
import { ClusterNameRoute } from 'lib/paths';
4-
import { useConnectors } from 'lib/hooks/api/kafkaConnect';
5-
import { useSearchParams } from 'react-router-dom';
62
import { ConnectorsTable } from 'components/Connect/List/ConnectorsTable/ConnectorsTable';
3+
import { FullConnectorInfo } from 'generated-sources';
74

8-
const List: React.FC = () => {
9-
const { clusterName } = useAppParams<ClusterNameRoute>();
10-
const [searchParams] = useSearchParams();
11-
const { data: connectors = [] } = useConnectors(
12-
clusterName,
13-
searchParams.get('q') || ''
14-
);
5+
interface ConnectorsListProps {
6+
connectors: FullConnectorInfo[];
7+
}
158

9+
const List: React.FC<ConnectorsListProps> = ({ connectors }) => {
1610
return <ConnectorsTable connectors={connectors} />;
1711
};
1812

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,44 @@
11
import React, { Suspense } from 'react';
22
import Search from 'components/common/Search/Search';
33
import PageLoader from 'components/common/PageLoader/PageLoader';
4+
import useAppParams from 'lib/hooks/useAppParams';
5+
import { ClusterNameRoute } from 'lib/paths';
6+
import { useConnectors } from 'lib/hooks/api/kafkaConnect';
7+
import { useSearchParams } from 'react-router-dom';
8+
import useFts from 'components/common/Fts/useFts';
9+
import Fts from 'components/common/Fts/Fts';
10+
import { FullConnectorInfo } from 'generated-sources';
411

512
import * as S from './ListPage.styled';
613
import List from './List';
714
import ConnectorsStatistics from './Statistics/Statistics';
815

9-
const ListPage: React.FC = () => (
10-
<>
11-
<ConnectorsStatistics />
12-
<S.Search hasInput>
13-
<Search placeholder="Search by Connect Name, Status or Type" />
14-
</S.Search>
15-
<Suspense fallback={<PageLoader />}>
16-
<List />
17-
</Suspense>
18-
</>
19-
);
16+
const emptyConnectors: FullConnectorInfo[] = [];
17+
18+
const ListPage: React.FC = () => {
19+
const { clusterName } = useAppParams<ClusterNameRoute>();
20+
const [searchParams] = useSearchParams();
21+
const { isFtsEnabled } = useFts('connects');
22+
const { data: connectors = emptyConnectors, isLoading } = useConnectors(
23+
clusterName,
24+
searchParams.get('q') || '',
25+
isFtsEnabled
26+
);
27+
28+
return (
29+
<>
30+
<ConnectorsStatistics connectors={connectors} isLoading={isLoading} />
31+
<S.Search hasInput>
32+
<Search
33+
placeholder="Search by Connect Name, Status or Type"
34+
extraActions={<Fts resourceName="connects" />}
35+
/>
36+
</S.Search>
37+
<Suspense fallback={<PageLoader />}>
38+
<List connectors={connectors} />
39+
</Suspense>
40+
</>
41+
);
42+
};
2043

2144
export default ListPage;

frontend/src/components/Connect/List/Statistics/Statistics.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
import React, { useMemo } from 'react';
1+
import React, { FC, useMemo } from 'react';
22
import * as Statistics from 'components/common/Statistics';
3-
import useAppParams from 'lib/hooks/useAppParams';
4-
import { ClusterNameRoute } from 'lib/paths';
5-
import { useConnectors } from 'lib/hooks/api/kafkaConnect';
3+
import { FullConnectorInfo } from 'generated-sources';
64

75
import { computeStatistics } from './models/computeStatistics';
86

9-
const ConnectorsStatistics = () => {
10-
const { clusterName } = useAppParams<ClusterNameRoute>();
11-
const { data: connectors = [], isLoading } = useConnectors(clusterName);
12-
7+
interface ConnectorsStatisticsProps {
8+
connectors: FullConnectorInfo[];
9+
isLoading: boolean;
10+
}
11+
const ConnectorsStatistics: FC<ConnectorsStatisticsProps> = ({
12+
connectors,
13+
isLoading,
14+
}) => {
1315
const statistics = useMemo(() => computeStatistics(connectors), [connectors]);
1416

1517
return (

frontend/src/components/Connect/List/Statistics/__tests__/Statistics.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('Kafka Connect Connectors Statistics', () => {
2525
function renderComponent({ data = [], isLoading }: RenderComponentProps) {
2626
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2727
useConnectorsMock.mockReturnValue({ data, isLoading } as any);
28-
render(<ConnectorsStatistics />);
28+
render(<ConnectorsStatistics connectors={data} isLoading={isLoading} />);
2929
}
3030

3131
describe('when data loading', () => {

frontend/src/components/Connect/List/__tests__/List.spec.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
useResetConnectorOffsets,
1616
useUpdateConnectorState,
1717
} from 'lib/hooks/api/kafkaConnect';
18+
import { FullConnectorInfo } from 'generated-sources';
1819

1920
const mockedUsedNavigate = jest.fn();
2021
const mockDelete = jest.fn();
@@ -34,11 +35,14 @@ jest.mock('lib/hooks/api/kafkaConnect', () => ({
3435

3536
const clusterName = 'local';
3637

37-
const renderComponent = (contextValue: ContextProps = initialValue) =>
38+
const renderComponent = (
39+
contextValue: ContextProps = initialValue,
40+
data: FullConnectorInfo[] = connectors
41+
) =>
3842
render(
3943
<ClusterContext.Provider value={contextValue}>
4044
<WithRoute path={clusterConnectorsPath()}>
41-
<List />
45+
<List connectors={data} />
4246
</WithRoute>
4347
</ClusterContext.Provider>,
4448
{ initialEntries: [clusterConnectorsPath(clusterName)] }
@@ -47,9 +51,6 @@ const renderComponent = (contextValue: ContextProps = initialValue) =>
4751
describe('Connectors List', () => {
4852
describe('when the connectors are loaded', () => {
4953
beforeEach(() => {
50-
(useConnectors as jest.Mock).mockImplementation(() => ({
51-
data: connectors,
52-
}));
5354
const restartConnector = jest.fn();
5455
(useUpdateConnectorState as jest.Mock).mockImplementation(() => ({
5556
mutateAsync: restartConnector,
@@ -84,7 +85,7 @@ describe('Connectors List', () => {
8485
});
8586

8687
it('renders empty table', async () => {
87-
renderComponent();
88+
renderComponent(undefined, []);
8889
expect(screen.getByRole('table')).toBeInTheDocument();
8990
expect(
9091
screen.getByRole('row', { name: 'No connectors found' })

frontend/src/components/ConsumerGroups/List.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ import { useConsumerGroups } from 'lib/hooks/api/consumers';
1717
import Tooltip from 'components/common/Tooltip/Tooltip';
1818
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
1919
import { useLocalStoragePersister } from 'components/common/NewTable/ColumnResizer/lib';
20+
import useFts from 'components/common/Fts/useFts';
21+
import Fts from 'components/common/Fts/Fts';
2022

2123
const List = () => {
2224
const { clusterName } = useAppParams<ClusterNameRoute>();
2325
const [searchParams] = useSearchParams();
2426
const navigate = useNavigate();
27+
const { isFtsEnabled } = useFts('consumer_groups');
2528

2629
const consumerGroups = useConsumerGroups({
2730
clusterName,
@@ -32,6 +35,7 @@ const List = () => {
3235
page: Number(searchParams.get('page') || 1),
3336
perPage: Number(searchParams.get('perPage') || PER_PAGE),
3437
search: searchParams.get('q') || '',
38+
fts: isFtsEnabled,
3539
});
3640

3741
const columns = React.useMemo<ColumnDef<ConsumerGroup>[]>(
@@ -104,7 +108,10 @@ const List = () => {
104108
<>
105109
<ResourcePageHeading text="Consumers" />
106110
<ControlPanelWrapper hasInput>
107-
<Search placeholder="Search by Consumer Group ID" />
111+
<Search
112+
placeholder="Search by Consumer Group ID"
113+
extraActions={<Fts resourceName="consumer_groups" />}
114+
/>
108115
</ControlPanelWrapper>
109116
<Table
110117
columns={columns}

0 commit comments

Comments
 (0)