Datagrid usage tracking (#69826)

datagrid usage tracking
This commit is contained in:
Victor Marin 2023-06-13 16:48:11 +03:00 committed by GitHub
parent 80c8701e80
commit 073c961330
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 3 deletions

View File

@ -11,7 +11,7 @@ import DataEditor, {
import React, { useEffect, useReducer } from 'react';
import { Field, PanelProps, FieldType, DataFrame } from '@grafana/data';
import { PanelDataErrorView } from '@grafana/runtime';
import { PanelDataErrorView, reportInteraction } from '@grafana/runtime';
import { usePanelContext, useTheme2 } from '@grafana/ui';
import '@glideapps/glide-data-grid/dist/index.css';
@ -35,6 +35,8 @@ import {
ROW_MARKER_NUMBER,
hasGridSelection,
updateSnapshot,
INTERACTION_EVENT_NAME,
INTERACTION_ITEM,
} from './utils';
export interface DataGridProps extends PanelProps<Options> {}
@ -103,11 +105,14 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
values[row] = newValue.data;
field.values = [...values];
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.EDIT_CELL });
updateSnapshot(frameCopy, onUpdateData);
};
const onColumnInputBlur = (columnName: string) => {
const len = frame.length ?? 0;
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.APPEND_COLUMN });
updateSnapshot(
{
...frame,
@ -132,10 +137,12 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
return { ...f, values };
});
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.APPEND_ROW });
updateSnapshot({ ...frame, fields, length: frame.length + 1 }, onUpdateData);
};
const onColumnResize = (column: GridColumn, width: number, columnIndex: number, newSizeWithGrow: number) => {
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.COLUMN_RESIZE });
dispatch({ type: DatagridActionType.columnResizeStart, payload: { columnIndex, width } });
};
@ -150,6 +157,7 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
const onDeletePressed = (selection: GridSelection) => {
if (selection.current && selection.current.range) {
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.DELETE_BTN_PRESSED, selection: 'grid-cell' });
updateSnapshot(clearCellsFromRangeSelection(frame, selection.current.range), onUpdateData);
return true;
}
@ -158,6 +166,7 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
const cols = selection.columns.toArray();
if (rows.length) {
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.DELETE_BTN_PRESSED, selection: 'rows' });
updateSnapshot(deleteRows(frame, rows), onUpdateData);
return true;
}
@ -176,6 +185,7 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
return field;
}),
};
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.DELETE_BTN_PRESSED, selection: 'columns' });
updateSnapshot(copiedFrame, onUpdateData);
return true;
}
@ -209,6 +219,7 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
const hasUpdated = await updateSnapshot({ ...frame, fields }, onUpdateData);
if (hasUpdated) {
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.COLUMN_REORDER });
dispatch({ type: DatagridActionType.columnMove, payload: { from, to } });
}
};
@ -222,10 +233,15 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
field.values.splice(to, 0, value);
}
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.ROW_REORDER });
updateSnapshot({ ...frame, fields }, onUpdateData);
};
const onColumnRename = () => {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.HEADER_MENU_ACTION,
menu_action: 'rename_column',
});
dispatch({ type: DatagridActionType.showColumnRenameInput });
};
@ -243,6 +259,7 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
};
const onGridSelectionChange = (selection: GridSelection) => {
reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.GRID_SELECTED });
dispatch({ type: DatagridActionType.multipleCellsSelected, payload: { selection } });
};

View File

@ -4,11 +4,19 @@ import React from 'react';
import { DataFrame, FieldType } from '@grafana/data';
import { convertFieldType } from '@grafana/data/src/transformations/transformers/convertFieldType';
import { reportInteraction } from '@grafana/runtime';
import { ContextMenu, MenuGroup, MenuItem } from '@grafana/ui';
import { MenuDivider } from '@grafana/ui/src/components/Menu/MenuDivider';
import { DatagridAction, DatagridActionType } from '../state';
import { cleanStringFieldAfterConversion, DatagridContextMenuData, deleteRows, EMPTY_DF } from '../utils';
import {
cleanStringFieldAfterConversion,
DatagridContextMenuData,
deleteRows,
EMPTY_DF,
INTERACTION_EVENT_NAME,
INTERACTION_ITEM,
} from '../utils';
interface ContextMenuProps {
menuData: DatagridContextMenuData;
@ -72,6 +80,10 @@ export const DatagridContextMenu = ({
}
if (row !== undefined && row >= 0) {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.CONTEXT_MENU_ACTION,
menu_action: 'row_delete',
});
saveData(deleteRows(data, [row], true));
}
}}
@ -91,6 +103,10 @@ export const DatagridContextMenu = ({
}
if (column !== undefined && column >= 0) {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.CONTEXT_MENU_ACTION,
menu_action: 'column_delete',
});
saveData({
...data,
fields: data.fields.filter((_, index) => index !== column),
@ -104,6 +120,10 @@ export const DatagridContextMenu = ({
<MenuItem
label="Clear row"
onClick={() => {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.CONTEXT_MENU_ACTION,
menu_action: 'row_clear',
});
saveData(deleteRows(data, [row]));
}}
/>
@ -114,6 +134,10 @@ export const DatagridContextMenu = ({
onClick={() => {
const field = data.fields[column];
field.values = field.values.map(() => null);
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.CONTEXT_MENU_ACTION,
menu_action: 'column_clear',
});
saveData({
...data,
});
@ -124,10 +148,23 @@ export const DatagridContextMenu = ({
<MenuItem
label="Remove all data"
onClick={() => {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.CONTEXT_MENU_ACTION,
menu_action: 'remove_all',
});
saveData(EMPTY_DF);
}}
/>
<MenuItem label="Search..." onClick={() => dispatch({ type: DatagridActionType.openSearch })} />
<MenuItem
label="Search..."
onClick={() => {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.CONTEXT_MENU_ACTION,
menu_action: 'open_search',
});
dispatch({ type: DatagridActionType.openSearch });
}}
/>
</>
);
@ -197,6 +234,10 @@ export const DatagridContextMenu = ({
};
copy.fields[column] = field;
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.HEADER_MENU_ACTION,
menu_action: 'convert_field',
});
saveData(copy);
}}
/>
@ -207,6 +248,10 @@ export const DatagridContextMenu = ({
<MenuItem
label={columnFreezeLabel}
onClick={() => {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.HEADER_MENU_ACTION,
menu_action: 'column_freeze',
});
if (columnFreezeIndex === columnIndex) {
dispatch({ type: DatagridActionType.columnFreezeReset });
} else {
@ -219,6 +264,10 @@ export const DatagridContextMenu = ({
<MenuItem
label="Delete column"
onClick={() => {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.HEADER_MENU_ACTION,
menu_action: 'delete_column',
});
saveData({
...data,
fields: data.fields.filter((_, index) => index !== column),
@ -233,6 +282,10 @@ export const DatagridContextMenu = ({
onClick={() => {
const field = data.fields[column];
field.values = field.values.map(() => null);
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.HEADER_MENU_ACTION,
menu_action: 'clear_column',
});
saveData({
...data,
});

View File

@ -17,6 +17,20 @@ export const ROW_MARKER_NUMBER = 'number';
export const DEFAULT_CONTEXT_MENU = { isContextMenuOpen: false };
export const DEFAULT_RENAME_INPUT_DATA = { isInputOpen: false };
export const INTERACTION_EVENT_NAME = 'datagrid_panel';
export const INTERACTION_ITEM = {
EDIT_CELL: 'edit_cell',
GRID_SELECTED: 'grid_selected',
APPEND_ROW: 'append_row',
APPEND_COLUMN: 'append_column',
DELETE_BTN_PRESSED: 'delete_btn_pressed',
COLUMN_RESIZE: 'column_resize',
COLUMN_REORDER: 'column_reorder',
ROW_REORDER: 'row_reorder',
CONTEXT_MENU_ACTION: 'context_menu_action',
HEADER_MENU_ACTION: 'header_menu_action',
};
export const EMPTY_DF = {
name: 'A',
fields: [],