UNPKG

23 kBJavaScriptView Raw
1import React from 'react';
2import PropTypes from 'prop-types';
3import { Table, Column, Cell } from 'fixed-data-table-2';
4import classNames from 'classnames';
5import * as Constants from './constants';
6import * as CellUtils from './CellUtils';
7import { HeaderCell } from './HeaderCell';
8import { TextCell } from './TextCell';
9import TouchWrapper from './TouchWrapper';
10import { RETURNED_DATA_TYPES } from './constants';
11import _ from 'lodash';
12import { StyleSheet, css } from 'aphrodite';
13
14export class HugeTable extends React.Component {
15 static propTypes = {
16 data: PropTypes.arrayOf(PropTypes.object),
17 options: PropTypes.shape({
18 height: PropTypes.number,
19 width: PropTypes.number,
20 mixedContentImage: PropTypes.func,
21 tableScrolled: PropTypes.func,
22 id: PropTypes.string,
23 maxTitleWidth: PropTypes.number,
24 maxContentWidth: PropTypes.number,
25 minColumnWidth: PropTypes.number,
26 rowNumberColumnWidth: PropTypes.number,
27 fontDetails: PropTypes.string,
28 headerOffsetWidth: PropTypes.number,
29 hideHeader: PropTypes.bool,
30 }),
31 schema: PropTypes.arrayOf(PropTypes.shape({
32 name: PropTypes.string,
33 type: PropTypes.string,
34 })),
35 renderers: PropTypes.shape(RETURNED_DATA_TYPES.reduce((initial, next) => {
36 return {
37 ...initial,
38 [next]: PropTypes.func,
39 };
40 }, {HEADER: PropTypes.func})),
41 onSchemaChange: PropTypes.func,
42 resizeByContent: PropTypes.bool,
43 hideRowNumbers: PropTypes.bool,
44 showScrollingArrows: PropTypes.bool,
45 scrollToNewColumn: PropTypes.bool,
46 onScrollToNewColumn: PropTypes.func,
47 rowHeight: PropTypes.number,
48 headerHeight: PropTypes.number,
49 cellPadding: PropTypes.shape ({
50 top: PropTypes.number,
51 bottom: PropTypes.number,
52 left: PropTypes.number,
53 right: PropTypes.number,
54 }),
55 lineHeight: PropTypes.number,
56 buttonColumnWidth: PropTypes.number,
57 activeColumnIndex: PropTypes.number,
58 onActiveColumnChange: PropTypes.func,
59 scrollToColumn: PropTypes.number,
60 disableClickEvents: PropTypes.bool,
61 resizeableColumns: PropTypes.bool,
62 reorderableColumns: PropTypes.bool,
63 }
64
65 static defaultProps = {
66 resizeableColumns: true,
67 reorderableColumns: true,
68 };
69
70 constructor(props) {
71 super(props);
72 const
73 cellPadding = props.cellPadding || Constants.CELL_PADDING,
74 lineHeight = props.lineHeight || Constants.LINE_HEIGHT,
75 headerHeight = props.headerHeight || Constants.HEADER_HEIGHT,
76 rowHeight = props.rowHeight || Constants.ROW_HEIGHT;
77 this.state = {
78 columnWidths: {},
79 isColumnResizing: undefined,
80 columnNameToDataTypeMap: {},
81 columnOrder: [],
82 currentSchema: [],
83 shouldActivateLeftScroll: false,
84 shouldActivateRightScroll: false,
85 scrollLeft: 0,
86 cellPadding,
87 lineHeight,
88 headerHeight,
89 rowHeight,
90 contentHeight: 500,
91 contentWidth: 500,
92 };
93
94 this.uniqueId = props.options.id || null;
95 if (this.uniqueId){
96 this.savedColumnsWidth = JSON.parse(localStorage.getItem('huge-table-column-widths')) || {};
97 this.savedColumnsWidth[this.uniqueId] = this.savedColumnsWidth[this.uniqueId] || {};
98 }
99
100 this.maxTitleWidth = props.options.maxTitleWidth || Constants.MAX_TITLE_WIDTH;
101 this.maxContentWidth = props.options.maxContentWidth || Constants.MAX_CONTENT_WIDTH;
102 this.fontDetails = props.options.fontDetails || Constants.FONT_DETAILS;
103 this.minColumnWidth = props.options.minColumnWidth || Constants.MIN_COLUMN_WIDTH;
104 this.headerOffsetWidth = props.options.headerOffsetWidth || 0;
105 }
106
107 componentDidMount() {
108 this.generateColumnToDataTypeMap(this.props.schema);
109 this.generateColumnWidths(this.props.schema, this.props.options.width);
110 this.generateInitialColumnOrder(this.props.schema);
111 this.checkForScrollArrows(this.state.scrollLeft);
112 }
113
114 componentWillReceiveProps(nextProps) {
115 if(this.props.schema !== nextProps.schema) {
116 this.generateColumnToDataTypeMap(nextProps.schema);
117 this.generateInitialColumnOrder(nextProps.schema);
118 }
119
120 if(this.props.schema !== nextProps.schema || this.props.options.width !== nextProps.options.width) {
121 this.generateColumnWidths(nextProps.schema, nextProps.options.width);
122 this.checkForScrollArrows(this.state.scrollLeft);
123 }
124
125 if(this.props.data.length !== nextProps.data.length) {
126 this.setContentHeight(nextProps.data);
127 }
128 }
129
130 componentDidUpdate(prevProps, prevState) {
131 if (prevState.columnOrder !== this.state.columnOrder && !_.isEqual(prevState.columnOrder, this.state.columnOrder)) {
132 this.reorderSchema(this.props.schema, this.state.columnOrder);
133 }
134 if (prevState.currentSchema !== this.state.currentSchema && !_.isEqual(prevState.currentSchema, this.state.currentSchema)) {
135 this.onSchemaChange(this.state.currentSchema, prevState.currentSchema);
136 this.checkForScrollArrows(this.state.scrollLeft);
137 }
138
139 if (prevState.currentSchema < this.state.currentSchema && this.state.shouldShowScrolls) {
140 this.scrollNewColumnIntoView();
141 this.checkForScrollArrows(this.state.scrollLeft);
142 }
143
144 if (prevProps.activeColumnIndex !== this.props.activeColumnIndex && this.props.onActiveColumnChange) {
145 this.props.onActiveColumnChange();
146 }
147
148 }
149
150 onScrollEnd = (scrollLeft) => {
151 this.setState({ scrollLeft });
152 }
153
154 onSchemaChange = (schema, prevSchema) => {
155 if (this.props.onSchemaChange) {
156 this.props.onSchemaChange(schema, prevSchema);
157 }
158 }
159
160 scrollNewColumnIntoView = () => {
161 if (this.refs.table && this.props.scrollToNewColumn) {
162 this.scrollAndCheckForArrows(this.refs.table.state.maxScrollX);
163 if (this.props.onScrollToNewColumn) {
164 this.props.onScrollToNewColumn();
165 }
166 }
167 }
168
169 reorderSchema = (schema, columnOrder) => {
170 const newSchema = [];
171 columnOrder.forEach(col => {
172 const newSchemaItem = schema.find(s => (s.id || s.name) === col);
173 if (newSchemaItem) {
174 newSchema.push(newSchemaItem);
175 }
176 });
177 this.setState({ currentSchema: newSchema });
178 }
179
180 setContentHeight = (data) => {
181 this.setState({
182 contentHeight: this.state.rowHeight * data.length + this.state.headerHeight,
183 });
184 }
185
186 generateInitialColumnOrder = (schema) => {
187 const columnOrder = schema.map(schemaItem => schemaItem.id || schemaItem.name);
188 this.setState({
189 columnOrder,
190 });
191 this.reorderSchema(schema, columnOrder);
192 }
193
194 generateColumnToDataTypeMap = (schema) => {
195 const columnNameToDataTypeMap = {};
196
197 schema.forEach((schemaItem) => {
198 columnNameToDataTypeMap[schemaItem.name] = schemaItem.type;
199 });
200
201 this.setState({columnNameToDataTypeMap});
202 }
203
204 generateColumnWidths = (schema, width, columnKey, newColumnWidth) => {
205 const columnWidths = {};
206 let isColumnResizing;
207 let contentWidth;
208
209 // Table width - rowNumberColumn (width + border) - columns border / columnsCount
210 const calculatedWidth = (width - Constants.ROW_NUMBER_COLUMN_WIDTH - 5 - (schema.length * 2)) / Math.max(schema.length, 1);
211 const defaultColumnWidth = Math.max(calculatedWidth, this.minColumnWidth);
212
213 schema.forEach((schemaItem) => {
214 const maxColumnWidth = this.props.resizeByContent ? this.getMaxColumnWidth(schemaItem, this.minColumnWidth) : defaultColumnWidth;
215 if (this.uniqueId){
216 //Reference the content width over the width set in state if we have data and we are passed the resizeByContent prop
217 if (this.props.data.length > 0 && this.props.resizeByContent) {
218 this.state.columnWidths[schemaItem.id || schemaItem.name] = this.savedColumnsWidth[this.uniqueId][schemaItem.id || schemaItem.name] || maxColumnWidth || this.state.columnWidths[schemaItem.id || schemaItem.name] || defaultColumnWidth;
219 } else {
220 this.state.columnWidths[schemaItem.id || schemaItem.name] = this.savedColumnsWidth[this.uniqueId][schemaItem.id || schemaItem.name] || this.state.columnWidths[schemaItem.id || schemaItem.name] || maxColumnWidth || defaultColumnWidth;
221 }
222 } else {
223 this.state.columnWidths[schemaItem.id || schemaItem.name] = this.state.columnWidths[schemaItem.id || schemaItem.name] || maxColumnWidth || defaultColumnWidth;
224 }
225 columnWidths[schemaItem.id || schemaItem.name] = this.state.columnWidths[schemaItem.id || schemaItem.name];
226 });
227
228 if (columnKey) {
229 columnWidths[columnKey] = newColumnWidth;
230 if (this.uniqueId){
231 this.savedColumnsWidth[this.uniqueId][columnKey] = newColumnWidth;
232 localStorage.setItem('huge-table-column-widths', JSON.stringify(this.savedColumnsWidth));
233 }
234 isColumnResizing = false;
235 }
236
237 contentWidth = schema.reduce((sum, item) => sum + columnWidths[item.id || item.name], 0) + Constants.ROW_NUMBER_COLUMN_WIDTH;
238 this.setState({
239 columnWidths,
240 isColumnResizing,
241 contentWidth,
242 });
243 }
244
245 getMaxColumnWidth = (schemaItem, defaultColumnWidth) => {
246 let maxColumnWidth = 0;
247 //Calculate the column width unless the content is an image
248 if (schemaItem.type !== Constants.ColumnTypes.IMAGE) {
249 this.props.data.forEach(row => {
250 const cellContent = this.getCellContent(row, schemaItem);
251 const cellText = this.getCellText(cellContent);
252 const cellColumnWidth = this.getContentSize(cellText, this.fontDetails);
253 maxColumnWidth = maxColumnWidth > cellColumnWidth ? maxColumnWidth : cellColumnWidth;
254 });
255
256 //If the content width is less than the max title width
257 //Set the column width based off of max title width
258 //Else set column width based off of content width
259 if (maxColumnWidth < this.maxTitleWidth) {
260 const titleWidth = this.getContentSize(schemaItem.name, this.fontDetails) + this.headerOffsetWidth;
261 maxColumnWidth = Math.max(titleWidth, maxColumnWidth);
262 maxColumnWidth = Math.min(maxColumnWidth, this.maxTitleWidth);
263 } else {
264 maxColumnWidth = Math.min(this.maxContentWidth, maxColumnWidth);
265 }
266 }
267 return maxColumnWidth > defaultColumnWidth ? maxColumnWidth : defaultColumnWidth;
268 }
269
270 getContentSize = (txt, font) => {
271 this.element = document.createElement('canvas');
272 this.context = this.element.getContext('2d');
273 this.context.font = font;
274 const tsize = {'width':this.context.measureText(txt).width};
275 return tsize.width;
276 }
277
278 setMaxHeaderWidth = (field) => {
279 let maxColumnWidth = this.getContentSize(field.name, this.fontDetails) + this.headerOffsetWidth;
280 maxColumnWidth = maxColumnWidth > this.minColumnWidth ? maxColumnWidth : this.minColumnWidth;
281
282 if (this.uniqueId){
283 this.savedColumnsWidth[this.uniqueId][field.id] = maxColumnWidth;
284 localStorage.setItem('huge-table-column-widths', JSON.stringify(this.savedColumnsWidth));
285 }
286
287 return maxColumnWidth;
288 }
289
290 resizeHeader = (field) => {
291 const columnWidths = { ...this.state.columnWidths };
292
293 columnWidths[field.id] = this.setMaxHeaderWidth(field);
294
295 this.setState({
296 columnWidths,
297 });
298 }
299
300 resizeAllHeaders = (fields) => {
301 const columnWidths = { ...this.state.columnWidths };
302
303 fields.forEach(field => {
304 columnWidths[field.id] = this.setMaxHeaderWidth(field);
305 });
306
307 this.setState({
308 columnWidths,
309 });
310 }
311
312 getCellContent = (row, schemaItem) => {
313 let content;
314 if (schemaItem.type === Constants.ColumnTypes.TEXT) {
315 const cellData = Array.isArray(row[schemaItem.name]) ? row[schemaItem.name][0] : row[schemaItem.name];
316 if (cellData !== undefined) {
317 content = cellData.text !== undefined ? cellData.text : '';
318 } else {
319 content = '';
320 }
321 } else if (schemaItem.type === Constants.ColumnTypes.IMAGE) {
322 content = '';
323 } else {
324 content = row[schemaItem.name + '/_text'] !== undefined ? row[schemaItem.name + '/_text'] : row[schemaItem.name];
325 }
326 return content;
327 }
328
329 getCellText = cellContent => {
330 if (Array.isArray(cellContent)) {
331 return this.getCellText(cellContent[0]);
332 } else if (typeof cellContent === 'object') {
333 return JSON.stringify(cellContent);
334 } else {
335 return cellContent;
336 }
337 }
338
339 createColumn = (schemaItem, idx) => {
340 let width = this.state.columnWidths[schemaItem.id || schemaItem.name];
341 const lastColumn = idx === (this.state.currentSchema.length - 1) && this.state.currentSchema.length > 1;
342 if (this.state.shouldShowScrolls && lastColumn) {
343 // this adds some extra room to accomodate the scrolling arrows
344 width = width + 120;
345 }
346 let cellClass = '', headerClass = '';
347 if (this.props.showScrollingArrows && this.state.shouldShowScrolls) {
348 if (this.props.hideRowNumbers && idx === 0) {
349 cellClass = 'hugetable-index-column nudge';
350 } else if (lastColumn) {
351 cellClass = 'last-column';
352 }
353 }
354
355 if (idx === this.props.activeColumnIndex) {
356 cellClass = `${cellClass} active-column`;
357 headerClass = 'active-column-header';
358 }
359 // if we are hiding the row numbers but showing scrolling arrows, need to nudge this column with padding
360
361
362 //Add styling for redactPII
363 let piiClass = '';
364 if (schemaItem.redactPII) {
365 piiClass = 'hide-pii';
366 }
367
368 return (
369 <Column
370 cellClassName={`${cellClass} huge-table-column-${idx} ${piiClass}`}
371 headerClassName={headerClass}
372 header={props => this.renderHeader({...props, cellData: {main: schemaItem.name}})}
373 columnKey={schemaItem.id || schemaItem.name}
374 minWidth={this.minColumnWidth}
375 width={width}
376 cell={(props) => this.cellRenderer({...props, schemaItem })}
377 key={schemaItem.name}
378 isResizable={this.props.resizeableColumns}
379 isReorderable={this.props.reorderableColumns}
380 />
381 );
382 }
383
384 renderHeader = (props) => {
385 if (!this.props.options.hideHeader) {
386 if(this.props.renderers && this.props.renderers.HEADER && typeof this.props.renderers.HEADER === 'function') {
387 return (
388 <Cell>
389 {this.props.renderers.HEADER(props)}
390 </Cell>
391 );
392 } else {
393 return <HeaderCell {...props} />;
394 }
395 }
396 }
397
398 getCellStyles = (columnDataType) => {
399 let cellStyles = {};
400
401 if (columnDataType == Constants.ColumnTypes.IMAGE) {
402 cellStyles = StyleSheet.create({
403 cellStyle: {
404 paddingTop: Constants.IMAGE_CELL_PADDING.cellPaddingTop,
405 paddingBottom: Constants.IMAGE_CELL_PADDING.cellPaddingBottom,
406 paddingLeft: Constants.IMAGE_CELL_PADDING.cellPaddingLeft,
407 paddingRight: Constants.IMAGE_CELL_PADDING.cellPaddingRight,
408 },
409 });
410 } else {
411 cellStyles = StyleSheet.create({
412 cellStyle: {
413 paddingTop: Constants.CELL_PADDING.cellPaddingTop,
414 paddingBottom: Constants.CELL_PADDING.cellPaddingBottom,
415 paddingLeft: Constants.CELL_PADDING.cellPaddingLeft,
416 paddingRight: Constants.CELL_PADDING.cellPaddingRight,
417 },
418 });
419 }
420 return (cellStyles);
421 };
422
423 cellRenderer = ({rowIndex, width, height, schemaItem}) => {
424 const rowObject = this.props.data[rowIndex];
425 const cellData = {};
426 cellData.main = rowObject[schemaItem.name];
427 Constants.RETURNED_DATA_TYPES.forEach(dataType => {
428 cellData[dataType] = rowObject[schemaItem.name + '/_' + dataType] || null;
429 });
430 const columnDataType = this.state.columnNameToDataTypeMap[schemaItem.name];
431 const cellCustomRenderer = this.props.renderers && this.props.renderers[columnDataType];
432 cellData.type = columnDataType;
433
434 return (
435 <Cell className={css(this.getCellStyles(columnDataType).cellStyle)}>
436 {CellUtils.getComponentDataType({
437 disableClickEvents: this.props.disableClickEvents,
438 columnDataType,
439 cellData,
440 width,
441 height,
442 columnKey: schemaItem.id || schemaItem.name,
443 mixedContentImage: this.props.options.mixedContentImage,
444 cellCustomRenderer,
445 rowIndex,
446
447 })}
448 </Cell>
449 );
450 }
451
452 onColumnResizeEndCallback = (newColumnWidth, columnKey) => {
453 this.generateColumnWidths(this.props.schema, this.props.options.width, columnKey, newColumnWidth);
454 }
455
456 onScroll = (scrollLeft, scrollTop) => {
457 this.setState({
458 scrollLeft: scrollLeft ? scrollLeft : this.state.scrollLeft,
459 scrollTop,
460 });
461 if(this.props.options.tableScrolled) {
462 this.props.options.tableScrolled(scrollLeft, scrollTop);
463 }
464 }
465
466 onContentDimensionsChange = (contentHeight, contentWidth) => {
467 this.setState({
468 contentWidth,
469 contentHeight,
470 });
471 }
472
473 onColumnReorderEndCallback = (event) => {
474 let columnOrder = this.state.columnOrder.filter((columnKey) => {
475 return columnKey !== event.reorderColumn;
476 });
477
478 if (event.columnAfter) {
479 const index = columnOrder.indexOf(event.columnAfter);
480 columnOrder.splice(index, 0, event.reorderColumn);
481 } else if (!event.columnAfter && event.columnBefore ) {
482 columnOrder.push(event.reorderColumn);
483 } else {
484 // in the case of the drag-and-drop event being aborted
485 columnOrder = this.state.columnOrder;
486 }
487
488 this.setState({
489 columnOrder,
490 });
491 }
492
493 handleMouseEnter = (scrollVal) => {
494 this.intervalId = setInterval(() => this.moveScrollPos(scrollVal), 10);
495 }
496
497 stopScrollInterval = () => {
498 clearInterval(this.intervalId);
499 this.intervalId = undefined;
500 }
501
502 moveScrollPos = (val) => {
503 if (this.state.scrollLeft === 0 && val >= 0 || this.state.scrollLeft > 0) {
504 const scrollLeft = this.state.scrollLeft + val >= 0 ? this.state.scrollLeft + val : 0;
505 this.scrollAndCheckForArrows(scrollLeft);
506 }
507 if (this.state.scrollLeft >= this.refs.table.state.maxScrollX) {
508 this.stopScrollInterval();
509 }
510 }
511
512 calcElementsWidth = (elementsArr) => {
513 return elementsArr.map(e => e.getBoundingClientRect().width).reduce((i, n) => i+n, 0);
514 }
515
516 getChildElements = () => {
517 const headerContainer = this.getHeaderContainer();
518 const childElements = headerContainer ? Array.from(this.getHeaderContainer().children) : [];
519 return childElements;
520 }
521
522 handleScroll = (scrollLeft) => {
523 this.setState({
524 scrollLeft,
525 });
526 return true;
527 }
528
529 checkForScrollArrows = (scrollLeft, allElementsWidth) => {
530 const ALL_ELEMENTS_WIDTH = allElementsWidth ? allElementsWidth : this.calcElementsWidth(this.getChildElements());
531 const shouldShowScrolls = ALL_ELEMENTS_WIDTH > this.props.options.width && this.props.showScrollingArrows;
532 this.setState({
533 shouldShowScrolls,
534 shouldActivateLeftScroll: scrollLeft > 0,
535 shouldActivateRightScroll: ALL_ELEMENTS_WIDTH-1 > (this.props.options.width + scrollLeft),
536 });
537 return true;
538 }
539
540 scrollAndCheckForArrows(scrollLeft) {
541 this.checkForScrollArrows(scrollLeft);
542 this.handleScroll(scrollLeft);
543 }
544
545 getListContainerWidth = () => {
546 return this.getHeaderContainer().getBoundingClientRect().width;
547 }
548
549 getHeaderContainer = () => {
550 const headerCell = document.querySelector('.hugetable-index-column');
551 return headerCell ? headerCell.parentElement : null;
552 }
553
554 render() {
555 const tableWidth = this.props.options.width;
556 const tableHeight = this.props.options.height - this.state.headerHeight;
557 const rowNumberColumnWidth = this.props.options.rowNumberColumnWidth ? this.props.options.rowNumberColumnWidth : Constants.ROW_NUMBER_COLUMN_WIDTH;
558
559 let leftScroll, rightScroll;
560 if(this.state.shouldShowScrolls) {
561 // increase the size of the row number column so there is no overlap
562 leftScroll = (
563 <section style={{ height: this.state.headerHeight }} className={classNames('scroll-toggle', 'left', {'active': this.state.shouldActivateLeftScroll})} onMouseEnter={() => this.handleMouseEnter(-10)} onMouseLeave={() => this.stopScrollInterval()}>
564 <i className="fa fa-chevron-left fa-lg"></i>
565 </section>
566 );
567
568 rightScroll = (
569 <section style={{ height: this.state.headerHeight }} className={classNames('scroll-toggle', 'right', {'active': this.state.shouldActivateRightScroll})} onMouseEnter={() => this.handleMouseEnter(10)} onMouseLeave={() => this.stopScrollInterval()}>
570 <i className="fa fa-chevron-right fa-lg"></i>
571 </section>
572 );
573 }
574
575 return (
576 <TouchWrapper
577 onScroll={this.onScroll}
578 tableWidth={tableWidth}
579 tableHeight={tableHeight}
580 contentWidth={this.state.contentWidth}
581 contentHeight={this.state.contentHeight}
582 >
583 <div style={{ position: 'relative', height: tableHeight, width: tableWidth }}>
584 {leftScroll}
585 {rightScroll}
586 <Table
587 onHorizontalScroll={this.checkForScrollArrows}
588 onScrollEnd={this.onScrollEnd}
589 ref="table"
590 rowHeight={this.state.rowHeight}
591 rowsCount={this.props.data.length}
592 width={tableWidth}
593 scrollLeft={this.state.scrollLeft}
594 scrollTop={this.state.scrollTop}
595 height={tableHeight}
596 headerHeight={this.state.headerHeight}
597 isColumnResizing={this.state.isColumnResizing}
598 onColumnResizeEndCallback={this.onColumnResizeEndCallback}
599 onContentDimensionsChange={this.onContentDimensionsChange}
600 onColumnReorderEndCallback={this.onColumnReorderEndCallback}
601 scrollToColumn={this.props.scrollToColumn}
602 isColumnReordering={false}
603
604 >
605 {(() => {
606 if (!this.props.hideRowNumbers) {
607 return (
608 <Column
609 cellClassName="hugetable-index-column"
610 key="hugetable-index-column"
611 columnKey="hugetable-index-column"
612 width={rowNumberColumnWidth}
613 header={props => this.renderHeader({...props, cellData: {main: '#'}})}
614 cell={(props) => <Cell><TextCell {...props} cellData={{main: props.rowIndex+1}}/></Cell>}
615 />
616 );
617 }
618 })()}
619 {this.state.currentSchema.map(this.createColumn)}
620 {(() => {
621 if (this.state.shouldShowScrolls) {
622 return (
623 <Column
624 cellClassName="huge-table-right-scroll-column"
625 key="huge-table-right-scroll-column"
626 columnKey="huge-table-right-scroll-column"
627 width={this.props.buttonColumnWidth ? 40 + this.props.buttonColumnWidth : 40}
628 header={props => this.renderHeader({...props, cellData: {main: ''}})}
629 cell={(props) => <Cell><TextCell {...props} cellData={{main: ''}}/></Cell>}
630 />
631 );
632 }
633 })()}
634 </Table>
635 </div>
636 </TouchWrapper>
637 );
638 }
639}