Skip to content

Commit 9e272e2

Browse files
authored
Merge branch 'main' into metrics-card
2 parents 126f0fb + 7e3bf3f commit 9e272e2

54 files changed

Lines changed: 1108 additions & 224 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"use client";
2+
3+
import { useRouter } from "next/navigation";
4+
import { useEffect } from "react";
5+
import { STORAGE_KEYS } from "@/lib/auth";
6+
7+
const FALLBACK_PATH = "/";
8+
9+
export default function AuthCallback() {
10+
const router = useRouter();
11+
12+
useEffect(() => {
13+
const returnTo =
14+
sessionStorage.getItem(STORAGE_KEYS.AUTH_RETURN_TO) ?? FALLBACK_PATH;
15+
sessionStorage.removeItem(STORAGE_KEYS.AUTH_RETURN_TO);
16+
17+
const search = window.location.search;
18+
router.replace(`${returnTo}${search}`);
19+
}, [router]);
20+
21+
return null;
22+
}

apps/apollo-vertex/app/patterns/notifications/in-product/notification-examples.tsx

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import {
55
InfoIcon,
66
OctagonXIcon,
77
TriangleAlertIcon,
8-
XIcon,
98
} from "lucide-react";
10-
import { type ReactNode, useEffect, useRef, useState } from "react";
9+
import { useEffect, useRef, useState } from "react";
1110
import { toast } from "sonner";
1211

1312
import { Alert, AlertDescription, AlertTitle } from "@/registry/alert/alert";
@@ -106,65 +105,37 @@ export function AlertExamples() {
106105
);
107106
}
108107

109-
function DismissibleAlert({
110-
children,
111-
status,
112-
visual = "outline",
113-
}: {
114-
children: ReactNode;
115-
status: "default" | "warning" | "error";
116-
visual?: "outline" | "tinted";
117-
}) {
118-
const [visible, setVisible] = useState(true);
119-
if (!visible) return null;
120-
return (
121-
<div className="relative">
122-
<Alert status={status} visual={visual}>
123-
{children}
124-
</Alert>
125-
<button
126-
type="button"
127-
onClick={() => setVisible(false)}
128-
className="absolute top-3 right-3 rounded-sm opacity-70 hover:opacity-100 transition-opacity"
129-
aria-label="Dismiss"
130-
>
131-
<XIcon className="h-4 w-4" />
132-
</button>
133-
</div>
134-
);
135-
}
136-
137108
export function AlertOutlineExamples() {
138109
const [resetKey, setResetKey] = useState(0);
139110

140111
return (
141112
<div className="space-y-3" key={resetKey}>
142-
<DismissibleAlert status="default">
113+
<Alert status="default" visual="outline" dismissible>
143114
<InfoIcon className="h-4 w-4" />
144115
<AlertTitle>New version available</AlertTitle>
145116
<AlertDescription>
146117
A new version of the platform is ready. Review the changelog for
147118
details.
148119
</AlertDescription>
149-
</DismissibleAlert>
120+
</Alert>
150121

151-
<DismissibleAlert status="warning">
122+
<Alert status="warning" visual="outline" dismissible>
152123
<TriangleAlertIcon className="h-4 w-4" />
153124
<AlertTitle>API rate limit approaching</AlertTitle>
154125
<AlertDescription>
155126
You have used 90% of your monthly API quota. Consider upgrading your
156127
plan.
157128
</AlertDescription>
158-
</DismissibleAlert>
129+
</Alert>
159130

160-
<DismissibleAlert status="error">
131+
<Alert status="error" visual="outline" dismissible>
161132
<OctagonXIcon className="h-4 w-4" />
162133
<AlertTitle>Connection failed</AlertTitle>
163134
<AlertDescription>
164135
Unable to reach the server. Check your network connection and try
165136
again.
166137
</AlertDescription>
167-
</DismissibleAlert>
138+
</Alert>
168139

169140
<button
170141
type="button"

apps/apollo-vertex/app/shadcn-components/alert/page.mdx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,27 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
6161
</Alert>
6262
```
6363

64+
### Dismissible
65+
66+
```tsx
67+
<Alert status="warning" visual="outline" dismissible onDismiss={() => console.log("dismissed")}>
68+
<TriangleAlertIcon className="h-4 w-4" />
69+
<AlertTitle>API rate limit approaching</AlertTitle>
70+
<AlertDescription>
71+
You have used 90% of your monthly API quota. Consider upgrading your plan.
72+
</AlertDescription>
73+
</Alert>
74+
```
75+
6476
### Props
6577

6678
| Prop | Type | Default | Description |
6779
|---|---|---|---|
6880
| `status` | `"default" \| "warning" \| "error"` || Sets the semantic status color |
6981
| `visual` | `"outline" \| "tinted"` || Sets the visual treatment |
7082
| `variant` | `"default" \| "destructive"` | `"default"` | Legacy shadcn variant (use `status` + `visual` instead) |
83+
| `dismissible` | `boolean` | `false` | Renders a close button and manages internal visibility |
84+
| `onDismiss` | `() => void` || Callback fired when the alert is dismissed |
7185

7286
## Complex alert patterns (edge cases)
7387

apps/apollo-vertex/app/shadcn-components/button/page.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ Displays a button or a component that looks like a button.
88
<div className="p-4 border rounded-lg mt-4 flex flex-wrap gap-2">
99
<Button>Default</Button>
1010
<Button variant="secondary">Secondary</Button>
11-
<Button variant="destructive">Destructive</Button>
1211
<Button variant="outline">Outline</Button>
1312
<Button variant="ghost">Ghost</Button>
13+
<Button variant="destructive">Destructive</Button>
14+
<Button variant="destructive-outline">Destructive outline</Button>
1415
<Button variant="link">Link</Button>
1516
</div>
1617

apps/apollo-vertex/app/vertex-components/ai-chat/page.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ The `model.vendor` field controls wire-format differences:
158158

159159
Return a choices object as a tool result content to render interactive suggestion buttons. Buttons disappear after the user sends another message.
160160

161+
> **Try it out** — type *"give me some choices"* in the demo above to see suggestion buttons in action. The demo uses the `presentChoices` example tool defined in `examples/choices-tool.ts`.
162+
161163
The choices format:
162164
```json
163165
{

apps/apollo-vertex/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"format:check": "biome format",
1616
"lint": "oxlint",
1717
"lint:fix": "oxlint --fix",
18-
"lint:deps": "depcruise registry --config .dependency-cruiser.js"
18+
"lint:deps": "depcruise registry --config .dependency-cruiser.js",
19+
"typecheck": "tsc --noEmit"
1920
},
2021
"keywords": [],
2122
"author": "",

apps/apollo-vertex/registry/ai-chat/components/ai-chat-message.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export function AiChatMessage({
2929
const displayName = assistantName ?? t("ai_assistant");
3030
const displayContent = getDisplayText(message);
3131

32+
// Don't render assistant messages if they have no text content and no children (e.g. calling tools)
33+
if (!isUser && !displayContent && !children) {
34+
return null;
35+
}
36+
3237
if (isUser) {
3338
return (
3439
<div className="flex w-full justify-end">

apps/apollo-vertex/registry/ai-chat/components/ai-chat.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ export function AiChat({
5656

5757
const latestChoices = findLatestChoices(messages);
5858

59-
const lastMessageIsAssistant = messages.at(-1)?.role === "assistant";
60-
const showLoadingIndicator = isLoading && !lastMessageIsAssistant;
59+
const lastMessage = messages.at(-1);
60+
const lastAssistantHasText =
61+
lastMessage?.role === "assistant" &&
62+
lastMessage.parts.some((p) => p.type === "text" && p.content);
63+
const showLoadingIndicator = isLoading && !lastAssistantHasText;
6164

6265
const defaultEmptyState = (
6366
<div className="flex flex-col items-center justify-center h-full text-center text-muted-foreground">
@@ -89,7 +92,7 @@ export function AiChat({
8992
<div
9093
role="alert"
9194
aria-live="assertive"
92-
className="mx-4 mb-2 flex items-start gap-2 rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive"
95+
className="mx-4 mb-2 flex items-start gap-2 rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive max-h-16 overflow-y-auto"
9396
>
9497
<AlertCircle
9598
className="h-4 w-4 flex-shrink-0 mt-0.5"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { toolDefinition } from "@tanstack/ai";
2+
import { clientTools } from "@tanstack/ai-client";
3+
import { z } from "zod";
4+
5+
const choiceOptionSchema = z.object({
6+
id: z.string().describe("Unique identifier for this option"),
7+
label: z.string().describe("Button text shown to the user"),
8+
value: z.string().optional().describe("Optional payload sent when selected"),
9+
recommended: z
10+
.boolean()
11+
.optional()
12+
.describe("Highlight this option as the recommended choice"),
13+
});
14+
15+
const presentChoicesInput = z.object({
16+
prompt: z.string().describe("Short label shown above the choice buttons"),
17+
options: z
18+
.array(choiceOptionSchema)
19+
.min(2)
20+
.max(4)
21+
.describe("2 to 4 options for the user to pick from"),
22+
});
23+
24+
const presentChoicesOutput = presentChoicesInput.extend({
25+
type: z.literal("choices"),
26+
});
27+
28+
const presentChoicesDef = toolDefinition({
29+
name: "presentChoices",
30+
description: `Present the user with 2–4 clickable choices.
31+
Call this tool whenever the user asks for choices, options, or wants to pick between alternatives.
32+
Mark one option as recommended when there is a clear best pick.`,
33+
inputSchema: presentChoicesInput,
34+
outputSchema: presentChoicesOutput,
35+
});
36+
37+
const presentChoices = presentChoicesDef.client((input) =>
38+
Object.assign({ type: "choices" as const }, input),
39+
);
40+
41+
export const choicesTools = clientTools(presentChoices);
42+
43+
export const CHOICES_TOOL_PROMPT = `
44+
You have a "presentChoices" tool.
45+
When the user asks for choices, options, or says things like "give me some choices", call this tool with 2–4 creative options.
46+
Always mark exactly one option as recommended.
47+
After calling the tool keep your text reply short — the UI renders the options as buttons so do NOT repeat them in prose.
48+
`.trim();

apps/apollo-vertex/registry/alert/alert.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
"use client";
2+
13
import { cva, type VariantProps } from "class-variance-authority";
4+
import { XIcon } from "lucide-react";
25
import * as React from "react";
36

47
import { cn } from "@/lib/utils";
@@ -69,24 +72,51 @@ const alertVariants = cva(
6972

7073
interface AlertProps
7174
extends React.ComponentProps<"div">,
72-
VariantProps<typeof alertVariants> {}
75+
VariantProps<typeof alertVariants> {
76+
dismissible?: boolean;
77+
onDismiss?: () => void;
78+
}
7379

7480
function Alert({
7581
className,
7682
variant,
7783
status,
7884
visual,
85+
dismissible,
86+
onDismiss,
7987
children,
8088
...props
8189
}: AlertProps) {
90+
const [visible, setVisible] = React.useState(true);
91+
92+
if (!visible) return null;
93+
8294
return (
8395
<div
8496
data-slot="alert"
8597
role="alert"
86-
className={cn(alertVariants({ variant, status, visual }), className)}
98+
className={cn(
99+
alertVariants({ variant, status, visual }),
100+
dismissible && "pr-10",
101+
className,
102+
)}
87103
{...props}
88104
>
89105
{children}
106+
{dismissible && (
107+
<button
108+
type="button"
109+
onClick={(e) => {
110+
e.stopPropagation();
111+
setVisible(false);
112+
onDismiss?.();
113+
}}
114+
className="absolute top-3 right-3 rounded-sm opacity-70 transition-opacity hover:opacity-100"
115+
aria-label="Dismiss"
116+
>
117+
<XIcon className="size-4" />
118+
</button>
119+
)}
90120
</div>
91121
);
92122
}

0 commit comments

Comments
 (0)