Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
844e34e
Impl HeartbeatSerde
Haarolean Sep 25, 2025
496aa43
Impl OffsetSyncSerde
Haarolean Sep 25, 2025
13c951f
Impl CheckpointSerde
Haarolean Sep 25, 2025
c25604b
lint
Haarolean Sep 25, 2025
de52924
Change result type from string to json in appropriate cases
Haarolean Sep 26, 2025
6146073
Impl tests
Haarolean Sep 26, 2025
fc59e6b
Logs
Haarolean Sep 26, 2025
267d52d
Split k/v methods
Haarolean Sep 26, 2025
89ca82c
Upd fields visibility
Haarolean Sep 27, 2025
1ea2aa6
Auto register serdes for well known topic patterns
Haarolean Sep 29, 2025
9c987ef
Simplify serialization
Haarolean Sep 29, 2025
7e25c7c
Reduced duplicate code
germanosin Sep 29, 2025
c5cb67d
Reduced duplicate code
germanosin Sep 29, 2025
40760ca
Reduced duplicate code
germanosin Sep 29, 2025
68a8a26
Reduced duplicate code
germanosin Sep 29, 2025
dfa9cbb
Reduced duplicate code
germanosin Sep 29, 2025
6b2431c
Reduced duplicate code
germanosin Sep 30, 2025
35f6c08
Reduced duplicate code
germanosin Sep 30, 2025
bf2fce1
BE: issue-1333 optional fts
germanosin Oct 2, 2025
57ede6c
FE: Add button for enabling topics fts search
Vixtir Oct 5, 2025
1b36d3a
FE: Fix tests, icon styles
Vixtir Oct 5, 2025
db6aca2
Merge main
germanosin Oct 8, 2025
552c305
Merge branch 'main' into issues/1333-optional-fts-fe
germanosin Oct 8, 2025
40d6a38
Add useFts to topic table
Vixtir Oct 8, 2025
1333af0
Merge branch 'main' into issues/1333-optional-fts-fe
germanosin Oct 8, 2025
fb7faa1
Merge branch 'main' into issues/1333-optional-fts-fe
germanosin Oct 12, 2025
ca25d84
FE: Add fts to other resources, add logic to show and handle fts button
Vixtir Oct 12, 2025
07190b2
FE: Use config vars
Vixtir Oct 15, 2025
4ed5e88
FE: Fix state sync
Vixtir Oct 15, 2025
2a96c1e
FE: Use config vars
Vixtir Oct 15, 2025
6384333
FE: Fix race condition in cluster context
Vixtir Oct 15, 2025
6f5b2ca
FE: Use config vars
Vixtir Oct 15, 2025
9ea7766
FE: Remove redundant connectors request
Vixtir Oct 15, 2025
353bbc2
FE: Fix test
Vixtir Oct 15, 2025
137037d
FE: Fix typos
Vixtir Oct 15, 2025
7470cbd
FE: Fix set params
Vixtir Oct 16, 2025
0285669
FE: Make a nav scrollbar thin
Vixtir Oct 16, 2025
362ff3c
FE: Add useFts deps
Vixtir Oct 18, 2025
40d03b2
Merge branch 'main' into issues/1333-optional-fts-fe
germanosin Oct 22, 2025
6946c5e
Merge branch 'main' into issues/1333-optional-fts-fe
Vixtir Oct 27, 2025
cc20280
Merge branch 'main' into issues/1333-optional-fts-fe
Vixtir Oct 31, 2025
5381d94
FE: Fix merge conflicts
Vixtir Oct 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion frontend/src/components/ACLPage/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourceP
import BreakableTextCell from 'components/common/NewTable/BreakableTextCell';
import { useQueryPersister } from 'components/common/NewTable/ColumnFilter';
import { ActionPermissionWrapper } from 'components/common/ActionComponent';
import useFts from 'components/common/Fts/useFts';
import Fts from 'components/common/Fts/Fts';
import ClusterContext from 'components/contexts/ClusterContext';

import * as S from './List.styled';
Expand All @@ -34,7 +36,8 @@ const ACList: React.FC = () => {
const { clusterName } = useAppParams<{ clusterName: ClusterName }>();
const [searchParams, setSearchParams] = useSearchParams();
const [search, setSearch] = useState(searchParams.get('q') || '');
const { data: aclList } = useAcls({ clusterName, search });
const { isFtsEnabled } = useFts('acl');
const { data: aclList } = useAcls({ clusterName, search, fts: isFtsEnabled });
const { deleteResource } = useDeleteAcl(clusterName);
const { isReadOnly } = React.useContext(ClusterContext);
const modal = useConfirm(true);
Expand Down Expand Up @@ -214,6 +217,7 @@ const ACList: React.FC = () => {
placeholder="Search by Principal Name"
value={search}
onChange={setSearch}
extraActions={<Fts resourceName="acl" />}
/>
</ControlPanelWrapper>
<Table
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import useFts from 'components/common/Fts/useFts';
import { useConsumerGroups } from 'lib/hooks/api/consumers';
import { useMemo } from 'react';

const useConsumerGroupsOptions = (clusterName: string) => {
const { data } = useConsumerGroups({ clusterName, search: '' });
const { isFtsEnabled } = useFts('consumer_groups');
const { data } = useConsumerGroups({
clusterName,
search: '',
fts: isFtsEnabled,
});
const consumerGroups = useMemo(() => {
return (
data?.consumerGroups?.map((cg) => {
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/components/ClusterPage/ClusterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const ClusterPage: React.FC = () => {
const { clusterName } = useAppParams<ClusterNameRoute>();
const appInfo = React.useContext(GlobalSettingsContext);

const { data } = useClusters();
const { data, isFetched } = useClusters();
const contextValue = React.useMemo(() => {
const cluster = data?.find(({ name }) => name === clusterName);
const features = cluster?.features || [];
Expand All @@ -61,9 +61,17 @@ const ClusterPage: React.FC = () => {
hasAclViewConfigured:
features.includes(ClusterFeaturesEnum.KAFKA_ACL_VIEW) ||
features.includes(ClusterFeaturesEnum.KAFKA_ACL_EDIT),
ftsEnabled: features.includes(ClusterFeaturesEnum.FTS_ENABLED),
ftsDefaultEnabled: features.includes(
ClusterFeaturesEnum.FTS_DEFAULT_ENABLED
),
};
}, [clusterName, data]);

if (!isFetched) {
return <PageLoader />;
}

return (
<Suspense fallback={<PageLoader />}>
<ClusterContext.Provider value={contextValue}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ describe('ClusterPage', () => {
const renderComponent = async (pathname: string, payload: Cluster[] = []) => {
(useClusters as jest.Mock).mockImplementation(() => ({
data: payload,
isFetched: true,
}));
await render(
<WithRoute path={`${clusterPath()}/*`}>
Expand Down
16 changes: 5 additions & 11 deletions frontend/src/components/Connect/List/List.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import React from 'react';
import useAppParams from 'lib/hooks/useAppParams';
import { ClusterNameRoute } from 'lib/paths';
import { useConnectors } from 'lib/hooks/api/kafkaConnect';
import { useSearchParams } from 'react-router-dom';
import { ConnectorsTable } from 'components/Connect/List/ConnectorsTable/ConnectorsTable';
import { FullConnectorInfo } from 'generated-sources';

const List: React.FC = () => {
const { clusterName } = useAppParams<ClusterNameRoute>();
const [searchParams] = useSearchParams();
const { data: connectors = [] } = useConnectors(
clusterName,
searchParams.get('q') || ''
);
interface ConnectorsListProps {
connectors: FullConnectorInfo[];
}

const List: React.FC<ConnectorsListProps> = ({ connectors }) => {
return <ConnectorsTable connectors={connectors} />;
};

Expand Down
45 changes: 34 additions & 11 deletions frontend/src/components/Connect/List/ListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,44 @@
import React, { Suspense } from 'react';
import Search from 'components/common/Search/Search';
import PageLoader from 'components/common/PageLoader/PageLoader';
import useAppParams from 'lib/hooks/useAppParams';
import { ClusterNameRoute } from 'lib/paths';
import { useConnectors } from 'lib/hooks/api/kafkaConnect';
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 * as S from './ListPage.styled';
import List from './List';
import ConnectorsStatistics from './Statistics/Statistics';

const ListPage: React.FC = () => (
<>
<ConnectorsStatistics />
<S.Search hasInput>
<Search placeholder="Search by Connect Name, Status or Type" />
</S.Search>
<Suspense fallback={<PageLoader />}>
<List />
</Suspense>
</>
);
const emptyConnectors: FullConnectorInfo[] = [];

const ListPage: React.FC = () => {
const { clusterName } = useAppParams<ClusterNameRoute>();
const [searchParams] = useSearchParams();
const { isFtsEnabled } = useFts('connects');
const { data: connectors = emptyConnectors, isLoading } = useConnectors(
clusterName,
searchParams.get('q') || '',
isFtsEnabled
);

return (
<>
<ConnectorsStatistics connectors={connectors} isLoading={isLoading} />
<S.Search hasInput>
<Search
placeholder="Search by Connect Name, Status or Type"
extraActions={<Fts resourceName="connects" />}
/>
</S.Search>
<Suspense fallback={<PageLoader />}>
<List connectors={connectors} />
</Suspense>
</>
);
};

export default ListPage;
18 changes: 10 additions & 8 deletions frontend/src/components/Connect/List/Statistics/Statistics.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React, { useMemo } from 'react';
import React, { FC, useMemo } from 'react';
import * as Statistics from 'components/common/Statistics';
import useAppParams from 'lib/hooks/useAppParams';
import { ClusterNameRoute } from 'lib/paths';
import { useConnectors } from 'lib/hooks/api/kafkaConnect';
import { FullConnectorInfo } from 'generated-sources';

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

const ConnectorsStatistics = () => {
const { clusterName } = useAppParams<ClusterNameRoute>();
const { data: connectors = [], isLoading } = useConnectors(clusterName);

interface ConnectorsStatisticsProps {
connectors: FullConnectorInfo[];
isLoading: boolean;
}
const ConnectorsStatistics: FC<ConnectorsStatisticsProps> = ({
connectors,
isLoading,
}) => {
const statistics = useMemo(() => computeStatistics(connectors), [connectors]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ 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(<ConnectorsStatistics />);
render(<ConnectorsStatistics connectors={data} isLoading={isLoading} />);
}

describe('when data loading', () => {
Expand Down
13 changes: 7 additions & 6 deletions frontend/src/components/Connect/List/__tests__/List.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
useResetConnectorOffsets,
useUpdateConnectorState,
} from 'lib/hooks/api/kafkaConnect';
import { FullConnectorInfo } from 'generated-sources';

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

const clusterName = 'local';

const renderComponent = (contextValue: ContextProps = initialValue) =>
const renderComponent = (
contextValue: ContextProps = initialValue,
data: FullConnectorInfo[] = connectors
) =>
render(
<ClusterContext.Provider value={contextValue}>
<WithRoute path={clusterConnectorsPath()}>
<List />
<List connectors={data} />
</WithRoute>
</ClusterContext.Provider>,
{ initialEntries: [clusterConnectorsPath(clusterName)] }
Expand All @@ -47,9 +51,6 @@ const renderComponent = (contextValue: ContextProps = initialValue) =>
describe('Connectors List', () => {
describe('when the connectors are loaded', () => {
beforeEach(() => {
(useConnectors as jest.Mock).mockImplementation(() => ({
data: connectors,
}));
const restartConnector = jest.fn();
(useUpdateConnectorState as jest.Mock).mockImplementation(() => ({
mutateAsync: restartConnector,
Expand Down Expand Up @@ -84,7 +85,7 @@ describe('Connectors List', () => {
});

it('renders empty table', async () => {
renderComponent();
renderComponent(undefined, []);
expect(screen.getByRole('table')).toBeInTheDocument();
expect(
screen.getByRole('row', { name: 'No connectors found' })
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/components/ConsumerGroups/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import { useConsumerGroups } from 'lib/hooks/api/consumers';
import Tooltip from 'components/common/Tooltip/Tooltip';
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
import { useLocalStoragePersister } from 'components/common/NewTable/ColumnResizer/lib';
import useFts from 'components/common/Fts/useFts';
import Fts from 'components/common/Fts/Fts';

const List = () => {
const { clusterName } = useAppParams<ClusterNameRoute>();
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const { isFtsEnabled } = useFts('consumer_groups');

const consumerGroups = useConsumerGroups({
clusterName,
Expand All @@ -32,6 +35,7 @@ const List = () => {
page: Number(searchParams.get('page') || 1),
perPage: Number(searchParams.get('perPage') || PER_PAGE),
search: searchParams.get('q') || '',
fts: isFtsEnabled,
});

const columns = React.useMemo<ColumnDef<ConsumerGroup>[]>(
Expand Down Expand Up @@ -104,7 +108,10 @@ const List = () => {
<>
<ResourcePageHeading text="Consumers" />
<ControlPanelWrapper hasInput>
<Search placeholder="Search by Consumer Group ID" />
<Search
placeholder="Search by Consumer Group ID"
extraActions={<Fts resourceName="consumer_groups" />}
/>
</ControlPanelWrapper>
<Table
columns={columns}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const Sidebar = styled.div<{ $visible: boolean }>(
left: 0;
bottom: 0;
padding: 16px;
scrollbar-gutter: stable;
scrollbar-width: thin;
overflow-y: auto;
transition:
width 0.25s,
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/components/Schemas/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { useNavigate, useSearchParams } from 'react-router-dom';
import { PER_PAGE } from 'lib/constants';
import { useGetSchemas } from 'lib/hooks/api/schemas';
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
import useFts from 'components/common/Fts/useFts';
import Fts from 'components/common/Fts/Fts';

import GlobalSchemaSelector from './GlobalSchemaSelector/GlobalSchemaSelector';

Expand All @@ -32,6 +34,7 @@ const List: React.FC = () => {
const { clusterName } = useAppParams<ClusterNameRoute>();
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const { isFtsEnabled } = useFts('schemas');
const {
isInitialLoading,
isError,
Expand All @@ -45,6 +48,7 @@ const List: React.FC = () => {
sortOrder:
(searchParams.get('sortDirection')?.toUpperCase() as SortOrder) ||
undefined,
fts: isFtsEnabled,
});

const columns = React.useMemo<ColumnDef<SchemaSubject>[]>(
Expand Down Expand Up @@ -111,7 +115,10 @@ const List: React.FC = () => {
)}
</ResourcePageHeading>
<ControlPanelWrapper hasInput>
<Search placeholder="Search by Schema Name" />
<Search
placeholder="Search by Schema Name"
extraActions={<Fts resourceName="schemas" />}
/>
</ControlPanelWrapper>
{isInitialLoading || isError ? (
<PageLoader />
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/components/Topics/List/ListPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ import PageLoader from 'components/common/PageLoader/PageLoader';
import TopicTable from 'components/Topics/List/TopicTable';
import { Action, ResourceType } from 'generated-sources';
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
import Fts from 'components/common/Fts/Fts';
import useFts from 'components/common/Fts/useFts';

const ListPage: React.FC = () => {
const { isReadOnly } = React.useContext(ClusterContext);
const [searchParams, setSearchParams] = useSearchParams();

useFts('topics');

// Set the search params to the url based on the localStorage value
React.useEffect(() => {
if (!searchParams.has('perPage')) {
Expand Down Expand Up @@ -62,7 +66,10 @@ const ListPage: React.FC = () => {
)}
</ResourcePageHeading>
<ControlPanelWrapper hasInput>
<Search placeholder="Search by Topic Name" />
<Search
placeholder="Search by Topic Name"
extraActions={<Fts resourceName="topics" />}
/>
<label>
<Switch
name="ShowInternalTopics"
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/components/Topics/List/TopicTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ClusterContext from 'components/contexts/ClusterContext';
import { useTopics } from 'lib/hooks/api/topics';
import { PER_PAGE } from 'lib/constants';
import { useLocalStoragePersister } from 'components/common/NewTable/ColumnResizer/lib';
import useFts from 'components/common/Fts/useFts';

import { TopicTitleCell } from './TopicTitleCell';
import ActionsCell from './ActionsCell';
Expand All @@ -18,8 +19,11 @@ const TopicTable: React.FC = () => {
const { clusterName } = useAppParams<{ clusterName: ClusterName }>();
const [searchParams] = useSearchParams();
const { isReadOnly } = React.useContext(ClusterContext);
const { isFtsEnabled } = useFts('topics');

const { data } = useTopics({
clusterName,
fts: isFtsEnabled,
page: Number(searchParams.get('page') || 1),
perPage: Number(searchParams.get('perPage') || PER_PAGE),
search: searchParams.get('q') || undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ describe('ListPage Component', () => {
hasKafkaConnectConfigured: true,
hasSchemaRegistryConfigured: true,
isTopicDeletionAllowed: true,
ftsEnabled: false,
ftsDefaultEnabled: false,
}}
>
<WithRoute path={clusterTopicsPath()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ describe('TopicTable Components', () => {
hasKafkaConnectConfigured: true,
hasSchemaRegistryConfigured: true,
isTopicDeletionAllowed,
ftsEnabled: false,
ftsDefaultEnabled: false,
}}
>
<WithRoute path={clusterTopicsPath()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const defaultContextValues = {
hasKafkaConnectConfigured: true,
hasSchemaRegistryConfigured: true,
isTopicDeletionAllowed: true,
ftsEnabled: false,
ftsDefaultEnabled: false,
};

jest.mock('lib/hooks/api/topics', () => ({
Expand Down
Loading
Loading