From 47f80b524127ddd51c8e9a41a7586150365e5540 Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Thu, 18 Dec 2025 21:47:18 -0300 Subject: [PATCH] Fixes on cert request UI --- .../ee/services/audit-log/audit-log-types.ts | 2 + .../server/routes/v1/certificate-router.ts | 4 +- .../components/CertificateRequestRow.tsx | 15 ++++--- .../components/CertificateRequestsSection.tsx | 36 ++++++++++------- .../components/CertificatesTable.tsx | 39 ++++++++++++------- 5 files changed, 60 insertions(+), 36 deletions(-) diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 88e4dc0776..cfee9084f9 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -4297,6 +4297,8 @@ interface ListCertificateRequestsEvent { limit: number; search?: string; status?: string; + count: number; + certificateRequestIds: string[]; }; } diff --git a/backend/src/server/routes/v1/certificate-router.ts b/backend/src/server/routes/v1/certificate-router.ts index 861f2d2b92..d598bd9aa6 100644 --- a/backend/src/server/routes/v1/certificate-router.ts +++ b/backend/src/server/routes/v1/certificate-router.ts @@ -448,7 +448,9 @@ export const registerCertificateRouter = async (server: FastifyZodProvider) => { offset: req.query.offset, limit: req.query.limit, search: req.query.search, - status: req.query.status + status: req.query.status, + count: certificateRequests.length, + certificateRequestIds: certificateRequests.map((certReq) => certReq.id) } } }); diff --git a/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestRow.tsx b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestRow.tsx index 27ff9b43c7..eaddf2752d 100644 --- a/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestRow.tsx +++ b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestRow.tsx @@ -9,6 +9,7 @@ import { DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, + IconButton, Td, Tooltip, Tr @@ -77,13 +78,15 @@ export const CertificateRequestRow = ({ request, onViewCertificates }: Props) => -
- - - -
+ + +
- + request.certificateId && onViewCertificates?.(request.certificateId)} disabled={!request.certificateId} diff --git a/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestsSection.tsx b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestsSection.tsx index add0f4f0c7..7b7abf9832 100644 --- a/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestsSection.tsx +++ b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestsSection.tsx @@ -63,6 +63,7 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro const [appliedFilters, setAppliedFilters] = useState({}); const [currentPage, setCurrentPage] = useState(1); + const [perPage, setPerPage] = useState(PAGE_SIZE); const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["issueCertificate"] as const); @@ -84,15 +85,15 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro const queryParams: TListCertificateRequestsParams = useMemo( () => ({ projectSlug: currentProject?.slug || "", - offset: (currentPage - 1) * PAGE_SIZE, - limit: PAGE_SIZE, + offset: (currentPage - 1) * perPage, + limit: perPage, sortBy: "createdAt", sortOrder: "desc", ...(debouncedSearch && { search: debouncedSearch }), ...(appliedFilters.status && { status: appliedFilters.status }), ...(profileIds && { profileIds }) }), - [currentProject?.slug, currentPage, debouncedSearch, appliedFilters.status, profileIds] + [currentProject?.slug, currentPage, perPage, debouncedSearch, appliedFilters.status, profileIds] ); const { @@ -130,14 +131,18 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro }; const isTableFiltered = useMemo( - () => Boolean(debouncedSearch || appliedFilters.status || appliedProfileIds.length), - [debouncedSearch, appliedFilters.status, appliedProfileIds.length] + () => Boolean(appliedFilters.status || appliedProfileIds.length), + [appliedFilters.status, appliedProfileIds.length] ); const hasPendingChanges = useMemo(() => { - if (pendingFilters.status !== appliedFilters.status) return true; - if (pendingProfileIds.length !== appliedProfileIds.length) return true; - return pendingProfileIds.some((id, index) => id !== appliedProfileIds[index]); + const pendingStatus = pendingFilters.status ?? undefined; + const appliedStatus = appliedFilters.status ?? undefined; + const statusChanged = pendingStatus !== appliedStatus; + const profileIdsChanged = + JSON.stringify([...pendingProfileIds].sort()) !== + JSON.stringify([...appliedProfileIds].sort()); + return statusChanged || profileIdsChanged; }, [pendingFilters.status, appliedFilters.status, pendingProfileIds, appliedProfileIds]); return ( @@ -203,7 +208,7 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro @@ -220,7 +225,7 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro @@ -258,7 +263,7 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro @@ -274,6 +279,8 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro }} placeholder="All events" className="w-full border-mineshaft-600 bg-mineshaft-700 text-bunker-200" + position="popper" + dropdownContainerClassName="max-w-none" > All events Pending @@ -287,7 +294,7 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro onClick={handleApplyFilters} className="w-full bg-primary font-medium text-black hover:bg-primary-600" size="sm" - disabled={!hasPendingChanges} + isDisabled={!hasPendingChanges} > Apply @@ -349,10 +356,11 @@ export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Pro setCurrentPage(page)} - onChangePerPage={() => { + onChangePerPage={(newPerPage) => { setCurrentPage(1); + setPerPage(newPerPage); }} /> diff --git a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx index 4898bf98a3..7a8e5b1d4d 100644 --- a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx +++ b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx @@ -220,9 +220,17 @@ export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) => setPendingProfileIds([]); }; - const isTableFiltered = Boolean( - appliedSearch || appliedFilters.status || appliedProfileIds.length - ); + const isTableFiltered = Boolean(appliedFilters.status || appliedProfileIds.length); + + const hasFilterChanges = useMemo(() => { + const pendingStatus = pendingFilters.status ?? undefined; + const appliedStatus = appliedFilters.status ?? undefined; + const statusChanged = pendingStatus !== appliedStatus; + const profileIdsChanged = + JSON.stringify([...pendingProfileIds].sort()) !== + JSON.stringify([...appliedProfileIds].sort()); + return statusChanged || profileIdsChanged; + }, [pendingFilters.status, appliedFilters.status, pendingProfileIds, appliedProfileIds]); return (
@@ -261,7 +269,7 @@ export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) => @@ -278,7 +286,7 @@ export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) => @@ -316,7 +324,7 @@ export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) => @@ -332,6 +340,8 @@ export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) => }} placeholder="All statuses" className="w-full border-mineshaft-600 bg-mineshaft-700 text-bunker-200" + position="popper" + dropdownContainerClassName="max-w-none" > All statuses Active @@ -349,10 +359,7 @@ export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) => }} className="w-full bg-primary font-medium text-black hover:bg-primary-600" size="sm" - disabled={ - pendingFilters.status === appliedFilters.status && - JSON.stringify(pendingProfileIds) === JSON.stringify(appliedProfileIds) - } + isDisabled={!hasFilterChanges} > Apply Filters @@ -503,11 +510,13 @@ export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) =>
-
- - - -
+ + +