Skip to content

Commit

Permalink
fix(plugin-chart-table): resize and totals formatting bug (#1082)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktmud authored and zhaoyongjie committed Nov 26, 2021
1 parent 5bae6a6 commit 6089bcf
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ const fractionDigits: ControlFormItemSpec<'Slider'> = {

const columnWidth: ControlFormItemSpec<'InputNumber'> = {
controlType: 'InputNumber',
label: t('Width'),
label: t('Min Width'),
description: t(
'Default column width in pixels, may still be restricted by the shortest/longest word in the column',
"Default minimal column width in pixels, actual width may still be larger than this if other columns don't need much space",
),
width: 120,
placeholder: 'auto',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import {
IdType,
Row,
} from 'react-table';
import { t } from '@superset-ui/core';
import { matchSorter, rankings } from 'match-sorter';
import GlobalFilter, { GlobalFilterProps } from './components/GlobalFilter';
import SelectPageSize, { SelectPageSizeProps, SizeOption } from './components/SelectPageSize';
Expand All @@ -45,8 +44,6 @@ import { PAGE_SIZE_OPTIONS } from '../consts';

export interface DataTableProps<D extends object> extends TableOptions<D> {
tableClassName?: string;
totals?: { value: string; className?: string }[];
totalsHeaderSpan?: number;
searchInput?: boolean | GlobalFilterProps<D>['searchInput'];
selectPageSize?: boolean | SelectPageSizeProps['selectRenderer'];
pageSizeOptions?: SizeOption[]; // available page size options
Expand All @@ -73,8 +70,6 @@ export default function DataTable<D extends object>({
tableClassName,
columns,
data,
totals,
totalsHeaderSpan,
serverPaginationData,
width: initialWidth = '100%',
height: initialHeight = 300,
Expand Down Expand Up @@ -159,6 +154,7 @@ export default function DataTable<D extends object>({
getTableBodyProps,
prepareRow,
headerGroups,
footerGroups,
page,
pageCount,
gotoPage,
Expand Down Expand Up @@ -198,6 +194,8 @@ export default function DataTable<D extends object>({
return (wrapStickyTable ? wrapStickyTable(getNoResults) : getNoResults()) as JSX.Element;
}

const shouldRenderFooter = columns.some(x => !!x.Footer);

const renderTable = () => (
<table {...getTableProps({ className: tableClassName })}>
<thead>
Expand Down Expand Up @@ -234,14 +232,16 @@ export default function DataTable<D extends object>({
</tr>
)}
</tbody>
{totals && (
{shouldRenderFooter && (
<tfoot>
<tr key="totals" className="dt-totals">
<td colSpan={totalsHeaderSpan}>{t('Totals')}</td>
{totals.map(item => (
<td className={item.className}>{item.value}</td>
))}
</tr>
{footerGroups.map(footerGroup => {
const { key: footerGroupKey, ...footerGroupProps } = footerGroup.getHeaderGroupProps();
return (
<tr key={footerGroupKey || footerGroup.id} {...footerGroupProps}>
{footerGroup.headers.map(column => column.render('Footer', { key: column.id }))}
</tr>
);
})}
</tfoot>
)}
</table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
UseSortByHooks,
Renderer,
HeaderProps,
TableFooterProps,
} from 'react-table';

import { UseStickyState, UseStickyTableOptions, UseStickyInstanceProps } from '../hooks/useSticky';
Expand Down Expand Up @@ -64,6 +65,7 @@ declare module 'react-table' {
// must define as a new property because it's not possible to override
// the existing `Header` renderer option
Header?: Renderer<TableSortByToggleProps & HeaderProps<D>>;
Footer?: Renderer<TableFooterProps<D>>;
}

export interface ColumnInstance<D extends object>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,24 +247,28 @@ export default function TableChart<D extends DataRecord = DataRecord>(
[filters, handleChange, isActiveFilterValue],
);

const getSharedStyle = (column: DataColumnMeta): CSSProperties => {
const { isNumeric, config = {} } = column;
const textAlign = config.horizontalAlign
? config.horizontalAlign
: isNumeric
? 'right'
: 'left';
return {
textAlign,
};
};

const getColumnConfigs = useCallback(
(column: DataColumnMeta, i: number): ColumnWithLooseAccessor<D> => {
const { key, label, dataType, isMetric, config = {} } = column;
const isNumber = dataType === GenericDataType.NUMERIC;
const isFilter = !isNumber && emitFilter;
const textAlign = config.horizontalAlign
? config.horizontalAlign
: isNumber
? 'right'
: 'left';
const { key, label, isNumeric, dataType, isMetric, config = {} } = column;
const isFilter = !isNumeric && emitFilter;
const columnWidth = Number.isNaN(Number(config.columnWidth))
? config.columnWidth
: Number(config.columnWidth);

// inline style for both th and td cell
const sharedStyle: CSSProperties = {
textAlign,
};
const sharedStyle: CSSProperties = getSharedStyle(column);

const alignPositiveNegative =
config.alignPositiveNegative === undefined ? defaultAlignPN : config.alignPositiveNegative;
Expand All @@ -287,7 +291,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
// typing is incorrect in current version of `@types/react-table`
// so we ask TS not to check.
accessor: ((datum: D) => datum[key]) as never,
Cell: ({ value }: { column: ColumnInstance<D>; value: DataRecordValue }) => {
Cell: ({ value }: { value: DataRecordValue }) => {
const [isHtml, text] = formatColumnValue(column, value);
const html = isHtml ? { __html: text } : undefined;
const cellProps = {
Expand Down Expand Up @@ -343,6 +347,15 @@ export default function TableChart<D extends DataRecord = DataRecord>(
<SortIcon column={col} />
</th>
),
Footer: totals ? (
i === 0 ? (
<th>{t('Totals')}</th>
) : (
<td style={sharedStyle}>
<strong>{formatColumnValue(column, totals[key])[1]}</strong>
</td>
)
) : undefined,
sortDescFirst: sortDesc,
sortType: getSortTypeByDataType(dataType),
};
Expand All @@ -357,6 +370,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
showCellBars,
sortDesc,
toggleFilter,
totals,
],
);

Expand All @@ -366,37 +380,17 @@ export default function TableChart<D extends DataRecord = DataRecord>(
updateExternalFormData(setDataMask, pageNumber, pageSize);
};

const totalsFormatted =
totals &&
columnsMeta
.filter(column => Object.keys(totals).includes(column.key))
.reduce(
(acc: { value: string; className: string }[], column) => [
...acc,
{
value: formatColumnValue(column, totals[column.key])[1],
className: column.dataType === GenericDataType.NUMERIC ? 'dt-metric' : '',
},
],
[],
);

const totalsHeaderSpan =
totalsFormatted &&
columnsMeta.filter(column => !column.isPercentMetric).length - totalsFormatted.length;

return (
<Styles>
<DataTable<D>
columns={columns}
totals={totalsFormatted}
totalsHeaderSpan={totalsHeaderSpan}
data={data}
rowCount={rowCount}
tableClassName="table table-striped table-condensed"
pageSize={pageSize}
serverPaginationData={serverPaginationData}
pageSizeOptions={pageSizeOptions}
width={width}
height={height}
serverPagination={serverPagination}
onServerPaginationChange={handleServerPaginationChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const translations: Partial<Record<Locale, typeof en>> = {
'Show Cell Bars': ['为指标添加条状图背景'],
'page_size.show': ['每页显示'],
'page_size.all': ['全部'],
'page_size.entries': [''],
'table.previous_page': ['以前的'],
'table.next_page': ['下一個'],
'page_size.entries': ['上一页'],
'table.previous_page': ['上一页'],
'table.next_page': ['下一页'],
'search.num_records': ['%s条记录...'],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ const processColumns = memoizeOne(function processColumns(props: TableChartProps
key,
label,
dataType,
isNumeric: dataType === GenericDataType.NUMERIC,
isMetric,
isPercentMetric,
formatter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface DataColumnMeta {
formatter?: TimeFormatter | NumberFormatter | CustomFormatter;
isMetric?: boolean;
isPercentMetric?: boolean;
isNumeric?: boolean;
config?: ColumnConfig;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ function formatValue(
formatter: DataColumnMeta['formatter'],
value: DataRecordValue,
): [boolean, string] {
if (value === null || typeof value === 'undefined') {
// render undefined as empty string
if (value === undefined) {
return [false, ''];
}
// render null as `N/A`
if (value === null) {
return [false, 'N/A'];
}
if (formatter) {
Expand Down

0 comments on commit 6089bcf

Please sign in to comment.