Skip to content

Commit 827f5c0

Browse files
authored
feat: add filtering support to event grid (#284)
* chore: bump `ag-grid-community` and `ag-grid-react` to `v34.1.2` * feat: add filtering support to event grid * fix: 2nd arg search * chore: cleanup
1 parent 166a823 commit 827f5c0

File tree

5 files changed

+117
-20
lines changed

5 files changed

+117
-20
lines changed

package-lock.json

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@
7979
"@fontsource-variable/roboto": "^5.2.5",
8080
"@fontsource/space-mono": "^5.2.5",
8181
"@microlink/react-json-view": "^1.26.2",
82-
"ag-grid-community": "^33.3.2",
83-
"ag-grid-react": "^33.3.2",
82+
"ag-grid-community": "^34.1.2",
83+
"ag-grid-react": "^34.1.2",
8484
"denque": "^2.1.0",
8585
"lucide-react": "^0.513.0",
8686
"react": "^19.1.0",
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import type { CustomFilterDisplayProps } from 'ag-grid-react';
2+
import { Check } from 'lucide-react';
3+
import type { Direction } from '../../../types/shared';
4+
import DirectionBadge from '../components/DirectionBadge';
5+
6+
const ALL_DIRECTIONS: Direction[] = [
7+
'renderer-to-main',
8+
'main-to-renderer',
9+
'service-worker-to-main',
10+
'main-to-service-worker',
11+
'renderer',
12+
'main',
13+
];
14+
15+
export default function DirectionFilter({
16+
model,
17+
onModelChange,
18+
}: CustomFilterDisplayProps<string[]>) {
19+
const selected: Direction[] = model ?? [];
20+
21+
const toggle = (dir: Direction) => {
22+
if (selected.includes(dir)) {
23+
const next = selected.filter((d) => d !== dir);
24+
onModelChange(next.length ? next : null);
25+
} else {
26+
onModelChange([...selected, dir]);
27+
}
28+
};
29+
30+
return (
31+
<div className="flex flex-col gap-1 p-1">
32+
{ALL_DIRECTIONS.map((dir) => {
33+
const isSelected = selected.includes(dir);
34+
return (
35+
<div
36+
key={dir}
37+
onClick={() => toggle(dir)}
38+
className="flex cursor-pointer items-center gap-1 rounded-sm p-1 transition-all duration-150"
39+
>
40+
<div
41+
className={`flex h-5 w-5 items-center justify-center rounded-sm border-2 transition-all duration-150 ${
42+
isSelected
43+
? 'border-blue-500 bg-blue-500 text-white'
44+
: 'border-gray-300 hover:border-gray-400 dark:border-charcoal-300'
45+
} `}
46+
>
47+
{isSelected && <Check size={12} strokeWidth={3} />}
48+
</div>
49+
<DirectionBadge direction={dir} />
50+
</div>
51+
);
52+
})}
53+
54+
{selected.length > 0 && (
55+
<div className="mt-1 flex items-center justify-center border-t border-gray-100 pt-1 dark:border-charcoal-300">
56+
<button
57+
onClick={() => onModelChange(null)}
58+
className="w-full text-center text-xs text-gray-500 transition-colors duration-150 hover:text-gray-700 dark:text-charcoal-100 dark:hover:text-gray-100"
59+
>
60+
Clear all
61+
</button>
62+
</div>
63+
)}
64+
</div>
65+
);
66+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { DoesFilterPassParams } from 'ag-grid-community';
2+
import type { Direction } from '../../../types/shared';
3+
4+
export const directionDoesFilterPass = ({
5+
model,
6+
node,
7+
handlerParams,
8+
}: DoesFilterPassParams<any, any, Direction[]>) => {
9+
if (!model || model.length === 0) return true;
10+
11+
const value: Direction | null | undefined = handlerParams.getValue(node);
12+
if (!value) return false;
13+
else return model.includes(value);
14+
};

src/extension/react/components/Panel.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ import {
1515
ScrollApiModule,
1616
TooltipModule,
1717
RowApiModule,
18+
TextFilterModule,
19+
NumberFilterModule,
20+
DateFilterModule,
21+
CustomFilterModule,
22+
ValidationModule,
1823
} from 'ag-grid-community';
1924
import { Ban, Lock, LockOpen, Moon, PanelBottom, PanelRight, Sun } from 'lucide-react';
2025
import { MSG_TYPE, PORT_NAME } from '../../../common/constants';
@@ -31,8 +36,15 @@ ModuleRegistry.registerModules([
3136
ScrollApiModule,
3237
TooltipModule,
3338
RowApiModule,
39+
TextFilterModule,
40+
NumberFilterModule,
41+
DateFilterModule,
42+
CustomFilterModule,
43+
ValidationModule,
3444
]);
3545
import { useDevtronContext } from '../context/context';
46+
import DirectionFilter from '../AgGridFilters/DirectionFilter';
47+
import { directionDoesFilterPass } from '../AgGridFilters/filters';
3648

3749
const isDev = process.env.NODE_ENV === 'development';
3850

@@ -219,7 +231,7 @@ function Panel() {
219231
field: 'serialNumber',
220232
width: 55,
221233
cellClass: 'flex !p-1 items-center h-full text-xs',
222-
headerClass: '!h-6',
234+
headerClass: '!h-6 !px-1.5',
223235
},
224236
{
225237
headerName: 'Time',
@@ -229,7 +241,7 @@ function Panel() {
229241
return formatTimestamp(params.value);
230242
},
231243
cellClass: 'flex !p-1 items-center h-full text-xs',
232-
headerClass: '!h-6',
244+
headerClass: '!h-6 !px-1.5',
233245
},
234246
{
235247
headerName: 'Direction',
@@ -239,14 +251,15 @@ function Panel() {
239251
return <DirectionBadge direction={params.value} />;
240252
},
241253
cellClass: 'flex !p-1 items-center h-full',
242-
headerClass: '!h-6',
254+
headerClass: '!h-6 !px-1.5',
255+
filter: { component: DirectionFilter, doesFilterPass: directionDoesFilterPass },
243256
},
244257
{
245258
headerName: 'Channel',
246259
field: 'channel',
247260
flex: 1,
248261
cellClass: 'font-roboto text-[13px] !p-1 h-full flex items-center',
249-
headerClass: '!h-6',
262+
headerClass: '!h-6 !px-1.5',
250263
cellRenderer: (params: ICellRendererParams<IpcEventDataIndexed>) => {
251264
return (
252265
<div title={params.value}>
@@ -259,6 +272,7 @@ function Panel() {
259272
</div>
260273
);
261274
},
275+
filter: 'agTextColumnFilter',
262276
},
263277
{
264278
headerName: 'Data',
@@ -270,8 +284,10 @@ function Panel() {
270284
return <span className="truncate font-space-mono text-xs">{preview}</span>;
271285
},
272286
cellClass: 'flex !p-1 items-center h-full',
273-
headerClass: '!h-6',
287+
headerClass: '!h-6 !px-1.5',
274288
resizable: false,
289+
filter: 'agTextColumnFilter',
290+
filterValueGetter: (params) => JSON.stringify(params.data?.args),
275291
},
276292
],
277293
[],
@@ -389,6 +405,7 @@ function Panel() {
389405
suppressCellFocus={true}
390406
headerHeight={25}
391407
rowHeight={29}
408+
enableFilterHandlers={true}
392409
/>
393410
</div>
394411
</div>

0 commit comments

Comments
 (0)