Skip to content

Commit c777d65

Browse files
committed
Improve Table schema and Examples tabs in the query feature for multiple tables
1 parent 5b4a32f commit c777d65

File tree

2 files changed

+95
-18
lines changed

2 files changed

+95
-18
lines changed

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/ExamplesContent.tsx

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import { useState } from "react";
12
import { Header3 } from "~/components/primitives/Headers";
23
import { Paragraph } from "~/components/primitives/Paragraph";
4+
import SegmentedControl from "~/components/primitives/SegmentedControl";
35
import type { QueryScope } from "~/services/queryService.server";
6+
import { querySchemas } from "~/v3/querySchemas";
47
import { TryableCodeBlock } from "./TRQLGuideContent";
58

69
// Example queries for the Examples tab
@@ -9,6 +12,7 @@ export const exampleQueries: Array<{
912
description: string;
1013
query: string;
1114
scope: QueryScope;
15+
table: string;
1216
}> = [
1317
{
1418
title: "Failed runs by task (past 7 days)",
@@ -23,6 +27,7 @@ GROUP BY task_identifier
2327
ORDER BY failed_count DESC
2428
LIMIT 20`,
2529
scope: "environment",
30+
table: "runs",
2631
},
2732
{
2833
title: "Execution duration p50 by task (past 7d)",
@@ -37,6 +42,7 @@ GROUP BY task_identifier
3742
ORDER BY p50_duration_ms DESC
3843
LIMIT 20`,
3944
scope: "environment",
45+
table: "runs",
4046
},
4147
{
4248
title: "Runs over time",
@@ -50,6 +56,7 @@ GROUP BY timeBucket
5056
ORDER BY timeBucket
5157
LIMIT 1000`,
5258
scope: "environment",
59+
table: "runs",
5360
},
5461
{
5562
title: "Most expensive 100 runs (past 7d)",
@@ -67,17 +74,75 @@ WHERE triggered_at > now() - INTERVAL 7 DAY
6774
ORDER BY total_cost DESC
6875
LIMIT 100`,
6976
scope: "environment",
77+
table: "runs",
78+
},
79+
{
80+
title: "CPU utilization over time",
81+
description: "Track process CPU utilization bucketed over time.",
82+
query: `SELECT
83+
timeBucket(),
84+
avg(value) AS avg_cpu
85+
FROM metrics
86+
WHERE metric_name = 'process.cpu.utilization'
87+
GROUP BY timeBucket
88+
ORDER BY timeBucket
89+
LIMIT 1000`,
90+
scope: "environment",
91+
table: "metrics",
92+
},
93+
{
94+
title: "Memory usage by task (past 7d)",
95+
description: "Average memory usage per task identifier over the last 7 days.",
96+
query: `SELECT
97+
task_identifier,
98+
avg(value) AS avg_memory
99+
FROM metrics
100+
WHERE metric_name = 'system.memory.usage'
101+
AND bucket_start > now() - INTERVAL 7 DAY
102+
GROUP BY task_identifier
103+
ORDER BY avg_memory DESC
104+
LIMIT 20`,
105+
scope: "environment",
106+
table: "metrics",
107+
},
108+
{
109+
title: "Available metric names",
110+
description: "List all distinct metric names collected in your environment.",
111+
query: `SELECT
112+
metric_name,
113+
count() AS sample_count
114+
FROM metrics
115+
GROUP BY metric_name
116+
ORDER BY sample_count DESC
117+
LIMIT 100`,
118+
scope: "environment",
119+
table: "metrics",
70120
},
71121
];
72122

123+
const tableOptions = querySchemas.map((s) => ({ label: s.name, value: s.name }));
124+
73125
export function ExamplesContent({
74126
onTryExample,
75127
}: {
76128
onTryExample: (query: string, scope: QueryScope) => void;
77129
}) {
130+
const [selectedTable, setSelectedTable] = useState(querySchemas[0].name);
131+
const filtered = exampleQueries.filter((e) => e.table === selectedTable);
132+
78133
return (
79134
<div className="space-y-6">
80-
{exampleQueries.map((example) => (
135+
<div className="sticky top-0 z-10 bg-background-bright pb-3">
136+
<SegmentedControl
137+
name="examples-table-selector"
138+
value={selectedTable}
139+
options={tableOptions}
140+
variant="secondary/small"
141+
fullWidth
142+
onChange={setSelectedTable}
143+
/>
144+
</div>
145+
{filtered.map((example) => (
81146
<div key={example.title}>
82147
<Header3 className="mb-1 text-text-bright">{example.title}</Header3>
83148
<Paragraph variant="small" className="mb-2 text-text-dimmed">

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/TableSchemaContent.tsx

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { useState } from "react";
12
import type { ColumnSchema } from "@internal/tsql";
23
import { Badge } from "~/components/primitives/Badge";
34
import { CopyableText } from "~/components/primitives/CopyableText";
45
import { Header3 } from "~/components/primitives/Headers";
56
import { Paragraph } from "~/components/primitives/Paragraph";
7+
import SegmentedControl from "~/components/primitives/SegmentedControl";
68
import { querySchemas } from "~/v3/querySchemas";
79

810
function ColumnHelpItem({ col }: { col: ColumnSchema }) {
@@ -42,26 +44,36 @@ function ColumnHelpItem({ col }: { col: ColumnSchema }) {
4244
);
4345
}
4446

47+
const tableOptions = querySchemas.map((s) => ({ label: s.name, value: s.name }));
48+
4549
export function TableSchemaContent() {
50+
const [selectedTable, setSelectedTable] = useState(querySchemas[0].name);
51+
const table = querySchemas.find((s) => s.name === selectedTable) ?? querySchemas[0];
52+
4653
return (
4754
<div>
48-
{querySchemas.map((table) => (
49-
<div key={table.name} className="mb-6">
50-
<div className="mb-2">
51-
<Header3 className="font-mono text-text-bright">{table.name}</Header3>
52-
{table.description && (
53-
<Paragraph variant="small" className="mt-1 text-text-dimmed">
54-
{table.description}
55-
</Paragraph>
56-
)}
57-
</div>
58-
<div className="flex flex-col gap-2 divide-y divide-grid-dimmed">
59-
{Object.values(table.columns).map((col) => (
60-
<ColumnHelpItem key={col.name} col={col} />
61-
))}
62-
</div>
63-
</div>
64-
))}
55+
<div className="sticky top-0 z-10 bg-background-bright pb-3">
56+
<SegmentedControl
57+
name="table-schema-selector"
58+
value={selectedTable}
59+
options={tableOptions}
60+
variant="secondary/small"
61+
fullWidth
62+
onChange={setSelectedTable}
63+
/>
64+
</div>
65+
<div className="mb-2">
66+
{table.description && (
67+
<Paragraph variant="small" className="text-text-dimmed">
68+
{table.description}
69+
</Paragraph>
70+
)}
71+
</div>
72+
<div className="flex flex-col gap-2 divide-y divide-grid-dimmed">
73+
{Object.values(table.columns).map((col) => (
74+
<ColumnHelpItem key={col.name} col={col} />
75+
))}
76+
</div>
6577
</div>
6678
);
6779
}

0 commit comments

Comments
 (0)