diff --git a/package-lock.json b/package-lock.json index 351f58c..7362713 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,8 @@ "@fontsource-variable/roboto": "^5.2.5", "@fontsource/space-mono": "^5.2.5", "@microlink/react-json-view": "^1.26.2", - "ag-grid-community": "^33.3.2", - "ag-grid-react": "^33.3.2", + "ag-grid-community": "^34.1.2", + "ag-grid-react": "^34.1.2", "denque": "^2.1.0", "lucide-react": "^0.513.0", "react": "^19.1.0", @@ -2671,27 +2671,27 @@ } }, "node_modules/ag-charts-types": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/ag-charts-types/-/ag-charts-types-11.3.2.tgz", - "integrity": "sha512-trPGqgGYiTeLgtf9nLuztDYOPOFOLbqHn1g2D99phf7QowcwdX0TPx0wfWG8Hm90LjB8IH+G2s3AZe2vrdAtMQ==", + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/ag-charts-types/-/ag-charts-types-12.1.2.tgz", + "integrity": "sha512-B5IEMzaDxpJRko9sREIBEZOn44tlMX353tMJ1RGYHZrjDFx4on/p6q3YxBvway3nViAM2POmFOS45+1fF9YC8g==", "license": "MIT" }, "node_modules/ag-grid-community": { - "version": "33.3.2", - "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-33.3.2.tgz", - "integrity": "sha512-9bx0e/+ykOyLvUxHqmdy0cRVANH6JAtv0yZdnBZEXYYqBAwN+G5a4NY+2I1KvoOCYzbk8SnStG7y4hCdVAAWOQ==", + "version": "34.1.2", + "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-34.1.2.tgz", + "integrity": "sha512-PN79zG/tigZaVKkQZXaithLO3j4JWp+9CjqEFth6kFUwMJ0E6OcNzNtn4NFEKM38fEdpGsr+k+gFk5KUE2h5fA==", "license": "MIT", "dependencies": { - "ag-charts-types": "11.3.2" + "ag-charts-types": "12.1.2" } }, "node_modules/ag-grid-react": { - "version": "33.3.2", - "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-33.3.2.tgz", - "integrity": "sha512-5bv4JIJvGov23sduIUIyQTqpa/qhoQrRkQm5pFOQb7RMwusfx6xBPrkLwIIlCJiQ8g0OOinxWzZ2kQ2Zml6tLw==", + "version": "34.1.2", + "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-34.1.2.tgz", + "integrity": "sha512-6l5+hp3O4VSZ1nc2IZSQyhNeUOZ4TDg4UVrpxsqV3xXBO1TRqmOhcsYBDJ95JZ8zSiAEvy7XKT3MSI7sJG+MFg==", "license": "MIT", "dependencies": { - "ag-grid-community": "33.3.2", + "ag-grid-community": "34.1.2", "prop-types": "^15.8.1" }, "peerDependencies": { diff --git a/package.json b/package.json index c9175d7..35f41cb 100644 --- a/package.json +++ b/package.json @@ -79,8 +79,8 @@ "@fontsource-variable/roboto": "^5.2.5", "@fontsource/space-mono": "^5.2.5", "@microlink/react-json-view": "^1.26.2", - "ag-grid-community": "^33.3.2", - "ag-grid-react": "^33.3.2", + "ag-grid-community": "^34.1.2", + "ag-grid-react": "^34.1.2", "denque": "^2.1.0", "lucide-react": "^0.513.0", "react": "^19.1.0", diff --git a/src/extension/react/AgGridFilters/DirectionFilter.tsx b/src/extension/react/AgGridFilters/DirectionFilter.tsx new file mode 100644 index 0000000..bbf3684 --- /dev/null +++ b/src/extension/react/AgGridFilters/DirectionFilter.tsx @@ -0,0 +1,66 @@ +import type { CustomFilterDisplayProps } from 'ag-grid-react'; +import { Check } from 'lucide-react'; +import type { Direction } from '../../../types/shared'; +import DirectionBadge from '../components/DirectionBadge'; + +const ALL_DIRECTIONS: Direction[] = [ + 'renderer-to-main', + 'main-to-renderer', + 'service-worker-to-main', + 'main-to-service-worker', + 'renderer', + 'main', +]; + +export default function DirectionFilter({ + model, + onModelChange, +}: CustomFilterDisplayProps) { + const selected: Direction[] = model ?? []; + + const toggle = (dir: Direction) => { + if (selected.includes(dir)) { + const next = selected.filter((d) => d !== dir); + onModelChange(next.length ? next : null); + } else { + onModelChange([...selected, dir]); + } + }; + + return ( +
+ {ALL_DIRECTIONS.map((dir) => { + const isSelected = selected.includes(dir); + return ( +
toggle(dir)} + className="flex cursor-pointer items-center gap-1 rounded-sm p-1 transition-all duration-150" + > +
+ {isSelected && } +
+ +
+ ); + })} + + {selected.length > 0 && ( +
+ +
+ )} +
+ ); +} diff --git a/src/extension/react/AgGridFilters/filters.ts b/src/extension/react/AgGridFilters/filters.ts new file mode 100644 index 0000000..0b16d50 --- /dev/null +++ b/src/extension/react/AgGridFilters/filters.ts @@ -0,0 +1,14 @@ +import type { DoesFilterPassParams } from 'ag-grid-community'; +import type { Direction } from '../../../types/shared'; + +export const directionDoesFilterPass = ({ + model, + node, + handlerParams, +}: DoesFilterPassParams) => { + if (!model || model.length === 0) return true; + + const value: Direction | null | undefined = handlerParams.getValue(node); + if (!value) return false; + else return model.includes(value); +}; diff --git a/src/extension/react/components/Panel.tsx b/src/extension/react/components/Panel.tsx index 20bdaf0..f83f391 100644 --- a/src/extension/react/components/Panel.tsx +++ b/src/extension/react/components/Panel.tsx @@ -15,6 +15,11 @@ import { ScrollApiModule, TooltipModule, RowApiModule, + TextFilterModule, + NumberFilterModule, + DateFilterModule, + CustomFilterModule, + ValidationModule, } from 'ag-grid-community'; import { Ban, Lock, LockOpen, Moon, PanelBottom, PanelRight, Sun } from 'lucide-react'; import { MSG_TYPE, PORT_NAME } from '../../../common/constants'; @@ -31,8 +36,15 @@ ModuleRegistry.registerModules([ ScrollApiModule, TooltipModule, RowApiModule, + TextFilterModule, + NumberFilterModule, + DateFilterModule, + CustomFilterModule, + ValidationModule, ]); import { useDevtronContext } from '../context/context'; +import DirectionFilter from '../AgGridFilters/DirectionFilter'; +import { directionDoesFilterPass } from '../AgGridFilters/filters'; const isDev = process.env.NODE_ENV === 'development'; @@ -219,7 +231,7 @@ function Panel() { field: 'serialNumber', width: 55, cellClass: 'flex !p-1 items-center h-full text-xs', - headerClass: '!h-6', + headerClass: '!h-6 !px-1.5', }, { headerName: 'Time', @@ -229,7 +241,7 @@ function Panel() { return formatTimestamp(params.value); }, cellClass: 'flex !p-1 items-center h-full text-xs', - headerClass: '!h-6', + headerClass: '!h-6 !px-1.5', }, { headerName: 'Direction', @@ -239,14 +251,15 @@ function Panel() { return ; }, cellClass: 'flex !p-1 items-center h-full', - headerClass: '!h-6', + headerClass: '!h-6 !px-1.5', + filter: { component: DirectionFilter, doesFilterPass: directionDoesFilterPass }, }, { headerName: 'Channel', field: 'channel', flex: 1, cellClass: 'font-roboto text-[13px] !p-1 h-full flex items-center', - headerClass: '!h-6', + headerClass: '!h-6 !px-1.5', cellRenderer: (params: ICellRendererParams) => { return (
@@ -259,6 +272,7 @@ function Panel() {
); }, + filter: 'agTextColumnFilter', }, { headerName: 'Data', @@ -270,8 +284,10 @@ function Panel() { return {preview}; }, cellClass: 'flex !p-1 items-center h-full', - headerClass: '!h-6', + headerClass: '!h-6 !px-1.5', resizable: false, + filter: 'agTextColumnFilter', + filterValueGetter: (params) => JSON.stringify(params.data?.args), }, ], [], @@ -389,6 +405,7 @@ function Panel() { suppressCellFocus={true} headerHeight={25} rowHeight={29} + enableFilterHandlers={true} />