Skip to content
This repository has been archived by the owner on Dec 10, 2021. It is now read-only.

feat: align metrics title to the right #721

Merged
merged 4 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 5 additions & 31 deletions plugins/plugin-chart-table/src/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
useSortBy,
useGlobalFilter,
PluginHook,
TableCellProps,
TableOptions,
FilterType,
IdType,
Expand All @@ -34,7 +33,6 @@ import GlobalFilter, { GlobalFilterProps } from './components/GlobalFilter';
import SelectPageSize, { SizeOption } from './components/SelectPageSize';
import SimplePagination from './components/Pagination';
import useSticky from './hooks/useSticky';
import useColumnCellProps from './hooks/useColumnCellProps';

export interface DataTableProps<D extends object> extends TableOptions<D> {
tableClassName?: string;
Expand Down Expand Up @@ -76,7 +74,6 @@ export default function DataTable<D extends object>({
useGlobalFilter,
useSortBy,
usePagination,
useColumnCellProps,
doSticky ? useSticky : [],
hooks || [],
].flat();
Expand Down Expand Up @@ -166,19 +163,10 @@ export default function DataTable<D extends object>({
return (
<tr key={headerGroupKey || headerGroup.id} {...headerGroupProps}>
{headerGroup.headers.map(column => {
const { key: headerKey, className, ...props } = column.getHeaderProps(
column.getSortByToggleProps(),
);
return (
<th
key={headerKey || column.id}
className={column.isSorted ? `${className || ''} is-sorted` : className}
{...props}
>
{column.render('Header')}
{column.render('SortIcon')}
</th>
);
return column.render('Header', {
key: column.id,
...column.getSortByToggleProps(),
});
})}
</tr>
);
Expand All @@ -191,21 +179,7 @@ export default function DataTable<D extends object>({
const { key: rowKey, ...rowProps } = row.getRowProps();
return (
<tr key={rowKey || row.id} {...rowProps}>
{row.cells.map(cell => {
const cellProps = cell.getCellProps() as TableCellProps & RenderHTMLCellProps;
const { key: cellKey, cellContent, ...restProps } = cellProps;
const key = cellKey || cell.column.id;
if (cellProps.dangerouslySetInnerHTML) {
return <td key={key} {...restProps} />;
}
// If cellProps renderes textContent already, then we don't have to
// render `Cell`. This saves some time for large tables.
return (
<td key={key} {...restProps}>
{cellContent || cell.render('Cell')}
</td>
);
})}
{row.cells.map(cell => cell.render('Cell', { key: cell.column.id }))}
</tr>
);
})
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion plugins/plugin-chart-table/src/DataTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
export * from './hooks/useColumnCellProps';
export * from './hooks/useSticky';
export * from './components/GlobalFilter';
export * from './components/Pagination';
Expand Down
22 changes: 11 additions & 11 deletions plugins/plugin-chart-table/src/DataTable/types/react-table.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import {
UseSortByHooks,
TableInstance,
ColumnInstance,
Column,
Renderer,
HeaderProps,
} from 'react-table';

import { UseColumnCellPropsColumnOption } from '../hooks/useColumnCellProps';
import { UseStickyState, UseStickyTableOptions, UseStickyInstanceProps } from '../hooks/useSticky';

declare module 'react-table' {
Expand Down Expand Up @@ -53,24 +53,24 @@ declare module 'react-table' {
UseSortByState<D>,
UseStickyState {}

export interface ColumnInterface<D extends object>
extends UseGlobalFiltersColumnOptions<D>,
UseSortByColumnOptions<D>,
UseColumnCellPropsColumnOption<D> {
SortIcon: Column['Header'];
}

// Typing from @types/react-table is incomplete
interface TableSortByToggleProps {
style?: React.CSSProperties;
title?: string;
onClick?: React.MouseEventHandler;
}

export interface ColumnInterface<D extends object>
extends UseGlobalFiltersColumnOptions<D>,
UseSortByColumnOptions<D> {
// must define as a new property because it's not possible to override
// the existing `Header` renderer option
Header?: Renderer<TableSortByToggleProps & HeaderProps<D>>;
}

export interface ColumnInstance<D extends object>
extends UseGlobalFiltersColumnOptions<D>,
UseSortByColumnProps<D>,
UseColumnCellPropsColumnOption<D> {
UseSortByColumnProps<D> {
getSortByToggleProps: (props?: Partial<TableSortByToggleProps>) => TableSortByToggleProps;
}

Expand Down
91 changes: 52 additions & 39 deletions plugins/plugin-chart-table/src/TableChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/
import React, { useState, useMemo, useCallback } from 'react';
import { ColumnInstance, Column, DefaultSortTypes } from 'react-table';
import { ColumnInstance, DefaultSortTypes, ColumnWithLooseAccessor } from 'react-table';
import { extent as d3Extent, max as d3Max } from 'd3-array';
import { FaSort, FaSortUp as FaSortAsc, FaSortDown as FaSortDesc } from 'react-icons/fa';
import { t } from '@superset-ui/translation';
Expand Down Expand Up @@ -83,7 +83,7 @@ function cellBar({
);
}

function SortIcon({ column }: { column: ColumnInstance }) {
function SortIcon<D extends object>({ column }: { column: ColumnInstance<D> }) {
const { isSorted, isSortedDesc } = column;
let sortIcon = <FaSort />;
if (isSorted) {
Expand Down Expand Up @@ -173,53 +173,66 @@ export default function TableChart<D extends DataRecord = DataRecord>(
);

const getColumnConfigs = useCallback(
(column: DataColumnMeta, i: number): Column<D> => {
(column: DataColumnMeta, i: number): ColumnWithLooseAccessor<D> => {
const { key, label, dataType } = column;
let className = '';
if (dataType === DataType.Number) {
className += ' dt-metric';
} else if (emitFilter) {
className += ' dt-is-filter';
}
const valueRange = showCellBars && getValueRange(key);
const cellProps: Column<D>['cellProps'] = ({ value: value_ }, sharedCellProps) => {
let className = '';
const value = value_ as DataRecordValue;
if (dataType === DataType.Number) {
className += ' dt-metric';
} else if (emitFilter) {
className += ' dt-is-filter';
if (isActiveFilterValue(key, value)) {
className += ' dt-is-active-filter';
}
}
const [isHtml, text] = formatValue(column, value);
const style = {
...sharedCellProps.style,
background: valueRange
? cellBar({
value: value as number,
valueRange,
alignPositiveNegative,
colorPositiveNegative,
})
: undefined,
};
return {
// show raw number in title in case of numeric values
title: typeof value === 'number' ? String(value) : undefined,
dangerouslySetInnerHTML: isHtml ? { __html: text } : undefined,
cellContent: text,
onClick: emitFilter && !valueRange ? () => toggleFilter(key, value) : undefined,
className,
style,
};
};
return {
id: String(i), // to allow duplicate column keys
// must use custom accessor to allow `.` in column names
// typing is incorrect in current version of `@types/react-table`
// so we ask TS not to check.
accessor: ((datum: D) => datum[key]) as never,
Header: label,
SortIcon,
Cell: ({ column: col, value }: { column: ColumnInstance<D>; value: DataRecordValue }) => {
const [isHtml, text] = formatValue(column, value);
const style = {
background: valueRange
? cellBar({
value: value as number,
valueRange,
alignPositiveNegative,
colorPositiveNegative,
})
: undefined,
};
const html = isHtml ? { __html: text } : undefined;
const cellProps = {
// show raw number in title in case of numeric values
title: typeof value === 'number' ? String(value) : undefined,
onClick: emitFilter && !valueRange ? () => toggleFilter(key, value) : undefined,
className: `${className}${
isActiveFilterValue(key, value) ? ' dt-is-active-filter' : ''
}`,
style,
};
if (html) {
// eslint-disable-next-line react/no-danger
return <td {...cellProps} dangerouslySetInnerHTML={html} />;
}
// If cellProps renderes textContent already, then we don't have to
// render `Cell`. This saves some time for large tables.
return <td {...cellProps}>{text}</td>;
},
Header: ({ column: col, title, onClick, style }) => {
return (
<th
title={title}
className={col.isSorted ? `${className || ''} is-sorted` : className}
style={style}
onClick={onClick}
>
{label}
<SortIcon column={col} />
</th>
);
},
sortDescFirst: sortDesc,
sortType: getSortTypeByDataType(dataType),
cellProps,
};
},
[
Expand Down