/** * 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 { ButtonGroup, Collapse, Well } from 'react-bootstrap'; import shortid from 'shortid'; import { t } from '@superset-ui/core'; import Fade from 'src/common/components/Fade'; import { Tooltip } from 'src/common/components/Tooltip'; import CopyToClipboard from '../../components/CopyToClipboard'; import Link from '../../components/Link'; 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, timeout: PropTypes.number, // used for tests }; const defaultProps = { actions: {}, table: null, timeout: 500, }; class TableElement extends React.PureComponent { constructor(props) { super(props); this.state = { sortColumns: false, expanded: true, hovered: false, }; this.removeFromStore = this.removeFromStore.bind(this); this.toggleSortColumns = this.toggleSortColumns.bind(this); this.removeTable = this.removeTable.bind(this); this.setHover = this.setHover.bind(this); } 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); } toggleTable(e) { e.preventDefault(); if (this.props.table.expanded) { this.props.actions.collapseTable(this.props.table); } else { this.props.actions.expandTable(this.props.table); } } removeTable() { this.setState({ expanded: false }); this.props.actions.removeDataPreview(this.props.table); } toggleSortColumns() { this.setState(prevState => ({ sortColumns: !prevState.sortColumns })); } removeFromStore() { this.props.actions.removeTable(this.props.table); } renderWell() { const { table } = this.props; let header; if (table.partitions) { let partitionQuery; let partitionClipBoard; if (table.partitions.partitionQuery) { ({ partitionQuery } = table.partitions.partitionQuery); 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.toggleTable(e); }} > {table.name}
{table.isMetadataLoading || table.isExtraMetadataLoading ? ( ) : ( {this.renderControls()} )} { this.toggleTable(e); }} className={ 'text-primary pointer m-l-10 ' + 'fa fa-lg ' + `fa-angle-${table.expanded ? 'up' : 'down'}` } />
); } 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.renderWell()}
{cols && cols.map(col => )}
); return metadata; } render() { return (
this.setHover(true)} onMouseLeave={() => this.setHover(false)} > {this.renderHeader()}
{this.renderBody()}
); } } TableElement.propTypes = propTypes; TableElement.defaultProps = defaultProps; export default TableElement;