import React from "react"; import { AutoTableRow } from "./auto-table-row/AutoTableRow"; export interface IColumnSort { index: number; isReversed: boolean; } export interface IAutoTableHeader { display: string; onClick?: () => any; } const instanceOfAutoTableHeader = (object: any): object is IAutoTableHeader => { if (typeof object === "object" && object !== null) { return "display" in object; } return false; }; export interface IAutoTableProps { /** * The headers of the table */ headers: Array; /** * Array of functions that describe how each cell of a row ought to be displayed. */ cells: Array<(element: T) => any>; /** * The array of elements to display (each element being its own row). */ elements: T[]; /** * Optional callback method that is triggered when a appUser clicks on a row. */ onRowClick?: (elementClicked: T) => any; /** * Optionally show a desired column as being sorted. * (This DOES NOT sort. Merely displays the header as such.) */ sortedColumn?: IColumnSort; className?: string; /** * So you want to show something else instead of this row.. what is it and which 0 index row to replace. */ overrideRow?: (element: T) => JSX.Element; overrideRowFn?: (element: T) => boolean; } export class AutoTable extends React.Component> { getHeaderText(header: IAutoTableHeader | string | number): string | number { if (instanceOfAutoTableHeader(header)) { return header.display; } else { return header; } } getHeaderOnClick( header: IAutoTableHeader | string | number ): (() => any) | undefined { if (instanceOfAutoTableHeader(header)) { return header.onClick; } } isHeaderClickable(header: IAutoTableHeader | string | number): boolean { return instanceOfAutoTableHeader(header); } shouldDisplayAscendingSort(index: number): boolean { return ( !!this.props.sortedColumn && this.props.sortedColumn.index === index && !this.props.sortedColumn.isReversed ); } shouldDisplayDescendingSort(index: number): boolean { return ( !!this.props.sortedColumn && this.props.sortedColumn.index === index && this.props.sortedColumn.isReversed ); } render() { return ( {this.props.headers.map((header, index) => ( ))} {this.props.elements.map((el, index) => this.props.overrideRow !== undefined && this.props.overrideRowFn !== undefined && this.props.overrideRowFn(el) ? ( this.props.overrideRow(el) ) : ( ) )}
{this.shouldDisplayAscendingSort(index) ? ( ) : null} {this.shouldDisplayDescendingSort(index) ? ( ) : null} {this.getHeaderText(header)}
); } }