From 68fa4d2665cc0742b2194533271ce562a3ebbf14 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Fri, 26 Aug 2022 13:35:26 -0300 Subject: [PATCH] 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 --- .../src/PivotTableChart.tsx | 4 ++-- .../src/DataTable/DataTable.tsx | 18 +++++++++++++++- .../plugin-chart-table/src/TableChart.tsx | 21 +++++++++++++++++++ .../plugin-chart-table/src/transformProps.ts | 7 ++++++- .../plugins/plugin-chart-table/src/types.ts | 6 ++++++ 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/superset-frontend/plugins/plugin-chart-pivot-table/src/PivotTableChart.tsx b/superset-frontend/plugins/plugin-chart-pivot-table/src/PivotTableChart.tsx index 924470559f..4d740148f7 100644 --- a/superset-frontend/plugins/plugin-chart-pivot-table/src/PivotTableChart.tsx +++ b/superset-frontend/plugins/plugin-chart-pivot-table/src/PivotTableChart.tsx @@ -365,8 +365,8 @@ export default function PivotTableChart(props: PivotTableProps) { const handleContextMenu = useCallback( ( e: MouseEvent, - colKey: DataRecordValue[] | undefined, - rowKey: DataRecordValue[] | undefined, + colKey: (string | number | boolean)[] | undefined, + rowKey: (string | number | boolean)[] | undefined, ) => { if (onContextMenu) { e.preventDefault(); diff --git a/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx b/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx index 85580e7b63..d107f2e5e1 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx @@ -23,6 +23,7 @@ import React, { HTMLProps, MutableRefObject, CSSProperties, + MouseEvent, } from 'react'; import { useTable, @@ -66,6 +67,7 @@ export interface DataTableProps extends TableOptions { rowCount: number; wrapperRef?: MutableRefObject; onColumnOrderChange: () => void; + onContextMenu?: (value: D, clientX: number, clientY: number) => void; } export interface RenderHTMLCellProps extends HTMLProps { @@ -98,6 +100,7 @@ export default typedMemo(function DataTable({ serverPagination, wrapperRef: userWrapperRef, onColumnOrderChange, + onContextMenu, ...moreUseTableOptions }: DataTableProps): JSX.Element { const tableHooks: PluginHook[] = [ @@ -270,7 +273,20 @@ export default typedMemo(function DataTable({ prepareRow(row); const { key: rowKey, ...rowProps } = row.getRowProps(); return ( - + { + if (onContextMenu) { + e.preventDefault(); + onContextMenu( + row.original, + e.nativeEvent.clientX, + e.nativeEvent.clientY, + ); + } + }} + > {row.cells.map(cell => cell.render('Cell', { key: cell.column.id }), )} diff --git a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx index 8acc06199f..98c19f20ba 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx @@ -39,6 +39,7 @@ import { ensureIsArray, GenericDataType, getTimeFormatterForGranularity, + QueryObjectFilterClause, styled, t, tn, @@ -205,6 +206,7 @@ export default function TableChart( sticky = true, // whether to use sticky header columnColorFormatters, allowRearrangeColumns = false, + onContextMenu, } = props; const timestampFormatter = useCallback( value => getTimeFormatterForGranularity(timeGrain)(value), @@ -576,6 +578,24 @@ export default function TableChart( 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 ( @@ -598,6 +618,7 @@ export default function TableChart( selectPageSize={pageSize !== null && SelectPageSize} // not in use in Superset, but needed for unit tests sticky={sticky} + onContextMenu={handleContextMenu} /> ); diff --git a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts index 5cf4fd1e83..bca48e6340 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts @@ -204,7 +204,11 @@ const transformProps = ( queriesData = [], filterState, ownState: serverPaginationData, - hooks: { onAddFilter: onChangeFilter, setDataMask = () => {} }, + hooks: { + onAddFilter: onChangeFilter, + setDataMask = () => {}, + onContextMenu, + }, } = chartProps; const { @@ -274,6 +278,7 @@ const transformProps = ( columnColorFormatters, timeGrain, allowRearrangeColumns, + onContextMenu, }; }; diff --git a/superset-frontend/plugins/plugin-chart-table/src/types.ts b/superset-frontend/plugins/plugin-chart-table/src/types.ts index f5b83fa8bf..6a5cb88f44 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/types.ts +++ b/superset-frontend/plugins/plugin-chart-table/src/types.ts @@ -30,6 +30,7 @@ import { ChartDataResponseResult, QueryFormData, SetDataMaskHook, + QueryObjectFilterClause, } from '@superset-ui/core'; import { ColorFormatters, ColumnConfig } from '@superset-ui/chart-controls'; @@ -111,6 +112,11 @@ export interface TableChartTransformedProps { onChangeFilter?: ChartProps['hooks']['onAddFilter']; columnColorFormatters?: ColorFormatters; allowRearrangeColumns?: boolean; + onContextMenu?: ( + filters: QueryObjectFilterClause[], + clientX: number, + clientY: number, + ) => void; } export default {};