feat: Adds drill to detail context menu to Table (#21168)

* feat: Adds drill to detail context menu to Table

* Improves context menu positioning

* Fixes Pivot Table typying
This commit is contained in:
Michael S. Molina 2022-08-26 13:35:26 -03:00 committed by GitHub
parent 982210ad83
commit 68fa4d2665
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 4 deletions

View File

@ -365,8 +365,8 @@ export default function PivotTableChart(props: PivotTableProps) {
const handleContextMenu = useCallback( const handleContextMenu = useCallback(
( (
e: MouseEvent, e: MouseEvent,
colKey: DataRecordValue[] | undefined, colKey: (string | number | boolean)[] | undefined,
rowKey: DataRecordValue[] | undefined, rowKey: (string | number | boolean)[] | undefined,
) => { ) => {
if (onContextMenu) { if (onContextMenu) {
e.preventDefault(); e.preventDefault();

View File

@ -23,6 +23,7 @@ import React, {
HTMLProps, HTMLProps,
MutableRefObject, MutableRefObject,
CSSProperties, CSSProperties,
MouseEvent,
} from 'react'; } from 'react';
import { import {
useTable, useTable,
@ -66,6 +67,7 @@ export interface DataTableProps<D extends object> extends TableOptions<D> {
rowCount: number; rowCount: number;
wrapperRef?: MutableRefObject<HTMLDivElement>; wrapperRef?: MutableRefObject<HTMLDivElement>;
onColumnOrderChange: () => void; onColumnOrderChange: () => void;
onContextMenu?: (value: D, clientX: number, clientY: number) => void;
} }
export interface RenderHTMLCellProps extends HTMLProps<HTMLTableCellElement> { export interface RenderHTMLCellProps extends HTMLProps<HTMLTableCellElement> {
@ -98,6 +100,7 @@ export default typedMemo(function DataTable<D extends object>({
serverPagination, serverPagination,
wrapperRef: userWrapperRef, wrapperRef: userWrapperRef,
onColumnOrderChange, onColumnOrderChange,
onContextMenu,
...moreUseTableOptions ...moreUseTableOptions
}: DataTableProps<D>): JSX.Element { }: DataTableProps<D>): JSX.Element {
const tableHooks: PluginHook<D>[] = [ const tableHooks: PluginHook<D>[] = [
@ -270,7 +273,20 @@ export default typedMemo(function DataTable<D extends object>({
prepareRow(row); prepareRow(row);
const { key: rowKey, ...rowProps } = row.getRowProps(); const { key: rowKey, ...rowProps } = row.getRowProps();
return ( return (
<tr key={rowKey || row.id} {...rowProps}> <tr
key={rowKey || row.id}
{...rowProps}
onContextMenu={(e: MouseEvent) => {
if (onContextMenu) {
e.preventDefault();
onContextMenu(
row.original,
e.nativeEvent.clientX,
e.nativeEvent.clientY,
);
}
}}
>
{row.cells.map(cell => {row.cells.map(cell =>
cell.render('Cell', { key: cell.column.id }), cell.render('Cell', { key: cell.column.id }),
)} )}

View File

@ -39,6 +39,7 @@ import {
ensureIsArray, ensureIsArray,
GenericDataType, GenericDataType,
getTimeFormatterForGranularity, getTimeFormatterForGranularity,
QueryObjectFilterClause,
styled, styled,
t, t,
tn, tn,
@ -205,6 +206,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
sticky = true, // whether to use sticky header sticky = true, // whether to use sticky header
columnColorFormatters, columnColorFormatters,
allowRearrangeColumns = false, allowRearrangeColumns = false,
onContextMenu,
} = props; } = props;
const timestampFormatter = useCallback( const timestampFormatter = useCallback(
value => getTimeFormatterForGranularity(timeGrain)(value), value => getTimeFormatterForGranularity(timeGrain)(value),
@ -576,6 +578,24 @@ export default function TableChart<D extends DataRecord = DataRecord>(
const { width: widthFromState, height: heightFromState } = tableSize; const { width: widthFromState, height: heightFromState } = tableSize;
const handleContextMenu =
onContextMenu && !isRawRecords
? (value: D, clientX: number, clientY: number) => {
const filters: QueryObjectFilterClause[] = [];
columnsMeta.forEach(col => {
if (!col.isMetric) {
filters.push({
col: col.key,
op: '==',
val: value[col.key] as string | number | boolean,
formattedVal: String(value[col.key]),
});
}
});
onContextMenu(filters, clientX, clientY);
}
: undefined;
return ( return (
<Styles> <Styles>
<DataTable<D> <DataTable<D>
@ -598,6 +618,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
selectPageSize={pageSize !== null && SelectPageSize} selectPageSize={pageSize !== null && SelectPageSize}
// not in use in Superset, but needed for unit tests // not in use in Superset, but needed for unit tests
sticky={sticky} sticky={sticky}
onContextMenu={handleContextMenu}
/> />
</Styles> </Styles>
); );

View File

@ -204,7 +204,11 @@ const transformProps = (
queriesData = [], queriesData = [],
filterState, filterState,
ownState: serverPaginationData, ownState: serverPaginationData,
hooks: { onAddFilter: onChangeFilter, setDataMask = () => {} }, hooks: {
onAddFilter: onChangeFilter,
setDataMask = () => {},
onContextMenu,
},
} = chartProps; } = chartProps;
const { const {
@ -274,6 +278,7 @@ const transformProps = (
columnColorFormatters, columnColorFormatters,
timeGrain, timeGrain,
allowRearrangeColumns, allowRearrangeColumns,
onContextMenu,
}; };
}; };

View File

@ -30,6 +30,7 @@ import {
ChartDataResponseResult, ChartDataResponseResult,
QueryFormData, QueryFormData,
SetDataMaskHook, SetDataMaskHook,
QueryObjectFilterClause,
} from '@superset-ui/core'; } from '@superset-ui/core';
import { ColorFormatters, ColumnConfig } from '@superset-ui/chart-controls'; import { ColorFormatters, ColumnConfig } from '@superset-ui/chart-controls';
@ -111,6 +112,11 @@ export interface TableChartTransformedProps<D extends DataRecord = DataRecord> {
onChangeFilter?: ChartProps['hooks']['onAddFilter']; onChangeFilter?: ChartProps['hooks']['onAddFilter'];
columnColorFormatters?: ColorFormatters; columnColorFormatters?: ColorFormatters;
allowRearrangeColumns?: boolean; allowRearrangeColumns?: boolean;
onContextMenu?: (
filters: QueryObjectFilterClause[],
clientX: number,
clientY: number,
) => void;
} }
export default {}; export default {};