This is an automated email from the ASF dual-hosted git repository. pawarprasad123 pushed a commit to branch atlas-2.6 in repository https://gitbox.apache.org/repos/asf/atlas.git
commit 186da082b8739db7762616d791dafbe92996a6d4 Author: Brijesh Bhalala <[email protected]> AuthorDate: Thu Jul 16 19:49:03 2026 +0530 ATLAS-5303: ATLAS React UI: Audit Filters dropdown UI breaks when audit table has no data (#694) ( cherry picked form the commit 0fd03e3ad04812596cc08d9158a48db71f1fea37) * ATLAS-5303: ATLAS React UI: Audit Filters dropdown UI breaks when audit table has no data * ATLAS-5303: ATLAS React UI: Audit Filters dropdown UI breaks when audit table has no data * ATLAS-5303: ATLAS React UI: Audit Filters dropdown UI breaks when audit table has no data --- .../views/Administrator/Audits/AdminAuditTable.tsx | 24 +++------ .../Audits/__tests__/AdminAuditTable.test.tsx | 62 ++++++++++++++++++---- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/dashboard/src/views/Administrator/Audits/AdminAuditTable.tsx b/dashboard/src/views/Administrator/Audits/AdminAuditTable.tsx index e8e72bd44..867328322 100644 --- a/dashboard/src/views/Administrator/Audits/AdminAuditTable.tsx +++ b/dashboard/src/views/Administrator/Audits/AdminAuditTable.tsx @@ -201,16 +201,14 @@ const AdminAuditTable = () => { <> <Grid container marginTop={0}> <Grid item md={12} p={2}> - <Stack alignItems="flex-start"> - <div - style={{ - height: !isEmpty(auditData) ? 0 : "32px" - }} - > - {!loader && ( + <Stack> + <TableLayout + fetchData={fetchAuditResult} + customLeftButton={ <CustomButton variant="outlined" size="small" + disabled={loader || (isEmpty(auditData) && isEmpty(queryApiObj))} onClick={handleClickFilterPopover} startIcon={ !filtersPopover ? ( @@ -219,20 +217,10 @@ const AdminAuditTable = () => { <KeyboardArrowDownOutlinedIcon /> ) } - sx={{ - zIndex: "99999", - marginTop: "13px !important", - marginLeft: "13px !important" - }} > Filters </CustomButton> - )} - </div> - </Stack> - <Stack> - <TableLayout - fetchData={fetchAuditResult} + } data={auditData || []} columns={defaultColumns} defaultColumnVisibility={defaultColumnVisibility(defaultColumns)} diff --git a/dashboard/src/views/Administrator/Audits/__tests__/AdminAuditTable.test.tsx b/dashboard/src/views/Administrator/Audits/__tests__/AdminAuditTable.test.tsx index 70d91f8ee..dbd844cd2 100644 --- a/dashboard/src/views/Administrator/Audits/__tests__/AdminAuditTable.test.tsx +++ b/dashboard/src/views/Administrator/Audits/__tests__/AdminAuditTable.test.tsx @@ -129,7 +129,8 @@ jest.mock('@components/Table/TableLayout', () => ({ tableFilters, expandRow, auditTableDetails, - queryBuilder + queryBuilder, + customLeftButton }: any) => { capturedFetchData = fetchData; capturedExpandRow = expandRow; @@ -144,6 +145,7 @@ jest.mock('@components/Table/TableLayout', () => ({ return ( <div data-testid="table-layout"> + <div data-testid="custom-left-button">{customLeftButton}</div> <div data-testid="table-fetching">{isFetching ? 'loading' : 'loaded'}</div> <div data-testid="table-data-count">{data?.length || 0}</div> <div data-testid="table-columns-count">{columns?.length || 0}</div> @@ -195,8 +197,8 @@ jest.mock('@mui/material', () => { }); jest.mock('@components/muiComponents', () => ({ - CustomButton: ({ children, onClick, startIcon, ...props }: any) => ( - <button onClick={onClick} data-testid="custom-button" {...props}> + CustomButton: ({ children, onClick, disabled, startIcon, ...props }: any) => ( + <button onClick={onClick} disabled={disabled} data-testid="custom-button" {...props}> {startIcon && <span data-testid="button-icon">{startIcon}</span>} {children} </button> @@ -281,12 +283,12 @@ describe('AdminAuditTable Component', () => { }, { timeout: 5000 }); }); - it('should not render filter button when loading', () => { + it('should disable filter button when loading', () => { render(<AdminAuditTable />); - // Initially loading, button should not be visible - const buttons = screen.queryAllByTestId('custom-button'); - expect(buttons.length).toBe(0); + // Initially loading, button should be disabled + const button = screen.getByTestId('custom-button'); + expect(button).toBeDisabled(); }); }); @@ -709,7 +711,7 @@ describe('AdminAuditTable Component', () => { }); describe('Filter Button Visibility', () => { - it('should hide filter button when auditData is not empty', async () => { + it('should render filter button when auditData is not empty', async () => { mockGetAuditData.mockResolvedValue({ data: mockAuditData }); render(<AdminAuditTable />); @@ -718,23 +720,61 @@ describe('AdminAuditTable Component', () => { expect(screen.getByTestId('table-data-count')).toHaveTextContent('2'); }, { timeout: 5000 }); - // Button container should have height 0 when data is present const buttons = screen.queryAllByTestId('custom-button'); expect(buttons.length).toBeGreaterThan(0); + + // Ensure the filter button is NOT disabled when data is present (and not loading) + const filterBtn = screen.getByText('Filters').closest('button'); + expect(filterBtn).not.toHaveAttribute('disabled'); }); - it('should show filter button when auditData is empty', async () => { + it('should disable filter button when auditData is empty and no active filters', async () => { mockGetAuditData.mockResolvedValue({ data: [] }); + mockIsEmpty.mockReturnValue(true); // both auditData and queryApiObj are empty render(<AdminAuditTable />); await waitFor(() => { - expect(mockGetAuditData).toHaveBeenCalled(); + expect(screen.getByTestId('table-data-count')).toHaveTextContent('0'); }, { timeout: 5000 }); + const filterBtn = screen.getByText('Filters').closest('button'); + expect(filterBtn).toHaveAttribute('disabled'); + }); + + it('should enable filter button when auditData is empty but filters are active', async () => { + mockGetAuditData.mockResolvedValue({ data: [] }); + // We simulate queryApiObj having active filters by making mockIsEmpty return false for objects + mockIsEmpty.mockImplementation((val) => { + if (Array.isArray(val)) return val.length === 0; // auditData + if (typeof val === 'object' && val !== null) return false; // active queryApiObj + return true; + }); + + render(<AdminAuditTable />); + await waitFor(() => { expect(screen.getByTestId('table-data-count')).toHaveTextContent('0'); }, { timeout: 5000 }); + + const filterBtn = screen.getByText('Filters').closest('button'); + expect(filterBtn).not.toBeDisabled(); + }); + + it('renders Filters inside TableLayout customLeftButton slot', async () => { + render(<AdminAuditTable />); + await waitFor(() => { + expect(screen.getByTestId('custom-left-button')).toBeInTheDocument(); + expect(screen.getByText('Filters')).toBeInTheDocument(); + }); + }); + + it('opens AuditFilters popover when Filters is enabled and clicked', async () => { + mockGetAuditData.mockResolvedValue({ data: mockAuditData }); + render(<AdminAuditTable />); + await waitFor(() => expect(screen.getByText('Filters').closest('button')).not.toBeDisabled()); + fireEvent.click(screen.getByText('Filters')); + expect(screen.getByTestId('audit-filters')).toBeInTheDocument(); }); });
