From 7cb737c86016a496d8849bb94c2095565bfdd3d3 Mon Sep 17 00:00:00 2001
From: Andrii Vorobiov
Date: Fri, 2 Oct 2020 12:36:07 +0300
Subject: [PATCH] ui: extend diagnostics column to allow activate and download
reports
Previously, Statements table had a Diagnostics column which allowed
users to request diagnostics reports for the first time and then
displayed status for requested report only. As result it wasn't
possible to download already generated report or request new one
report from statements table.
With current changes, Diagnostics column allows to request new
reports everytime when previous reports are generated.
Also it provides a list with links to download previous reports.
The main change is to provide a list of available (or requested)
reports for every statement (instead of a single, most recent
report as it was before). Then extracted `StatementsPage` component
(from `admin-ui-components` package) handles all rendering logic
for this list of reports.
Minor changes:
- `WAITING FOR QUERY` status is renamed to `WAITING` for new design
- `getDiagnosticsStatus` utility function is reused to reduce code
duplication
Resolves: #50824
Release note (admin ui change): Diagnostics column (on statements table)
has been changed and includes `Activate` button and dropdown list to
download completed reports. Also diagnostics badge status is changed from
`WAITING FOR QUERY` to `WAITING`.
---
pkg/ui/src/redux/statements/statementsSelectors.ts | 9 ++++-----
.../statements/diagnostics/diagnosticStatusBadge.tsx | 4 ++--
.../statements/diagnostics/diagnosticStatuses.ts | 2 +-
.../views/statements/diagnostics/diagnosticsUtils.ts | 2 +-
pkg/ui/src/views/statements/statementsPage.tsx | 11 +++++++----
pkg/ui/src/views/statements/statementsTable.tsx | 3 ++-
.../src/views/statements/statementsTableContent.tsx | 5 +++--
7 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/pkg/ui/src/redux/statements/statementsSelectors.ts b/pkg/ui/src/redux/statements/statementsSelectors.ts
index 0aa192cf8273..02bae177cd9e 100644
--- a/pkg/ui/src/redux/statements/statementsSelectors.ts
+++ b/pkg/ui/src/redux/statements/statementsSelectors.ts
@@ -8,7 +8,7 @@
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
-import { chain, sortBy, last } from "lodash";
+import { chain, orderBy } from "lodash";
import { createSelector } from "reselect";
import { AdminUIState } from "src/redux/state";
import { cockroach } from "src/js/protos";
@@ -44,14 +44,13 @@ export const statementDiagnosticsReportsInFlight = createSelector(
);
type StatementDiagnosticsDictionary = {
- [statementFingerprint: string]: IStatementDiagnosticsReport;
+ [statementFingerprint: string]: IStatementDiagnosticsReport[];
};
-export const selectLastDiagnosticsReportPerStatement = createSelector(
+export const selectDiagnosticsReportsPerStatement = createSelector(
selectStatementDiagnosticsReports,
(diagnosticsReports: IStatementDiagnosticsReport[]): StatementDiagnosticsDictionary => chain(diagnosticsReports)
.groupBy(diagnosticsReport => diagnosticsReport.statement_fingerprint)
- // Perform ASC sorting and take the last item
- .mapValues(diagnostics => last(sortBy(diagnostics, d => d.requested_at.seconds.toNumber())))
+ .mapValues(diagnostics => orderBy(diagnostics, d => d.requested_at.seconds.toNumber(), ["desc"]))
.value(),
);
diff --git a/pkg/ui/src/views/statements/diagnostics/diagnosticStatusBadge.tsx b/pkg/ui/src/views/statements/diagnostics/diagnosticStatusBadge.tsx
index cfa44170a33d..01748eaada9b 100644
--- a/pkg/ui/src/views/statements/diagnostics/diagnosticStatusBadge.tsx
+++ b/pkg/ui/src/views/statements/diagnostics/diagnosticStatusBadge.tsx
@@ -24,7 +24,7 @@ function mapDiagnosticsStatusToBadge(diagnosticsStatus: DiagnosticStatuses) {
switch (diagnosticsStatus) {
case "READY":
return "success";
- case "WAITING FOR QUERY":
+ case "WAITING":
return "info";
case "ERROR":
return "danger";
@@ -50,7 +50,7 @@ function mapStatusToDescription(diagnosticsStatus: DiagnosticStatuses) {
);
- case "WAITING FOR QUERY":
+ case "WAITING":
return (
diff --git a/pkg/ui/src/views/statements/diagnostics/diagnosticStatuses.ts b/pkg/ui/src/views/statements/diagnostics/diagnosticStatuses.ts
index 5657edb92279..96ae8058a55a 100644
--- a/pkg/ui/src/views/statements/diagnostics/diagnosticStatuses.ts
+++ b/pkg/ui/src/views/statements/diagnostics/diagnosticStatuses.ts
@@ -8,4 +8,4 @@
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
-export type DiagnosticStatuses = "READY" | "WAITING FOR QUERY" | "ERROR";
+export type DiagnosticStatuses = "READY" | "WAITING" | "ERROR";
diff --git a/pkg/ui/src/views/statements/diagnostics/diagnosticsUtils.ts b/pkg/ui/src/views/statements/diagnostics/diagnosticsUtils.ts
index 650da86e0616..3bdb418d817d 100644
--- a/pkg/ui/src/views/statements/diagnostics/diagnosticsUtils.ts
+++ b/pkg/ui/src/views/statements/diagnostics/diagnosticsUtils.ts
@@ -19,7 +19,7 @@ export function getDiagnosticsStatus(diagnosticsRequest: IStatementDiagnosticsRe
return "READY";
}
- return "WAITING FOR QUERY";
+ return "WAITING";
}
export function sortByRequestedAtField(a: IStatementDiagnosticsReport, b: IStatementDiagnosticsReport) {
diff --git a/pkg/ui/src/views/statements/statementsPage.tsx b/pkg/ui/src/views/statements/statementsPage.tsx
index 4f144e21180e..2820cd6ca52f 100644
--- a/pkg/ui/src/views/statements/statementsPage.tsx
+++ b/pkg/ui/src/views/statements/statementsPage.tsx
@@ -30,7 +30,7 @@ import { appAttr } from "src/util/constants";
import { TimestampToMoment } from "src/util/convert";
import { PrintTime } from "src/views/reports/containers/range/print";
import {
- selectLastDiagnosticsReportPerStatement,
+ selectDiagnosticsReportsPerStatement,
} from "src/redux/statements/statementsSelectors";
import { createStatementDiagnosticsAlertLocalSetting } from "src/redux/alerts";
import { getMatchParamByName } from "src/util/query";
@@ -42,8 +42,10 @@ import {
trackStatementsSearchAction,
trackTableSortAction,
} from "src/redux/analyticsActions";
+import { trackDownloadDiagnosticsBundle } from "src/util/analytics";
type ICollectedStatementStatistics = protos.cockroach.server.serverpb.StatementsResponse.ICollectedStatementStatistics;
+type IStatementDiagnosticsReport = protos.cockroach.server.serverpb.IStatementDiagnosticsReport;
interface StatementsSummaryData {
statement: string;
@@ -60,11 +62,11 @@ function keyByStatementAndImplicitTxn(stmt: ExecutionStatistics): string {
export const selectStatements = createSelector(
(state: AdminUIState) => state.cachedData.statements,
(_state: AdminUIState, props: RouteComponentProps) => props,
- selectLastDiagnosticsReportPerStatement,
+ selectDiagnosticsReportsPerStatement,
(
state: CachedDataReducerState,
props: RouteComponentProps,
- lastDiagnosticsReportPerStatement,
+ diagnosticsReportsPerStatement,
) => {
if (!state.data) {
return null;
@@ -108,7 +110,7 @@ export const selectStatements = createSelector(
label: stmt.statement,
implicitTxn: stmt.implicitTxn,
stats: combineStatementStats(stmt.stats),
- diagnosticsReport: lastDiagnosticsReportPerStatement[stmt.statement],
+ diagnosticsReports: diagnosticsReportsPerStatement[stmt.statement],
};
});
},
@@ -185,6 +187,7 @@ const StatementsPageConnected = withRouter(connect(
onSearchComplete: (results: AggregateStatistics[]) => trackStatementsSearchAction(results.length),
onPageChanged: trackStatementsPaginationAction,
onSortingChange: trackTableSortAction,
+ onDiagnosticsReportDownload: (report: IStatementDiagnosticsReport) => trackDownloadDiagnosticsBundle(report.statement_fingerprint),
},
)(StatementsPage));
diff --git a/pkg/ui/src/views/statements/statementsTable.tsx b/pkg/ui/src/views/statements/statementsTable.tsx
index 920d4991a142..865316c1f553 100644
--- a/pkg/ui/src/views/statements/statementsTable.tsx
+++ b/pkg/ui/src/views/statements/statementsTable.tsx
@@ -22,6 +22,7 @@ import IStatementDiagnosticsReport = cockroach.server.serverpb.IStatementDiagnos
import { ActivateDiagnosticsModalRef } from "./diagnostics/activateDiagnosticsModal";
import styles from "./statementsTable.module.styl";
import { StatementTableTitle, StatementTableCell, NodeNames } from "./statementsTableContent";
+import { getDiagnosticsStatus } from "src/views/statements/diagnostics";
const cx = classNames.bind(styles);
const longToInt = (d: number | Long) => FixLong(d).toInt();
@@ -78,7 +79,7 @@ export function makeStatementsColumns(
cell: StatementTableCell.diagnostics(activateDiagnosticsRef),
sort: (stmt) => {
if (stmt.diagnosticsReport) {
- return stmt.diagnosticsReport.completed ? "READY" : "WAITING FOR QUERY";
+ return getDiagnosticsStatus(stmt.diagnosticsReport);
}
return null;
},
diff --git a/pkg/ui/src/views/statements/statementsTableContent.tsx b/pkg/ui/src/views/statements/statementsTableContent.tsx
index dc275e1d729d..ef14983b4e9a 100644
--- a/pkg/ui/src/views/statements/statementsTableContent.tsx
+++ b/pkg/ui/src/views/statements/statementsTableContent.tsx
@@ -19,6 +19,7 @@ import { ActivateDiagnosticsModalRef } from "./diagnostics/activateDiagnosticsMo
import { DiagnosticStatusBadge } from "./diagnostics/diagnosticStatusBadge";
import { shortStatement } from "./statementsTable";
import styles from "./statementsTableContent.module.styl";
+import { getDiagnosticsStatus } from "src/views/statements/diagnostics";
export type NodeNames = { [nodeId: string]: string };
@@ -90,7 +91,7 @@ export const StatementTableTitle = {
diagnostics
{" for each statement. If activated, this displays the status of diagnostics collection ("}
- WAITING FOR QUERY
, READY
, OR ERROR
).
+ WAITING
, READY
, OR ERROR
).
}
@@ -202,7 +203,7 @@ export const StatementTableCell = {
),
diagnostics: (activateDiagnosticsRef: React.RefObject