diff --git a/src/app/components/chat-panel/chat-panel.component.html b/src/app/components/chat-panel/chat-panel.component.html index 9cd2958a..039be315 100644 --- a/src/app/components/chat-panel/chat-panel.component.html +++ b/src/app/components/chat-panel/chat-panel.component.html @@ -73,6 +73,7 @@ @if (shouldShowMessageCard(message)) { { + const markdownContent = '# Welcome to the App\n\nThis is the landing page.'; + const encodedContent = encodeURIComponent(markdownContent); + const queryParams = { + [LANDING_PAGE_CONTENT_QUERY_PARAM]: encodedContent, + }; + mockActivatedRoute.snapshot!.queryParams = queryParams; + mockActivatedRoute.queryParams = of(queryParams); + + // Mock session service to return a new session + mockSessionService.createSessionResponse.next( + {id: SESSION_1_ID, state: {}, events: []}); + + fixture = TestBed.createComponent(ChatComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + tick(); // Allow component to stabilize and load session + + // Manually call displayLandingPageContent to simulate the effect + (component as any).displayLandingPageContent(); + tick(); + + const messages = component.messages(); + expect(messages.length).toBe(1); + expect(messages[0].role).toBe('bot'); + expect(messages[0].text).toBe(markdownContent); + expect(messages[0].isLanding).toBeTrue(); + })); }); describe('Session Management', () => { diff --git a/src/app/components/chat/chat.component.ts b/src/app/components/chat/chat.component.ts index c4215294..abed84e2 100644 --- a/src/app/components/chat/chat.component.ts +++ b/src/app/components/chat/chat.component.ts @@ -79,6 +79,8 @@ const ROOT_AGENT = 'root_agent'; export const INITIAL_USER_INPUT_QUERY_PARAM = 'q'; /** Query parameter for hiding the side panel. */ export const HIDE_SIDE_PANEL_QUERY_PARAM = 'hideSidePanel'; +/** Query parameter for landing page content. */ +export const LANDING_PAGE_CONTENT_QUERY_PARAM = 'landing'; /** A2A data part markers */ @@ -273,6 +275,7 @@ export class ChatComponent implements OnInit, AfterViewInit, OnDestroy { this.router.navigate([], { relativeTo: this.activatedRoute, queryParams: {app: app[0]}, + queryParamsHandling: 'merge', }); } }), @@ -467,6 +470,26 @@ export class ChatComponent implements OnInit, AfterViewInit, OnDestroy { }); } + private displayLandingPageContent() { + this.activatedRoute.queryParams.pipe(first()).subscribe(params => { + const landingContent = params[LANDING_PAGE_CONTENT_QUERY_PARAM]; + if (landingContent) { + try { + const decodedContent = decodeURIComponent(landingContent); + // Check if the landing message already exists + if (!this.messages().some(m => m.isLanding)) { + this.messages.update(messages => [ + {role: 'bot', text: decodedContent, isLanding: true}, + ...messages + ]); + } + } catch (e) { + console.error('Error decoding landing page content:', e); + } + } + }); + } + private hideSidePanelIfNeeded() { this.activatedRoute.queryParams .pipe( @@ -486,6 +509,7 @@ export class ChatComponent implements OnInit, AfterViewInit, OnDestroy { this.artifacts = []; this.userInput = ''; this.longRunningEvents = []; + this.displayLandingPageContent(); } createSession() { @@ -1709,6 +1733,8 @@ export class ChatComponent implements OnInit, AfterViewInit, OnDestroy { } this.loadTraceData(); }); + + this.displayLandingPageContent(); } protected updateWithSelectedEvalCase(evalCase: EvalCase) {