Skip to content

Commit 3056a51

Browse files
matt-aitkensamejr
andauthored
Query improvements (#2905)
What changed - Upgraded recharts to 2.15.2 - Added multiple chart types and components: big number, line, stacked, bar (including zoomable & reference line), big dataset bar, and usage graph - Implemented custom legend with animated values, tooltip showing x-axis data, and hover/highlight behaviors for stacks and legend - Added loading, no-data, and invalid chart states plus loading spinners and improved loading animations/layout - Storybook integration: initial charts setup, separate chart files, alphabetized menu, chart state toggles, and story updates - Interaction & UX improvements: zooming (drag/select), crosshair pointer, show/select dates while zooming, prevent text selection on drag, hide mouse wheel zoom, capped legend items, axis/legend styling tweaks, better spacing, and min-height for charts - Data & state handling: moved date data to route for unified zooming, moved chartState to main Chart component, moved hard-coded/mock data out of components, and set chart data when zooming to start/end dates - Performance & animation: turned off/reduced chart animations, sped up animated numbers, removed hover transitions for bars - New UI primitives and layout: Card component, small card updates, SVG icons, improved segmented control and popover variants, table improvements (resizable columns, filtering, sorting, scrolling fixes) - Various fixes and polish: tooltip style fixes, legend value updates, hover/leave state resets, bar width fixes for small datasets, type/import fixes, and numerous small style/typo tweaks --------- Co-authored-by: James Ritchie <james@trigger.dev>
1 parent 23ec5ff commit 3056a51

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+7863
-2394
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
export function AbacusIcon({ className }: { className?: string }) {
2+
return (
3+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
4+
<g clipPath="url(#clip0_16909_120578)">
5+
<path
6+
d="M4 3V21"
7+
stroke="currentColor"
8+
strokeWidth="2"
9+
strokeLinecap="round"
10+
strokeLinejoin="round"
11+
/>
12+
<path
13+
d="M20 21V3"
14+
stroke="currentColor"
15+
strokeWidth="2"
16+
strokeLinecap="round"
17+
strokeLinejoin="round"
18+
/>
19+
<path
20+
d="M8 5L8 6"
21+
stroke="currentColor"
22+
strokeWidth="2"
23+
strokeLinecap="round"
24+
strokeLinejoin="round"
25+
/>
26+
<path
27+
d="M14 5L14 6"
28+
stroke="currentColor"
29+
strokeWidth="2"
30+
strokeLinecap="round"
31+
strokeLinejoin="round"
32+
/>
33+
<path
34+
d="M15 10L15 11"
35+
stroke="currentColor"
36+
strokeWidth="2"
37+
strokeLinecap="round"
38+
strokeLinejoin="round"
39+
/>
40+
<path
41+
d="M9 10L9 11"
42+
stroke="currentColor"
43+
strokeWidth="2"
44+
strokeLinecap="round"
45+
strokeLinejoin="round"
46+
/>
47+
<path
48+
d="M12 15L12 16"
49+
stroke="currentColor"
50+
strokeWidth="2"
51+
strokeLinecap="round"
52+
strokeLinejoin="round"
53+
/>
54+
<path
55+
d="M8 15L8 16"
56+
stroke="currentColor"
57+
strokeWidth="2"
58+
strokeLinecap="round"
59+
strokeLinejoin="round"
60+
/>
61+
<path
62+
d="M3 21H21"
63+
stroke="currentColor"
64+
strokeWidth="2"
65+
strokeLinecap="round"
66+
strokeLinejoin="round"
67+
/>
68+
</g>
69+
</svg>
70+
);
71+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export function ArrowTopRightBottomLeftIcon({ className }: { className?: string }) {
2+
return (
3+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
4+
<path
5+
d="M14.8258 10.5L20.125 5.20083V8.5625C20.125 9.08027 20.5447 9.5 21.0625 9.5C21.5803 9.5 22 9.08027 22 8.5625V2.9375C22 2.41973 21.5803 2 21.0625 2H15.4375C14.9197 2 14.5 2.41973 14.5 2.9375C14.5 3.45527 14.9197 3.875 15.4375 3.875H18.7992L13.5 9.17417C13.1339 9.54029 13.1339 10.1339 13.5 10.5C13.8661 10.8661 14.4597 10.8661 14.8258 10.5Z"
6+
fill="currentColor"
7+
/>
8+
<path
9+
d="M2 21.0625V15.4375C2 14.9197 2.41973 14.5 2.9375 14.5C3.45527 14.5 3.875 14.9197 3.875 15.4375V18.7992L9.17417 13.5C9.54029 13.1339 10.1339 13.1339 10.5 13.5C10.8661 13.8661 10.8661 14.4597 10.5 14.8258L5.20083 20.125H8.5625C9.08027 20.125 9.5 20.5447 9.5 21.0625C9.5 21.5803 9.08027 22 8.5625 22H2.9375C2.69757 22 2.45765 21.9085 2.27459 21.7254C2.1847 21.6355 2.11689 21.5319 2.07114 21.4214C2.0253 21.3108 2 21.1896 2 21.0625Z"
10+
fill="currentColor"
11+
/>
12+
<path
13+
d="M14.8258 10.5L20.125 5.20083V10C20.125 10.5178 20.5447 10.9375 21.0625 10.9375C21.5803 10.9375 22 10.5178 22 10V2.9375C22 2.41973 21.5803 2 21.0625 2H14C13.4822 2 13.0625 2.41973 13.0625 2.9375C13.0625 3.45527 13.4822 3.875 14 3.875H18.7992L13.5 9.17417C13.1339 9.54029 13.1339 10.1339 13.5 10.5C13.8661 10.8661 14.4597 10.8661 14.8258 10.5Z"
14+
fill="currentColor"
15+
/>
16+
<path
17+
d="M2 21.0625V13.9375C2 13.4197 2.41973 13 2.9375 13C3.45527 13 3.875 13.4197 3.875 13.9375V18.7992L9.17417 13.5C9.54029 13.1339 10.1339 13.1339 10.5 13.5C10.8661 13.8661 10.8661 14.4597 10.5 14.8258L5.20083 20.125H10.0625C10.5803 20.125 11 20.5447 11 21.0625C11 21.5803 10.5803 22 10.0625 22H2.9375C2.69757 22 2.45765 21.9085 2.27459 21.7254C2.1847 21.6355 2.11689 21.5319 2.07114 21.4214C2.0253 21.3108 2 21.1896 2 21.0625Z"
18+
fill="currentColor"
19+
/>
20+
</svg>
21+
);
22+
}

apps/webapp/app/components/code/AIQueryInput.tsx

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,22 @@ import { Spinner } from "~/components/primitives/Spinner";
1818
import { useEnvironment } from "~/hooks/useEnvironment";
1919
import { useOrganization } from "~/hooks/useOrganizations";
2020
import { useProject } from "~/hooks/useProject";
21+
import type { AITimeFilter } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/types";
2122
import { cn } from "~/utils/cn";
2223

2324
type StreamEventType =
2425
| { type: "thinking"; content: string }
2526
| { type: "tool_call"; tool: string; args: unknown }
26-
| { type: "result"; success: true; query: string }
27+
| { type: "time_filter"; filter: AITimeFilter }
28+
| { type: "result"; success: true; query: string; timeFilter?: AITimeFilter }
2729
| { type: "result"; success: false; error: string };
2830

2931
export type AIQueryMode = "new" | "edit";
3032

3133
interface AIQueryInputProps {
3234
onQueryGenerated: (query: string) => void;
35+
/** Called when the AI sets a time filter - updates URL search params */
36+
onTimeFilterChange?: (filter: AITimeFilter) => void;
3337
/** Set this to a prompt to auto-populate and immediately submit */
3438
autoSubmitPrompt?: string;
3539
/** Change this to force re-submission even if prompt is the same */
@@ -40,6 +44,7 @@ interface AIQueryInputProps {
4044

4145
export function AIQueryInput({
4246
onQueryGenerated,
47+
onTimeFilterChange,
4348
autoSubmitPrompt,
4449
autoSubmitKey,
4550
getCurrentQuery,
@@ -174,10 +179,32 @@ export function AIQueryInput({
174179
setThinking((prev) => prev + event.content);
175180
break;
176181
case "tool_call":
177-
setThinking((prev) => prev + `\nValidating query...\n`);
182+
if (event.tool === "setTimeFilter") {
183+
setThinking((prev) => {
184+
if (prev.trimEnd().endsWith("Setting time filter...")) {
185+
return prev;
186+
}
187+
return prev + `\nSetting time filter...\n`;
188+
});
189+
} else {
190+
setThinking((prev) => {
191+
if (prev.trimEnd().endsWith("Validating query...")) {
192+
return prev;
193+
}
194+
return prev + `\nValidating query...\n`;
195+
});
196+
}
197+
break;
198+
case "time_filter":
199+
// Apply time filter immediately when the AI sets it
200+
onTimeFilterChange?.(event.filter);
178201
break;
179202
case "result":
180203
if (event.success) {
204+
// Apply time filter if included in result (backup in case time_filter event was missed)
205+
if (event.timeFilter) {
206+
onTimeFilterChange?.(event.timeFilter);
207+
}
181208
onQueryGenerated(event.query);
182209
setPrompt("");
183210
setLastResult("success");
@@ -189,7 +216,7 @@ export function AIQueryInput({
189216
break;
190217
}
191218
},
192-
[onQueryGenerated]
219+
[onQueryGenerated, onTimeFilterChange]
193220
);
194221

195222
const handleSubmit = useCallback(
@@ -359,10 +386,10 @@ export function AIQueryInput({
359386
{isLoading
360387
? "AI is thinking..."
361388
: lastResult === "success"
362-
? "Query generated"
363-
: lastResult === "error"
364-
? "Generation failed"
365-
: "AI response"}
389+
? "Query generated"
390+
: lastResult === "error"
391+
? "Generation failed"
392+
: "AI response"}
366393
</span>
367394
</div>
368395
{isLoading ? (

0 commit comments

Comments
 (0)