/** * 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 PropTypes from 'prop-types'; import Collapse from 'src/components/Collapse'; import Card from 'src/components/Card'; import ButtonGroup from 'src/components/ButtonGroup'; import shortid from 'shortid'; import { t, styled } from '@superset-ui/core'; import { debounce } from 'lodash'; import { Tooltip } from 'src/components/Tooltip'; import CopyToClipboard from '../../components/CopyToClipboard'; import { IconTooltip } from '../../components/IconTooltip'; import ColumnElement from './ColumnElement'; import ShowSQL from './ShowSQL'; import ModalTrigger from '../../components/ModalTrigger'; import Loading from '../../components/Loading'; const propTypes = { table: PropTypes.object, actions: PropTypes.object, }; const defaultProps = { actions: {}, table: null, }; const StyledSpan = styled.span` color: ${({ theme }) => theme.colors.primary.dark1}; &: hover { color: ${({ theme }) => theme.colors.primary.dark2}; } cursor: pointer; `; const Fade = styled.div` transition: all ${({ theme }) => theme.transitionTiming}s; opacity: ${props => (props.hovered ? 1 : 0)}; `; class TableElement extends React.PureComponent { constructor(props) { super(props); this.state = { sortColumns: false, hovered: false, }; this.toggleSortColumns = this.toggleSortColumns.bind(this); this.removeTable = this.removeTable.bind(this); this.setHover = debounce(this.setHover.bind(this), 100); } setHover(hovered) { this.setState({ hovered }); } popSelectStar() { const qe = { id: shortid.generate(), title: this.props.table.name, dbId: this.props.table.dbId, autorun: true, sql: this.props.table.selectStar, }; this.props.actions.addQueryEditor(qe); } removeTable() { this.props.actions.removeDataPreview(this.props.table); this.props.actions.removeTable(this.props.table); } toggleSortColumns() { this.setState(prevState => ({ sortColumns: !prevState.sortColumns })); } renderWell() { const { table } = this.props; let header; if (table.partitions) { let partitionQuery; let partitionClipBoard; if (table.partitions.partitionQuery) { ({ partitionQuery } = table.partitions); const tt = t('Copy partition query to clipboard'); partitionClipBoard = ( } /> ); } let latest = Object.entries(table.partitions?.latest || []).map( ([key, value]) => `${key}=${value}`, ); latest = latest.join('/'); header = (
{t('latest partition:')} {latest} {' '} {partitionClipBoard}
); } return header; } renderControls() { let keyLink; const { table } = this.props; if (table.indexes && table.indexes.length > 0) { keyLink = ( {t('Keys for table')} {table.name} } modalBody={table.indexes.map((ix, i) => (
{JSON.stringify(ix, null, '  ')}
))} triggerNode={ } /> ); } return ( {keyLink} {table.selectStar && ( } text={table.selectStar} shouldShowText={false} tooltipText={t('Copy SELECT statement to the clipboard')} /> )} {table.view && ( )} ); } renderHeader() { const { table } = this.props; return (
this.setHover(true)} onMouseLeave={() => this.setHover(false)} > {table.name}
{table.isMetadataLoading || table.isExtraMetadataLoading ? ( ) : ( e.stopPropagation()} > {this.renderControls()} )}
); } renderBody() { const { table } = this.props; let cols; if (table.columns) { cols = table.columns.slice(); if (this.state.sortColumns) { cols.sort((a, b) => { const colA = a.name.toUpperCase(); const colB = b.name.toUpperCase(); if (colA < colB) { return -1; } if (colA > colB) { return 1; } return 0; }); } } const metadata = (
this.setHover(true)} onMouseLeave={() => this.setHover(false)} css={{ paddingTop: 6 }} > {this.renderWell()}
{cols && cols.map(col => )}
); return metadata; } render() { return ( {this.renderBody()} ); } } TableElement.propTypes = propTypes; TableElement.defaultProps = defaultProps; export default TableElement;