Skip to content

Commit

Permalink
Add telemetry to every filter action in entity data table (#21309)
Browse files Browse the repository at this point in the history
* Add telemetry to every filter action in entity data table
  • Loading branch information
maxiadlovskii authored Jan 15, 2025
1 parent c8dd9d5 commit d5a741f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ describe('<EntityFilters />', () => {
},
];

const EntityFilters = (props: Optional<React.ComponentProps<typeof OriginalEntityFilters>, 'setUrlQueryFilters' | 'attributes'>) => (
<OriginalEntityFilters setUrlQueryFilters={setUrlQueryFilters} attributes={attributes} {...props} />
const EntityFilters = (props: Optional<React.ComponentProps<typeof OriginalEntityFilters>, 'setUrlQueryFilters' | 'attributes' | 'appSection'>) => (
<OriginalEntityFilters setUrlQueryFilters={setUrlQueryFilters} attributes={attributes} appSection="test-app-section" {...props} />
);

const dropdownIsHidden = (dropdownTitle: string) => expect(screen.queryByRole('heading', { name: new RegExp(dropdownTitle, 'i') })).not.toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import type { Attributes } from 'stores/PaginationTypes';
import type { Filters, Filter, UrlQueryFilters } from 'components/common/EntityFilters/types';
import ActiveFilters from 'components/common/EntityFilters/ActiveFilters';
import useFiltersWithTitle from 'components/common/EntityFilters/hooks/useFiltersWithTitle';
import useSendTelemetry from 'logic/telemetry/useSendTelemetry';
import useLocation from 'routing/useLocation';
import { TELEMETRY_EVENT_TYPE } from 'logic/telemetry/Constants';
import { getPathnameWithoutId } from 'util/URLUtils';

import { ROW_MIN_HEIGHT } from './Constants';

Expand All @@ -40,13 +44,17 @@ const FilterCreation = styled.div`
`;

type Props = {
attributes: Attributes,
attributes?: Attributes,
urlQueryFilters: UrlQueryFilters | undefined,
setUrlQueryFilters: (urlQueryFilters: UrlQueryFilters) => void,
filterValueRenderers?: { [attributeId: string]: (value: Filter['value'], title: string) => React.ReactNode };
filterValueRenderers?: { [attributeId: string]: (value: Filter['value'], title: string) => React.ReactNode },
appSection: string,
}

const EntityFilters = ({ attributes = [], filterValueRenderers, urlQueryFilters, setUrlQueryFilters }: Props) => {
const EntityFilters = ({ attributes = [], filterValueRenderers = undefined, urlQueryFilters, setUrlQueryFilters, appSection }: Props) => {
const { pathname } = useLocation();
const sendTelemetry = useSendTelemetry();

const {
data: activeFilters,
onChange: onChangeFiltersWithTitle,
Expand All @@ -68,13 +76,27 @@ const EntityFilters = ({ attributes = [], filterValueRenderers, urlQueryFilters,
}, [onChangeFiltersWithTitle, setUrlQueryFilters]);

const onCreateFilter = useCallback((attributeId: string, filter: Filter) => {
sendTelemetry(TELEMETRY_EVENT_TYPE.ENTITY_DATA_TABLE.FILTER_CREATED, {
app_pathname: getPathnameWithoutId(pathname),
app_section: appSection,
app_action_value: 'filter-created',
attribute_id: attributeId,
});

onChangeFilters(OrderedMap(activeFilters).set(
attributeId,
[...(activeFilters?.get(attributeId) ?? []), filter],
));
}, [activeFilters, onChangeFilters]);
}, [activeFilters, appSection, onChangeFilters, pathname, sendTelemetry]);

const onDeleteFilter = useCallback((attributeId: string, filterId: string) => {
sendTelemetry(TELEMETRY_EVENT_TYPE.ENTITY_DATA_TABLE.FILTER_DELETED, {
app_pathname: getPathnameWithoutId(pathname),
app_section: appSection,
app_action_value: 'filter-deleted',
attribute_id: attributeId,
});

const filterGroup = activeFilters.get(attributeId);
const updatedFilterGroup = filterGroup.filter(({ value }) => value !== filterId);

Expand All @@ -83,16 +105,23 @@ const EntityFilters = ({ attributes = [], filterValueRenderers, urlQueryFilters,
}

return onChangeFilters(activeFilters.remove(attributeId));
}, [activeFilters, onChangeFilters]);
}, [activeFilters, appSection, onChangeFilters, pathname, sendTelemetry]);

const onChangeFilter = useCallback((attributeId: string, prevValue: string, newFilter: Filter) => {
sendTelemetry(TELEMETRY_EVENT_TYPE.ENTITY_DATA_TABLE.FILTER_CHANGED, {
app_pathname: getPathnameWithoutId(pathname),
app_section: appSection,
app_action_value: 'filter-value-changed',
attribute_id: attributeId,
});

const filterGroup = activeFilters.get(attributeId);
const targetFilterIndex = filterGroup.findIndex(({ value }) => value === prevValue);
const updatedFilterGroup = [...filterGroup];
updatedFilterGroup[targetFilterIndex] = newFilter;

onChangeFilters(activeFilters.set(attributeId, updatedFilterGroup));
}, [activeFilters, onChangeFilters]);
}, [activeFilters, appSection, onChangeFilters, pathname, sendTelemetry]);

if (!filterableAttributes.length) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,16 @@ const PaginatedEntityTable = <T extends EntityBase, M = unknown>({
setUrlQueryFilters(newUrlQueryFilters);
}, [paginationQueryParameter, setUrlQueryFilters]);

const appSection = `${tableLayout.entityTableId}-list`;

const {
onPageSizeChange,
onSearch,
onSearchReset,
onColumnsChange,
onSortChange,
} = useTableEventHandlers({
appSection: `${tableLayout.entityTableId}-list`,
appSection,
paginationQueryParameter,
updateTableLayout,
setQuery,
Expand Down Expand Up @@ -146,7 +148,8 @@ const PaginatedEntityTable = <T extends EntityBase, M = unknown>({
<EntityFilters attributes={attributes}
urlQueryFilters={urlQueryFilters}
setUrlQueryFilters={onChangeFilters}
filterValueRenderers={filterValueRenderers} />
filterValueRenderers={filterValueRenderers}
appSection={appSection} />
</div>
</SearchForm>
{topRightCol}
Expand Down
3 changes: 3 additions & 0 deletions graylog2-web-interface/src/logic/telemetry/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,5 +405,8 @@ export const TELEMETRY_EVENT_TYPE = {
COLUMNS_CHANGED: 'Entity Data Table Columns Changed',
SORT_CHANGED: 'Entity Data Table Sort Changed',
PAGE_SIZE_CHANGED: 'Entity Data Table Page Size Changed',
FILTER_CREATED: 'Entity Data Table Filter Created',
FILTER_DELETED: 'Entity Data Table Filter Deleted',
FILTER_CHANGED: 'Entity Data Table Filter Changed',
},
} as const;

0 comments on commit d5a741f

Please sign in to comment.