export function prepareColumns()

in viz-lib/src/visualizations/table/utils.js [48:147]


export function prepareColumns(columns, searchInput, orderBy, onOrderByChange) {
  columns = filter(columns, "visible");
  columns = sortBy(columns, "order");

  const isMultiColumnSort = orderBy.length > 1;
  const orderByInfo = getOrderByInfo(orderBy);

  let tableColumns = map(columns, column => {
    const isAscend = orderByInfo[column.name] && orderByInfo[column.name].direction === "ascend";
    const isDescend = orderByInfo[column.name] && orderByInfo[column.name].direction === "descend";

    const sortColumnIndex = isMultiColumnSort && orderByInfo[column.name] ? orderByInfo[column.name].index : null;

    const result = {
      key: column.name,
      dataIndex: `record[${JSON.stringify(column.name)}]`,
      align: column.alignContent,
      title: (
        <React.Fragment>
          {column.description && (
            <span style={{ paddingRight: 5 }}>
              <Tooltip placement="top" title={column.description}>
                <div className="table-visualization-heading">
                  <i className="fa fa-info-circle" aria-hidden="true"></i>
                </div>
              </Tooltip>
            </span>
          )}
          <Tooltip placement="top" title={column.title}>
            <div className="table-visualization-heading" data-sort-column-index={sortColumnIndex}>
              {column.title}
            </div>
          </Tooltip>
          <span className="ant-table-column-sorter">
            <div className="ant-table-column-sorter-inner ant-table-column-sorter-inner-full">
              <Icon
                className={`ant-table-column-sorter-up ${isAscend ? "on" : "off"}`}
                type="caret-up"
                theme="filled"
              />
              <Icon
                className={`ant-table-column-sorter-down ${isDescend ? "on" : "off"}`}
                type="caret-down"
                theme="filled"
              />
            </div>
          </span>
        </React.Fragment>
      ),
      onHeaderCell: () => ({
        className: cx("ant-table-column-has-actions ant-table-column-has-sorters", {
          "table-visualization-column-is-sorted": isAscend || isDescend,
        }),
        onClick: event => onOrderByChange(toggleOrderBy(column.name, orderBy, event.shiftKey)),
      }),
    };

    const initColumn = ColumnTypes[column.displayAs];
    const Component = initColumn(column);
    result.render = (unused, row) => ({
      children: <Component row={row.record} />,
      props: { className: `display-as-${column.displayAs}` },
    });

    return result;
  });

  tableColumns.push({
    key: "###Redash::Visualizations::Table::Spacer###",
    dataIndex: null,
    title: "",
    className: "table-visualization-spacer",
    render: () => "",
    onHeaderCell: () => ({ className: "table-visualization-spacer" }),
  });

  if (searchInput) {
    // We need a merged head cell through entire row. With Ant's Table the only way to do it
    // is to add a single child to every column move `dataIndex` property to it and set
    // `colSpan` to 0 for every child cell except of the 1st one - which should be expanded.
    tableColumns = map(tableColumns, ({ title, align, key, onHeaderCell, ...rest }, index) => ({
      key: key + "(parent)",
      title,
      align,
      onHeaderCell,
      children: [
        {
          ...rest,
          key: key + "(child)",
          align,
          colSpan: index === 0 ? tableColumns.length : 0,
          title: index === 0 ? searchInput : null,
          onHeaderCell: () => ({ className: "table-visualization-search" }),
        },
      ],
    }));
  }

  return tableColumns;
}