import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { keys, omit } from 'lodash'; import Button from 'components/buttons/Button'; import campaignInterface from 'interfaces/campaign'; import filterArrayByHash from 'utilities/filter_array_by_hash'; import Icon from 'components/icons/Icon'; import InputField from 'components/forms/fields/InputField'; import QueryResultsRow from 'components/queries/QueryResultsTable/QueryResultsRow'; import QueryProgressDetails from 'components/queries/QueryProgressDetails'; import Spinner from 'components/loaders/Spinner'; const baseClass = 'query-results-table'; class QueryResultsTable extends Component { static propTypes = { campaign: campaignInterface.isRequired, onExportQueryResults: PropTypes.func, onToggleQueryFullScreen: PropTypes.func, isQueryFullScreen: PropTypes.bool, isQueryShrinking: PropTypes.bool, onRunQuery: PropTypes.func.isRequired, onStopQuery: PropTypes.func.isRequired, queryIsRunning: PropTypes.bool, queryTimerMilliseconds: PropTypes.number, }; constructor (props) { super(props); this.state = { resultsFilter: {}, }; } onFilterAttribute = (attribute) => { return (value) => { const { resultsFilter } = this.state; this.setState({ resultsFilter: { ...resultsFilter, [attribute]: value, }, }); return false; }; } onSetActiveColumn = (activeColumn) => { return () => { this.setState({ activeColumn }); }; } renderTableHeaderRowData = (column, index) => { const filterable = column === 'hostname' ? 'host_hostname' : column; const { activeColumn, resultsFilter } = this.state; const { onFilterAttribute, onSetActiveColumn } = this; const filterIconClassName = classnames(`${baseClass}__filter-icon`, { [`${baseClass}__filter-icon--is-active`]: activeColumn === column, }); return ( {column} ); } renderTableHeaderRow = () => { const { campaign } = this.props; const { renderTableHeaderRowData } = this; const { query_results: queryResults } = campaign; const queryAttrs = omit(queryResults[0], ['host_hostname']); const queryResultColumns = keys(queryAttrs); return ( {renderTableHeaderRowData('hostname', -1)} {queryResultColumns.map((column, i) => { return renderTableHeaderRowData(column, i); })} ); } renderTableRows = () => { const { campaign } = this.props; const { query_results: queryResults } = campaign; const { resultsFilter } = this.state; const filteredQueryResults = filterArrayByHash(queryResults, resultsFilter); return filteredQueryResults.map((queryResult) => { return ( ); }); } renderTable = () => { const { renderTableHeaderRow, renderTableRows, } = this; const { queryIsRunning, campaign } = this.props; const { query_results: queryResults } = campaign; const loading = queryIsRunning && (!queryResults || !queryResults.length); if (loading) { return ; } return ( {renderTableHeaderRow()} {renderTableRows()}
); } render () { const { campaign, onExportQueryResults, isQueryFullScreen, isQueryShrinking, onToggleQueryFullScreen, onRunQuery, onStopQuery, queryIsRunning, queryTimerMilliseconds, } = this.props; const { renderTable } = this; const { hosts_count: hostsCount, query_results: queryResults } = campaign; const hasNoResults = !queryIsRunning && (!hostsCount.successful || (!queryResults || !queryResults.length)); const resultsTableWrapClass = classnames(baseClass, { [`${baseClass}--full-screen`]: isQueryFullScreen, [`${baseClass}--shrinking`]: isQueryShrinking, [`${baseClass}__no-results`]: hasNoResults, }); const toggleFullScreenBtnClass = classnames(`${baseClass}__fullscreen-btn`, { [`${baseClass}__fullscreen-btn--active`]: isQueryFullScreen, }); return (
{isQueryFullScreen && }
{hasNoResults && No results found} {!hasNoResults && renderTable()}
); } } export default QueryResultsTable;