From 4b97405662f30299f6ee24a63b33a073c61e9232 Mon Sep 17 00:00:00 2001 From: Poleg Kashti Date: Sat, 26 Oct 2024 19:32:53 +0300 Subject: [PATCH 1/3] Closes #621 --- .../io/kafbat/ui/controller/AclsController.java | 3 ++- .../io/kafbat/ui/service/acl/AclsService.java | 3 ++- .../main/resources/swagger/kafbat-ui-api.yaml | 5 +++++ frontend/src/components/ACLPage/List/List.tsx | 17 +++++++++++++++-- frontend/src/lib/hooks/api/acl.ts | 15 +++++++++++---- 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/io/kafbat/ui/controller/AclsController.java b/api/src/main/java/io/kafbat/ui/controller/AclsController.java index bbb30b5c6..b99c8106d 100644 --- a/api/src/main/java/io/kafbat/ui/controller/AclsController.java +++ b/api/src/main/java/io/kafbat/ui/controller/AclsController.java @@ -67,6 +67,7 @@ public Mono>> listAcls(String clusterName, KafkaAclResourceTypeDTO resourceTypeDto, String resourceName, KafkaAclNamePatternTypeDTO namePatternTypeDto, + String search, ServerWebExchange exchange) { AccessContext context = AccessContext.builder() .cluster(clusterName) @@ -87,7 +88,7 @@ public Mono>> listAcls(String clusterName, return validateAccess(context).then( Mono.just( ResponseEntity.ok( - aclsService.listAcls(getCluster(clusterName), filter) + aclsService.listAcls(getCluster(clusterName), filter, search) .map(ClusterMapper::toKafkaAclDto))) ).doOnEach(sig -> audit(context, sig)); } diff --git a/api/src/main/java/io/kafbat/ui/service/acl/AclsService.java b/api/src/main/java/io/kafbat/ui/service/acl/AclsService.java index b3877a336..6a2b48632 100644 --- a/api/src/main/java/io/kafbat/ui/service/acl/AclsService.java +++ b/api/src/main/java/io/kafbat/ui/service/acl/AclsService.java @@ -68,10 +68,11 @@ public Mono deleteAcl(KafkaCluster cluster, AclBinding aclBinding) { .doOnSuccess(v -> log.info("ACL DELETED: [{}]", aclString)); } - public Flux listAcls(KafkaCluster cluster, ResourcePatternFilter filter) { + public Flux listAcls(KafkaCluster cluster, ResourcePatternFilter filter, String principalSearch) { return adminClientService.get(cluster) .flatMap(c -> c.listAcls(filter)) .flatMapIterable(acls -> acls) + .filter(acl -> principalSearch == null || acl.entry().principal().contains(principalSearch)) .sort(Comparator.comparing(AclBinding::toString)); //sorting to keep stable order on different calls } diff --git a/contract/src/main/resources/swagger/kafbat-ui-api.yaml b/contract/src/main/resources/swagger/kafbat-ui-api.yaml index 5eede6cef..9b4b7d26d 100644 --- a/contract/src/main/resources/swagger/kafbat-ui-api.yaml +++ b/contract/src/main/resources/swagger/kafbat-ui-api.yaml @@ -1943,6 +1943,11 @@ paths: required: false schema: $ref: '#/components/schemas/KafkaAclNamePatternType' + - name: search + in: query + required: false + schema: + type: string responses: 200: description: OK diff --git a/frontend/src/components/ACLPage/List/List.tsx b/frontend/src/components/ACLPage/List/List.tsx index 26155172b..e3c1d3501 100644 --- a/frontend/src/components/ACLPage/List/List.tsx +++ b/frontend/src/components/ACLPage/List/List.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; import { ColumnDef, Row } from '@tanstack/react-table'; import PageHeading from 'components/common/PageHeading/PageHeading'; import Table from 'components/common/NewTable'; @@ -20,12 +21,16 @@ import { useTheme } from 'styled-components'; import ACLFormContext from 'components/ACLPage/Form/AclFormContext'; import PlusIcon from 'components/common/Icons/PlusIcon'; import ActionButton from 'components/common/ActionComponent/ActionButton/ActionButton'; +import { ControlPanelWrapper } from 'components/common/ControlPanel/ControlPanel.styled'; +import Search from 'components/common/Search/Search'; import * as S from './List.styled'; const ACList: React.FC = () => { const { clusterName } = useAppParams<{ clusterName: ClusterName }>(); - const { data: aclList } = useAcls(clusterName); + const [searchParams, setSearchParams] = useSearchParams(); + const [search, setSearch] = useState(searchParams.get('q') || ''); + const { data: aclList } = useAcls({ clusterName, search }); const { deleteResource } = useDeleteAcl(clusterName); const modal = useConfirm(true); const theme = useTheme(); @@ -36,6 +41,11 @@ const ACList: React.FC = () => { } = useBoolean(); const [rowId, setRowId] = React.useState(''); + // Set the search params to the url based on the localStorage value + useEffect(() => { + setSearch(searchParams.get('q') || ''); + }, [searchParams]); + const handleDeleteClick = (acl: KafkaAcl | null) => { if (acl) { modal('Are you sure want to delete this ACL record?', () => @@ -162,6 +172,9 @@ const ACList: React.FC = () => { Create ACL + + + api.listAcls({ clusterName }), + ['clusters', clusterName, 'acls', { search }], + () => api.listAcls({ + clusterName, + search + }), { - suspense: false, + keepPreviousData: true, + suspense: false, } ); } From d447acfce27661528ff64d1e253aefb1072cdc65 Mon Sep 17 00:00:00 2001 From: Poleg Kashti Date: Sat, 26 Oct 2024 20:13:23 +0300 Subject: [PATCH 2/3] Fix(List.tsx): remove unused variable --- frontend/src/components/ACLPage/List/List.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/ACLPage/List/List.tsx b/frontend/src/components/ACLPage/List/List.tsx index e3c1d3501..9808a6c1c 100644 --- a/frontend/src/components/ACLPage/List/List.tsx +++ b/frontend/src/components/ACLPage/List/List.tsx @@ -28,7 +28,7 @@ import * as S from './List.styled'; const ACList: React.FC = () => { const { clusterName } = useAppParams<{ clusterName: ClusterName }>(); - const [searchParams, setSearchParams] = useSearchParams(); + const [searchParams] = useSearchParams(); const [search, setSearch] = useState(searchParams.get('q') || ''); const { data: aclList } = useAcls({ clusterName, search }); const { deleteResource } = useDeleteAcl(clusterName); From 7ea90923a88e60bce6c2c46a43332fdca1829a7d Mon Sep 17 00:00:00 2001 From: Poleg Kashti Date: Sat, 26 Oct 2024 20:59:58 +0300 Subject: [PATCH 3/3] Fix(acl.ts): lint warnings --- frontend/src/lib/hooks/api/acl.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/frontend/src/lib/hooks/api/acl.ts b/frontend/src/lib/hooks/api/acl.ts index 7e69f2eb4..a1c1b1ad1 100644 --- a/frontend/src/lib/hooks/api/acl.ts +++ b/frontend/src/lib/hooks/api/acl.ts @@ -14,19 +14,23 @@ import { KafkaAcl, } from 'generated-sources'; -export function useAcls({ clusterName, search }: { - clusterName: ClusterName; - search?: string; +export function useAcls({ + clusterName, + search, +}: { + clusterName: ClusterName; + search?: string; }) { return useQuery( ['clusters', clusterName, 'acls', { search }], - () => api.listAcls({ + () => + api.listAcls({ clusterName, - search - }), + search, + }), { - keepPreviousData: true, - suspense: false, + keepPreviousData: true, + suspense: false, } ); }