mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
parent
80c8701e80
commit
073c961330
@ -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 } });
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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: [],
|
||||
|
Loading…
Reference in New Issue
Block a user