feat: support customizing TTD welcome screen (#10719)

* feat: support customizing TTD welcome screen

* remove debug
This commit is contained in:
David Luzar
2026-01-30 16:28:36 +01:00
committed by GitHub
parent f5cf81ce42
commit 802cde3501
7 changed files with 44 additions and 19 deletions
@@ -48,14 +48,14 @@ $verticalBreakpoint: 861px;
} }
} }
&__empty-state { &__welcome-screen {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 100%; height: 100%;
min-height: 200px; min-height: 200px;
&-content { &__welcome-message {
text-align: center; text-align: center;
h3 { h3 {
@@ -6,6 +6,8 @@ import { InlineIcon } from "../../InlineIcon";
import { t } from "../../../i18n"; import { t } from "../../../i18n";
import { TTDWelcomeMessage } from "../TTDWelcomeMessage";
import { ChatMessage } from "./ChatMessage"; import { ChatMessage } from "./ChatMessage";
import type { TChat, TTTDDialog } from "../types"; import type { TChat, TTTDDialog } from "../types";
@@ -20,13 +22,13 @@ export const ChatInterface = ({
onGenerate, onGenerate,
isGenerating, isGenerating,
rateLimits, rateLimits,
placeholder,
onAbort, onAbort,
onMermaidTabClick, onMermaidTabClick,
onAiRepairClick, onAiRepairClick,
onDeleteMessage, onDeleteMessage,
onInsertMessage, onInsertMessage,
onRetry, onRetry,
renderWelcomeScreen,
renderWarning, renderWarning,
}: { }: {
chatId: string; chatId: string;
@@ -41,17 +43,13 @@ export const ChatInterface = ({
} | null; } | null;
onViewAsMermaid?: () => void; onViewAsMermaid?: () => void;
generatedResponse?: string | null; generatedResponse?: string | null;
placeholder: {
title: string;
description: string;
hint: string;
};
onAbort?: () => void; onAbort?: () => void;
onMermaidTabClick?: (message: TChat.ChatMessage) => void; onMermaidTabClick?: (message: TChat.ChatMessage) => void;
onAiRepairClick?: (message: TChat.ChatMessage) => void; onAiRepairClick?: (message: TChat.ChatMessage) => void;
onDeleteMessage?: (messageId: string) => void; onDeleteMessage?: (messageId: string) => void;
onInsertMessage?: (message: TChat.ChatMessage) => void; onInsertMessage?: (message: TChat.ChatMessage) => void;
onRetry?: (message: TChat.ChatMessage) => void; onRetry?: (message: TChat.ChatMessage) => void;
renderWelcomeScreen?: TTTDDialog.renderWelcomeScreen;
renderWarning?: TTTDDialog.renderWarning; renderWarning?: TTTDDialog.renderWarning;
}) => { }) => {
const messagesEndRef = useRef<HTMLDivElement>(null); const messagesEndRef = useRef<HTMLDivElement>(null);
@@ -113,12 +111,12 @@ export const ChatInterface = ({
<div className="chat-interface"> <div className="chat-interface">
<div className="chat-interface__messages"> <div className="chat-interface__messages">
{messages.length === 0 ? ( {messages.length === 0 ? (
<div className="chat-interface__empty-state"> <div className="chat-interface__welcome-screen">
<div className="chat-interface__empty-state-content"> {renderWelcomeScreen ? (
<h3>{placeholder.title}</h3> renderWelcomeScreen({ rateLimits: rateLimits ?? null })
<p>{placeholder.description}</p> ) : (
<p>{placeholder.hint}</p> <TTDWelcomeMessage />
</div> )}
</div> </div>
) : ( ) : (
messages.map((message, index) => ( messages.map((message, index) => (
@@ -40,6 +40,7 @@ export const TTDChatPanel = ({
onInsertMessage, onInsertMessage,
onRetry, onRetry,
onViewAsMermaid, onViewAsMermaid,
renderWelcomeScreen,
renderWarning, renderWarning,
}: { }: {
chatId: string; chatId: string;
@@ -68,6 +69,7 @@ export const TTDChatPanel = ({
onViewAsMermaid: () => void; onViewAsMermaid: () => void;
renderWelcomeScreen?: TTTDDialog.renderWelcomeScreen;
renderWarning?: TTTDDialog.renderWarning; renderWarning?: TTTDDialog.renderWarning;
}) => { }) => {
const [rateLimits] = useAtom(rateLimitsAtom); const [rateLimits] = useAtom(rateLimitsAtom);
@@ -151,11 +153,7 @@ export const TTDChatPanel = ({
onInsertMessage={onInsertMessage} onInsertMessage={onInsertMessage}
onRetry={onRetry} onRetry={onRetry}
rateLimits={rateLimits} rateLimits={rateLimits}
placeholder={{ renderWelcomeScreen={renderWelcomeScreen}
title: t("chat.placeholder.title"),
description: t("chat.placeholder.description"),
hint: t("chat.placeholder.hint"),
}}
renderWarning={renderWarning} renderWarning={renderWarning}
/> />
</TTDDialogPanel> </TTDDialogPanel>
@@ -15,6 +15,8 @@ import { TTDDialogTab } from "./TTDDialogTab";
import "./TTDDialog.scss"; import "./TTDDialog.scss";
import { TTDWelcomeMessage } from "./TTDWelcomeMessage";
import type { import type {
MermaidToExcalidrawLibProps, MermaidToExcalidrawLibProps,
TTDPersistenceAdapter, TTDPersistenceAdapter,
@@ -25,6 +27,7 @@ export const TTDDialog = (
props: props:
| { | {
onTextSubmit: TTTDDialog.onTextSubmit; onTextSubmit: TTTDDialog.onTextSubmit;
renderWelcomeScreen?: TTTDDialog.renderWelcomeScreen;
renderWarning?: TTTDDialog.renderWarning; renderWarning?: TTTDDialog.renderWarning;
persistenceAdapter: TTDPersistenceAdapter; persistenceAdapter: TTDPersistenceAdapter;
} }
@@ -39,6 +42,8 @@ export const TTDDialog = (
return <TTDDialogBase {...props} tab={appState.openDialog.tab} />; return <TTDDialogBase {...props} tab={appState.openDialog.tab} />;
}; };
TTDDialog.WelcomeMessage = TTDWelcomeMessage;
/** /**
* Text to diagram (TTD) dialog * Text to diagram (TTD) dialog
*/ */
@@ -54,6 +59,7 @@ const TTDDialogBase = withInternalFallback(
onTextSubmit( onTextSubmit(
props: TTTDDialog.OnTextSubmitProps, props: TTTDDialog.OnTextSubmitProps,
): Promise<TTTDDialog.OnTextSubmitRetValue>; ): Promise<TTTDDialog.OnTextSubmitRetValue>;
renderWelcomeScreen?: TTTDDialog.renderWelcomeScreen;
renderWarning?: TTTDDialog.renderWarning; renderWarning?: TTTDDialog.renderWarning;
persistenceAdapter: TTDPersistenceAdapter; persistenceAdapter: TTDPersistenceAdapter;
} }
@@ -110,6 +116,7 @@ const TTDDialogBase = withInternalFallback(
<TextToDiagram <TextToDiagram
mermaidToExcalidrawLib={mermaidToExcalidrawLib} mermaidToExcalidrawLib={mermaidToExcalidrawLib}
onTextSubmit={rest.onTextSubmit} onTextSubmit={rest.onTextSubmit}
renderWelcomeScreen={rest.renderWelcomeScreen}
renderWarning={rest.renderWarning} renderWarning={rest.renderWarning}
persistenceAdapter={rest.persistenceAdapter} persistenceAdapter={rest.persistenceAdapter}
/> />
@@ -0,0 +1,11 @@
import { t } from "../../i18n";
export const TTDWelcomeMessage = () => {
return (
<div className="chat-interface__welcome-screen__welcome-message">
<h3>{t("chat.placeholder.title")}</h3>
<p>{t("chat.placeholder.description")}</p>
<p>{t("chat.placeholder.hint")}</p>
</div>
);
};
@@ -35,6 +35,7 @@ import type {
const TextToDiagramContent = ({ const TextToDiagramContent = ({
mermaidToExcalidrawLib, mermaidToExcalidrawLib,
onTextSubmit, onTextSubmit,
renderWelcomeScreen,
renderWarning, renderWarning,
persistenceAdapter, persistenceAdapter,
}: { }: {
@@ -42,6 +43,7 @@ const TextToDiagramContent = ({
onTextSubmit: ( onTextSubmit: (
props: TTTDDialog.OnTextSubmitProps, props: TTTDDialog.OnTextSubmitProps,
) => Promise<TTTDDialog.OnTextSubmitRetValue>; ) => Promise<TTTDDialog.OnTextSubmitRetValue>;
renderWelcomeScreen?: TTTDDialog.renderWelcomeScreen;
renderWarning?: TTTDDialog.renderWarning; renderWarning?: TTTDDialog.renderWarning;
persistenceAdapter: TTDPersistenceAdapter; persistenceAdapter: TTDPersistenceAdapter;
}) => { }) => {
@@ -220,6 +222,7 @@ const TextToDiagramContent = ({
onRetry={handleRetry} onRetry={handleRetry}
onViewAsMermaid={onViewAsMermaid} onViewAsMermaid={onViewAsMermaid}
renderWarning={renderWarning} renderWarning={renderWarning}
renderWelcomeScreen={renderWelcomeScreen}
/> />
{showPreview && ( {showPreview && (
<TTDPreviewPanel <TTDPreviewPanel
@@ -237,6 +240,7 @@ const TextToDiagramContent = ({
export const TextToDiagram = ({ export const TextToDiagram = ({
mermaidToExcalidrawLib, mermaidToExcalidrawLib,
onTextSubmit, onTextSubmit,
renderWelcomeScreen,
renderWarning, renderWarning,
persistenceAdapter, persistenceAdapter,
}: { }: {
@@ -244,6 +248,7 @@ export const TextToDiagram = ({
onTextSubmit( onTextSubmit(
props: TTTDDialog.OnTextSubmitProps, props: TTTDDialog.OnTextSubmitProps,
): Promise<TTTDDialog.OnTextSubmitRetValue>; ): Promise<TTTDDialog.OnTextSubmitRetValue>;
renderWelcomeScreen?: TTTDDialog.renderWelcomeScreen;
renderWarning?: TTTDDialog.renderWarning; renderWarning?: TTTDDialog.renderWarning;
persistenceAdapter: TTDPersistenceAdapter; persistenceAdapter: TTDPersistenceAdapter;
}) => { }) => {
@@ -251,6 +256,7 @@ export const TextToDiagram = ({
<TextToDiagramContent <TextToDiagramContent
mermaidToExcalidrawLib={mermaidToExcalidrawLib} mermaidToExcalidrawLib={mermaidToExcalidrawLib}
onTextSubmit={onTextSubmit} onTextSubmit={onTextSubmit}
renderWelcomeScreen={renderWelcomeScreen}
renderWarning={renderWarning} renderWarning={renderWarning}
persistenceAdapter={persistenceAdapter} persistenceAdapter={persistenceAdapter}
/> />
@@ -116,4 +116,9 @@ export namespace TTTDDialog {
export type renderWarning = ( export type renderWarning = (
chatMessage: TChat.ChatMessage, chatMessage: TChat.ChatMessage,
) => React.ReactNode | undefined; ) => React.ReactNode | undefined;
export type renderWelcomeScreen = (props: {
/** null if not rate limit data currently available */
rateLimits: RateLimits | null;
}) => React.ReactNode | undefined;
} }