Skip to content

Commit 6df7452

Browse files
refactor(ui): remove "Clear all" button from filter pills strip (#10481)
1 parent 6f6d62f commit 6df7452

File tree

6 files changed

+11
-506
lines changed

6 files changed

+11
-506
lines changed

ui/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ All notable changes to the **Prowler UI** are documented in this file.
77
### 🔄 Changed
88

99
- Attack Paths custom openCypher queries now use a code editor with syntax highlighting and line numbers [(#10445)](https://github.com/prowler-cloud/prowler/pull/10445)
10+
- Filter summary strip: removed redundant "Clear all" link next to pills (use top-bar Clear Filters instead) and switched chip variant from `outline` to `tag` for consistency [(#10481)](https://github.com/prowler-cloud/prowler/pull/10481)
1011

1112
### 🐞 Fixed
1213

ui/components/filters/filter-summary-strip.test.tsx

Lines changed: 4 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import {
3838
// TODO (E2E): Full filter strip flow should be covered in Playwright tests:
3939
// - Filter chips appear after staging selections in the findings page
4040
// - Removing a chip via the X button un-stages that filter value
41-
// - "Clear all" removes all staged filter chips at once
4241
// - Chips disappear after applying filters (pending state resets to URL state)
4342
// ──────────────────────────────────────────────────────────────────────────
4443

@@ -55,15 +54,10 @@ describe("FilterSummaryStrip", () => {
5554
it("should not render anything", () => {
5655
// Given
5756
const onRemove = vi.fn();
58-
const onClearAll = vi.fn();
5957

6058
// When
6159
const { container } = render(
62-
<FilterSummaryStrip
63-
chips={[]}
64-
onRemove={onRemove}
65-
onClearAll={onClearAll}
66-
/>,
60+
<FilterSummaryStrip chips={[]} onRemove={onRemove} />,
6761
);
6862

6963
// Then
@@ -77,16 +71,9 @@ describe("FilterSummaryStrip", () => {
7771
it("should render a chip for each filter value", () => {
7872
// Given
7973
const onRemove = vi.fn();
80-
const onClearAll = vi.fn();
8174

8275
// When
83-
render(
84-
<FilterSummaryStrip
85-
chips={mockChips}
86-
onRemove={onRemove}
87-
onClearAll={onClearAll}
88-
/>,
89-
);
76+
render(<FilterSummaryStrip chips={mockChips} onRemove={onRemove} />);
9077

9178
// Then — 3 chips should be visible (2 severity + 1 status)
9279
expect(screen.getAllByTestId("badge")).toHaveLength(3);
@@ -95,7 +82,6 @@ describe("FilterSummaryStrip", () => {
9582
it("should display the label and value text for each chip", () => {
9683
// Given
9784
const onRemove = vi.fn();
98-
const onClearAll = vi.fn();
9985

10086
// When
10187
render(
@@ -108,7 +94,6 @@ describe("FilterSummaryStrip", () => {
10894
},
10995
]}
11096
onRemove={onRemove}
111-
onClearAll={onClearAll}
11297
/>,
11398
);
11499

@@ -120,7 +105,6 @@ describe("FilterSummaryStrip", () => {
120105
it("should display displayValue when provided instead of value", () => {
121106
// Given
122107
const onRemove = vi.fn();
123-
const onClearAll = vi.fn();
124108

125109
// When
126110
render(
@@ -134,7 +118,6 @@ describe("FilterSummaryStrip", () => {
134118
},
135119
]}
136120
onRemove={onRemove}
137-
onClearAll={onClearAll}
138121
/>,
139122
);
140123

@@ -143,39 +126,12 @@ describe("FilterSummaryStrip", () => {
143126
expect(screen.queryByText("FAIL")).not.toBeInTheDocument();
144127
});
145128

146-
it("should render a 'Clear all' button", () => {
147-
// Given
148-
const onRemove = vi.fn();
149-
const onClearAll = vi.fn();
150-
151-
// When
152-
render(
153-
<FilterSummaryStrip
154-
chips={mockChips}
155-
onRemove={onRemove}
156-
onClearAll={onClearAll}
157-
/>,
158-
);
159-
160-
// Then
161-
expect(
162-
screen.getByRole("button", { name: "Clear all" }),
163-
).toBeInTheDocument();
164-
});
165-
166129
it("should render an aria-label region for accessibility", () => {
167130
// Given
168131
const onRemove = vi.fn();
169-
const onClearAll = vi.fn();
170132

171133
// When
172-
render(
173-
<FilterSummaryStrip
174-
chips={mockChips}
175-
onRemove={onRemove}
176-
onClearAll={onClearAll}
177-
/>,
178-
);
134+
render(<FilterSummaryStrip chips={mockChips} onRemove={onRemove} />);
179135

180136
// Then
181137
expect(
@@ -191,7 +147,6 @@ describe("FilterSummaryStrip", () => {
191147
// Given
192148
const user = userEvent.setup();
193149
const onRemove = vi.fn();
194-
const onClearAll = vi.fn();
195150

196151
render(
197152
<FilterSummaryStrip
@@ -203,7 +158,6 @@ describe("FilterSummaryStrip", () => {
203158
},
204159
]}
205160
onRemove={onRemove}
206-
onClearAll={onClearAll}
207161
/>,
208162
);
209163

@@ -222,15 +176,8 @@ describe("FilterSummaryStrip", () => {
222176
// Given
223177
const user = userEvent.setup();
224178
const onRemove = vi.fn();
225-
const onClearAll = vi.fn();
226179

227-
render(
228-
<FilterSummaryStrip
229-
chips={mockChips}
230-
onRemove={onRemove}
231-
onClearAll={onClearAll}
232-
/>,
233-
);
180+
render(<FilterSummaryStrip chips={mockChips} onRemove={onRemove} />);
234181

235182
// When — click the X button for "high" severity
236183
const removeHighButton = screen.getByRole("button", {
@@ -243,30 +190,4 @@ describe("FilterSummaryStrip", () => {
243190
expect(onRemove).toHaveBeenCalledTimes(1);
244191
});
245192
});
246-
247-
// ── onClearAll interaction ───────────────────────────────────────────────
248-
249-
describe("onClearAll", () => {
250-
it("should call onClearAll when 'Clear all' is clicked", async () => {
251-
// Given
252-
const user = userEvent.setup();
253-
const onRemove = vi.fn();
254-
const onClearAll = vi.fn();
255-
256-
render(
257-
<FilterSummaryStrip
258-
chips={mockChips}
259-
onRemove={onRemove}
260-
onClearAll={onClearAll}
261-
/>,
262-
);
263-
264-
// When
265-
await user.click(screen.getByRole("button", { name: "Clear all" }));
266-
267-
// Then
268-
expect(onClearAll).toHaveBeenCalledTimes(1);
269-
expect(onRemove).not.toHaveBeenCalled();
270-
});
271-
});
272193
});

ui/components/filters/filter-summary-strip.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ export interface FilterSummaryStripProps {
2121
chips: FilterChip[];
2222
/** Called when the user clicks the X on a chip */
2323
onRemove: (key: string, value: string) => void;
24-
/** Called when the user clicks "Clear all" */
25-
onClearAll: () => void;
2624
/** Optional extra class names for the outer wrapper */
2725
className?: string;
2826
}
@@ -33,13 +31,11 @@ export interface FilterSummaryStripProps {
3331
*
3432
* - Hidden when `chips` is empty.
3533
* - Each chip carries its own X button to remove that single value.
36-
* - A "Clear all" link removes everything at once.
3734
* - Reusable: no Findings-specific logic, driven entirely by props.
3835
*/
3936
export const FilterSummaryStrip = ({
4037
chips,
4138
onRemove,
42-
onClearAll,
4339
className,
4440
}: FilterSummaryStripProps) => {
4541
if (chips.length === 0) return null;
@@ -54,7 +50,7 @@ export const FilterSummaryStrip = ({
5450
{chips.map((chip) => (
5551
<Badge
5652
key={`${chip.key}-${chip.value}`}
57-
variant="outline"
53+
variant="tag"
5854
className="flex items-center gap-1 pr-1"
5955
>
6056
<span className="text-text-neutral-primary text-xs">
@@ -71,14 +67,6 @@ export const FilterSummaryStrip = ({
7167
</button>
7268
</Badge>
7369
))}
74-
75-
<button
76-
type="button"
77-
onClick={onClearAll}
78-
className="text-text-neutral-secondary hover:text-text-neutral-primary text-xs underline-offset-2 hover:underline focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-none"
79-
>
80-
Clear all
81-
</button>
8270
</div>
8371
);
8472
};

ui/components/findings/findings-filters.tsx

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ export const FindingsFilters = ({
119119
applyAll,
120120
discardAll,
121121
clearAndApply,
122-
clearKeys,
123122
hasChanges,
124123
changeCount,
125124
getFilterValue,
@@ -199,20 +198,6 @@ export const FindingsFilters = ({
199198
setPending(filterKey, nextValues);
200199
};
201200

202-
// Handler for clearing all chips: clears only the filter keys visible as chips,
203-
// without touching provider/account selectors.
204-
const PROVIDER_KEYS = new Set([
205-
"filter[provider_type__in]",
206-
"filter[provider_id__in]",
207-
]);
208-
209-
const handleClearAllChips = () => {
210-
const chipKeys = Array.from(new Set(filterChips.map((c) => c.key))).filter(
211-
(k) => !PROVIDER_KEYS.has(k),
212-
);
213-
clearKeys(chipKeys);
214-
};
215-
216201
// Derive pending muted state for the checkbox.
217202
// Note: "filter[muted]" participates in batch mode — applyAll includes it
218203
// when present in pending state, and the defaultParams option ensures
@@ -291,11 +276,7 @@ export const FindingsFilters = ({
291276
</div>
292277

293278
{/* Summary strip: shown below filter bar when there are pending changes */}
294-
<FilterSummaryStrip
295-
chips={filterChips}
296-
onRemove={handleChipRemove}
297-
onClearAll={handleClearAllChips}
298-
/>
279+
<FilterSummaryStrip chips={filterChips} onRemove={handleChipRemove} />
299280

300281
{/* Expandable filters section */}
301282
{hasCustomFilters && (

0 commit comments

Comments
 (0)