import React, { Component } from 'react'; import { SimpleTable, Container, TruncatedText, SVGIcon, Tooltip, Tags } from 'ca-ui-toolkit'; import PropTypes from 'prop-types'; import menuOverflow16 from '@ba-ui-toolkit/ba-graphics/dist/icons/overflow-menu--horizontal_16.svg'; import './ListView.scss'; const COL_LENGTH = 4; /* Use in HomeView.js import { ListView } from '../ListView/ListView.js'; ...
} stringGetter={stringGetter} glassContext={glassContext} entries={this._formatAssets()} entryAssets={assets} allowUploadFiles={allowUploadFiles} homeView={homeView} stateId={stateId}/> */ export class ListView extends Component { static propTypes = { /** Custom class name(s) */ className: PropTypes.string, /** The glass context handed down */ glassContext: PropTypes.object, /** A reference to the ES5 homeView object */ homeView: PropTypes.object, /** A copy of the i18n object used to translate strings */ stringGetter: PropTypes.object, /** A list of the list entries formatted properly for use from the ca-ui-toolkit */ entries: PropTypes.array, /** A list of the list entries unformatted with all information. This is to be used by glassContext */ entryAssets: PropTypes.array, /** a boolean showing whether or not something can be uploaded if there is no data */ allowUploadFiles: PropTypes.bool, /** An id used to remove context menus for list entries */ stateId: PropTypes.string, /** Height Value for SimpleTable Component */ height: PropTypes.string.isRequired }; static defaultProps = { entries: [] } constructor(props) { super(props); } state = { data: [], headerData: [ { label: '' }, { label: '' }, { label: '' }, { label: '' } ], menuLoading: false }; componentDidMount(){ // Data preparation for rendering const { entries, stringGetter } = this.props; this.setState({ entries: entries }); this.setState({ data: this.dataPrep(entries) }); this.setState({ headerData: [ { label: stringGetter.get('list_header_name') }, { label: stringGetter.get('list_header_type') }, { label: stringGetter.get('list_header_last_modified') }, { label: '' } ] }); } componentDidUpdate(prevProps) { // In case if entries removed, refresh the list if(prevProps.entries.length !== this.props.entries.length) this.setState({ data: this.dataPrep(this.props.entries) }); else{ for(let i = 0; i < this.props.entries.length; i++){ if(prevProps.entries[i].label !== this.props.entries[i].label || prevProps.entries[i].date !== this.props.entries[i].date){ this.setState({ data: this.dataPrep(this.props.entries) }); break; } } } } // Handler for data preparation and formating dataPrep = (data) => { const result = data.map(element => [ { label: element.label }, { label: element.type }, { label: element.date }, { label: '' } ]); return result; } // Return the value in the designated table cell _getValue = (row, col) => { if (this.state.data.length > row && this.state.data[row].length > col) { return this.state.data[row][col].label; } return null; }; // Function for rendering the table body _cellRenderer(row, col) { /* Three situations of cell content: - Text (Name, Last updated) - Asset tag (Type) - Overflow menu icon */ // Must: check the length first -> row length are fixed before state updates (concurrency issue) if(row >= this.props.entryAssets.length) return; if(col === 0) { return ( { this._openEntryViaTabbing(e, row); }} value={this.state.data[row][col].label} title={this.state.data[row][col].label} location='end' className='cell_assetName' /> ); } else if (col === 1) { const typeName = this.state.data[row][col].label; const asset = this.props.entryAssets[row]; let tagColor; let supportedtypeName = typeName ? typeName[0].toUpperCase() + typeName.slice(1).toLowerCase() : ''; /** * dashboard/report/story => purple tags * exploration/notebooks = blue tags * data upload, data sets, data module, data = green tags * others = grey tags */ if(asset.type === 'report' || asset.type === 'reportView' || asset.type === 'interactiveReport' || asset.type === 'powerPlay8Report' || (asset.type === 'exploration' && (!asset.tags || asset.tags[0] !== 'explore'))){ tagColor = 'purple'; }else if((asset.type === 'exploration' && asset.tags && asset.tags[0] === 'explore') || asset.type === 'jupyterNotebook'){ tagColor = 'blue'; }else if(asset.type === 'dataSet2' || asset.type === 'module' || asset.type === 'uploadedFile' || asset.type === 'URL'){ tagColor = 'teal'; // If it's data and only one word, make all lowercased according to design doc supportedtypeName = supportedtypeName && supportedtypeName.split(' ').length === 1? supportedtypeName.toLowerCase() : supportedtypeName; }else{ tagColor = 'gray'; } return ( ); } else if (col === 3) { return (
{ this._openActionMenu(e, row); }}> { this._openActionMenu(e); }}/>
); } else { return ( ); } } // Handler for waking the action menu while clicking the menu icon on each table row _openActionMenu(e, index=e.target.id.split('_')[1]) { e.stopPropagation(); // If not a shift click, ctrl click or a right click or the user pressed enter on the context menu if((e.type == 'click' && !e.shiftKey && !e.ctrlKey && e.nativeEvent.which !== 3) || (e.type=='keyup' && e.keyCode === 13)) { this.setState({ menuLoading: true }); e.persist(); const { homeView, entryAssets } = this.props; let asset = entryAssets[index]; if(homeView && homeView.requiresAssetVerification) { homeView.loadAssetContextMenu(asset, e).then(function() { this.setState({ menuLoading: false }); }.bind(this)); } } } // Handler to open the project via tabbing action _openEntryViaTabbing(e, index=e.target.id.split('_')[1]){ e.stopPropagation(); // If not a shift click, ctrl click or a right click or the user pressed enter on the context menu if((e.type == 'click' && !e.shiftKey && !e.ctrlKey && e.nativeEvent.which !== 3) || (e.type=='keyup' && e.keyCode === 13)) { e.persist(); this._openEntry(index); } } // Handler for clicking the entry to open the detail page _openEntry(row){ this.props.homeView.onTileClick(this.props.entryAssets[row]); } // Function used to render the table header _headerRenderer(col) { return (
); } render() { /* Dynamic allocation for width division to avoid horizontal scrolling Original Proportion in design spec is: 544:205:314 If necessary, reduced by 15% to make sure that moreButton won't be jumped outside of the table */ return ( ( {this._cellRenderer(row, col)} )} headerRenderer={col => ( {this._headerRenderer(col)} )} onRowClick={row => this._openEntry(row) } /> ); } }