Skip to content

Commit 31e9b59

Browse files
committed
ui: show txn fingerprint details page with unspecified app
Previously, when the app was not specified in the url search params for the txn details fingerprint page, the page would fail to load. This commit allows the page to load when there is no app specified but a fingerprint id that matches the requested page in the payload. The first matching fingerprint id is loaded. Additionally, the TransactionDetailsLink will not include the appNames search param unless the provided prop is non-nullish. Fixes: cockroachdb#107731 Release note (bug fix): Txn fingerprint details page in the console UI should load with the fingerprint details even if no app is specified in the URL.
1 parent 3bbf620 commit 31e9b59

File tree

3 files changed

+69
-27
lines changed

3 files changed

+69
-27
lines changed

pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetailsUtils.spec.tsx

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,68 @@ import { shuffle } from "lodash";
1818
import Long from "long";
1919

2020
describe("getTxnFromSqlStatsTxns", () => {
21-
//TODO
22-
it("should return the first txn with the fingerprint ID and app name specified", () => {
23-
const app = "cockroach";
24-
const txns = [
25-
{ id: 1, app: "hello_world" },
26-
{ id: 2, app },
27-
{ id: 3, app: "cockrooch" },
28-
{ id: 3, app },
29-
{ id: 4, app: "my_app" },
30-
].map(txn =>
31-
mockTxnStats({
32-
stats_data: {
33-
transaction_fingerprint_id: Long.fromInt(txn.id),
34-
app: txn.app,
35-
},
36-
}),
37-
);
21+
it.each([
22+
[
23+
[
24+
{ id: 1, app: "hello_world" },
25+
{ id: 2, app: "cockroach" },
26+
{ id: 3, app: "" },
27+
{ id: 3, app: "cockroach" },
28+
{ id: 3, app: "cockroach" },
29+
{ id: 3, app: "my_app" },
30+
{ id: 4, app: "my_app" },
31+
],
32+
"3", // fingerprint id
33+
["cockroach", "my_app"], // app name
34+
3, // Expected idx.
35+
],
36+
[
37+
[
38+
{ id: 1, app: "hello_world" },
39+
{ id: 2, app: "cockroach_app" },
40+
{ id: 3, app: "" },
41+
{ id: 3, app: "cockroach" },
42+
{ id: 3, app: "my_app" },
43+
{ id: 4, app: "my_app" },
44+
],
45+
"3", // fingerprint id
46+
["cockroach", "my_app"], // app name
47+
3, // Expected idx.
48+
],
49+
[
50+
[
51+
{ id: 1, app: "hello_world" },
52+
{ id: 2, app: "cockroach" },
53+
{ id: 2, app: "cockrooch" },
54+
{ id: 3, app: "cockroach" },
55+
{ id: 4, app: "my_app" },
56+
],
57+
"2", // fingerprint id
58+
null, // app names
59+
1, // Expected idx.
60+
],
61+
])(
62+
"should return the first txn with the fingerprint ID and app name specified",
63+
(
64+
txnsToMock,
65+
fingerprintID: string,
66+
apps: string[] | null,
67+
expectedIdx: number,
68+
) => {
69+
const txns = txnsToMock.map((txn: { id: number; app: string }) =>
70+
mockTxnStats({
71+
stats_data: {
72+
transaction_fingerprint_id: Long.fromInt(txn.id),
73+
app: txn.app,
74+
},
75+
}),
76+
);
3877

39-
const expectedTxn = txns[3];
40-
const txn = getTxnFromSqlStatsTxns(txns, "3", [app]);
41-
expect(txn).toEqual(expectedTxn);
42-
});
78+
const expectedTxn = txns[expectedIdx];
79+
const txn = getTxnFromSqlStatsTxns(txns, fingerprintID, apps);
80+
expect(txn).toEqual(expectedTxn);
81+
},
82+
);
4383

4484
it("should return null if no txn can be found", () => {
4585
const txns = [1, 2, 3, 4, 5, 6].map(txn =>
@@ -60,7 +100,6 @@ describe("getTxnFromSqlStatsTxns", () => {
60100
[null, "123", null],
61101
[null, null, ["app"]],
62102
[[mockTxnStats()], null, null],
63-
[[mockTxnStats()], "123", null],
64103
[[mockTxnStats()], "123", []],
65104
[[mockTxnStats()], null, ["app"]],
66105
[[mockTxnStats()], "", ["app"]],

pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetailsUtils.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ export const getTxnFromSqlStatsTxns = (
4141
txnFingerprintID: string | null,
4242
apps: string[] | null,
4343
): Transaction | null => {
44-
if (!txns?.length || !apps?.length || !txnFingerprintID) {
44+
if (!txns?.length || !txnFingerprintID) {
4545
return null;
4646
}
4747

4848
return txns.find(
4949
txn =>
5050
txn.stats_data.transaction_fingerprint_id.toString() ===
5151
txnFingerprintID &&
52-
(apps.length ? apps.includes(txn.stats_data.app ?? unset) : true),
52+
(apps?.length ? apps.includes(txn.stats_data.app ?? unset) : true),
5353
);
5454
};
5555

pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,12 @@ interface TransactionLinkTargetProps {
8282
export const TransactionLinkTarget = (
8383
props: TransactionLinkTargetProps,
8484
): string => {
85-
const searchParams = propsToQueryString({
86-
[appNamesAttr]: [props.application],
87-
});
85+
let searchParams = "";
86+
if (props.application != null) {
87+
searchParams = propsToQueryString({
88+
[appNamesAttr]: [props.application],
89+
});
90+
}
8891

8992
return `/transaction/${props.transactionFingerprintId}?${searchParams}`;
9093
};

0 commit comments

Comments
 (0)