mirror of https://github.com/apache/superset.git
chore: type FilterableTable (#10073)
This commit is contained in:
parent
a6390afb89
commit
2e76fbb7e5
|
@ -9753,6 +9753,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/cheerio": {
|
||||||
|
"version": "0.22.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.18.tgz",
|
||||||
|
"integrity": "sha512-Fq7R3fINAPSdUEhOyjG4iVxgHrOnqDJbY0/BUuiN0pvD/rfmZWekVZnv+vcs8TtpA2XF50uv50LaE4EnpEL/Hw==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/classnames": {
|
"@types/classnames": {
|
||||||
"version": "2.2.9",
|
"version": "2.2.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.9.tgz",
|
||||||
|
@ -9852,6 +9860,15 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/enzyme": {
|
||||||
|
"version": "3.10.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.5.tgz",
|
||||||
|
"integrity": "sha512-R+phe509UuUYy9Tk0YlSbipRpfVtIzb/9BHn5pTEtjJTF5LXvUjrIQcZvNyANNEyFrd2YGs196PniNT1fgvOQA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/cheerio": "*",
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/eslint-visitor-keys": {
|
"@types/eslint-visitor-keys": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
|
||||||
|
@ -10123,6 +10140,15 @@
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-virtualized": {
|
||||||
|
"version": "9.21.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-virtualized/-/react-virtualized-9.21.10.tgz",
|
||||||
|
"integrity": "sha512-f5Ti3A7gGdLkPPFNHTrvKblpsPNBiQoSorOEOD+JPx72g/Ng2lOt4MYfhvQFQNgyIrAro+Z643jbcKafsMW2ag==",
|
||||||
|
"requires": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/react-window": {
|
"@types/react-window": {
|
||||||
"version": "1.8.2",
|
"version": "1.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.2.tgz",
|
||||||
|
|
|
@ -101,9 +101,11 @@
|
||||||
"@superset-ui/translation": "^0.13.27",
|
"@superset-ui/translation": "^0.13.27",
|
||||||
"@superset-ui/validator": "^0.13.27",
|
"@superset-ui/validator": "^0.13.27",
|
||||||
"@types/classnames": "^2.2.9",
|
"@types/classnames": "^2.2.9",
|
||||||
|
"@types/enzyme": "^3.10.5",
|
||||||
"@types/react-bootstrap": "^0.32.21",
|
"@types/react-bootstrap": "^0.32.21",
|
||||||
"@types/react-json-tree": "^0.6.11",
|
"@types/react-json-tree": "^0.6.11",
|
||||||
"@types/react-select": "^3.0.12",
|
"@types/react-select": "^3.0.12",
|
||||||
|
"@types/react-virtualized": "^9.21.10",
|
||||||
"@types/react-window": "^1.8.2",
|
"@types/react-window": "^1.8.2",
|
||||||
"@types/redux-localstorage": "^1.0.8",
|
"@types/redux-localstorage": "^1.0.8",
|
||||||
"@types/rison": "0.0.6",
|
"@types/rison": "0.0.6",
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount, ReactWrapper } from 'enzyme';
|
||||||
import FilterableTable, {
|
import FilterableTable, {
|
||||||
MAX_COLUMNS_FOR_TABLE,
|
MAX_COLUMNS_FOR_TABLE,
|
||||||
} from 'src/components/FilterableTable/FilterableTable';
|
} from 'src/components/FilterableTable/FilterableTable';
|
||||||
|
@ -32,7 +32,7 @@ describe('FilterableTable', () => {
|
||||||
],
|
],
|
||||||
height: 500,
|
height: 500,
|
||||||
};
|
};
|
||||||
let wrapper;
|
let wrapper: ReactWrapper;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = mount(<FilterableTable {...mockedProps} />);
|
wrapper = mount(<FilterableTable {...mockedProps} />);
|
||||||
});
|
});
|
||||||
|
@ -53,11 +53,11 @@ describe('FilterableTable', () => {
|
||||||
(_, x) => `col_${x}`,
|
(_, x) => `col_${x}`,
|
||||||
),
|
),
|
||||||
data: [
|
data: [
|
||||||
Object.assign(
|
{
|
||||||
...Array.from(Array(wideTableColumns)).map((val, x) => ({
|
...Array.from(Array(wideTableColumns)).map((val, x) => ({
|
||||||
[`col_${x}`]: x,
|
[`col_${x}`]: x,
|
||||||
})),
|
})),
|
||||||
),
|
},
|
||||||
],
|
],
|
||||||
height: 500,
|
height: 500,
|
||||||
};
|
};
|
|
@ -17,7 +17,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { List } from 'immutable';
|
import { List } from 'immutable';
|
||||||
import PropTypes from 'prop-types';
|
// @ts-ignore
|
||||||
import JSONbig from 'json-bigint';
|
import JSONbig from 'json-bigint';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import JSONTree from 'react-json-tree';
|
import JSONTree from 'react-json-tree';
|
||||||
|
@ -28,6 +28,7 @@ import {
|
||||||
SortDirection,
|
SortDirection,
|
||||||
SortIndicator,
|
SortIndicator,
|
||||||
Table,
|
Table,
|
||||||
|
SortDirectionType,
|
||||||
} from 'react-virtualized';
|
} from 'react-virtualized';
|
||||||
import { getMultipleTextDimensions } from '@superset-ui/dimension';
|
import { getMultipleTextDimensions } from '@superset-ui/dimension';
|
||||||
import { t } from '@superset-ui/translation';
|
import { t } from '@superset-ui/translation';
|
||||||
|
@ -37,7 +38,9 @@ import CopyToClipboard from '../CopyToClipboard';
|
||||||
import ModalTrigger from '../ModalTrigger';
|
import ModalTrigger from '../ModalTrigger';
|
||||||
import TooltipWrapper from '../TooltipWrapper';
|
import TooltipWrapper from '../TooltipWrapper';
|
||||||
|
|
||||||
function safeJsonObjectParse(data) {
|
function safeJsonObjectParse(
|
||||||
|
data: unknown,
|
||||||
|
): null | unknown[] | Record<string, unknown> {
|
||||||
// First perform a cheap proxy to avoid calling JSON.parse on data that is clearly not a
|
// First perform a cheap proxy to avoid calling JSON.parse on data that is clearly not a
|
||||||
// JSON object or array
|
// JSON object or array
|
||||||
if (
|
if (
|
||||||
|
@ -85,31 +88,43 @@ const JSON_TREE_THEME = {
|
||||||
// when more than MAX_COLUMNS_FOR_TABLE are returned, switch from table to grid view
|
// when more than MAX_COLUMNS_FOR_TABLE are returned, switch from table to grid view
|
||||||
export const MAX_COLUMNS_FOR_TABLE = 50;
|
export const MAX_COLUMNS_FOR_TABLE = 50;
|
||||||
|
|
||||||
const propTypes = {
|
type CellDataType = string | number | null;
|
||||||
orderedColumnKeys: PropTypes.array.isRequired,
|
type Datum = Record<string, CellDataType>;
|
||||||
data: PropTypes.array.isRequired,
|
|
||||||
height: PropTypes.number.isRequired,
|
|
||||||
filterText: PropTypes.string,
|
|
||||||
headerHeight: PropTypes.number,
|
|
||||||
overscanColumnCount: PropTypes.number,
|
|
||||||
overscanRowCount: PropTypes.number,
|
|
||||||
rowHeight: PropTypes.number,
|
|
||||||
striped: PropTypes.bool,
|
|
||||||
expandedColumns: PropTypes.array,
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultProps = {
|
interface FilterableTableProps {
|
||||||
filterText: '',
|
orderedColumnKeys: string[];
|
||||||
headerHeight: 32,
|
data: Record<string, unknown>[];
|
||||||
overscanColumnCount: 10,
|
height: number;
|
||||||
overscanRowCount: 10,
|
filterText: string;
|
||||||
rowHeight: 32,
|
headerHeight: number;
|
||||||
striped: true,
|
overscanColumnCount: number;
|
||||||
expandedColumns: [],
|
overscanRowCount: number;
|
||||||
};
|
rowHeight: number;
|
||||||
|
striped: boolean;
|
||||||
|
expandedColumns: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export default class FilterableTable extends PureComponent {
|
interface FilterableTableState {
|
||||||
constructor(props) {
|
sortBy?: string;
|
||||||
|
sortDirection: SortDirectionType;
|
||||||
|
fitted: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class FilterableTable extends PureComponent<
|
||||||
|
FilterableTableProps,
|
||||||
|
FilterableTableState
|
||||||
|
> {
|
||||||
|
static defaultProps = {
|
||||||
|
filterText: '',
|
||||||
|
headerHeight: 32,
|
||||||
|
overscanColumnCount: 10,
|
||||||
|
overscanRowCount: 10,
|
||||||
|
rowHeight: 32,
|
||||||
|
striped: true,
|
||||||
|
expandedColumns: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props: FilterableTableProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.list = List(this.formatTableData(props.data));
|
this.list = List(this.formatTableData(props.data));
|
||||||
this.addJsonModal = this.addJsonModal.bind(this);
|
this.addJsonModal = this.addJsonModal.bind(this);
|
||||||
|
@ -140,7 +155,6 @@ export default class FilterableTable extends PureComponent {
|
||||||
this.totalTableHeight = props.height;
|
this.totalTableHeight = props.height;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
sortBy: null,
|
|
||||||
sortDirection: SortDirection.ASC,
|
sortDirection: SortDirection.ASC,
|
||||||
fitted: false,
|
fitted: false,
|
||||||
};
|
};
|
||||||
|
@ -152,7 +166,7 @@ export default class FilterableTable extends PureComponent {
|
||||||
this.fitTableToWidthIfNeeded();
|
this.fitTableToWidthIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
getDatum(list, index) {
|
getDatum(list: List<Datum>, index: number) {
|
||||||
return list.get(index % list.size);
|
return list.get(index % list.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,9 +176,10 @@ export default class FilterableTable extends PureComponent {
|
||||||
const cellContent = [].concat(
|
const cellContent = [].concat(
|
||||||
...this.props.orderedColumnKeys.map(key =>
|
...this.props.orderedColumnKeys.map(key =>
|
||||||
this.list
|
this.list
|
||||||
.map(data =>
|
.map((data: Datum) =>
|
||||||
this.getCellContent({ cellData: data[key], columnKey: key }),
|
this.getCellContent({ cellData: data[key], columnKey: key }),
|
||||||
)
|
)
|
||||||
|
// @ts-ignore
|
||||||
.push(key)
|
.push(key)
|
||||||
.toJS(),
|
.toJS(),
|
||||||
),
|
),
|
||||||
|
@ -191,7 +206,13 @@ export default class FilterableTable extends PureComponent {
|
||||||
return widthsByColumnKey;
|
return widthsByColumnKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCellContent({ cellData, columnKey }) {
|
getCellContent({
|
||||||
|
cellData,
|
||||||
|
columnKey,
|
||||||
|
}: {
|
||||||
|
cellData: CellDataType;
|
||||||
|
columnKey: string;
|
||||||
|
}) {
|
||||||
if (cellData === null) {
|
if (cellData === null) {
|
||||||
return <i className="text-muted">NULL</i>;
|
return <i className="text-muted">NULL</i>;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +229,14 @@ export default class FilterableTable extends PureComponent {
|
||||||
return this.complexColumns[columnKey] ? truncated : content;
|
return this.complexColumns[columnKey] ? truncated : content;
|
||||||
}
|
}
|
||||||
|
|
||||||
formatTableData(data) {
|
list: List<Datum>;
|
||||||
|
complexColumns: Record<string, boolean>;
|
||||||
|
widthsForColumnsByKey: Record<string, number>;
|
||||||
|
totalTableWidth: number;
|
||||||
|
totalTableHeight: number;
|
||||||
|
container: React.RefObject<HTMLDivElement>;
|
||||||
|
|
||||||
|
formatTableData(data: Record<string, unknown>[]): Datum[] {
|
||||||
const formattedData = data.map(row => {
|
const formattedData = data.map(row => {
|
||||||
const newRow = {};
|
const newRow = {};
|
||||||
for (const k in row) {
|
for (const k in row) {
|
||||||
|
@ -224,7 +252,7 @@ export default class FilterableTable extends PureComponent {
|
||||||
return formattedData;
|
return formattedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMatch(text, row) {
|
hasMatch(text: string, row: Datum) {
|
||||||
const values = [];
|
const values = [];
|
||||||
for (const key in row) {
|
for (const key in row) {
|
||||||
if (row.hasOwnProperty(key)) {
|
if (row.hasOwnProperty(key)) {
|
||||||
|
@ -243,7 +271,7 @@ export default class FilterableTable extends PureComponent {
|
||||||
return values.some(v => v.includes(lowerCaseText));
|
return values.some(v => v.includes(lowerCaseText));
|
||||||
}
|
}
|
||||||
|
|
||||||
rowClassName({ index }) {
|
rowClassName({ index }: { index: number }) {
|
||||||
let className = '';
|
let className = '';
|
||||||
if (this.props.striped) {
|
if (this.props.striped) {
|
||||||
className = index % 2 === 0 ? 'even-row' : 'odd-row';
|
className = index % 2 === 0 ? 'even-row' : 'odd-row';
|
||||||
|
@ -251,12 +279,18 @@ export default class FilterableTable extends PureComponent {
|
||||||
return className;
|
return className;
|
||||||
}
|
}
|
||||||
|
|
||||||
sort({ sortBy, sortDirection }) {
|
sort({
|
||||||
|
sortBy,
|
||||||
|
sortDirection,
|
||||||
|
}: {
|
||||||
|
sortBy: string;
|
||||||
|
sortDirection: SortDirectionType;
|
||||||
|
}) {
|
||||||
this.setState({ sortBy, sortDirection });
|
this.setState({ sortBy, sortDirection });
|
||||||
}
|
}
|
||||||
|
|
||||||
fitTableToWidthIfNeeded() {
|
fitTableToWidthIfNeeded() {
|
||||||
const containerWidth = this.container.clientWidth;
|
const containerWidth = this.container.current!.clientWidth;
|
||||||
if (this.totalTableWidth < containerWidth) {
|
if (this.totalTableWidth < containerWidth) {
|
||||||
// fit table width if content doesn't fill the width of the container
|
// fit table width if content doesn't fill the width of the container
|
||||||
this.totalTableWidth = containerWidth;
|
this.totalTableWidth = containerWidth;
|
||||||
|
@ -264,7 +298,11 @@ export default class FilterableTable extends PureComponent {
|
||||||
this.setState({ fitted: true });
|
this.setState({ fitted: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
addJsonModal(node, jsonObject, jsonString) {
|
addJsonModal(
|
||||||
|
node: React.ReactNode,
|
||||||
|
jsonObject: Record<string, unknown> | unknown[],
|
||||||
|
jsonString: CellDataType,
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<ModalTrigger
|
<ModalTrigger
|
||||||
modalBody={<JSONTree data={jsonObject} theme={JSON_TREE_THEME} />}
|
modalBody={<JSONTree data={jsonObject} theme={JSON_TREE_THEME} />}
|
||||||
|
@ -279,24 +317,36 @@ export default class FilterableTable extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sortResults(sortBy, descending) {
|
sortResults(sortBy: string, descending: boolean) {
|
||||||
return (a, b) => {
|
return (a: Datum, b: Datum) => {
|
||||||
if (a[sortBy] === b[sortBy]) {
|
const aValue = a[sortBy];
|
||||||
|
const bValue = b[sortBy];
|
||||||
|
if (aValue === bValue) {
|
||||||
// equal items sort equally
|
// equal items sort equally
|
||||||
return 0;
|
return 0;
|
||||||
} else if (a[sortBy] === null) {
|
} else if (aValue === null) {
|
||||||
// nulls sort after anything else
|
// nulls sort after anything else
|
||||||
return 1;
|
return 1;
|
||||||
} else if (b[sortBy] === null) {
|
} else if (bValue === null) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (descending) {
|
} else if (descending) {
|
||||||
return a[sortBy] < b[sortBy] ? 1 : -1;
|
return aValue < bValue ? 1 : -1;
|
||||||
}
|
}
|
||||||
return a[sortBy] < b[sortBy] ? -1 : 1;
|
return aValue < bValue ? -1 : 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTableHeader({ dataKey, label, sortBy, sortDirection }) {
|
renderTableHeader({
|
||||||
|
dataKey,
|
||||||
|
label,
|
||||||
|
sortBy,
|
||||||
|
sortDirection,
|
||||||
|
}: {
|
||||||
|
dataKey: string;
|
||||||
|
label: string;
|
||||||
|
sortBy: string;
|
||||||
|
sortDirection: SortDirectionType;
|
||||||
|
}) {
|
||||||
const className =
|
const className =
|
||||||
this.props.expandedColumns.indexOf(label) > -1
|
this.props.expandedColumns.indexOf(label) > -1
|
||||||
? 'header-style-disabled'
|
? 'header-style-disabled'
|
||||||
|
@ -313,7 +363,15 @@ export default class FilterableTable extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderGridCellHeader({ columnIndex, key, style }) {
|
renderGridCellHeader({
|
||||||
|
columnIndex,
|
||||||
|
key,
|
||||||
|
style,
|
||||||
|
}: {
|
||||||
|
columnIndex: number;
|
||||||
|
key: string;
|
||||||
|
style: React.CSSProperties;
|
||||||
|
}) {
|
||||||
const label = this.props.orderedColumnKeys[columnIndex];
|
const label = this.props.orderedColumnKeys[columnIndex];
|
||||||
const className =
|
const className =
|
||||||
this.props.expandedColumns.indexOf(label) > -1
|
this.props.expandedColumns.indexOf(label) > -1
|
||||||
|
@ -322,7 +380,13 @@ export default class FilterableTable extends PureComponent {
|
||||||
return (
|
return (
|
||||||
<TooltipWrapper key={key} label="header" tooltip={label}>
|
<TooltipWrapper key={key} label="header" tooltip={label}>
|
||||||
<div
|
<div
|
||||||
style={{ ...style, top: style.top - GRID_POSITION_ADJUSTMENT }}
|
style={{
|
||||||
|
...style,
|
||||||
|
top:
|
||||||
|
typeof style.top === 'number'
|
||||||
|
? style.top - GRID_POSITION_ADJUSTMENT
|
||||||
|
: style.top,
|
||||||
|
}}
|
||||||
className={`${className} grid-cell grid-header-cell`}
|
className={`${className} grid-cell grid-header-cell`}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
|
@ -331,14 +395,30 @@ export default class FilterableTable extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderGridCell({ columnIndex, key, rowIndex, style }) {
|
renderGridCell({
|
||||||
|
columnIndex,
|
||||||
|
key,
|
||||||
|
rowIndex,
|
||||||
|
style,
|
||||||
|
}: {
|
||||||
|
columnIndex: number;
|
||||||
|
key: string;
|
||||||
|
rowIndex: number;
|
||||||
|
style: React.CSSProperties;
|
||||||
|
}) {
|
||||||
const columnKey = this.props.orderedColumnKeys[columnIndex];
|
const columnKey = this.props.orderedColumnKeys[columnIndex];
|
||||||
const cellData = this.list.get(rowIndex)[columnKey];
|
const cellData = this.list.get(rowIndex)[columnKey];
|
||||||
const content = this.getCellContent({ cellData, columnKey });
|
const content = this.getCellContent({ cellData, columnKey });
|
||||||
const cellNode = (
|
const cellNode = (
|
||||||
<div
|
<div
|
||||||
key={key}
|
key={key}
|
||||||
style={{ ...style, top: style.top - GRID_POSITION_ADJUSTMENT }}
|
style={{
|
||||||
|
...style,
|
||||||
|
top:
|
||||||
|
typeof style.top === 'number'
|
||||||
|
? style.top - GRID_POSITION_ADJUSTMENT
|
||||||
|
: style.top,
|
||||||
|
}}
|
||||||
className={`grid-cell ${this.rowClassName({ index: rowIndex })}`}
|
className={`grid-cell ${this.rowClassName({ index: rowIndex })}`}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
|
@ -362,14 +442,17 @@ export default class FilterableTable extends PureComponent {
|
||||||
|
|
||||||
let { height } = this.props;
|
let { height } = this.props;
|
||||||
let totalTableHeight = height;
|
let totalTableHeight = height;
|
||||||
if (this.container && this.totalTableWidth > this.container.clientWidth) {
|
if (
|
||||||
|
this.container.current &&
|
||||||
|
this.totalTableWidth > this.container.current.clientWidth
|
||||||
|
) {
|
||||||
// exclude the height of the horizontal scroll bar from the height of the table
|
// exclude the height of the horizontal scroll bar from the height of the table
|
||||||
// and the height of the table container if the content overflows
|
// and the height of the table container if the content overflows
|
||||||
height -= SCROLL_BAR_HEIGHT;
|
height -= SCROLL_BAR_HEIGHT;
|
||||||
totalTableHeight -= SCROLL_BAR_HEIGHT;
|
totalTableHeight -= SCROLL_BAR_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getColumnWidth = ({ index }) =>
|
const getColumnWidth = ({ index }: { index: number }) =>
|
||||||
this.widthsForColumnsByKey[orderedColumnKeys[index]];
|
this.widthsForColumnsByKey[orderedColumnKeys[index]];
|
||||||
|
|
||||||
// fix height of filterable table
|
// fix height of filterable table
|
||||||
|
@ -413,7 +496,13 @@ export default class FilterableTable extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTableCell({ cellData, columnKey }) {
|
renderTableCell({
|
||||||
|
cellData,
|
||||||
|
columnKey,
|
||||||
|
}: {
|
||||||
|
cellData: CellDataType;
|
||||||
|
columnKey: string;
|
||||||
|
}) {
|
||||||
const cellNode = this.getCellContent({ cellData, columnKey });
|
const cellNode = this.getCellContent({ cellData, columnKey });
|
||||||
const jsonObject = safeJsonObjectParse(cellData);
|
const jsonObject = safeJsonObjectParse(cellData);
|
||||||
if (jsonObject) {
|
if (jsonObject) {
|
||||||
|
@ -432,30 +521,33 @@ export default class FilterableTable extends PureComponent {
|
||||||
rowHeight,
|
rowHeight,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let sortedAndFilteredList = this.list;
|
let sortedAndFilteredList: List<Datum> = this.list;
|
||||||
// filter list
|
// filter list
|
||||||
if (filterText) {
|
if (filterText) {
|
||||||
sortedAndFilteredList = this.list.filter(row =>
|
sortedAndFilteredList = this.list.filter((row: Datum) =>
|
||||||
this.hasMatch(filterText, row),
|
this.hasMatch(filterText, row),
|
||||||
);
|
) as List<Datum>;
|
||||||
}
|
}
|
||||||
// sort list
|
// sort list
|
||||||
if (sortBy) {
|
if (sortBy) {
|
||||||
sortedAndFilteredList = sortedAndFilteredList.sort(
|
sortedAndFilteredList = sortedAndFilteredList.sort(
|
||||||
this.sortResults(sortBy, sortDirection === SortDirection.DESC),
|
this.sortResults(sortBy, sortDirection === SortDirection.DESC),
|
||||||
);
|
) as List<Datum>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { height } = this.props;
|
let { height } = this.props;
|
||||||
let totalTableHeight = height;
|
let totalTableHeight = height;
|
||||||
if (this.container && this.totalTableWidth > this.container.clientWidth) {
|
if (
|
||||||
|
this.container.current &&
|
||||||
|
this.totalTableWidth > this.container.current.clientWidth
|
||||||
|
) {
|
||||||
// exclude the height of the horizontal scroll bar from the height of the table
|
// exclude the height of the horizontal scroll bar from the height of the table
|
||||||
// and the height of the table container if the content overflows
|
// and the height of the table container if the content overflows
|
||||||
height -= SCROLL_BAR_HEIGHT;
|
height -= SCROLL_BAR_HEIGHT;
|
||||||
totalTableHeight -= SCROLL_BAR_HEIGHT;
|
totalTableHeight -= SCROLL_BAR_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rowGetter = ({ index }) =>
|
const rowGetter = ({ index }: { index: number }) =>
|
||||||
this.getDatum(sortedAndFilteredList, index);
|
this.getDatum(sortedAndFilteredList, index);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -504,6 +596,3 @@ export default class FilterableTable extends PureComponent {
|
||||||
return this.renderTable();
|
return this.renderTable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterableTable.propTypes = propTypes;
|
|
||||||
FilterableTable.defaultProps = defaultProps;
|
|
Loading…
Reference in New Issue