Skip to content

Commit 0fd03e3

Browse files
authored
ATLAS-5303: ATLAS React UI: Audit Filters dropdown UI breaks when audit table has no data (#694)
* 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
1 parent 400db52 commit 0fd03e3

2 files changed

Lines changed: 57 additions & 29 deletions

File tree

‎dashboard/src/views/Administrator/Audits/AdminAuditTable.tsx‎

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -201,16 +201,14 @@ const AdminAuditTable = () => {
201201
<>
202202
<Grid container marginTop={0}>
203203
<Grid item md={12} p={2}>
204-
<Stack alignItems="flex-start">
205-
<div
206-
style={{
207-
height: !isEmpty(auditData) ? 0 : "32px"
208-
}}
209-
>
210-
{!loader && (
204+
<Stack>
205+
<TableLayout
206+
fetchData={fetchAuditResult}
207+
customLeftButton={
211208
<CustomButton
212209
variant="outlined"
213210
size="small"
211+
disabled={loader || (isEmpty(auditData) && isEmpty(queryApiObj))}
214212
onClick={handleClickFilterPopover}
215213
startIcon={
216214
!filtersPopover ? (
@@ -219,20 +217,10 @@ const AdminAuditTable = () => {
219217
<KeyboardArrowDownOutlinedIcon />
220218
)
221219
}
222-
sx={{
223-
zIndex: "99999",
224-
marginTop: "13px !important",
225-
marginLeft: "13px !important"
226-
}}
227220
>
228221
Filters
229222
</CustomButton>
230-
)}
231-
</div>
232-
</Stack>
233-
<Stack>
234-
<TableLayout
235-
fetchData={fetchAuditResult}
223+
}
236224
data={auditData || []}
237225
columns={defaultColumns}
238226
defaultColumnVisibility={defaultColumnVisibility(defaultColumns)}

‎dashboard/src/views/Administrator/Audits/__tests__/AdminAuditTable.test.tsx‎

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ jest.mock('@components/Table/TableLayout', () => ({
129129
tableFilters,
130130
expandRow,
131131
auditTableDetails,
132-
queryBuilder
132+
queryBuilder,
133+
customLeftButton
133134
}: any) => {
134135
capturedFetchData = fetchData;
135136
capturedExpandRow = expandRow;
@@ -144,6 +145,7 @@ jest.mock('@components/Table/TableLayout', () => ({
144145

145146
return (
146147
<div data-testid="table-layout">
148+
<div data-testid="custom-left-button">{customLeftButton}</div>
147149
<div data-testid="table-fetching">{isFetching ? 'loading' : 'loaded'}</div>
148150
<div data-testid="table-data-count">{data?.length || 0}</div>
149151
<div data-testid="table-columns-count">{columns?.length || 0}</div>
@@ -195,8 +197,8 @@ jest.mock('@mui/material', () => {
195197
});
196198

197199
jest.mock('@components/muiComponents', () => ({
198-
CustomButton: ({ children, onClick, startIcon, ...props }: any) => (
199-
<button onClick={onClick} data-testid="custom-button" {...props}>
200+
CustomButton: ({ children, onClick, disabled, startIcon, ...props }: any) => (
201+
<button onClick={onClick} disabled={disabled} data-testid="custom-button" {...props}>
200202
{startIcon && <span data-testid="button-icon">{startIcon}</span>}
201203
{children}
202204
</button>
@@ -281,12 +283,12 @@ describe('AdminAuditTable Component', () => {
281283
}, { timeout: 5000 });
282284
});
283285

284-
it('should not render filter button when loading', () => {
286+
it('should disable filter button when loading', () => {
285287
render(<AdminAuditTable />);
286288

287-
// Initially loading, button should not be visible
288-
const buttons = screen.queryAllByTestId('custom-button');
289-
expect(buttons.length).toBe(0);
289+
// Initially loading, button should be disabled
290+
const button = screen.getByTestId('custom-button');
291+
expect(button).toBeDisabled();
290292
});
291293
});
292294

@@ -709,7 +711,7 @@ describe('AdminAuditTable Component', () => {
709711
});
710712

711713
describe('Filter Button Visibility', () => {
712-
it('should hide filter button when auditData is not empty', async () => {
714+
it('should render filter button when auditData is not empty', async () => {
713715
mockGetAuditData.mockResolvedValue({ data: mockAuditData });
714716

715717
render(<AdminAuditTable />);
@@ -718,23 +720,61 @@ describe('AdminAuditTable Component', () => {
718720
expect(screen.getByTestId('table-data-count')).toHaveTextContent('2');
719721
}, { timeout: 5000 });
720722

721-
// Button container should have height 0 when data is present
722723
const buttons = screen.queryAllByTestId('custom-button');
723724
expect(buttons.length).toBeGreaterThan(0);
725+
726+
// Ensure the filter button is NOT disabled when data is present (and not loading)
727+
const filterBtn = screen.getByText('Filters').closest('button');
728+
expect(filterBtn).not.toHaveAttribute('disabled');
724729
});
725730

726-
it('should show filter button when auditData is empty', async () => {
731+
it('should disable filter button when auditData is empty and no active filters', async () => {
727732
mockGetAuditData.mockResolvedValue({ data: [] });
733+
mockIsEmpty.mockReturnValue(true); // both auditData and queryApiObj are empty
728734

729735
render(<AdminAuditTable />);
730736

731737
await waitFor(() => {
732-
expect(mockGetAuditData).toHaveBeenCalled();
738+
expect(screen.getByTestId('table-data-count')).toHaveTextContent('0');
733739
}, { timeout: 5000 });
734740

741+
const filterBtn = screen.getByText('Filters').closest('button');
742+
expect(filterBtn).toHaveAttribute('disabled');
743+
});
744+
745+
it('should enable filter button when auditData is empty but filters are active', async () => {
746+
mockGetAuditData.mockResolvedValue({ data: [] });
747+
// We simulate queryApiObj having active filters by making mockIsEmpty return false for objects
748+
mockIsEmpty.mockImplementation((val) => {
749+
if (Array.isArray(val)) return val.length === 0; // auditData
750+
if (typeof val === 'object' && val !== null) return false; // active queryApiObj
751+
return true;
752+
});
753+
754+
render(<AdminAuditTable />);
755+
735756
await waitFor(() => {
736757
expect(screen.getByTestId('table-data-count')).toHaveTextContent('0');
737758
}, { timeout: 5000 });
759+
760+
const filterBtn = screen.getByText('Filters').closest('button');
761+
expect(filterBtn).not.toBeDisabled();
762+
});
763+
764+
it('renders Filters inside TableLayout customLeftButton slot', async () => {
765+
render(<AdminAuditTable />);
766+
await waitFor(() => {
767+
expect(screen.getByTestId('custom-left-button')).toBeInTheDocument();
768+
expect(screen.getByText('Filters')).toBeInTheDocument();
769+
});
770+
});
771+
772+
it('opens AuditFilters popover when Filters is enabled and clicked', async () => {
773+
mockGetAuditData.mockResolvedValue({ data: mockAuditData });
774+
render(<AdminAuditTable />);
775+
await waitFor(() => expect(screen.getByText('Filters').closest('button')).not.toBeDisabled());
776+
fireEvent.click(screen.getByText('Filters'));
777+
expect(screen.getByTestId('audit-filters')).toBeInTheDocument();
738778
});
739779
});
740780

0 commit comments

Comments
 (0)