/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import React from 'react'; import cx from 'classnames'; import { TableInstance } from 'react-table'; import { styled } from '@superset-ui/core'; import Icon from 'src/components/Icon'; interface TableCollectionProps { getTableProps: (userProps?: any) => any; getTableBodyProps: (userProps?: any) => any; prepareRow: TableInstance['prepareRow']; headerGroups: TableInstance['headerGroups']; rows: TableInstance['rows']; columns: TableInstance['column'][]; loading: boolean; highlightRowId?: number; } export const Table = styled.table` background-color: ${({ theme }) => theme.colors.grayscale.light5}; border-collapse: separate; border-radius: ${({ theme }) => theme.borderRadius}px; thead > tr > th { border: 0; } tbody { tr:first-of-type > td { border-top: 0; } } th { background: ${({ theme }) => theme.colors.grayscale.light5}; position: sticky; top: 0; &:first-of-type { padding-left: ${({ theme }) => theme.gridUnit * 4}px; } &.xs { min-width: 25px; } &.sm { min-width: 50px; } &.md { min-width: 75px; } &.lg { min-width: 100px; } &.xl { min-width: 150px; } &.xxl { min-width: 200px; } span { white-space: nowrap; display: flex; align-items: center; line-height: 2; } svg { display: inline-block; position: relative; } } td { &.xs { width: 25px; } &.sm { width: 50px; } &.md { width: 75px; } &.lg { width: 100px; } &.xl { width: 150px; } &.xxl { width: 200px; } } .table-cell-loader { position: relative; .loading-bar { background-color: ${({ theme }) => theme.colors.secondary.light4}; border-radius: 7px; span { visibility: hidden; } } &:after { position: absolute; transform: translateY(-50%); top: 50%; left: 0; content: ''; display: block; width: 100%; height: 48px; background-image: linear-gradient( 100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0) 80% ); background-size: 200px 48px; background-position: -100px 0; background-repeat: no-repeat; animation: loading-shimmer 1s infinite; } } .actions { white-space: nowrap; min-width: 100px; svg, i { margin-right: 8px; &:hover { path { fill: ${({ theme }) => theme.colors.primary.base}; } } } } .table-row { .actions { opacity: 0; font-size: ${({ theme }) => theme.typography.sizes.xl}px; } &:hover { background-color: ${({ theme }) => theme.colors.secondary.light5}; .actions { opacity: 1; transition: opacity ease-in ${({ theme }) => theme.transitionTiming}s; } } } .table-row-selected { background-color: ${({ theme }) => theme.colors.secondary.light4}; &:hover { background-color: ${({ theme }) => theme.colors.secondary.light4}; } } .table-cell { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; max-width: 300px; line-height: 1; vertical-align: middle; &:first-of-type { padding-left: ${({ theme }) => theme.gridUnit * 4}px; } } @keyframes loading-shimmer { 40% { background-position: 100% 0; } 100% { background-position: 100% 0; } } `; Table.displayName = 'table'; export default React.memo( ({ getTableProps, getTableBodyProps, prepareRow, headerGroups, columns, rows, loading, highlightRowId, }: TableCollectionProps) => ( {headerGroups.map(headerGroup => ( {headerGroup.headers.map(column => { let sortIcon = ; if (column.isSorted && column.isSortedDesc) { sortIcon = ; } else if (column.isSorted && !column.isSortedDesc) { sortIcon = ; } return column.hidden ? null : ( ); })} ))} {loading && rows.length === 0 && [...new Array(25)].map((_, i) => ( {columns.map((column, i2) => { if (column.hidden) return null; return ( ); })} ))} {rows.length > 0 && rows.map(row => { prepareRow(row); // @ts-ignore const rowId = row.original.id; return ( {row.cells.map(cell => { if (cell.column.hidden) return null; const columnCellProps = cell.column.cellProps || {}; return ( ); })} ); })}
{column.render('Header')} {column.canSort && sortIcon}
LOADING
{cell.render('Cell')}
), );