Skip to content

Commit

Permalink
Style DB queries on the front-end
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-johansson authored and eandre committed Sep 21, 2022
1 parent 1c981ce commit 43a88f0
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 17 deletions.
15 changes: 15 additions & 0 deletions cli/daemon/dash/dashapp/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,18 @@ global.getByTextContent = (text) => {
return elementHasText && childrenDontHaveText;
});
};

Range.prototype.getBoundingClientRect = () => ({
bottom: 0,
height: 0,
left: 0,
right: 0,
top: 0,
width: 0,
});

Range.prototype.getClientRects = () => ({
item: () => null,
length: 0,
[Symbol.iterator]: jest.fn(),
});
34 changes: 17 additions & 17 deletions cli/daemon/dash/dashapp/src/components/trace/SpanDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
} from "./model";
import { latencyStr, svcColor } from "./util";
import CM from "~c/api/cm/CM";
import { ModeSpec, ModeSpecOptions } from "codemirror";

interface Props {
trace: Trace;
Expand Down Expand Up @@ -89,7 +90,7 @@ const SpanDetail: FunctionComponent<Props> = (props) => {
</span>
</div>

<div className="wrap [&>*]:basis-1/5 flex w-full flex-row flex-wrap py-3 [&>*]:min-w-[150px] [&>*]:pb-2">
<div className="wrap flex w-full flex-row flex-wrap py-3 [&>*]:min-w-[150px] [&>*]:basis-1/5 [&>*]:pb-2">
<div className="body-sm flex items-center">
<div>{icons.clock("h-5 w-auto")}</div>
<span className="mx-1 font-semibold">
Expand Down Expand Up @@ -441,6 +442,7 @@ const GoroutineDetail: FunctionComponent<{
.${clsid}:hover { background-color: ${color}; }
`}</style>
<div
data-testid={clsid}
className={`absolute ${clsid}`}
onMouseEnter={(e) => setHover(e, ev)}
onMouseLeave={(e) => setHover(e, null)}
Expand Down Expand Up @@ -554,6 +556,7 @@ const GoroutineDetail: FunctionComponent<{
</div>
</div>
<div
data-testid="trace-tooltip"
ref={tooltipRef}
className="absolute z-40 w-full max-w-md pr-2"
style={{
Expand Down Expand Up @@ -623,7 +626,7 @@ const PubsubPublishTooltip: FunctionComponent<{
? latencyStr(publish.end_time - publish.start_time)
: "Unknown"}
<button
className="focus:outline-none -mr-1"
className="-mr-1 focus:outline-none"
onClick={() => props.onStackTrace(publish.stack)}
>
{icons.stackTrace("m-1 h-4 w-auto")}
Expand Down Expand Up @@ -764,7 +767,7 @@ const DBQueryTooltip: FunctionComponent<{
<div className="text-gray-500 ml-auto flex items-center text-sm font-normal">
{q.end_time ? latencyStr(q.end_time - q.start_time) : "Unknown"}
<button
className="focus:outline-none -mr-1"
className="-mr-1 focus:outline-none"
onClick={() => props.onStackTrace(q.stack)}
>
{icons.stackTrace("m-1 h-4 w-auto")}
Expand All @@ -776,16 +779,7 @@ const DBQueryTooltip: FunctionComponent<{
<h4 className="text-gray-300 mb-2 font-sans text-xs font-semibold uppercase leading-3 tracking-wider">
Query
</h4>
{q.html_query !== null ? (
<pre
className="border-gray-200 overflow-auto rounded border bg-[#fff] p-2 text-sm"
dangerouslySetInnerHTML={{ __html: decodeBase64(q.html_query) }}
/>
) : (
<pre className="border-gray-200 overflow-auto rounded border bg-black p-2 text-sm text-white">
{decodeBase64(q.query)}
</pre>
)}
{renderData([q.query], "sql")}
</div>

<div className="mt-4">
Expand Down Expand Up @@ -831,7 +825,7 @@ const RPCCallTooltip: FunctionComponent<{
<div className="text-gray-500 ml-auto flex items-center text-sm font-normal">
{c.end_time ? latencyStr(c.end_time - c.start_time) : "Unknown"}
<button
className="focus:outline-none -mr-1"
className="-mr-1 focus:outline-none"
onClick={() => props.onStackTrace(c.stack)}
>
{icons.stackTrace("m-1 h-4 w-auto")}
Expand Down Expand Up @@ -997,7 +991,13 @@ const HTTPCallTooltip: FunctionComponent<{
);
};

const renderData = (data: Base64EncodedBytes[]) => {
const renderData = (
data: Base64EncodedBytes[],
mode: string | ModeSpec<ModeSpecOptions> = {
name: "javascript",
json: true,
}
) => {
const raw = decodeBase64(data[0]);
let pretty = raw;
try {
Expand All @@ -1014,7 +1014,7 @@ const renderData = (data: Base64EncodedBytes[]) => {
value: pretty,
readOnly: true,
theme: "encore",
mode: { name: "javascript", json: true },
mode: mode,
}}
noShadow={true}
/>
Expand Down Expand Up @@ -1095,7 +1095,7 @@ const renderLog = (
return (
<div key={key} className="flex items-center gap-x-1.5">
<button
className="focus:outline-none -ml-2 -mr-1"
className="-ml-2 -mr-1 focus:outline-none"
onClick={() => onStackTrace(log.stack)}
>
{icons.stackTrace("m-1 h-4 w-auto")}
Expand Down
139 changes: 139 additions & 0 deletions cli/daemon/dash/dashapp/src/components/trace/SpanDetails.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import SpanDetail from "~c/trace/SpanDetail";
import userEvent from "@testing-library/user-event";

describe("SpanDetails", () => {
it("should show correctly styled SQL code when hovering over trace", async () => {
const trace = {
id: "3c326bf5-9742-13b6-c6c7-a6f867390aed",
date: "2022-09-21T13:40:52.031442+02:00",
start_time: 0,
end_time: 818993,
root: {
id: "4922198311992459089",
type: "RPC",
parent_id: null,
goid: 1,
start_time: 0,
end_time: 818993,
svc_name: "user",
rpc_name: "Read",
topic_name: "",
subscriber_name: "",
msg_id: "",
attempt: 0,
published: null,
call_loc: null,
def_loc: 32,
inputs: ["IjprZXki"],
outputs: ["ewogICJLZXkiOiAiOmtleSIsCiAgIlZhbHVlIjogIjp2YWx1ZSIKfQ=="],
err: null,
err_stack: null,
events: [
{
type: "DBQuery",
goid: 1,
txid: null,
call_loc: 0,
start_time: 4041,
end_time: 816712,
query:
"U0VMRUNUIGtleSwgdmFsdWUgRlJPTSAia2V5X3ZhbHVlcyIgV0hFUkUga2V5PSQx",
html_query:
"PHByZSB0YWJpbmRleD0iMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6I2ZmZjsiPjxjb2RlPjxzcGFuIHN0eWxlPSJkaXNwbGF5OmZsZXg7Ij48c3Bhbj48c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+U0VMRUNUPC9zcGFuPiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+a2V5PC9zcGFuPiwgPHNwYW4gc3R5bGU9ImNvbG9yOiMwMGYiPnZhbHVlPC9zcGFuPiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+RlJPTTwvc3Bhbj4gPHNwYW4gc3R5bGU9ImNvbG9yOiNhMzE1MTUiPjwvc3Bhbj48c3BhbiBzdHlsZT0iY29sb3I6I2EzMTUxNSI+JiMzNDs8L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiNhMzE1MTUiPmtleV92YWx1ZXM8L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiNhMzE1MTUiPiYjMzQ7PC9zcGFuPiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+V0hFUkU8L3NwYW4+IDxzcGFuIHN0eWxlPSJjb2xvcjojMDBmIj5rZXk8L3NwYW4+PSQxPC9zcGFuPjwvc3Bhbj48L2NvZGU+PC9wcmU+",
err: null,
stack: {
frames: [],
},
},
],
children: [],
},
auth: null,
uid: null,
user_data: null,
locations: {
"32": {
id: 32,
filepath: "user/read.go",
start_pos: 513,
end_pos: 578,
src_line_start: 33,
src_line_end: 33,
src_col_start: 1,
src_col_end: 66,
rpc_def: {
service_name: "user",
rpc_name: "Read",
context:
"func Read(ctx context.Context, key string) (*KeyValuePair, error)",
},
},
},
meta: {
svcs: [],
},
};
const req = {
id: "4922198311992459089",
type: "RPC",
parent_id: null,
goid: 1,
start_time: 0,
end_time: 818993,
svc_name: "user",
rpc_name: "Read",
topic_name: "",
subscriber_name: "",
msg_id: "",
attempt: 0,
published: null,
call_loc: null,
def_loc: 32,
inputs: ["IjprZXki"],
outputs: ["ewogICJLZXkiOiAiOmtleSIsCiAgIlZhbHVlIjogIjp2YWx1ZSIKfQ=="],
err: null,
err_stack: null,
events: [
{
type: "DBQuery",
goid: 1,
txid: null,
call_loc: 0,
start_time: 4041,
end_time: 816712,
query:
"U0VMRUNUIGtleSwgdmFsdWUgRlJPTSAia2V5X3ZhbHVlcyIgV0hFUkUga2V5PSQx",
html_query:
"PHByZSB0YWJpbmRleD0iMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6I2ZmZjsiPjxjb2RlPjxzcGFuIHN0eWxlPSJkaXNwbGF5OmZsZXg7Ij48c3Bhbj48c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+U0VMRUNUPC9zcGFuPiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+a2V5PC9zcGFuPiwgPHNwYW4gc3R5bGU9ImNvbG9yOiMwMGYiPnZhbHVlPC9zcGFuPiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+RlJPTTwvc3Bhbj4gPHNwYW4gc3R5bGU9ImNvbG9yOiNhMzE1MTUiPjwvc3Bhbj48c3BhbiBzdHlsZT0iY29sb3I6I2EzMTUxNSI+JiMzNDs8L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiNhMzE1MTUiPmtleV92YWx1ZXM8L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiNhMzE1MTUiPiYjMzQ7PC9zcGFuPiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwZiI+V0hFUkU8L3NwYW4+IDxzcGFuIHN0eWxlPSJjb2xvcjojMDBmIj5rZXk8L3NwYW4+PSQxPC9zcGFuPjwvc3Bhbj48L2NvZGU+PC9wcmU+",
err: null,
stack: {
frames: [],
},
},
],
children: [],
};

render(
<SpanDetail
trace={trace as any}
req={req as any}
onStackTrace={() => {}}
/>
);

const traceBar = screen.getByTestId("ev-4922198311992459089-1-0");
await userEvent.hover(traceBar);

await waitFor(() => {
const tooltipEl = screen.getByTestId("trace-tooltip");
const divEl = tooltipEl.querySelector(".CodeMirror.cm-s-encore");

expect(divEl!.textContent).toEqual(
'SELECT key, value FROM "key_values" WHERE key=$1'
);
});
});
});

0 comments on commit 43a88f0

Please sign in to comment.