This is an automated email from the ASF dual-hosted git repository. erikrit pushed a commit to branch revert-11046-reactable/timetable in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
commit 1474fd77c4c468acbec572f7cfb6dea2b222f6e6 Author: Erik Ritter <[email protected]> AuthorDate: Fri Oct 2 21:23:35 2020 -0700 Revert "refactor: Remove usages of reactable from TimeTable (#11046)" This reverts commit f01b8a30f7af781b06d06e12fd6d895002333a02. --- .../src/components/ListView/ListView.tsx | 60 ++---- .../src/components/ListView/TableCollection.tsx | 12 +- superset-frontend/src/components/ListView/utils.ts | 4 +- .../src/visualizations/TimeTable/TimeTable.jsx | 206 ++++++++++----------- 4 files changed, 126 insertions(+), 156 deletions(-) diff --git a/superset-frontend/src/components/ListView/ListView.tsx b/superset-frontend/src/components/ListView/ListView.tsx index 72948d5..e0e19c5 100644 --- a/superset-frontend/src/components/ListView/ListView.tsx +++ b/superset-frontend/src/components/ListView/ListView.tsx @@ -17,7 +17,6 @@ * under the License. */ import { t, styled } from '@superset-ui/core'; -import { css } from '@emotion/core'; import React, { useState } from 'react'; import { Alert } from 'react-bootstrap'; import { Empty } from 'src/common/components'; @@ -38,11 +37,7 @@ import { } from './types'; import { ListViewError, useListViewState } from './utils'; -interface ListViewStylesProps { - fullHeight: boolean; -} - -const ListViewStyles = styled.div<ListViewStylesProps>` +const ListViewStyles = styled.div` text-align: center; .superset-list-view { @@ -53,12 +48,8 @@ const ListViewStyles = styled.div<ListViewStylesProps>` padding-bottom: 48px; .body { - ${({ fullHeight }) => - !fullHeight && - css` - overflow: scroll; - max-height: 64vh; - `}; + overflow: scroll; + max-height: 64vh; } } @@ -211,9 +202,6 @@ export interface ListViewProps<T extends object = any> { renderCard?: (row: T & { loading: boolean }) => React.ReactNode; cardSortSelectOptions?: Array<CardSortSelectOption>; defaultViewMode?: ViewModeType; - sticky?: boolean; - fullHeight?: boolean; - manualSortBy?: boolean; } function ListView<T extends object = any>({ @@ -233,9 +221,6 @@ function ListView<T extends object = any>({ renderCard, cardSortSelectOptions, defaultViewMode = 'card', - sticky = true, - fullHeight = false, - manualSortBy = true, }: ListViewProps<T>) { const { getTableProps, @@ -259,10 +244,8 @@ function ListView<T extends object = any>({ initialPageSize, initialSort, initialFilters: filters, - manualSortBy, }); const filterable = Boolean(filters.length); - const withPagination = Boolean(count); if (filterable) { const columnAccessors = columns.reduce( (acc, col) => ({ ...acc, [col.accessor || col.id]: true }), @@ -283,7 +266,7 @@ function ListView<T extends object = any>({ ); return ( - <ListViewStyles fullHeight={fullHeight}> + <ListViewStyles> <div className={`superset-list-view ${className}`}> <div className="header"> {cardViewEnabled && ( @@ -367,7 +350,6 @@ function ListView<T extends object = any>({ rows={rows} columns={columns} loading={loading} - sticky={sticky} /> )} {!loading && rows.length === 0 && ( @@ -378,25 +360,23 @@ function ListView<T extends object = any>({ </div> </div> - {withPagination && ( - <div className="pagination-container"> - <Pagination - totalPages={pageCount || 0} - currentPage={pageCount ? pageIndex + 1 : 0} - onChange={(p: number) => gotoPage(p - 1)} - hideFirstAndLastPageLinks - /> - <div className="row-count-container"> - {!loading && - t( - '%s-%s of %s', - pageSize * pageIndex + (rows.length && 1), - pageSize * pageIndex + rows.length, - count, - )} - </div> + <div className="pagination-container"> + <Pagination + totalPages={pageCount || 0} + currentPage={pageCount ? pageIndex + 1 : 0} + onChange={(p: number) => gotoPage(p - 1)} + hideFirstAndLastPageLinks + /> + <div className="row-count-container"> + {!loading && + t( + '%s-%s of %s', + pageSize * pageIndex + (rows.length && 1), + pageSize * pageIndex + rows.length, + count, + )} </div> - )} + </div> </ListViewStyles> ); } diff --git a/superset-frontend/src/components/ListView/TableCollection.tsx b/superset-frontend/src/components/ListView/TableCollection.tsx index a68bcf4..4dbbc86 100644 --- a/superset-frontend/src/components/ListView/TableCollection.tsx +++ b/superset-frontend/src/components/ListView/TableCollection.tsx @@ -30,19 +30,14 @@ interface TableCollectionProps { rows: TableInstance['rows']; columns: TableInstance['column'][]; loading: boolean; - sticky: boolean; } -interface TableProps { - sticky: boolean; -} - -const Table = styled.table<TableProps>` +const Table = styled.table` border-collapse: separate; th { background: ${({ theme }) => theme.colors.grayscale.light5}; - position: ${({ sticky }) => sticky && 'sticky'}; + position: sticky; top: 0; &:first-of-type { @@ -204,10 +199,9 @@ export default function TableCollection({ columns, rows, loading, - sticky, }: TableCollectionProps) { return ( - <Table {...getTableProps()} sticky={sticky} className="table table-hover"> + <Table {...getTableProps()} className="table table-hover"> <thead> {headerGroups.map(headerGroup => ( <tr {...headerGroup.getHeaderGroupProps()}> diff --git a/superset-frontend/src/components/ListView/utils.ts b/superset-frontend/src/components/ListView/utils.ts index 92605d2..c8ecc95 100644 --- a/superset-frontend/src/components/ListView/utils.ts +++ b/superset-frontend/src/components/ListView/utils.ts @@ -110,7 +110,6 @@ interface UseListViewConfig { Header: (conf: any) => React.ReactNode; Cell: (conf: any) => React.ReactNode; }; - manualSortBy: boolean; } export function useListViewState({ @@ -123,7 +122,6 @@ export function useListViewState({ initialSort = [], bulkSelectMode = false, bulkSelectColumnConfig, - manualSortBy, }: UseListViewConfig) { const [query, setQuery] = useQueryParams({ filters: JsonParam, @@ -179,9 +177,9 @@ export function useListViewState({ initialState, manualFilters: true, manualPagination: true, + manualSortBy: true, autoResetFilters: false, pageCount: Math.ceil(count / initialPageSize), - manualSortBy, }, useFilters, useSortBy, diff --git a/superset-frontend/src/visualizations/TimeTable/TimeTable.jsx b/superset-frontend/src/visualizations/TimeTable/TimeTable.jsx index d27a1e8..c384cb0 100644 --- a/superset-frontend/src/visualizations/TimeTable/TimeTable.jsx +++ b/superset-frontend/src/visualizations/TimeTable/TimeTable.jsx @@ -20,14 +20,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import Mustache from 'mustache'; import { scaleLinear } from 'd3-scale'; +import { Table, Thead, Th, Tr, Td } from 'reactable-arc'; import { formatNumber, formatTime } from '@superset-ui/core'; import { InfoTooltipWithTrigger, MetricOption, } from '@superset-ui/chart-controls'; import moment from 'moment'; -import ListView from 'src/components/ListView'; -import { memoize } from 'lodash-es'; + import FormattedNumber from './FormattedNumber'; import SparklineCell from './SparklineCell'; import './TimeTable.less'; @@ -90,68 +90,6 @@ const defaultProps = { }; class TimeTable extends React.PureComponent { - memoizedColumns = memoize(() => [ - { accessor: 'metric', Header: 'Metric' }, - ...this.props.columnConfigs.map((columnConfig, i) => ({ - accessor: columnConfig.key, - cellProps: columnConfig.colType === 'spark' && { style: { width: '1%' } }, - Header: () => ( - <> - {columnConfig.label}{' '} - {columnConfig.tooltip && ( - <InfoTooltipWithTrigger - tooltip={columnConfig.tooltip} - label={`tt-col-${i}`} - placement="top" - /> - )} - </> - ), - sortType: (rowA, rowB, columnId) => { - const rowAVal = rowA.values[columnId].props['data-value']; - const rowBVal = rowB.values[columnId].props['data-value']; - return rowAVal - rowBVal; - }, - })), - ]); - - memoizedRows = memoize(() => { - const entries = Object.keys(this.props.data) - .sort() - .map(time => ({ ...this.props.data[time], time })); - const reversedEntries = entries.concat().reverse(); - - return this.props.rows.map(row => { - const valueField = row.label || row.metric_name; - const cellValues = this.props.columnConfigs.reduce( - (acc, columnConfig) => { - if (columnConfig.colType === 'spark') { - return { - ...acc, - [columnConfig.key]: this.renderSparklineCell( - valueField, - columnConfig, - entries, - ), - }; - } - return { - ...acc, - [columnConfig.key]: this.renderValueCell( - valueField, - columnConfig, - reversedEntries, - ), - }; - }, - {}, - ); - return { ...row, ...cellValues, metric: this.renderLeftCell(row) }; - }); - }); - - initialSort = [{ id: 'metric', desc: false }]; - renderLeftCell(row) { const { rowType, url } = this.props; const context = { metric: row }; @@ -169,9 +107,10 @@ class TimeTable extends React.PureComponent { return column.label; } + const metric = row; return ( <MetricOption - metric={row} + metric={metric} url={fullUrl} showFormula={false} openInNewWindow @@ -197,27 +136,32 @@ class TimeTable extends React.PureComponent { } return ( - <SparklineCell - width={parseInt(column.width, 10) || 300} - height={parseInt(column.height, 10) || 50} - data={sparkData} - data-value={sparkData[sparkData.length - 1]} - ariaLabel={`spark-${valueField}`} - numberFormat={column.d3format} - yAxisBounds={column.yAxisBounds} - showYAxis={column.showYAxis} - renderTooltip={({ index }) => ( - <div> - <strong>{formatNumber(column.d3format, sparkData[index])}</strong> + <Td + column={column.key} + key={column.key} + value={sparkData[sparkData.length - 1]} + > + <SparklineCell + width={parseInt(column.width, 10) || 300} + height={parseInt(column.height, 10) || 50} + data={sparkData} + ariaLabel={`spark-${valueField}`} + numberFormat={column.d3format} + yAxisBounds={column.yAxisBounds} + showYAxis={column.showYAxis} + renderTooltip={({ index }) => ( <div> - {formatTime( - column.dateFormat, - moment.utc(entries[index].time).toDate(), - )} + <strong>{formatNumber(column.d3format, sparkData[index])}</strong> + <div> + {formatTime( + column.dateFormat, + moment.utc(entries[index].time).toDate(), + )} + </div> </div> - </div> - )} - /> + )} + /> + </Td> ); } @@ -260,9 +204,10 @@ class TimeTable extends React.PureComponent { const color = colorFromBounds(v, column.bounds); return ( - <span + <Td + column={column.key} key={column.key} - data-value={v} + value={v} style={ color && { boxShadow: `inset 0px -2.5px 0px 0px ${color}`, @@ -271,34 +216,87 @@ class TimeTable extends React.PureComponent { } > {errorMsg ? ( - { errorMsg } + <div>{errorMsg}</div> ) : ( - <span style={{ color }}> + <div style={{ color }}> <FormattedNumber num={v} format={column.d3format} /> - </span> + </div> + )} + </Td> + ); + } + + renderRow(row, entries, reversedEntries) { + const { columnConfigs } = this.props; + const valueField = row.label || row.metric_name; + const leftCell = this.renderLeftCell(row); + + return ( + <Tr key={leftCell}> + <Td column="metric" data={leftCell}> + {leftCell} + </Td> + {columnConfigs.map(c => + c.colType === 'spark' + ? this.renderSparklineCell(valueField, c, entries) + : this.renderValueCell(valueField, c, reversedEntries), )} - </span> + </Tr> ); } render() { - const { className, height } = this.props; + const { + className, + height, + data, + columnConfigs, + rowType, + rows, + } = this.props; + + const entries = Object.keys(data) + .sort() + .map(time => ({ ...data[time], time })); + const reversedEntries = entries.concat().reverse(); + + const defaultSort = + rowType === 'column' && columnConfigs.length + ? { + column: columnConfigs[0].key, + direction: 'desc', + } + : false; return ( <div className={`time-table ${className}`} style={{ height }}> - <ListView - columns={this.memoizedColumns()} - data={this.memoizedRows()} - count={0} - // we don't use pagination - pageSize={0} - initialSort={this.initialSort} - fetchData={() => {}} - loading={false} - sticky={false} - fullHeight - manualSortBy={false} - /> + <Table + className="table table-no-hover" + defaultSort={defaultSort} + sortBy={defaultSort} + sortable={columnConfigs.map(c => c.key)} + > + <Thead> + <Th column="metric">Metric</Th> + {columnConfigs.map((c, i) => ( + <Th + key={c.key} + column={c.key} + width={c.colType === 'spark' ? '1%' : null} + > + {c.label}{' '} + {c.tooltip && ( + <InfoTooltipWithTrigger + tooltip={c.tooltip} + label={`tt-col-${i}`} + placement="top" + /> + )} + </Th> + ))} + </Thead> + {rows.map(row => this.renderRow(row, entries, reversedEntries))} + </Table> </div> ); }
