Query Buttons: Export Results and Export Errors (#638)

* Fullscreen mode always an option
* Export Results button iff results && no errors
* Export Errors button added

Suggestion added by: @noahtalerman <noah@fleetdm.com>
This commit is contained in:
RachelElysia 2021-04-19 18:20:24 -04:00 committed by GitHub
parent f37d872dd4
commit 03a68348ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 6 deletions

View File

@ -18,6 +18,7 @@ class QueryResultsTable extends Component {
static propTypes = {
campaign: campaignInterface.isRequired,
onExportQueryResults: PropTypes.func,
onExportErrorsResults: PropTypes.func,
onToggleQueryFullScreen: PropTypes.func,
isQueryFullScreen: PropTypes.bool,
isQueryShrinking: PropTypes.bool,
@ -148,6 +149,7 @@ class QueryResultsTable extends Component {
const {
campaign,
onExportQueryResults,
onExportErrorsResults,
isQueryFullScreen,
isQueryShrinking,
onToggleQueryFullScreen,
@ -200,8 +202,11 @@ class QueryResultsTable extends Component {
onClick={onToggleQueryFullScreen}
variant="grey"
>
<KolideIcon name={isQueryFullScreen ? "windowed" : "fullscreen"} />
<KolideIcon
name={isQueryFullScreen ? "windowed" : "fullscreen"}
/>
</Button>
{!hasNoResults && !queryIsRunning && (
<Button
className={`${baseClass}__export-btn`}
onClick={onExportQueryResults}
@ -209,6 +214,7 @@ class QueryResultsTable extends Component {
>
Export results
</Button>
)}
</header>
<span className={`${baseClass}__table-title`}>Results</span>
<div className={`${baseClass}__results-table-wrapper`}>
@ -223,12 +229,25 @@ class QueryResultsTable extends Component {
{!hasNoResults && renderTable()}
</div>
{hasErrors && (
<div className={`${baseClass}__error-table-container`}>
<span className={`${baseClass}__table-title`}>Errors</span>
<div className={`${baseClass}__error-table-wrapper`}>
{renderErrorsTable()}
<>
<div className={`${baseClass}__error-table-container`}>
<header className={`${baseClass}__button-wrap`}>
<div>
<Button
className={`${baseClass}__export-btn`}
onClick={onExportErrorsResults}
variant="inverse"
>
Export errors
</Button>
</div>
</header>
<span className={`${baseClass}__table-title`}>Errors</span>
<div className={`${baseClass}__error-table-wrapper`}>
{renderErrorsTable()}
</div>
</div>
</div>
</>
)}
</div>
);

View File

@ -13,6 +13,7 @@
&__button-wrap {
@include clearfix;
margin-top: 20px;
}
&__export-btn {

View File

@ -200,6 +200,32 @@ export class QueryPage extends Component {
return false;
};
onExportErrorsResults = (evt) => {
evt.preventDefault();
const { campaign } = this.state;
const { errors } = campaign;
if (errors) {
const csv = convertToCSV(errors, (fields) => {
const result = filter(fields, (f) => f !== "host_hostname");
result.unshift("host_hostname");
return result;
});
const formattedTime = moment(new Date()).format("MM-DD-YY hh-mm-ss");
const filename = `${this.csvQueryName} Errors (${formattedTime}).csv`;
const file = new global.window.File([csv], filename, {
type: "text/csv",
});
FileSaver.saveAs(file);
}
return false;
};
onFetchTargets = (query, targetResponse) => {
const { dispatch } = this.props;
const { targets_count: targetsCount } = targetResponse;
@ -522,6 +548,7 @@ export class QueryPage extends Component {
} = this.state;
const {
onExportQueryResults,
onExportErrorsResults,
onToggleQueryFullScreen,
onRunQuery,
onStopQuery,
@ -546,6 +573,7 @@ export class QueryPage extends Component {
<QueryResultsTable
campaign={campaign}
onExportQueryResults={onExportQueryResults}
onExportErrorsResults={onExportErrorsResults}
isQueryFullScreen={isQueryFullScreen}
isQueryShrinking={isQueryShrinking}
onToggleQueryFullScreen={onToggleQueryFullScreen}