@ah-oh/ao-workspaces-design-system 0.0.53 → 0.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,7 +27,9 @@ import { MarkdownComponent } from 'ngx-markdown';
27
27
  import { CdkMenu, CdkMenuItem } from '@angular/cdk/menu';
28
28
  import { Overlay, CdkOverlayOrigin, CdkConnectedOverlay } from '@angular/cdk/overlay';
29
29
  import { ComponentPortal } from '@angular/cdk/portal';
30
- import { SurfaceComponent, A2uiRendererService, BasicCatalogBase, A2UI_RENDERER_CONFIG, provideMarkdownRenderer } from '@a2ui/angular/v0_9';
30
+ import { SurfaceComponent, A2uiRendererService, CatalogComponent, BasicCatalogBase, A2UI_RENDERER_CONFIG, provideMarkdownRenderer } from '@a2ui/angular/v0_9';
31
+ import { ChoicePickerApi } from '@a2ui/web_core/v0_9/basic_catalog';
32
+ import { renderMarkdown } from '@a2ui/markdown-it';
31
33
 
32
34
  class DesignSystem {
33
35
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DesignSystem, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -5146,7 +5148,8 @@ class WorkspaceNavbarService {
5146
5148
  companies = new BehaviorSubject([]);
5147
5149
  companies$ = this.companies.asObservable();
5148
5150
  companiesSignal = toSignal(this.companies$);
5149
- activeAppId;
5151
+ activeAppId = new BehaviorSubject(undefined);
5152
+ activeAppIdSignal = toSignal(this.activeAppId.asObservable());
5150
5153
  loginUrl = 'https://login.ah-oh.com';
5151
5154
  production = true;
5152
5155
  preserveRedirectUrl = true;
@@ -5154,10 +5157,10 @@ class WorkspaceNavbarService {
5154
5157
  return this.session.value;
5155
5158
  }
5156
5159
  get currentAppId() {
5157
- return this.activeAppId;
5160
+ return this.activeAppId.value;
5158
5161
  }
5159
5162
  init(config) {
5160
- this.activeAppId = config.appId;
5163
+ this.activeAppId.next(config.appId);
5161
5164
  this.production = config.production;
5162
5165
  this.preserveRedirectUrl = config.preserveRedirectUrl ?? true;
5163
5166
  if (config.loginUrl) {
@@ -5179,6 +5182,7 @@ class WorkspaceNavbarService {
5179
5182
  ...res,
5180
5183
  isExternalUser: res.companyId !== res.enabledCompanyId,
5181
5184
  };
5185
+ this.activeAppId.next(userSession.appId ?? userSession.product ?? config.appId);
5182
5186
  this.session.next(userSession);
5183
5187
  this.loadWorkspaceApps().subscribe();
5184
5188
  this.findEnabledCompanies().subscribe();
@@ -5196,21 +5200,11 @@ class WorkspaceNavbarService {
5196
5200
  }
5197
5201
  loadWorkspaceApps() {
5198
5202
  return this.http.get(WorkspaceNavbarService.WORKSPACE_APPS_URL).pipe(map$1(response => {
5199
- let apps = [...response.products, ...response.customApps];
5200
- if (!this.production) {
5201
- apps = apps.map(app => ({
5202
- ...app,
5203
- baseUrl: app.testingUrl ?? this.getLegacyDevUrl(app.appId),
5204
- }));
5205
- response = {
5206
- ...response,
5207
- products: apps.filter(a => response.products.some(p => p.appId === a.appId)),
5208
- customApps: apps.filter(a => response.customApps.some(c => c.appId === a.appId)),
5209
- };
5210
- }
5211
- this.workspaceApps.next(apps);
5212
- this.workspaceAppsResponse.next(response);
5213
- return apps;
5203
+ const normalizedResponse = this.normalizeWorkspaceAppsResponse(response);
5204
+ const workspaceApps = [...normalizedResponse.products, ...normalizedResponse.customApps];
5205
+ this.workspaceApps.next(workspaceApps);
5206
+ this.workspaceAppsResponse.next(normalizedResponse);
5207
+ return workspaceApps;
5214
5208
  }), catchError(err => {
5215
5209
  console.error('Failed to load workspace apps:', err);
5216
5210
  return of([]);
@@ -5230,14 +5224,16 @@ class WorkspaceNavbarService {
5230
5224
  if (!session) {
5231
5225
  throw new Error('Session is not initialized.');
5232
5226
  }
5233
- const appId = args.appId ?? this.activeAppId ?? 'admin';
5227
+ const appId = args.appId ?? this.currentAppId ?? 'admin';
5234
5228
  const companyId = args.companyId ?? session.enabledCompanyId;
5235
5229
  return this.http
5236
5230
  .get(`/auth-api/users/new-company/${companyId}/${session.userId}/${appId}`)
5237
5231
  .pipe(tap(({ jwtKey }) => {
5238
5232
  const app = this.workspaceApps.value.find(a => a.appId === appId);
5239
- const url = (args.isTesting ? app?.testingUrl : app?.baseUrl) ?? window.location.origin;
5240
- window.location.href = `${url}?jwtKey=${jwtKey}`;
5233
+ const targetUrl = app
5234
+ ? this.getRuntimeBaseUrl(app, args.isTesting)
5235
+ : window.location.origin;
5236
+ window.location.href = this.buildJwtRedirectUrl({ targetUrl, jwtKey });
5241
5237
  }));
5242
5238
  }
5243
5239
  switchApp(appId, isTesting = false) {
@@ -5252,15 +5248,18 @@ class WorkspaceNavbarService {
5252
5248
  return this.http
5253
5249
  .get(`/auth-api/users/new-company/${session.enabledCompanyId}/${session.userId}/${appId}`)
5254
5250
  .pipe(tap(({ jwtKey }) => {
5255
- const url = isTesting && app.testingUrl ? app.testingUrl : app.baseUrl;
5256
- window.location.href = `${url}?jwtKey=${jwtKey}`;
5251
+ const targetUrl = this.getRuntimeBaseUrl(app, isTesting);
5252
+ window.location.href = this.buildJwtRedirectUrl({ targetUrl, jwtKey });
5257
5253
  }));
5258
5254
  }
5259
5255
  createCompany() {
5260
5256
  return this.http
5261
5257
  .get(`${WorkspaceNavbarService.AUTH_BASE_URL}/jwt-key`)
5262
5258
  .pipe(tap(({ jwtKey }) => {
5263
- window.location.href = `${this.loginUrl}/create-company?product=${this.activeAppId}&jwtKey=${jwtKey}`;
5259
+ window.location.href = this.buildLoginPathUrl('create-company', {
5260
+ product: this.currentAppId,
5261
+ jwtKey,
5262
+ });
5264
5263
  }));
5265
5264
  }
5266
5265
  signOut() {
@@ -5271,13 +5270,14 @@ class WorkspaceNavbarService {
5271
5270
  }));
5272
5271
  }
5273
5272
  buildLoginUrl() {
5274
- let url = `${this.loginUrl}?product=${this.activeAppId}`;
5273
+ const url = new URL(this.loginUrl, window.location.origin);
5274
+ url.searchParams.set('product', this.currentAppId ?? 'admin');
5275
5275
  if (this.preserveRedirectUrl) {
5276
5276
  const currentUrl = new URL(window.location.href);
5277
5277
  currentUrl.searchParams.delete('jwtKey');
5278
- url += `&redirectUrl=${encodeURIComponent(currentUrl.toString())}`;
5278
+ url.searchParams.set('redirectUrl', currentUrl.toString());
5279
5279
  }
5280
- return url;
5280
+ return url.toString();
5281
5281
  }
5282
5282
  replaceSessionParams(url) {
5283
5283
  const session = this.session.value;
@@ -5290,7 +5290,7 @@ class WorkspaceNavbarService {
5290
5290
  const app = this.workspaceApps.value.find(a => a.appId === appId);
5291
5291
  if (!app)
5292
5292
  return undefined;
5293
- return isTesting && app.testingUrl ? app.testingUrl : app.baseUrl;
5293
+ return this.getRuntimeBaseUrl(app, isTesting);
5294
5294
  }
5295
5295
  getCompanyLogo(companyId) {
5296
5296
  return this.http.get(`${WorkspaceNavbarService.COMPANY_URL}/${companyId}/logo`);
@@ -5308,6 +5308,45 @@ class WorkspaceNavbarService {
5308
5308
  };
5309
5309
  return devUrls[appId] ?? `http://localhost:4200`;
5310
5310
  }
5311
+ normalizeWorkspaceAppsResponse(response) {
5312
+ if (this.production) {
5313
+ return response;
5314
+ }
5315
+ return {
5316
+ ...response,
5317
+ products: response.products.map(app => this.withRuntimeBaseUrl(app)),
5318
+ customApps: response.customApps.map(app => this.withRuntimeBaseUrl(app)),
5319
+ };
5320
+ }
5321
+ withRuntimeBaseUrl(app) {
5322
+ return {
5323
+ ...app,
5324
+ baseUrl: this.getRuntimeBaseUrl(app),
5325
+ };
5326
+ }
5327
+ getRuntimeBaseUrl(app, isTesting = false) {
5328
+ if (isTesting && app.testingUrl) {
5329
+ return app.testingUrl;
5330
+ }
5331
+ if (!this.production) {
5332
+ return app.testingUrl ?? this.getLegacyDevUrl(app.appId);
5333
+ }
5334
+ return app.baseUrl;
5335
+ }
5336
+ buildJwtRedirectUrl(arg) {
5337
+ const url = new URL(arg.targetUrl, window.location.origin);
5338
+ url.searchParams.set('jwtKey', arg.jwtKey);
5339
+ return url.toString();
5340
+ }
5341
+ buildLoginPathUrl(path, params) {
5342
+ const baseUrl = this.loginUrl.endsWith('/') ? this.loginUrl : `${this.loginUrl}/`;
5343
+ const url = new URL(path, baseUrl);
5344
+ Object.entries(params).forEach(([key, value]) => {
5345
+ if (value)
5346
+ url.searchParams.set(key, value);
5347
+ });
5348
+ return url.toString();
5349
+ }
5311
5350
  getEnabledApps() {
5312
5351
  const session = this.session.value;
5313
5352
  return session?.enabledApps ?? this.buildLegacyEnabledApps(session);
@@ -6930,11 +6969,11 @@ class ChatMessageComponent {
6930
6969
  }
6931
6970
  }
6932
6971
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6933
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ChatMessageComponent, isStandalone: true, selector: "lib-chat-message", inputs: { parts: { classPropertyName: "parts", publicName: "parts", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, showTyping: { classPropertyName: "showTyping", publicName: "showTyping", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"message\" [class.right]=\"side() === 'right'\" [class.left]=\"side() === 'left'\">\n @for (part of normalisedParts(); track $index) {\n @switch (part.kind) {\n @case ('text') {\n <markdown\n [data]=\"part.content\"\n (ready)=\"onMarkdownReady($any($event))\"\n ></markdown>\n }\n @case ('a2ui') {\n <a2ui-v09-surface [surfaceId]=\"part.surface.surfaceId\"></a2ui-v09-surface>\n }\n }\n }\n @if (showTyping()) {\n <div class=\"typing-indicator\">\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n</div>\n", styles: [".message{padding:8px;border-radius:4px;background-color:#fff;position:relative}.message:before{content:\"\";height:0;width:0;position:absolute;bottom:0;border:12px solid;border-color:transparent transparent white transparent}.message.right{margin-left:32px;border-bottom-right-radius:0}.message.right:before{left:auto;right:-12px}.message.left{margin-right:32px;margin-left:0;border-bottom-left-radius:0}.message.left:before{left:-12px;right:auto}.message ::ng-deep markdown p:last-child{margin-bottom:0}.message .typing-indicator{margin:24px auto;display:flex;justify-content:center;flex-direction:row;gap:1px}.message .typing-indicator div{width:9px;height:9px;border-radius:50%;background-color:var(--color-grey-mid)}.message .typing-indicator div:nth-child(1){animation:.9s blink infinite 0s}.message .typing-indicator div:nth-child(2){animation:.9s blink infinite .3s}.message .typing-indicator div:nth-child(3){animation:.9s blink infinite .6s}@keyframes blink{0%{opacity:.5;transform:scaleY(1),translateY(0)}20%{transform:scaleY(.4) translateY(6px)}50%{opacity:1;transform:scaleY(1) translateY(0)}to{opacity:.5}}\n"], dependencies: [{ kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: SurfaceComponent, selector: "a2ui-v09-surface", inputs: ["surfaceId", "dataContextPath"] }] });
6972
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ChatMessageComponent, isStandalone: true, selector: "lib-chat-message", inputs: { parts: { classPropertyName: "parts", publicName: "parts", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, showTyping: { classPropertyName: "showTyping", publicName: "showTyping", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"message\" [class.right]=\"side() === 'right'\" [class.left]=\"side() === 'left'\">\n @for (part of normalisedParts(); track $index) {\n @switch (part.kind) {\n @case ('text') {\n <markdown\n [data]=\"part.content\"\n (ready)=\"onMarkdownReady($any($event))\"\n ></markdown>\n }\n @case ('a2ui') {\n <a2ui-v09-surface [surfaceId]=\"part.surface.surfaceId\"></a2ui-v09-surface>\n }\n }\n }\n @if (showTyping()) {\n <div class=\"typing-indicator\">\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n</div>\n", styles: [".message{padding:12px 14px;border-radius:8px;background-color:#fff;color:var(--color-text-primary, #252525);font-size:14px;line-height:1.45;max-width:430px;position:relative}.message:before{content:\"\";height:0;width:0;position:absolute;bottom:0;border:12px solid;border-color:transparent transparent white transparent}.message.right{margin-left:32px;border-bottom-right-radius:0;align-self:flex-end}.message.right:before{left:auto;right:-12px}.message.left{margin-right:32px;margin-left:0;border-bottom-left-radius:0;align-self:flex-start}.message.left:before{left:-12px;right:auto}.message ::ng-deep markdown p{margin:0 0 10px}.message ::ng-deep markdown p:last-child{margin-bottom:0}.message ::ng-deep a2ui-v09-surface{display:block;margin-top:8px}.message ::ng-deep .a2ui-text h1,.message ::ng-deep .a2ui-text h2,.message ::ng-deep .a2ui-text h3,.message ::ng-deep .a2ui-text h4{font-weight:600}.message .typing-indicator{margin:24px auto;display:flex;justify-content:center;flex-direction:row;gap:1px}.message .typing-indicator div{width:9px;height:9px;border-radius:50%;background-color:var(--color-grey-mid)}.message .typing-indicator div:nth-child(1){animation:.9s blink infinite 0s}.message .typing-indicator div:nth-child(2){animation:.9s blink infinite .3s}.message .typing-indicator div:nth-child(3){animation:.9s blink infinite .6s}@keyframes blink{0%{opacity:.5;transform:scaleY(1),translateY(0)}20%{transform:scaleY(.4) translateY(6px)}50%{opacity:1;transform:scaleY(1) translateY(0)}to{opacity:.5}}\n"], dependencies: [{ kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: SurfaceComponent, selector: "a2ui-v09-surface", inputs: ["surfaceId", "dataContextPath"] }] });
6934
6973
  }
6935
6974
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatMessageComponent, decorators: [{
6936
6975
  type: Component,
6937
- args: [{ selector: 'lib-chat-message', imports: [MarkdownComponent, SurfaceComponent], template: "<div class=\"message\" [class.right]=\"side() === 'right'\" [class.left]=\"side() === 'left'\">\n @for (part of normalisedParts(); track $index) {\n @switch (part.kind) {\n @case ('text') {\n <markdown\n [data]=\"part.content\"\n (ready)=\"onMarkdownReady($any($event))\"\n ></markdown>\n }\n @case ('a2ui') {\n <a2ui-v09-surface [surfaceId]=\"part.surface.surfaceId\"></a2ui-v09-surface>\n }\n }\n }\n @if (showTyping()) {\n <div class=\"typing-indicator\">\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n</div>\n", styles: [".message{padding:8px;border-radius:4px;background-color:#fff;position:relative}.message:before{content:\"\";height:0;width:0;position:absolute;bottom:0;border:12px solid;border-color:transparent transparent white transparent}.message.right{margin-left:32px;border-bottom-right-radius:0}.message.right:before{left:auto;right:-12px}.message.left{margin-right:32px;margin-left:0;border-bottom-left-radius:0}.message.left:before{left:-12px;right:auto}.message ::ng-deep markdown p:last-child{margin-bottom:0}.message .typing-indicator{margin:24px auto;display:flex;justify-content:center;flex-direction:row;gap:1px}.message .typing-indicator div{width:9px;height:9px;border-radius:50%;background-color:var(--color-grey-mid)}.message .typing-indicator div:nth-child(1){animation:.9s blink infinite 0s}.message .typing-indicator div:nth-child(2){animation:.9s blink infinite .3s}.message .typing-indicator div:nth-child(3){animation:.9s blink infinite .6s}@keyframes blink{0%{opacity:.5;transform:scaleY(1),translateY(0)}20%{transform:scaleY(.4) translateY(6px)}50%{opacity:1;transform:scaleY(1) translateY(0)}to{opacity:.5}}\n"] }]
6976
+ args: [{ selector: 'lib-chat-message', imports: [MarkdownComponent, SurfaceComponent], template: "<div class=\"message\" [class.right]=\"side() === 'right'\" [class.left]=\"side() === 'left'\">\n @for (part of normalisedParts(); track $index) {\n @switch (part.kind) {\n @case ('text') {\n <markdown\n [data]=\"part.content\"\n (ready)=\"onMarkdownReady($any($event))\"\n ></markdown>\n }\n @case ('a2ui') {\n <a2ui-v09-surface [surfaceId]=\"part.surface.surfaceId\"></a2ui-v09-surface>\n }\n }\n }\n @if (showTyping()) {\n <div class=\"typing-indicator\">\n <div></div>\n <div></div>\n <div></div>\n </div>\n }\n</div>\n", styles: [".message{padding:12px 14px;border-radius:8px;background-color:#fff;color:var(--color-text-primary, #252525);font-size:14px;line-height:1.45;max-width:430px;position:relative}.message:before{content:\"\";height:0;width:0;position:absolute;bottom:0;border:12px solid;border-color:transparent transparent white transparent}.message.right{margin-left:32px;border-bottom-right-radius:0;align-self:flex-end}.message.right:before{left:auto;right:-12px}.message.left{margin-right:32px;margin-left:0;border-bottom-left-radius:0;align-self:flex-start}.message.left:before{left:-12px;right:auto}.message ::ng-deep markdown p{margin:0 0 10px}.message ::ng-deep markdown p:last-child{margin-bottom:0}.message ::ng-deep a2ui-v09-surface{display:block;margin-top:8px}.message ::ng-deep .a2ui-text h1,.message ::ng-deep .a2ui-text h2,.message ::ng-deep .a2ui-text h3,.message ::ng-deep .a2ui-text h4{font-weight:600}.message .typing-indicator{margin:24px auto;display:flex;justify-content:center;flex-direction:row;gap:1px}.message .typing-indicator div{width:9px;height:9px;border-radius:50%;background-color:var(--color-grey-mid)}.message .typing-indicator div:nth-child(1){animation:.9s blink infinite 0s}.message .typing-indicator div:nth-child(2){animation:.9s blink infinite .3s}.message .typing-indicator div:nth-child(3){animation:.9s blink infinite .6s}@keyframes blink{0%{opacity:.5;transform:scaleY(1),translateY(0)}20%{transform:scaleY(.4) translateY(6px)}50%{opacity:1;transform:scaleY(1) translateY(0)}to{opacity:.5}}\n"] }]
6938
6977
  }], propDecorators: { parts: [{ type: i0.Input, args: [{ isSignal: true, alias: "parts", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], showTyping: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTyping", required: false }] }] } });
6939
6978
 
6940
6979
  class RobinChatService {
@@ -7033,12 +7072,11 @@ class ChatComponent {
7033
7072
  dispatcher = inject(RobinChatActionDispatcher);
7034
7073
  authService = inject(WorkspaceNavbarService);
7035
7074
  destroyRef = inject(DestroyRef);
7075
+ appName = inject(ROBIN_SEARCH_APP_NAME);
7036
7076
  product;
7037
- handbookType;
7038
7077
  currentThreadId;
7039
7078
  ngOnInit() {
7040
7079
  this.product = this.resolveProduct();
7041
- this.handbookType = this.product;
7042
7080
  this.dispatcher.responses$
7043
7081
  .pipe(takeUntilDestroyed(this.destroyRef))
7044
7082
  .subscribe(response => this.handleResponse(response));
@@ -7091,7 +7129,12 @@ class ChatComponent {
7091
7129
  for (const turn of projected) {
7092
7130
  for (const part of turn.parts) {
7093
7131
  if (part.kind === 'a2ui') {
7094
- this.renderer.processMessages(part.surface.messages);
7132
+ try {
7133
+ this.renderer.processMessages(part.surface.messages);
7134
+ }
7135
+ catch (error) {
7136
+ console.warn('[RobinChat] A2UI history render failed', error);
7137
+ }
7095
7138
  }
7096
7139
  }
7097
7140
  }
@@ -7123,7 +7166,7 @@ class ChatComponent {
7123
7166
  question: 'Bitte begrüße den User kurz und biete Hilfe an.',
7124
7167
  threadId: this.currentThreadId,
7125
7168
  product: this.product,
7126
- handbookType: this.handbookType,
7169
+ appName: this.appName,
7127
7170
  type: this.searchType ?? null,
7128
7171
  })
7129
7172
  .then(response => this.handleResponse(response))
@@ -7137,7 +7180,7 @@ class ChatComponent {
7137
7180
  question,
7138
7181
  threadId: this.currentThreadId,
7139
7182
  product: this.product,
7140
- handbookType: this.handbookType,
7183
+ appName: this.appName,
7141
7184
  type: this.searchType ?? null,
7142
7185
  })
7143
7186
  .then(response => this.handleResponse(response))
@@ -7145,32 +7188,47 @@ class ChatComponent {
7145
7188
  }
7146
7189
  handleResponse(response) {
7147
7190
  this.setThreadId(response.threadId);
7148
- this.retireOldSurfaces(response);
7149
- for (const part of response.parts) {
7150
- if (part.kind === 'a2ui') {
7191
+ this.tryRetireOldSurfaces();
7192
+ this.appendAssistantTurn(this.processA2uiParts(response.parts));
7193
+ this.threads.set(undefined);
7194
+ this.activeRequest.set(false);
7195
+ }
7196
+ tryRetireOldSurfaces() {
7197
+ try {
7198
+ this.retireOldSurfaces();
7199
+ }
7200
+ catch (error) {
7201
+ console.warn('[RobinChat] A2UI surface retirement failed', error);
7202
+ }
7203
+ }
7204
+ processA2uiParts(parts) {
7205
+ const renderable = [];
7206
+ for (const part of parts) {
7207
+ if (part.kind !== 'a2ui') {
7208
+ renderable.push(part);
7209
+ continue;
7210
+ }
7211
+ try {
7151
7212
  this.renderer.processMessages(part.surface.messages);
7213
+ renderable.push(part);
7214
+ }
7215
+ catch (error) {
7216
+ console.warn('[RobinChat] A2UI render failed', error);
7152
7217
  }
7153
7218
  }
7154
- this.appendAssistantTurn(response.parts);
7155
- this.threads.set(undefined);
7156
- this.activeRequest.set(false);
7219
+ return renderable.length > 0 ? renderable : [{ kind: 'text', content: ERROR_FALLBACK }];
7157
7220
  }
7158
7221
  /**
7159
7222
  * Removes A2UI surfaces from the renderer that belong to older turns and
7160
7223
  * strips their `a2ui` parts so the chat history doesn't accumulate stale
7161
7224
  * interactive cards as the conversation progresses.
7162
7225
  */
7163
- retireOldSurfaces(response) {
7164
- const incoming = new Set(response.parts
7165
- .filter(part => part.kind === 'a2ui')
7166
- .map(part => part.surface.surfaceId));
7226
+ retireOldSurfaces() {
7167
7227
  const toDelete = [];
7168
7228
  const nextTurns = this.turns().map(turn => {
7169
7229
  const filtered = turn.parts.filter(part => {
7170
7230
  if (part.kind !== 'a2ui')
7171
7231
  return true;
7172
- if (incoming.has(part.surface.surfaceId))
7173
- return true;
7174
7232
  toDelete.push(part.surface.surfaceId);
7175
7233
  return false;
7176
7234
  });
@@ -7227,11 +7285,11 @@ class ChatComponent {
7227
7285
  }
7228
7286
  }
7229
7287
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7230
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ChatComponent, isStandalone: true, selector: "lib-chat", inputs: { searchType: "searchType" }, outputs: { closed: "closed" }, viewQueries: [{ propertyName: "historyElement", first: true, predicate: ["conversation"], descendants: true }, { propertyName: "textField", first: true, predicate: ["textField"], descendants: true }], ngImport: i0, template: "<div class=\"sidebar\">\n @if (showHistory()) {\n <div class=\"chat-history\">\n <div class=\"header\">\n <h3>Verlauf</h3>\n </div>\n <div class=\"history-items\">\n @if (threads() === undefined) {\n <div class=\"history-empty\">L\u00E4dt\u2026</div>\n } @else if (threads()!.length === 0) {\n <div class=\"history-empty\">Noch keine Gespr\u00E4che.</div>\n }\n @for (item of threads(); track item.threadId) {\n <div class=\"chat-history-item\" (click)=\"openThread(item.threadId)\">\n <div class=\"preview\">{{ item.lastMessage }}</div>\n <div class=\"footer\">\n <div>{{ item.messageCount }} Nachrichten</div>\n <div>{{ item.updatedAt | date: 'dd.MM.yyyy HH:mm' }}</div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <div class=\"chat\">\n <div class=\"header\">\n <button ao-button variant=\"outline\" (click)=\"toggleHistory()\">\n <ao-icon [svg]=\"historyIcon\"></ao-icon>\n </button>\n <h2>Hilfecenter</h2>\n <div class=\"flex\">\n <button ao-button variant=\"outline\" (click)=\"newChat()\">\n <ao-icon [svg]=\"addIcon\"></ao-icon>\n </button>\n <button ao-button variant=\"outline\" (click)=\"showHistory.set(false); closed.emit()\">\n <ao-icon [svg]=\"closeIcon\"></ao-icon>\n </button>\n </div>\n </div>\n <div class=\"conversation-history\" #conversation>\n @for (turn of turns(); track $index) {\n <lib-chat-message\n [parts]=\"turn.parts\"\n [side]=\"turn.role === 'assistant' ? 'left' : 'right'\"\n >\n </lib-chat-message>\n }\n @if (activeRequest()) {\n <lib-chat-message [showTyping]=\"true\" side=\"left\"></lib-chat-message>\n }\n </div>\n\n <div class=\"input\">\n <textarea\n #textField\n rows=\"1\"\n class=\"textarea\"\n [formControl]=\"inputControl\"\n (keydown.enter)=\"send(); $event.stopPropagation(); $event.preventDefault()\"\n (input)=\"setSize()\"\n ></textarea>\n <button ao-button variant=\"primary\" (click)=\"send()\" class=\"send-button\">\n <ao-icon [svg]=\"sendIcon\"></ao-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.sidebar{display:flex;flex-direction:row;height:100%;position:relative}.header{background-color:#fff;padding:4px;display:flex;height:50px;flex-direction:row;align-items:center}.header h2,.header h3{margin:0}.header h2{font-size:24px}.header h3{font-size:16px}.chat{display:flex;flex-direction:column;height:100%;width:500px;background-color:#f3f3f3;border-left:1px solid #e9e9e9}.chat .header{justify-content:space-between}.chat .header .flex{display:flex;align-items:center;gap:10px}.conversation-history{--a2ui-color-primary: #212121;--a2ui-color-on-primary: #ffffff;--a2ui-color-secondary: #e9e9e9;--a2ui-color-on-secondary: #212121;--a2ui-color-surface: #ffffff;--a2ui-color-on-background: #212121;--a2ui-color-input: #ffffff;--a2ui-color-on-input: #212121;--a2ui-color-border: #e9e9e9;--a2ui-color-error: #ff004d;--a2ui-text-color: #212121;--a2ui-text-color-text: #212121;--a2ui-text-caption-color: #909090;--a2ui-text-a-color: #ff004d;--a2ui-text-a-font-weight: 600;--a2ui-spacing-xs: 5px;--a2ui-spacing-s: 10px;--a2ui-spacing-m: 15px;--a2ui-spacing-l: 20px;--a2ui-spacing-xl: 25px;--a2ui-row-gap: 12px;--a2ui-column-gap: 12px;--a2ui-list-gap: 8px;--a2ui-list-padding: 0;--a2ui-font-family-title: inherit;--a2ui-font-size-2xl: 28px;--a2ui-font-size-xl: 22px;--a2ui-font-size-l: 18px;--a2ui-font-size-m: 15px;--a2ui-font-size-s: 13px;--a2ui-font-size-xs: 12px;--a2ui-line-height-headings: 1.3;--a2ui-line-height-body: 1.55;--a2ui-label-font-size: 13px;--a2ui-border-width: 1px;--a2ui-border-radius: 8px;--a2ui-card-background: #ffffff;--a2ui-card-border-radius: 12px;--a2ui-card-padding: 20px;--a2ui-card-margin: 0;--a2ui-card-border: none;--a2ui-card-box-shadow: 0 1px 3px rgb(0 0 0 / 6%);--a2ui-button-background: #ffffff;--a2ui-button-border: 1px solid #212121;--a2ui-button-border-radius: 999px;--a2ui-button-padding: 10px 22px;--a2ui-button-margin: 0;--a2ui-button-box-shadow: none;--a2ui-button-font-weight: 600;--a2ui-choicepicker-gap: 10px;--a2ui-choicepicker-padding: 0;--a2ui-choicepicker-checkbox-size: 18px;--a2ui-choicepicker-chip-background: #ffffff;--a2ui-choicepicker-chip-background-selected: #212121;--a2ui-choicepicker-chip-border: 1px solid #212121;--a2ui-choicepicker-chip-border-radius: 999px;--a2ui-choicepicker-chip-padding: 8px 16px;--a2ui-checkbox-background: #ffffff;--a2ui-checkbox-border: 1px solid #212121;--a2ui-checkbox-border-radius: 4px;--a2ui-checkbox-size: 18px;--a2ui-checkbox-gap: 10px;--a2ui-checkbox-label-font-weight: 500;--a2ui-checkbox-margin: 0;--a2ui-textfield-border: 1px solid #e9e9e9;--a2ui-textfield-border-radius: 8px;--a2ui-textfield-padding: 10px 14px;--a2ui-textfield-color-border-focus: #ff004d;--a2ui-textfield-color-error: #ff004d;--a2ui-textfield-label-font-weight: 500;--a2ui-textfield-label-font-size: 13px;--a2ui-divider-spacing: 10px;accent-color:#ff004d}.conversation-history ::ng-deep .a2ui-chip:not(.active){color:#212121}.conversation-history{display:flex;flex-direction:column;gap:16px;padding:20px;flex-grow:1;min-height:0;overflow-y:auto}.conversation-history markdown{display:block}.possible-questions{padding:0 20px 10px;display:flex;flex-wrap:wrap;gap:8px}.possible-questions .question-chip{cursor:pointer;transition:all .2s ease;background-color:#e9e9e9;padding:8px;border-radius:5px}.possible-questions .question-chip:hover{transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.input{margin:0 10px 10px;position:relative}.input .textarea{font-family:inherit;z-index:10000;padding:10px 65px 10px 10px;width:100%;box-sizing:border-box;min-height:43px;resize:none}.input .send-button{position:absolute;right:10px;bottom:9px}.chat-history{background-color:#f3f3f3;border-left:1px solid #e9e9e9;width:300px;height:100vh;overflow:auto;position:fixed;right:500px;top:0}.chat-history .header{justify-content:center}.chat-history .history-items{display:flex;flex-direction:column;gap:8px;padding:8px;overflow:auto}.chat-history .history-items .history-empty{padding:16px 8px;color:#909090;text-align:center;font-size:13px}.chat-history .history-items .chat-history-item{cursor:pointer;background-color:#fff;border-radius:4px;padding:8px}.chat-history .history-items .chat-history-item:hover{filter:brightness(.97)}.chat-history .history-items .chat-history-item .preview{font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.chat-history .history-items .chat-history-item .footer{color:#909090;font-size:11px;display:flex;flex-direction:row;justify-content:space-between}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ChatMessageComponent, selector: "lib-chat-message", inputs: ["parts", "side", "showTyping"] }, { kind: "component", type: IconComponent, selector: "ao-icon", inputs: ["svg", "size"] }, { kind: "component", type: ButtonComponent, selector: "button[ao-button], a[ao-button]", inputs: ["variant", "icon", "iconTrailing"] }, { kind: "pipe", type: DatePipe, name: "date" }] });
7288
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ChatComponent, isStandalone: true, selector: "lib-chat", inputs: { searchType: "searchType" }, outputs: { closed: "closed" }, viewQueries: [{ propertyName: "historyElement", first: true, predicate: ["conversation"], descendants: true }, { propertyName: "textField", first: true, predicate: ["textField"], descendants: true }], ngImport: i0, template: "<div class=\"sidebar\">\n @if (showHistory()) {\n <div class=\"chat-history\">\n <div class=\"header\">\n <h3>Verlauf</h3>\n </div>\n <div class=\"history-items\">\n @if (threads() === undefined) {\n <div class=\"history-empty\">L\u00E4dt\u2026</div>\n } @else if (threads()!.length === 0) {\n <div class=\"history-empty\">Noch keine Gespr\u00E4che.</div>\n }\n @for (item of threads(); track item.threadId) {\n <div class=\"chat-history-item\" (click)=\"openThread(item.threadId)\">\n <div class=\"preview\">{{ item.lastMessage }}</div>\n <div class=\"footer\">\n <div>{{ item.messageCount }} Nachrichten</div>\n <div>{{ item.updatedAt | date: 'dd.MM.yyyy HH:mm' }}</div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <div class=\"chat\">\n <div class=\"header\">\n <button ao-button variant=\"outline\" (click)=\"toggleHistory()\">\n <ao-icon [svg]=\"historyIcon\"></ao-icon>\n </button>\n <h2>Hilfecenter</h2>\n <div class=\"flex\">\n <button ao-button variant=\"outline\" (click)=\"newChat()\">\n <ao-icon [svg]=\"addIcon\"></ao-icon>\n </button>\n <button ao-button variant=\"outline\" (click)=\"showHistory.set(false); closed.emit()\">\n <ao-icon [svg]=\"closeIcon\"></ao-icon>\n </button>\n </div>\n </div>\n <div class=\"conversation-history\" #conversation>\n @for (turn of turns(); track $index) {\n <lib-chat-message\n [parts]=\"turn.parts\"\n [side]=\"turn.role === 'assistant' ? 'left' : 'right'\"\n >\n </lib-chat-message>\n }\n @if (activeRequest()) {\n <lib-chat-message [showTyping]=\"true\" side=\"left\"></lib-chat-message>\n }\n </div>\n\n <div class=\"input\">\n <textarea\n #textField\n rows=\"1\"\n class=\"textarea\"\n [formControl]=\"inputControl\"\n (keydown.enter)=\"send(); $event.stopPropagation(); $event.preventDefault()\"\n (input)=\"setSize()\"\n ></textarea>\n <button ao-button variant=\"primary\" (click)=\"send()\" class=\"send-button\">\n <ao-icon [svg]=\"sendIcon\"></ao-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.sidebar{display:flex;flex-direction:row;height:100%;position:relative}.header{background-color:#fff;padding:6px 8px;display:flex;height:50px;flex-direction:row;align-items:center}.header h2,.header h3{margin:0}.header h2{font-size:18px;font-weight:600}.header h3{font-size:16px}.chat{display:flex;flex-direction:column;height:100%;width:500px;background-color:#f3f3f3;border-left:1px solid #e9e9e9}.chat .header{justify-content:space-between}.chat .header .flex{display:flex;align-items:center;gap:10px}.conversation-history{--a2ui-color-primary: #212121;--a2ui-color-on-primary: #ffffff;--a2ui-color-surface: #ffffff;--a2ui-color-on-background: #212121;--a2ui-color-border: #e9e9e9;--a2ui-text-color-text: #212121;--a2ui-text-caption-color: #909090;--a2ui-text-a-color: #ff004d;--a2ui-spacing-xs: 5px;--a2ui-spacing-s: 10px;--a2ui-spacing-m: 15px;--a2ui-spacing-l: 20px;--a2ui-row-gap: 12px;--a2ui-column-gap: 10px;--a2ui-font-family-title: inherit;--a2ui-font-size-2xl: 22px;--a2ui-font-size-xl: 19px;--a2ui-font-size-l: 16px;--a2ui-font-size-m: 14px;--a2ui-font-size-s: 13px;--a2ui-font-size-xs: 12px;--a2ui-card-background: #ffffff;--a2ui-card-border-radius: 8px;--a2ui-card-padding: 14px;--a2ui-card-border: none;--a2ui-button-background: #ffffff;--a2ui-button-border: 1px solid #212121;--a2ui-button-border-radius: 999px;--a2ui-button-padding: 8px 14px;--a2ui-button-font-weight: 500;--a2ui-choicepicker-gap: 10px;--a2ui-choicepicker-padding: 0;--a2ui-choicepicker-checkbox-size: 18px;--a2ui-choicepicker-chip-background: #ffffff;--a2ui-choicepicker-chip-background-selected: #212121;--a2ui-choicepicker-chip-border: 1px solid #212121;--a2ui-choicepicker-chip-border-radius: 999px;--a2ui-choicepicker-chip-padding: 7px 14px;--a2ui-choicepicker-chip-color: #212121;--a2ui-choicepicker-chip-border-hover: #ff004d;--a2ui-checkbox-border: 1px solid #212121;--a2ui-checkbox-border-radius: 4px;--a2ui-checkbox-size: 18px;--a2ui-textfield-border: 1px solid #e9e9e9;--a2ui-textfield-border-radius: 8px;--a2ui-textfield-padding: 10px 14px;--a2ui-textfield-color-border-focus: #ff004d;accent-color:#ff004d}.conversation-history ::ng-deep .a2ui-chip:not(.active){color:#212121}.conversation-history{display:flex;flex-direction:column;gap:16px;padding:16px;flex-grow:1;min-height:0;overflow-y:auto}.conversation-history markdown{display:block}.possible-questions{padding:0 20px 10px;display:flex;flex-wrap:wrap;gap:8px}.possible-questions .question-chip{cursor:pointer;transition:all .2s ease;background-color:#e9e9e9;padding:8px;border-radius:5px}.possible-questions .question-chip:hover{transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.input{margin:0 12px 12px;position:relative}.input .textarea{font-family:inherit;background:#212121;border:1px solid #212121;border-radius:4px;color:#fff;z-index:10000;padding:12px 64px 12px 12px;width:100%;box-sizing:border-box;min-height:43px;resize:none}.input .textarea:focus{border-color:#ff004d;outline:none}.input .send-button{position:absolute;right:10px;bottom:9px}.chat-history{background-color:#f3f3f3;border-left:1px solid #e9e9e9;width:300px;height:100vh;overflow:auto;position:fixed;right:500px;top:0}.chat-history .header{justify-content:center}.chat-history .history-items{display:flex;flex-direction:column;gap:8px;padding:8px;overflow:auto}.chat-history .history-items .history-empty{padding:16px 8px;color:#909090;text-align:center;font-size:13px}.chat-history .history-items .chat-history-item{cursor:pointer;background-color:#fff;border-radius:4px;padding:8px}.chat-history .history-items .chat-history-item:hover{filter:brightness(.97)}.chat-history .history-items .chat-history-item .preview{font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.chat-history .history-items .chat-history-item .footer{color:#909090;font-size:11px;display:flex;flex-direction:row;justify-content:space-between}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ChatMessageComponent, selector: "lib-chat-message", inputs: ["parts", "side", "showTyping"] }, { kind: "component", type: IconComponent, selector: "ao-icon", inputs: ["svg", "size"] }, { kind: "component", type: ButtonComponent, selector: "button[ao-button], a[ao-button]", inputs: ["variant", "icon", "iconTrailing"] }, { kind: "pipe", type: DatePipe, name: "date" }] });
7231
7289
  }
7232
7290
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatComponent, decorators: [{
7233
7291
  type: Component,
7234
- args: [{ selector: 'lib-chat', imports: [ReactiveFormsModule, ChatMessageComponent, IconComponent, ButtonComponent, DatePipe], template: "<div class=\"sidebar\">\n @if (showHistory()) {\n <div class=\"chat-history\">\n <div class=\"header\">\n <h3>Verlauf</h3>\n </div>\n <div class=\"history-items\">\n @if (threads() === undefined) {\n <div class=\"history-empty\">L\u00E4dt\u2026</div>\n } @else if (threads()!.length === 0) {\n <div class=\"history-empty\">Noch keine Gespr\u00E4che.</div>\n }\n @for (item of threads(); track item.threadId) {\n <div class=\"chat-history-item\" (click)=\"openThread(item.threadId)\">\n <div class=\"preview\">{{ item.lastMessage }}</div>\n <div class=\"footer\">\n <div>{{ item.messageCount }} Nachrichten</div>\n <div>{{ item.updatedAt | date: 'dd.MM.yyyy HH:mm' }}</div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <div class=\"chat\">\n <div class=\"header\">\n <button ao-button variant=\"outline\" (click)=\"toggleHistory()\">\n <ao-icon [svg]=\"historyIcon\"></ao-icon>\n </button>\n <h2>Hilfecenter</h2>\n <div class=\"flex\">\n <button ao-button variant=\"outline\" (click)=\"newChat()\">\n <ao-icon [svg]=\"addIcon\"></ao-icon>\n </button>\n <button ao-button variant=\"outline\" (click)=\"showHistory.set(false); closed.emit()\">\n <ao-icon [svg]=\"closeIcon\"></ao-icon>\n </button>\n </div>\n </div>\n <div class=\"conversation-history\" #conversation>\n @for (turn of turns(); track $index) {\n <lib-chat-message\n [parts]=\"turn.parts\"\n [side]=\"turn.role === 'assistant' ? 'left' : 'right'\"\n >\n </lib-chat-message>\n }\n @if (activeRequest()) {\n <lib-chat-message [showTyping]=\"true\" side=\"left\"></lib-chat-message>\n }\n </div>\n\n <div class=\"input\">\n <textarea\n #textField\n rows=\"1\"\n class=\"textarea\"\n [formControl]=\"inputControl\"\n (keydown.enter)=\"send(); $event.stopPropagation(); $event.preventDefault()\"\n (input)=\"setSize()\"\n ></textarea>\n <button ao-button variant=\"primary\" (click)=\"send()\" class=\"send-button\">\n <ao-icon [svg]=\"sendIcon\"></ao-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.sidebar{display:flex;flex-direction:row;height:100%;position:relative}.header{background-color:#fff;padding:4px;display:flex;height:50px;flex-direction:row;align-items:center}.header h2,.header h3{margin:0}.header h2{font-size:24px}.header h3{font-size:16px}.chat{display:flex;flex-direction:column;height:100%;width:500px;background-color:#f3f3f3;border-left:1px solid #e9e9e9}.chat .header{justify-content:space-between}.chat .header .flex{display:flex;align-items:center;gap:10px}.conversation-history{--a2ui-color-primary: #212121;--a2ui-color-on-primary: #ffffff;--a2ui-color-secondary: #e9e9e9;--a2ui-color-on-secondary: #212121;--a2ui-color-surface: #ffffff;--a2ui-color-on-background: #212121;--a2ui-color-input: #ffffff;--a2ui-color-on-input: #212121;--a2ui-color-border: #e9e9e9;--a2ui-color-error: #ff004d;--a2ui-text-color: #212121;--a2ui-text-color-text: #212121;--a2ui-text-caption-color: #909090;--a2ui-text-a-color: #ff004d;--a2ui-text-a-font-weight: 600;--a2ui-spacing-xs: 5px;--a2ui-spacing-s: 10px;--a2ui-spacing-m: 15px;--a2ui-spacing-l: 20px;--a2ui-spacing-xl: 25px;--a2ui-row-gap: 12px;--a2ui-column-gap: 12px;--a2ui-list-gap: 8px;--a2ui-list-padding: 0;--a2ui-font-family-title: inherit;--a2ui-font-size-2xl: 28px;--a2ui-font-size-xl: 22px;--a2ui-font-size-l: 18px;--a2ui-font-size-m: 15px;--a2ui-font-size-s: 13px;--a2ui-font-size-xs: 12px;--a2ui-line-height-headings: 1.3;--a2ui-line-height-body: 1.55;--a2ui-label-font-size: 13px;--a2ui-border-width: 1px;--a2ui-border-radius: 8px;--a2ui-card-background: #ffffff;--a2ui-card-border-radius: 12px;--a2ui-card-padding: 20px;--a2ui-card-margin: 0;--a2ui-card-border: none;--a2ui-card-box-shadow: 0 1px 3px rgb(0 0 0 / 6%);--a2ui-button-background: #ffffff;--a2ui-button-border: 1px solid #212121;--a2ui-button-border-radius: 999px;--a2ui-button-padding: 10px 22px;--a2ui-button-margin: 0;--a2ui-button-box-shadow: none;--a2ui-button-font-weight: 600;--a2ui-choicepicker-gap: 10px;--a2ui-choicepicker-padding: 0;--a2ui-choicepicker-checkbox-size: 18px;--a2ui-choicepicker-chip-background: #ffffff;--a2ui-choicepicker-chip-background-selected: #212121;--a2ui-choicepicker-chip-border: 1px solid #212121;--a2ui-choicepicker-chip-border-radius: 999px;--a2ui-choicepicker-chip-padding: 8px 16px;--a2ui-checkbox-background: #ffffff;--a2ui-checkbox-border: 1px solid #212121;--a2ui-checkbox-border-radius: 4px;--a2ui-checkbox-size: 18px;--a2ui-checkbox-gap: 10px;--a2ui-checkbox-label-font-weight: 500;--a2ui-checkbox-margin: 0;--a2ui-textfield-border: 1px solid #e9e9e9;--a2ui-textfield-border-radius: 8px;--a2ui-textfield-padding: 10px 14px;--a2ui-textfield-color-border-focus: #ff004d;--a2ui-textfield-color-error: #ff004d;--a2ui-textfield-label-font-weight: 500;--a2ui-textfield-label-font-size: 13px;--a2ui-divider-spacing: 10px;accent-color:#ff004d}.conversation-history ::ng-deep .a2ui-chip:not(.active){color:#212121}.conversation-history{display:flex;flex-direction:column;gap:16px;padding:20px;flex-grow:1;min-height:0;overflow-y:auto}.conversation-history markdown{display:block}.possible-questions{padding:0 20px 10px;display:flex;flex-wrap:wrap;gap:8px}.possible-questions .question-chip{cursor:pointer;transition:all .2s ease;background-color:#e9e9e9;padding:8px;border-radius:5px}.possible-questions .question-chip:hover{transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.input{margin:0 10px 10px;position:relative}.input .textarea{font-family:inherit;z-index:10000;padding:10px 65px 10px 10px;width:100%;box-sizing:border-box;min-height:43px;resize:none}.input .send-button{position:absolute;right:10px;bottom:9px}.chat-history{background-color:#f3f3f3;border-left:1px solid #e9e9e9;width:300px;height:100vh;overflow:auto;position:fixed;right:500px;top:0}.chat-history .header{justify-content:center}.chat-history .history-items{display:flex;flex-direction:column;gap:8px;padding:8px;overflow:auto}.chat-history .history-items .history-empty{padding:16px 8px;color:#909090;text-align:center;font-size:13px}.chat-history .history-items .chat-history-item{cursor:pointer;background-color:#fff;border-radius:4px;padding:8px}.chat-history .history-items .chat-history-item:hover{filter:brightness(.97)}.chat-history .history-items .chat-history-item .preview{font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.chat-history .history-items .chat-history-item .footer{color:#909090;font-size:11px;display:flex;flex-direction:row;justify-content:space-between}\n"] }]
7292
+ args: [{ selector: 'lib-chat', imports: [ReactiveFormsModule, ChatMessageComponent, IconComponent, ButtonComponent, DatePipe], template: "<div class=\"sidebar\">\n @if (showHistory()) {\n <div class=\"chat-history\">\n <div class=\"header\">\n <h3>Verlauf</h3>\n </div>\n <div class=\"history-items\">\n @if (threads() === undefined) {\n <div class=\"history-empty\">L\u00E4dt\u2026</div>\n } @else if (threads()!.length === 0) {\n <div class=\"history-empty\">Noch keine Gespr\u00E4che.</div>\n }\n @for (item of threads(); track item.threadId) {\n <div class=\"chat-history-item\" (click)=\"openThread(item.threadId)\">\n <div class=\"preview\">{{ item.lastMessage }}</div>\n <div class=\"footer\">\n <div>{{ item.messageCount }} Nachrichten</div>\n <div>{{ item.updatedAt | date: 'dd.MM.yyyy HH:mm' }}</div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <div class=\"chat\">\n <div class=\"header\">\n <button ao-button variant=\"outline\" (click)=\"toggleHistory()\">\n <ao-icon [svg]=\"historyIcon\"></ao-icon>\n </button>\n <h2>Hilfecenter</h2>\n <div class=\"flex\">\n <button ao-button variant=\"outline\" (click)=\"newChat()\">\n <ao-icon [svg]=\"addIcon\"></ao-icon>\n </button>\n <button ao-button variant=\"outline\" (click)=\"showHistory.set(false); closed.emit()\">\n <ao-icon [svg]=\"closeIcon\"></ao-icon>\n </button>\n </div>\n </div>\n <div class=\"conversation-history\" #conversation>\n @for (turn of turns(); track $index) {\n <lib-chat-message\n [parts]=\"turn.parts\"\n [side]=\"turn.role === 'assistant' ? 'left' : 'right'\"\n >\n </lib-chat-message>\n }\n @if (activeRequest()) {\n <lib-chat-message [showTyping]=\"true\" side=\"left\"></lib-chat-message>\n }\n </div>\n\n <div class=\"input\">\n <textarea\n #textField\n rows=\"1\"\n class=\"textarea\"\n [formControl]=\"inputControl\"\n (keydown.enter)=\"send(); $event.stopPropagation(); $event.preventDefault()\"\n (input)=\"setSize()\"\n ></textarea>\n <button ao-button variant=\"primary\" (click)=\"send()\" class=\"send-button\">\n <ao-icon [svg]=\"sendIcon\"></ao-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.sidebar{display:flex;flex-direction:row;height:100%;position:relative}.header{background-color:#fff;padding:6px 8px;display:flex;height:50px;flex-direction:row;align-items:center}.header h2,.header h3{margin:0}.header h2{font-size:18px;font-weight:600}.header h3{font-size:16px}.chat{display:flex;flex-direction:column;height:100%;width:500px;background-color:#f3f3f3;border-left:1px solid #e9e9e9}.chat .header{justify-content:space-between}.chat .header .flex{display:flex;align-items:center;gap:10px}.conversation-history{--a2ui-color-primary: #212121;--a2ui-color-on-primary: #ffffff;--a2ui-color-surface: #ffffff;--a2ui-color-on-background: #212121;--a2ui-color-border: #e9e9e9;--a2ui-text-color-text: #212121;--a2ui-text-caption-color: #909090;--a2ui-text-a-color: #ff004d;--a2ui-spacing-xs: 5px;--a2ui-spacing-s: 10px;--a2ui-spacing-m: 15px;--a2ui-spacing-l: 20px;--a2ui-row-gap: 12px;--a2ui-column-gap: 10px;--a2ui-font-family-title: inherit;--a2ui-font-size-2xl: 22px;--a2ui-font-size-xl: 19px;--a2ui-font-size-l: 16px;--a2ui-font-size-m: 14px;--a2ui-font-size-s: 13px;--a2ui-font-size-xs: 12px;--a2ui-card-background: #ffffff;--a2ui-card-border-radius: 8px;--a2ui-card-padding: 14px;--a2ui-card-border: none;--a2ui-button-background: #ffffff;--a2ui-button-border: 1px solid #212121;--a2ui-button-border-radius: 999px;--a2ui-button-padding: 8px 14px;--a2ui-button-font-weight: 500;--a2ui-choicepicker-gap: 10px;--a2ui-choicepicker-padding: 0;--a2ui-choicepicker-checkbox-size: 18px;--a2ui-choicepicker-chip-background: #ffffff;--a2ui-choicepicker-chip-background-selected: #212121;--a2ui-choicepicker-chip-border: 1px solid #212121;--a2ui-choicepicker-chip-border-radius: 999px;--a2ui-choicepicker-chip-padding: 7px 14px;--a2ui-choicepicker-chip-color: #212121;--a2ui-choicepicker-chip-border-hover: #ff004d;--a2ui-checkbox-border: 1px solid #212121;--a2ui-checkbox-border-radius: 4px;--a2ui-checkbox-size: 18px;--a2ui-textfield-border: 1px solid #e9e9e9;--a2ui-textfield-border-radius: 8px;--a2ui-textfield-padding: 10px 14px;--a2ui-textfield-color-border-focus: #ff004d;accent-color:#ff004d}.conversation-history ::ng-deep .a2ui-chip:not(.active){color:#212121}.conversation-history{display:flex;flex-direction:column;gap:16px;padding:16px;flex-grow:1;min-height:0;overflow-y:auto}.conversation-history markdown{display:block}.possible-questions{padding:0 20px 10px;display:flex;flex-wrap:wrap;gap:8px}.possible-questions .question-chip{cursor:pointer;transition:all .2s ease;background-color:#e9e9e9;padding:8px;border-radius:5px}.possible-questions .question-chip:hover{transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.input{margin:0 12px 12px;position:relative}.input .textarea{font-family:inherit;background:#212121;border:1px solid #212121;border-radius:4px;color:#fff;z-index:10000;padding:12px 64px 12px 12px;width:100%;box-sizing:border-box;min-height:43px;resize:none}.input .textarea:focus{border-color:#ff004d;outline:none}.input .send-button{position:absolute;right:10px;bottom:9px}.chat-history{background-color:#f3f3f3;border-left:1px solid #e9e9e9;width:300px;height:100vh;overflow:auto;position:fixed;right:500px;top:0}.chat-history .header{justify-content:center}.chat-history .history-items{display:flex;flex-direction:column;gap:8px;padding:8px;overflow:auto}.chat-history .history-items .history-empty{padding:16px 8px;color:#909090;text-align:center;font-size:13px}.chat-history .history-items .chat-history-item{cursor:pointer;background-color:#fff;border-radius:4px;padding:8px}.chat-history .history-items .chat-history-item:hover{filter:brightness(.97)}.chat-history .history-items .chat-history-item .preview{font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.chat-history .history-items .chat-history-item .footer{color:#909090;font-size:11px;display:flex;flex-direction:row;justify-content:space-between}\n"] }]
7235
7293
  }], propDecorators: { historyElement: [{
7236
7294
  type: ViewChild,
7237
7295
  args: ['conversation']
@@ -7295,6 +7353,9 @@ class WorkspaceNavbarComponent {
7295
7353
  const url = this.currentUrl() ?? '';
7296
7354
  return this.findBestRouteMatch(url, this.activeSubTopNavItems())?.id ?? '';
7297
7355
  }, ...(ngDevMode ? [{ debugName: "activeSubTopNavItemId" }] : /* istanbul ignore next */ []));
7356
+ activeWorkspaceAppId = computed(() => {
7357
+ return this.workspaceNavbarService.activeAppIdSignal() ?? this.appId();
7358
+ }, ...(ngDevMode ? [{ debugName: "activeWorkspaceAppId" }] : /* istanbul ignore next */ []));
7298
7359
  signOutIcon = phosphorSignOut;
7299
7360
  plusIcon = phosphorPlus;
7300
7361
  chatIcon = phosphorRobot;
@@ -7319,9 +7380,7 @@ class WorkspaceNavbarComponent {
7319
7380
  icon: this.resolveIcon(app),
7320
7381
  tooltip: app.name,
7321
7382
  });
7322
- const productItems = response.products
7323
- .map(mapApp)
7324
- .sort((a, b) => {
7383
+ const productItems = response.products.map(mapApp).sort((a, b) => {
7325
7384
  const indexA = this.productOrder.indexOf(a.id.toLowerCase());
7326
7385
  const indexB = this.productOrder.indexOf(b.id.toLowerCase());
7327
7386
  const posA = indexA === -1 ? this.productOrder.length : indexA;
@@ -7403,7 +7462,7 @@ class WorkspaceNavbarComponent {
7403
7462
  this.workspaceNavbarService.signOut().subscribe();
7404
7463
  return;
7405
7464
  }
7406
- if (item.id === this.appId()) {
7465
+ if (item.id === this.activeWorkspaceAppId()) {
7407
7466
  return;
7408
7467
  }
7409
7468
  const apps = this.workspaceNavbarService.workspaceAppsSignal() ?? [];
@@ -7456,7 +7515,7 @@ class WorkspaceNavbarComponent {
7456
7515
  });
7457
7516
  }
7458
7517
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkspaceNavbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7459
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: WorkspaceNavbarComponent, isStandalone: true, selector: "ao-workspace-navbar", inputs: { appId: { classPropertyName: "appId", publicName: "appId", isSignal: true, isRequired: true, transformFunction: null }, production: { classPropertyName: "production", publicName: "production", isSignal: true, isRequired: false, transformFunction: null }, topNavItems: { classPropertyName: "topNavItems", publicName: "topNavItems", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, notificationCount: { classPropertyName: "notificationCount", publicName: "notificationCount", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, recommendedFilters: { classPropertyName: "recommendedFilters", publicName: "recommendedFilters", isSignal: true, isRequired: false, transformFunction: null }, activeFilter: { classPropertyName: "activeFilter", publicName: "activeFilter", isSignal: true, isRequired: false, transformFunction: null }, resultGroups: { classPropertyName: "resultGroups", publicName: "resultGroups", isSignal: true, isRequired: false, transformFunction: null }, pageSuggestion: { classPropertyName: "pageSuggestion", publicName: "pageSuggestion", isSignal: true, isRequired: false, transformFunction: null }, aiSuggestions: { classPropertyName: "aiSuggestions", publicName: "aiSuggestions", isSignal: true, isRequired: false, transformFunction: null }, searchLoading: { classPropertyName: "searchLoading", publicName: "searchLoading", isSignal: true, isRequired: false, transformFunction: null }, searchError: { classPropertyName: "searchError", publicName: "searchError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeFilter: "activeFilterChange", topNavItemClick: "topNavItemClick", topNavItemChange: "topNavItemChange", subTopNavItemClick: "subTopNavItemClick", subTopNavItemChange: "subTopNavItemChange", appSwitched: "appSwitched", searchSubmit: "searchSubmit", searchQueryChange: "searchQueryChange", searchViewAll: "searchViewAll", searchResultSelect: "searchResultSelect", searchAiSuggestionSelect: "searchAiSuggestionSelect", searchPageSuggestionSelect: "searchPageSuggestionSelect", searchFilterSelect: "searchFilterSelect", searchFilterClear: "searchFilterClear", notificationClick: "notificationClick" }, host: { classAttribute: "ao-workspace-navbar" }, ngImport: i0, template: "<ao-side-nav\n [items]=\"workspaceAppNavItems()\"\n [bottomItems]=\"bottomNavItems()\"\n [activeItemId]=\"appId()\"\n [expanded]=\"false\"\n (itemClick)=\"onSideNavItemClick($event)\"\n>\n <ao-logo-menu\n aoSideNavLogo\n [items]=\"companyMenuItems()\"\n [selectedItem]=\"selectedCompanyId()\"\n (selectionChange)=\"onCompanyChange($event)\"\n >\n @if (companyLogo()) {\n <img [src]=\"companyLogo()\" alt=\"Logo\" class=\"workspace-navbar__logo\" />\n } @else {\n <svg\n class=\"workspace-navbar__logo\"\n width=\"96\"\n height=\"120\"\n viewBox=\"0 0 96 120\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"Logo\"\n role=\"img\"\n >\n <path\n d=\"M36.6592 37.5955L31.1625 31.4924C28.1349 28.1284 28.4073 22.9247 31.7689 19.8971C33.2769 18.5401 35.2266 17.7918 37.2633 17.7918C39.5929 17.7918 41.8195 18.7781 43.3664 20.4967C45.458 22.824 46.0484 26.0826 44.911 28.998C44.4465 30.1903 43.7234 31.2338 42.7623 32.0988L36.6592 37.5955ZM95.5987 76.4613L83.6854 63.2299L70.4585 75.1363L48.5725 50.8269L54.6802 45.3279C57.6779 42.6253 60.035 39.2156 61.4949 35.4696C65.0969 26.2497 63.2204 15.9497 56.6001 8.58568C46.9981 -2.06444 30.5149 -2.92488 19.8556 6.66801C9.20088 16.2655 8.3359 32.7464 17.9311 43.4057L23.4255 49.5065L14.1118 57.8957C13.5099 58.438 12.9287 58.9621 12.3817 59.4792L12.3703 59.4655L11.2742 60.4518C4.49141 66.5572 0.493621 74.9372 0.0153502 84.045C-0.00525137 84.4317 -0.000673098 84.8185 0.00390115 85.2029L0.0084674 85.7086L0.00160688 87.1494L17.7823 87.1503L17.7938 85.7224L17.7915 85.4134C17.7892 85.2716 17.7869 85.1297 17.7938 84.9809C18.0203 80.6216 19.938 76.61 23.1852 73.6855L35.341 62.7379L57.2271 87.0473L45.0712 97.995C42.1055 100.668 38.261 102.151 34.2449 102.174L32.817 102.183V120L34.2586 119.998C42.6547 119.977 50.7258 116.86 56.9868 111.226L69.1404 100.281L81.0446 113.503L94.276 101.592L82.3718 88.3677L95.5987 76.4613Z\"\n fill=\"#FF004D\"\n />\n </svg>\n }\n </ao-logo-menu>\n</ao-side-nav>\n\n<div class=\"workspace-navbar__main\" [class.workspace-navbar__main--with-subnav]=\"hasSubTopNav()\">\n <div\n class=\"workspace-navbar__nav-wrapper\"\n [class.workspace-navbar__nav-wrapper--hidden]=\"navHidden()\"\n >\n <ao-top-nav\n [items]=\"topNavItems()\"\n [activeItemId]=\"activeTopNavItemId()\"\n [showSearch]=\"showSearch()\"\n [showNotifications]=\"showNotifications()\"\n [notificationCount]=\"notificationCount()\"\n [searchPlaceholder]=\"searchPlaceholder()\"\n [recommendedFilters]=\"recommendedFilters()\"\n [(activeFilter)]=\"activeFilter\"\n [resultGroups]=\"resultGroups()\"\n [pageSuggestion]=\"pageSuggestion()\"\n [aiSuggestions]=\"aiSuggestions()\"\n [searchLoading]=\"searchLoading()\"\n [searchError]=\"searchError()\"\n (itemClick)=\"onTopNavClick($event)\"\n (itemChange)=\"onTopNavChange($event)\"\n (searchSubmit)=\"searchSubmit.emit($event)\"\n (searchQueryChange)=\"searchQueryChange.emit($event)\"\n (searchViewAll)=\"searchViewAll.emit($event)\"\n (searchResultSelect)=\"searchResultSelect.emit($event)\"\n (searchAiSuggestionSelect)=\"searchAiSuggestionSelect.emit($event)\"\n (searchPageSuggestionSelect)=\"searchPageSuggestionSelect.emit($event)\"\n (searchFilterSelect)=\"searchFilterSelect.emit($event)\"\n (searchFilterClear)=\"searchFilterClear.emit()\"\n (notificationClick)=\"onNotificationClick()\"\n [showTools]=\"showTools()\"\n />\n\n @if (hasSubTopNav()) {\n <ao-sub-top-nav\n [items]=\"activeSubTopNavItems()\"\n [activeItemId]=\"activeSubTopNavItemId()\"\n (itemClick)=\"onSubTopNavClick($event)\"\n (itemChange)=\"onSubTopNavChange($event)\"\n />\n }\n </div>\n\n <main class=\"workspace-navbar__content\">\n <ng-content />\n </main>\n</div>\n\n<button ao-button class=\"handbook-chat\" variant=\"primary\" (click)=\"chatOpen.set(!chatOpen())\">\n <ao-icon [svg]=\"chatIcon\" />\n</button>\n\n<div class=\"chat-container\" [class.open]=\"chatOpen()\">\n <lib-chat [searchType]=\"activeFilter()?.type\" (closed)=\"chatOpen.set(false)\" />\n</div>\n", styles: [":host{display:block;min-height:100vh}.workspace-navbar__main{margin-left:70px;padding-top:50px;min-height:100vh}.workspace-navbar__main.workspace-navbar__main--with-subnav{padding-top:100px}.workspace-navbar__nav-wrapper{position:fixed;top:0;left:0;right:0;z-index:3;transform:translateY(0);transition:transform .25s ease}.workspace-navbar__nav-wrapper--hidden{transform:translateY(-100%)}.workspace-navbar__content{padding:30px 0}.workspace-navbar__logo{max-width:32px;max-height:32px;object-fit:contain}.handbook-chat{position:fixed;right:1.5em;bottom:1.5em;z-index:100}.chat-container{position:fixed;width:500px;height:100vh;right:0;top:0;margin-right:-500px;transition:margin-right .5s ease-in-out;background-color:#fff}.chat-container.open{margin-right:0;z-index:501}\n"], dependencies: [{ kind: "component", type: SideNavComponent, selector: "ao-side-nav", inputs: ["items", "bottomItems", "activeItemId", "expanded"], outputs: ["activeItemIdChange", "itemClick", "itemChange", "bottomItemClick"] }, { kind: "component", type: TopNavComponent, selector: "ao-top-nav", inputs: ["items", "activeItemId", "showSearch", "showNotifications", "notificationCount", "searchPlaceholder", "showTools", "recommendedFilters", "activeFilter", "resultGroups", "pageSuggestion", "aiSuggestions", "searchLoading", "searchError"], outputs: ["activeItemIdChange", "activeFilterChange", "itemClick", "itemChange", "searchSubmit", "searchQueryChange", "searchResultSelect", "searchAiSuggestionSelect", "searchPageSuggestionSelect", "searchFilterSelect", "searchFilterClear", "searchViewAll", "notificationClick"] }, { kind: "component", type: SubTopNavComponent, selector: "ao-sub-top-nav", inputs: ["items", "activeItemId"], outputs: ["activeItemIdChange", "itemClick", "itemChange"] }, { kind: "component", type: LogoMenuComponent, selector: "ao-logo-menu", inputs: ["items", "selectedItem", "searchPlaceholder"], outputs: ["selectedItemChange", "selectionChange"] }, { kind: "component", type: IconComponent, selector: "ao-icon", inputs: ["svg", "size"] }, { kind: "component", type: ButtonComponent, selector: "button[ao-button], a[ao-button]", inputs: ["variant", "icon", "iconTrailing"] }, { kind: "component", type: ChatComponent, selector: "lib-chat", inputs: ["searchType"], outputs: ["closed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7518
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: WorkspaceNavbarComponent, isStandalone: true, selector: "ao-workspace-navbar", inputs: { appId: { classPropertyName: "appId", publicName: "appId", isSignal: true, isRequired: true, transformFunction: null }, production: { classPropertyName: "production", publicName: "production", isSignal: true, isRequired: false, transformFunction: null }, topNavItems: { classPropertyName: "topNavItems", publicName: "topNavItems", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, notificationCount: { classPropertyName: "notificationCount", publicName: "notificationCount", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, recommendedFilters: { classPropertyName: "recommendedFilters", publicName: "recommendedFilters", isSignal: true, isRequired: false, transformFunction: null }, activeFilter: { classPropertyName: "activeFilter", publicName: "activeFilter", isSignal: true, isRequired: false, transformFunction: null }, resultGroups: { classPropertyName: "resultGroups", publicName: "resultGroups", isSignal: true, isRequired: false, transformFunction: null }, pageSuggestion: { classPropertyName: "pageSuggestion", publicName: "pageSuggestion", isSignal: true, isRequired: false, transformFunction: null }, aiSuggestions: { classPropertyName: "aiSuggestions", publicName: "aiSuggestions", isSignal: true, isRequired: false, transformFunction: null }, searchLoading: { classPropertyName: "searchLoading", publicName: "searchLoading", isSignal: true, isRequired: false, transformFunction: null }, searchError: { classPropertyName: "searchError", publicName: "searchError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeFilter: "activeFilterChange", topNavItemClick: "topNavItemClick", topNavItemChange: "topNavItemChange", subTopNavItemClick: "subTopNavItemClick", subTopNavItemChange: "subTopNavItemChange", appSwitched: "appSwitched", searchSubmit: "searchSubmit", searchQueryChange: "searchQueryChange", searchViewAll: "searchViewAll", searchResultSelect: "searchResultSelect", searchAiSuggestionSelect: "searchAiSuggestionSelect", searchPageSuggestionSelect: "searchPageSuggestionSelect", searchFilterSelect: "searchFilterSelect", searchFilterClear: "searchFilterClear", notificationClick: "notificationClick" }, host: { classAttribute: "ao-workspace-navbar" }, ngImport: i0, template: "<ao-side-nav\n [items]=\"workspaceAppNavItems()\"\n [bottomItems]=\"bottomNavItems()\"\n [activeItemId]=\"activeWorkspaceAppId()\"\n [expanded]=\"false\"\n (itemClick)=\"onSideNavItemClick($event)\"\n>\n <ao-logo-menu\n aoSideNavLogo\n [items]=\"companyMenuItems()\"\n [selectedItem]=\"selectedCompanyId()\"\n (selectionChange)=\"onCompanyChange($event)\"\n >\n @if (companyLogo()) {\n <img [src]=\"companyLogo()\" alt=\"Logo\" class=\"workspace-navbar__logo\" />\n } @else {\n <svg\n class=\"workspace-navbar__logo\"\n width=\"96\"\n height=\"120\"\n viewBox=\"0 0 96 120\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"Logo\"\n role=\"img\"\n >\n <path\n d=\"M36.6592 37.5955L31.1625 31.4924C28.1349 28.1284 28.4073 22.9247 31.7689 19.8971C33.2769 18.5401 35.2266 17.7918 37.2633 17.7918C39.5929 17.7918 41.8195 18.7781 43.3664 20.4967C45.458 22.824 46.0484 26.0826 44.911 28.998C44.4465 30.1903 43.7234 31.2338 42.7623 32.0988L36.6592 37.5955ZM95.5987 76.4613L83.6854 63.2299L70.4585 75.1363L48.5725 50.8269L54.6802 45.3279C57.6779 42.6253 60.035 39.2156 61.4949 35.4696C65.0969 26.2497 63.2204 15.9497 56.6001 8.58568C46.9981 -2.06444 30.5149 -2.92488 19.8556 6.66801C9.20088 16.2655 8.3359 32.7464 17.9311 43.4057L23.4255 49.5065L14.1118 57.8957C13.5099 58.438 12.9287 58.9621 12.3817 59.4792L12.3703 59.4655L11.2742 60.4518C4.49141 66.5572 0.493621 74.9372 0.0153502 84.045C-0.00525137 84.4317 -0.000673098 84.8185 0.00390115 85.2029L0.0084674 85.7086L0.00160688 87.1494L17.7823 87.1503L17.7938 85.7224L17.7915 85.4134C17.7892 85.2716 17.7869 85.1297 17.7938 84.9809C18.0203 80.6216 19.938 76.61 23.1852 73.6855L35.341 62.7379L57.2271 87.0473L45.0712 97.995C42.1055 100.668 38.261 102.151 34.2449 102.174L32.817 102.183V120L34.2586 119.998C42.6547 119.977 50.7258 116.86 56.9868 111.226L69.1404 100.281L81.0446 113.503L94.276 101.592L82.3718 88.3677L95.5987 76.4613Z\"\n fill=\"#FF004D\"\n />\n </svg>\n }\n </ao-logo-menu>\n</ao-side-nav>\n\n<div class=\"workspace-navbar__main\" [class.workspace-navbar__main--with-subnav]=\"hasSubTopNav()\">\n <div\n class=\"workspace-navbar__nav-wrapper\"\n [class.workspace-navbar__nav-wrapper--hidden]=\"navHidden()\"\n >\n <ao-top-nav\n [items]=\"topNavItems()\"\n [activeItemId]=\"activeTopNavItemId()\"\n [showSearch]=\"showSearch()\"\n [showNotifications]=\"showNotifications()\"\n [notificationCount]=\"notificationCount()\"\n [searchPlaceholder]=\"searchPlaceholder()\"\n [recommendedFilters]=\"recommendedFilters()\"\n [(activeFilter)]=\"activeFilter\"\n [resultGroups]=\"resultGroups()\"\n [pageSuggestion]=\"pageSuggestion()\"\n [aiSuggestions]=\"aiSuggestions()\"\n [searchLoading]=\"searchLoading()\"\n [searchError]=\"searchError()\"\n (itemClick)=\"onTopNavClick($event)\"\n (itemChange)=\"onTopNavChange($event)\"\n (searchSubmit)=\"searchSubmit.emit($event)\"\n (searchQueryChange)=\"searchQueryChange.emit($event)\"\n (searchViewAll)=\"searchViewAll.emit($event)\"\n (searchResultSelect)=\"searchResultSelect.emit($event)\"\n (searchAiSuggestionSelect)=\"searchAiSuggestionSelect.emit($event)\"\n (searchPageSuggestionSelect)=\"searchPageSuggestionSelect.emit($event)\"\n (searchFilterSelect)=\"searchFilterSelect.emit($event)\"\n (searchFilterClear)=\"searchFilterClear.emit()\"\n (notificationClick)=\"onNotificationClick()\"\n [showTools]=\"showTools()\"\n />\n\n @if (hasSubTopNav()) {\n <ao-sub-top-nav\n [items]=\"activeSubTopNavItems()\"\n [activeItemId]=\"activeSubTopNavItemId()\"\n (itemClick)=\"onSubTopNavClick($event)\"\n (itemChange)=\"onSubTopNavChange($event)\"\n />\n }\n </div>\n\n <main class=\"workspace-navbar__content\">\n <ng-content />\n </main>\n</div>\n\n<button ao-button class=\"handbook-chat\" variant=\"primary\" (click)=\"chatOpen.set(!chatOpen())\">\n <ao-icon [svg]=\"chatIcon\" />\n</button>\n\n<div class=\"chat-container\" [class.open]=\"chatOpen()\">\n <lib-chat [searchType]=\"activeFilter()?.type\" (closed)=\"chatOpen.set(false)\" />\n</div>\n", styles: [":host{display:block;min-height:100vh}.workspace-navbar__main{margin-left:70px;padding-top:50px;min-height:100vh}.workspace-navbar__main.workspace-navbar__main--with-subnav{padding-top:100px}.workspace-navbar__nav-wrapper{position:fixed;top:0;left:0;right:0;z-index:3;transform:translateY(0);transition:transform .25s ease}.workspace-navbar__nav-wrapper--hidden{transform:translateY(-100%)}.workspace-navbar__content{padding:30px 0}.workspace-navbar__logo{max-width:32px;max-height:32px;object-fit:contain}.handbook-chat{position:fixed;right:1.5em;bottom:1.5em;z-index:100}.chat-container{position:fixed;width:500px;height:100vh;right:0;top:0;margin-right:-500px;transition:margin-right .5s ease-in-out;background-color:#fff}.chat-container.open{margin-right:0;z-index:501}\n"], dependencies: [{ kind: "component", type: SideNavComponent, selector: "ao-side-nav", inputs: ["items", "bottomItems", "activeItemId", "expanded"], outputs: ["activeItemIdChange", "itemClick", "itemChange", "bottomItemClick"] }, { kind: "component", type: TopNavComponent, selector: "ao-top-nav", inputs: ["items", "activeItemId", "showSearch", "showNotifications", "notificationCount", "searchPlaceholder", "showTools", "recommendedFilters", "activeFilter", "resultGroups", "pageSuggestion", "aiSuggestions", "searchLoading", "searchError"], outputs: ["activeItemIdChange", "activeFilterChange", "itemClick", "itemChange", "searchSubmit", "searchQueryChange", "searchResultSelect", "searchAiSuggestionSelect", "searchPageSuggestionSelect", "searchFilterSelect", "searchFilterClear", "searchViewAll", "notificationClick"] }, { kind: "component", type: SubTopNavComponent, selector: "ao-sub-top-nav", inputs: ["items", "activeItemId"], outputs: ["activeItemIdChange", "itemClick", "itemChange"] }, { kind: "component", type: LogoMenuComponent, selector: "ao-logo-menu", inputs: ["items", "selectedItem", "searchPlaceholder"], outputs: ["selectedItemChange", "selectionChange"] }, { kind: "component", type: IconComponent, selector: "ao-icon", inputs: ["svg", "size"] }, { kind: "component", type: ButtonComponent, selector: "button[ao-button], a[ao-button]", inputs: ["variant", "icon", "iconTrailing"] }, { kind: "component", type: ChatComponent, selector: "lib-chat", inputs: ["searchType"], outputs: ["closed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7460
7519
  }
7461
7520
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkspaceNavbarComponent, decorators: [{
7462
7521
  type: Component,
@@ -7470,9 +7529,149 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
7470
7529
  ChatComponent,
7471
7530
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
7472
7531
  class: 'ao-workspace-navbar',
7473
- }, template: "<ao-side-nav\n [items]=\"workspaceAppNavItems()\"\n [bottomItems]=\"bottomNavItems()\"\n [activeItemId]=\"appId()\"\n [expanded]=\"false\"\n (itemClick)=\"onSideNavItemClick($event)\"\n>\n <ao-logo-menu\n aoSideNavLogo\n [items]=\"companyMenuItems()\"\n [selectedItem]=\"selectedCompanyId()\"\n (selectionChange)=\"onCompanyChange($event)\"\n >\n @if (companyLogo()) {\n <img [src]=\"companyLogo()\" alt=\"Logo\" class=\"workspace-navbar__logo\" />\n } @else {\n <svg\n class=\"workspace-navbar__logo\"\n width=\"96\"\n height=\"120\"\n viewBox=\"0 0 96 120\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"Logo\"\n role=\"img\"\n >\n <path\n d=\"M36.6592 37.5955L31.1625 31.4924C28.1349 28.1284 28.4073 22.9247 31.7689 19.8971C33.2769 18.5401 35.2266 17.7918 37.2633 17.7918C39.5929 17.7918 41.8195 18.7781 43.3664 20.4967C45.458 22.824 46.0484 26.0826 44.911 28.998C44.4465 30.1903 43.7234 31.2338 42.7623 32.0988L36.6592 37.5955ZM95.5987 76.4613L83.6854 63.2299L70.4585 75.1363L48.5725 50.8269L54.6802 45.3279C57.6779 42.6253 60.035 39.2156 61.4949 35.4696C65.0969 26.2497 63.2204 15.9497 56.6001 8.58568C46.9981 -2.06444 30.5149 -2.92488 19.8556 6.66801C9.20088 16.2655 8.3359 32.7464 17.9311 43.4057L23.4255 49.5065L14.1118 57.8957C13.5099 58.438 12.9287 58.9621 12.3817 59.4792L12.3703 59.4655L11.2742 60.4518C4.49141 66.5572 0.493621 74.9372 0.0153502 84.045C-0.00525137 84.4317 -0.000673098 84.8185 0.00390115 85.2029L0.0084674 85.7086L0.00160688 87.1494L17.7823 87.1503L17.7938 85.7224L17.7915 85.4134C17.7892 85.2716 17.7869 85.1297 17.7938 84.9809C18.0203 80.6216 19.938 76.61 23.1852 73.6855L35.341 62.7379L57.2271 87.0473L45.0712 97.995C42.1055 100.668 38.261 102.151 34.2449 102.174L32.817 102.183V120L34.2586 119.998C42.6547 119.977 50.7258 116.86 56.9868 111.226L69.1404 100.281L81.0446 113.503L94.276 101.592L82.3718 88.3677L95.5987 76.4613Z\"\n fill=\"#FF004D\"\n />\n </svg>\n }\n </ao-logo-menu>\n</ao-side-nav>\n\n<div class=\"workspace-navbar__main\" [class.workspace-navbar__main--with-subnav]=\"hasSubTopNav()\">\n <div\n class=\"workspace-navbar__nav-wrapper\"\n [class.workspace-navbar__nav-wrapper--hidden]=\"navHidden()\"\n >\n <ao-top-nav\n [items]=\"topNavItems()\"\n [activeItemId]=\"activeTopNavItemId()\"\n [showSearch]=\"showSearch()\"\n [showNotifications]=\"showNotifications()\"\n [notificationCount]=\"notificationCount()\"\n [searchPlaceholder]=\"searchPlaceholder()\"\n [recommendedFilters]=\"recommendedFilters()\"\n [(activeFilter)]=\"activeFilter\"\n [resultGroups]=\"resultGroups()\"\n [pageSuggestion]=\"pageSuggestion()\"\n [aiSuggestions]=\"aiSuggestions()\"\n [searchLoading]=\"searchLoading()\"\n [searchError]=\"searchError()\"\n (itemClick)=\"onTopNavClick($event)\"\n (itemChange)=\"onTopNavChange($event)\"\n (searchSubmit)=\"searchSubmit.emit($event)\"\n (searchQueryChange)=\"searchQueryChange.emit($event)\"\n (searchViewAll)=\"searchViewAll.emit($event)\"\n (searchResultSelect)=\"searchResultSelect.emit($event)\"\n (searchAiSuggestionSelect)=\"searchAiSuggestionSelect.emit($event)\"\n (searchPageSuggestionSelect)=\"searchPageSuggestionSelect.emit($event)\"\n (searchFilterSelect)=\"searchFilterSelect.emit($event)\"\n (searchFilterClear)=\"searchFilterClear.emit()\"\n (notificationClick)=\"onNotificationClick()\"\n [showTools]=\"showTools()\"\n />\n\n @if (hasSubTopNav()) {\n <ao-sub-top-nav\n [items]=\"activeSubTopNavItems()\"\n [activeItemId]=\"activeSubTopNavItemId()\"\n (itemClick)=\"onSubTopNavClick($event)\"\n (itemChange)=\"onSubTopNavChange($event)\"\n />\n }\n </div>\n\n <main class=\"workspace-navbar__content\">\n <ng-content />\n </main>\n</div>\n\n<button ao-button class=\"handbook-chat\" variant=\"primary\" (click)=\"chatOpen.set(!chatOpen())\">\n <ao-icon [svg]=\"chatIcon\" />\n</button>\n\n<div class=\"chat-container\" [class.open]=\"chatOpen()\">\n <lib-chat [searchType]=\"activeFilter()?.type\" (closed)=\"chatOpen.set(false)\" />\n</div>\n", styles: [":host{display:block;min-height:100vh}.workspace-navbar__main{margin-left:70px;padding-top:50px;min-height:100vh}.workspace-navbar__main.workspace-navbar__main--with-subnav{padding-top:100px}.workspace-navbar__nav-wrapper{position:fixed;top:0;left:0;right:0;z-index:3;transform:translateY(0);transition:transform .25s ease}.workspace-navbar__nav-wrapper--hidden{transform:translateY(-100%)}.workspace-navbar__content{padding:30px 0}.workspace-navbar__logo{max-width:32px;max-height:32px;object-fit:contain}.handbook-chat{position:fixed;right:1.5em;bottom:1.5em;z-index:100}.chat-container{position:fixed;width:500px;height:100vh;right:0;top:0;margin-right:-500px;transition:margin-right .5s ease-in-out;background-color:#fff}.chat-container.open{margin-right:0;z-index:501}\n"] }]
7532
+ }, template: "<ao-side-nav\n [items]=\"workspaceAppNavItems()\"\n [bottomItems]=\"bottomNavItems()\"\n [activeItemId]=\"activeWorkspaceAppId()\"\n [expanded]=\"false\"\n (itemClick)=\"onSideNavItemClick($event)\"\n>\n <ao-logo-menu\n aoSideNavLogo\n [items]=\"companyMenuItems()\"\n [selectedItem]=\"selectedCompanyId()\"\n (selectionChange)=\"onCompanyChange($event)\"\n >\n @if (companyLogo()) {\n <img [src]=\"companyLogo()\" alt=\"Logo\" class=\"workspace-navbar__logo\" />\n } @else {\n <svg\n class=\"workspace-navbar__logo\"\n width=\"96\"\n height=\"120\"\n viewBox=\"0 0 96 120\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"Logo\"\n role=\"img\"\n >\n <path\n d=\"M36.6592 37.5955L31.1625 31.4924C28.1349 28.1284 28.4073 22.9247 31.7689 19.8971C33.2769 18.5401 35.2266 17.7918 37.2633 17.7918C39.5929 17.7918 41.8195 18.7781 43.3664 20.4967C45.458 22.824 46.0484 26.0826 44.911 28.998C44.4465 30.1903 43.7234 31.2338 42.7623 32.0988L36.6592 37.5955ZM95.5987 76.4613L83.6854 63.2299L70.4585 75.1363L48.5725 50.8269L54.6802 45.3279C57.6779 42.6253 60.035 39.2156 61.4949 35.4696C65.0969 26.2497 63.2204 15.9497 56.6001 8.58568C46.9981 -2.06444 30.5149 -2.92488 19.8556 6.66801C9.20088 16.2655 8.3359 32.7464 17.9311 43.4057L23.4255 49.5065L14.1118 57.8957C13.5099 58.438 12.9287 58.9621 12.3817 59.4792L12.3703 59.4655L11.2742 60.4518C4.49141 66.5572 0.493621 74.9372 0.0153502 84.045C-0.00525137 84.4317 -0.000673098 84.8185 0.00390115 85.2029L0.0084674 85.7086L0.00160688 87.1494L17.7823 87.1503L17.7938 85.7224L17.7915 85.4134C17.7892 85.2716 17.7869 85.1297 17.7938 84.9809C18.0203 80.6216 19.938 76.61 23.1852 73.6855L35.341 62.7379L57.2271 87.0473L45.0712 97.995C42.1055 100.668 38.261 102.151 34.2449 102.174L32.817 102.183V120L34.2586 119.998C42.6547 119.977 50.7258 116.86 56.9868 111.226L69.1404 100.281L81.0446 113.503L94.276 101.592L82.3718 88.3677L95.5987 76.4613Z\"\n fill=\"#FF004D\"\n />\n </svg>\n }\n </ao-logo-menu>\n</ao-side-nav>\n\n<div class=\"workspace-navbar__main\" [class.workspace-navbar__main--with-subnav]=\"hasSubTopNav()\">\n <div\n class=\"workspace-navbar__nav-wrapper\"\n [class.workspace-navbar__nav-wrapper--hidden]=\"navHidden()\"\n >\n <ao-top-nav\n [items]=\"topNavItems()\"\n [activeItemId]=\"activeTopNavItemId()\"\n [showSearch]=\"showSearch()\"\n [showNotifications]=\"showNotifications()\"\n [notificationCount]=\"notificationCount()\"\n [searchPlaceholder]=\"searchPlaceholder()\"\n [recommendedFilters]=\"recommendedFilters()\"\n [(activeFilter)]=\"activeFilter\"\n [resultGroups]=\"resultGroups()\"\n [pageSuggestion]=\"pageSuggestion()\"\n [aiSuggestions]=\"aiSuggestions()\"\n [searchLoading]=\"searchLoading()\"\n [searchError]=\"searchError()\"\n (itemClick)=\"onTopNavClick($event)\"\n (itemChange)=\"onTopNavChange($event)\"\n (searchSubmit)=\"searchSubmit.emit($event)\"\n (searchQueryChange)=\"searchQueryChange.emit($event)\"\n (searchViewAll)=\"searchViewAll.emit($event)\"\n (searchResultSelect)=\"searchResultSelect.emit($event)\"\n (searchAiSuggestionSelect)=\"searchAiSuggestionSelect.emit($event)\"\n (searchPageSuggestionSelect)=\"searchPageSuggestionSelect.emit($event)\"\n (searchFilterSelect)=\"searchFilterSelect.emit($event)\"\n (searchFilterClear)=\"searchFilterClear.emit()\"\n (notificationClick)=\"onNotificationClick()\"\n [showTools]=\"showTools()\"\n />\n\n @if (hasSubTopNav()) {\n <ao-sub-top-nav\n [items]=\"activeSubTopNavItems()\"\n [activeItemId]=\"activeSubTopNavItemId()\"\n (itemClick)=\"onSubTopNavClick($event)\"\n (itemChange)=\"onSubTopNavChange($event)\"\n />\n }\n </div>\n\n <main class=\"workspace-navbar__content\">\n <ng-content />\n </main>\n</div>\n\n<button ao-button class=\"handbook-chat\" variant=\"primary\" (click)=\"chatOpen.set(!chatOpen())\">\n <ao-icon [svg]=\"chatIcon\" />\n</button>\n\n<div class=\"chat-container\" [class.open]=\"chatOpen()\">\n <lib-chat [searchType]=\"activeFilter()?.type\" (closed)=\"chatOpen.set(false)\" />\n</div>\n", styles: [":host{display:block;min-height:100vh}.workspace-navbar__main{margin-left:70px;padding-top:50px;min-height:100vh}.workspace-navbar__main.workspace-navbar__main--with-subnav{padding-top:100px}.workspace-navbar__nav-wrapper{position:fixed;top:0;left:0;right:0;z-index:3;transform:translateY(0);transition:transform .25s ease}.workspace-navbar__nav-wrapper--hidden{transform:translateY(-100%)}.workspace-navbar__content{padding:30px 0}.workspace-navbar__logo{max-width:32px;max-height:32px;object-fit:contain}.handbook-chat{position:fixed;right:1.5em;bottom:1.5em;z-index:100}.chat-container{position:fixed;width:500px;height:100vh;right:0;top:0;margin-right:-500px;transition:margin-right .5s ease-in-out;background-color:#fff}.chat-container.open{margin-right:0;z-index:501}\n"] }]
7474
7533
  }], ctorParameters: () => [], propDecorators: { appId: [{ type: i0.Input, args: [{ isSignal: true, alias: "appId", required: true }] }], production: [{ type: i0.Input, args: [{ isSignal: true, alias: "production", required: false }] }], topNavItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "topNavItems", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], showNotifications: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNotifications", required: false }] }], notificationCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "notificationCount", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], recommendedFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "recommendedFilters", required: false }] }], activeFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeFilter", required: false }] }, { type: i0.Output, args: ["activeFilterChange"] }], resultGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "resultGroups", required: false }] }], pageSuggestion: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSuggestion", required: false }] }], aiSuggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiSuggestions", required: false }] }], searchLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchLoading", required: false }] }], searchError: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchError", required: false }] }], topNavItemClick: [{ type: i0.Output, args: ["topNavItemClick"] }], topNavItemChange: [{ type: i0.Output, args: ["topNavItemChange"] }], subTopNavItemClick: [{ type: i0.Output, args: ["subTopNavItemClick"] }], subTopNavItemChange: [{ type: i0.Output, args: ["subTopNavItemChange"] }], appSwitched: [{ type: i0.Output, args: ["appSwitched"] }], searchSubmit: [{ type: i0.Output, args: ["searchSubmit"] }], searchQueryChange: [{ type: i0.Output, args: ["searchQueryChange"] }], searchViewAll: [{ type: i0.Output, args: ["searchViewAll"] }], searchResultSelect: [{ type: i0.Output, args: ["searchResultSelect"] }], searchAiSuggestionSelect: [{ type: i0.Output, args: ["searchAiSuggestionSelect"] }], searchPageSuggestionSelect: [{ type: i0.Output, args: ["searchPageSuggestionSelect"] }], searchFilterSelect: [{ type: i0.Output, args: ["searchFilterSelect"] }], searchFilterClear: [{ type: i0.Output, args: ["searchFilterClear"] }], notificationClick: [{ type: i0.Output, args: ["notificationClick"] }] } });
7475
7534
 
7535
+ /**
7536
+ * Robin-flavoured ChoicePicker that keeps the basic A2UI look but turns chip
7537
+ * selections into server actions so quick-reply chips behave like chat buttons.
7538
+ */
7539
+ class AoChoicePickerComponent extends CatalogComponent {
7540
+ displayStyle = computed(() => this.readString('displayStyle') ?? 'checkbox', ...(ngDevMode ? [{ debugName: "displayStyle" }] : /* istanbul ignore next */ []));
7541
+ options = computed(() => this.readOptions(), ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
7542
+ selectedValue = computed(() => this.readSelectedValues(), ...(ngDevMode ? [{ debugName: "selectedValue" }] : /* istanbul ignore next */ []));
7543
+ renderer = inject(A2uiRendererService);
7544
+ isMultiple() {
7545
+ return this.readString('variant') === 'multipleSelection';
7546
+ }
7547
+ isSelected(value) {
7548
+ return this.selectedValue().includes(value);
7549
+ }
7550
+ selectOption(option) {
7551
+ const nextValue = this.getNextValue(option.value);
7552
+ this.props()['value']?.onUpdate([...nextValue]);
7553
+ if (this.displayStyle() === 'chips')
7554
+ this.dispatchSelection(option, nextValue);
7555
+ }
7556
+ getNextValue(value) {
7557
+ if (!this.isMultiple())
7558
+ return [value];
7559
+ if (this.isSelected(value))
7560
+ return this.selectedValue().filter(item => item !== value);
7561
+ return [...this.selectedValue(), value];
7562
+ }
7563
+ dispatchSelection(option, selectedValues) {
7564
+ const surface = this.renderer.surfaceGroup.getSurface(this.surfaceId());
7565
+ if (!surface)
7566
+ return;
7567
+ void surface.dispatchAction({
7568
+ event: {
7569
+ name: 'choiceSelected',
7570
+ context: {
7571
+ componentId: this.componentId(),
7572
+ label: option.label,
7573
+ selectedValue: option.value,
7574
+ selectedValues: [...selectedValues],
7575
+ },
7576
+ },
7577
+ }, this.componentId());
7578
+ }
7579
+ readString(key) {
7580
+ const value = this.props()[key]?.value();
7581
+ return typeof value === 'string' ? value : undefined;
7582
+ }
7583
+ readSelectedValues() {
7584
+ const value = this.props()['value']?.value();
7585
+ if (!Array.isArray(value))
7586
+ return [];
7587
+ return value.filter((item) => typeof item === 'string');
7588
+ }
7589
+ readOptions() {
7590
+ const value = this.props()['options']?.value();
7591
+ if (!Array.isArray(value))
7592
+ return [];
7593
+ return value.filter(this.isChoicePickerOption);
7594
+ }
7595
+ isChoicePickerOption(value) {
7596
+ if (!value || typeof value !== 'object')
7597
+ return false;
7598
+ const option = value;
7599
+ return typeof option['label'] === 'string' && typeof option['value'] === 'string';
7600
+ }
7601
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoChoicePickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
7602
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: AoChoicePickerComponent, isStandalone: true, selector: "lib-ao-choice-picker", usesInheritance: true, ngImport: i0, template: `
7603
+ <div class="a2ui-choice-picker">
7604
+ @if (displayStyle() === 'chips') {
7605
+ <div class="a2ui-chips-group">
7606
+ @for (option of options(); track option.value) {
7607
+ <button
7608
+ type="button"
7609
+ class="a2ui-chip"
7610
+ [class.active]="isSelected(option.value)"
7611
+ (click)="selectOption(option)"
7612
+ >
7613
+ {{ option.label }}
7614
+ </button>
7615
+ }
7616
+ </div>
7617
+ } @else {
7618
+ <div class="a2ui-options-group">
7619
+ @for (option of options(); track option.value) {
7620
+ <label class="a2ui-option-label">
7621
+ <input
7622
+ [type]="isMultiple() ? 'checkbox' : 'radio'"
7623
+ [name]="componentId()"
7624
+ [value]="option.value"
7625
+ [checked]="isSelected(option.value)"
7626
+ (change)="selectOption(option)"
7627
+ class="a2ui-option-input"
7628
+ />
7629
+ <span class="a2ui-option-text">{{ option.label }}</span>
7630
+ </label>
7631
+ }
7632
+ </div>
7633
+ }
7634
+ </div>
7635
+ `, isInline: true, styles: [".a2ui-choice-picker{padding:var(--a2ui-choicepicker-padding, 0);width:100%}.a2ui-options-group,.a2ui-chips-group{display:flex;flex-wrap:wrap;gap:var(--a2ui-choicepicker-gap, var(--a2ui-spacing-xs, .25rem))}.a2ui-options-group{flex-direction:column}.a2ui-option-label{align-items:center;color:var(--a2ui-text-color-text, var(--a2ui-color-on-background, #333));cursor:pointer;display:flex;gap:var(--a2ui-choicepicker-gap, var(--a2ui-spacing-xs, .25rem))}.a2ui-option-input{height:var(--a2ui-choicepicker-checkbox-size, 1rem);width:var(--a2ui-choicepicker-checkbox-size, 1rem)}.a2ui-chip{background:var(--a2ui-choicepicker-chip-background, var(--a2ui-color-surface, #fff));border:var(--a2ui-choicepicker-chip-border, 1px solid var(--a2ui-color-border, #ccc));border-radius:var(--a2ui-choicepicker-chip-border-radius, 100px);color:var(--a2ui-choicepicker-chip-color, var(--a2ui-color-on-background, #333));cursor:pointer;font:inherit;padding:var( --a2ui-choicepicker-chip-padding, var(--a2ui-spacing-s, .5rem) var(--a2ui-spacing-m, 1rem) );transition:background-color .16s ease,border-color .16s ease,color .16s ease,transform .16s ease}.a2ui-chip:hover{border-color:var(--a2ui-choicepicker-chip-border-hover, var(--a2ui-color-primary, #17e));transform:translateY(-1px)}.a2ui-chip.active{background:var( --a2ui-choicepicker-chip-background-selected, var(--a2ui-color-primary, #17e) );border-color:var( --a2ui-choicepicker-chip-background-selected, var(--a2ui-color-primary, #17e) );color:var(--a2ui-color-on-primary, #fff)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7636
+ }
7637
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoChoicePickerComponent, decorators: [{
7638
+ type: Component,
7639
+ args: [{ selector: 'lib-ao-choice-picker', template: `
7640
+ <div class="a2ui-choice-picker">
7641
+ @if (displayStyle() === 'chips') {
7642
+ <div class="a2ui-chips-group">
7643
+ @for (option of options(); track option.value) {
7644
+ <button
7645
+ type="button"
7646
+ class="a2ui-chip"
7647
+ [class.active]="isSelected(option.value)"
7648
+ (click)="selectOption(option)"
7649
+ >
7650
+ {{ option.label }}
7651
+ </button>
7652
+ }
7653
+ </div>
7654
+ } @else {
7655
+ <div class="a2ui-options-group">
7656
+ @for (option of options(); track option.value) {
7657
+ <label class="a2ui-option-label">
7658
+ <input
7659
+ [type]="isMultiple() ? 'checkbox' : 'radio'"
7660
+ [name]="componentId()"
7661
+ [value]="option.value"
7662
+ [checked]="isSelected(option.value)"
7663
+ (change)="selectOption(option)"
7664
+ class="a2ui-option-input"
7665
+ />
7666
+ <span class="a2ui-option-text">{{ option.label }}</span>
7667
+ </label>
7668
+ }
7669
+ </div>
7670
+ }
7671
+ </div>
7672
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-choice-picker{padding:var(--a2ui-choicepicker-padding, 0);width:100%}.a2ui-options-group,.a2ui-chips-group{display:flex;flex-wrap:wrap;gap:var(--a2ui-choicepicker-gap, var(--a2ui-spacing-xs, .25rem))}.a2ui-options-group{flex-direction:column}.a2ui-option-label{align-items:center;color:var(--a2ui-text-color-text, var(--a2ui-color-on-background, #333));cursor:pointer;display:flex;gap:var(--a2ui-choicepicker-gap, var(--a2ui-spacing-xs, .25rem))}.a2ui-option-input{height:var(--a2ui-choicepicker-checkbox-size, 1rem);width:var(--a2ui-choicepicker-checkbox-size, 1rem)}.a2ui-chip{background:var(--a2ui-choicepicker-chip-background, var(--a2ui-color-surface, #fff));border:var(--a2ui-choicepicker-chip-border, 1px solid var(--a2ui-color-border, #ccc));border-radius:var(--a2ui-choicepicker-chip-border-radius, 100px);color:var(--a2ui-choicepicker-chip-color, var(--a2ui-color-on-background, #333));cursor:pointer;font:inherit;padding:var( --a2ui-choicepicker-chip-padding, var(--a2ui-spacing-s, .5rem) var(--a2ui-spacing-m, 1rem) );transition:background-color .16s ease,border-color .16s ease,color .16s ease,transform .16s ease}.a2ui-chip:hover{border-color:var(--a2ui-choicepicker-chip-border-hover, var(--a2ui-color-primary, #17e));transform:translateY(-1px)}.a2ui-chip.active{background:var( --a2ui-choicepicker-chip-background-selected, var(--a2ui-color-primary, #17e) );border-color:var( --a2ui-choicepicker-chip-background-selected, var(--a2ui-color-primary, #17e) );color:var(--a2ui-color-on-primary, #fff)}\n"] }]
7673
+ }] });
7674
+
7476
7675
  const AO_CATALOG_ID = 'ah-oh.com:robin-v1';
7477
7676
  /**
7478
7677
  * Robin's design-system catalog. Phase 1 delegates entirely to the upstream
@@ -7487,7 +7686,12 @@ const AO_CATALOG_ID = 'ah-oh.com:robin-v1';
7487
7686
  */
7488
7687
  class AoCatalog extends BasicCatalogBase {
7489
7688
  constructor() {
7490
- super({ id: AO_CATALOG_ID });
7689
+ super({
7690
+ id: AO_CATALOG_ID,
7691
+ components: {
7692
+ choicePicker: { ...ChoicePickerApi, component: AoChoicePickerComponent },
7693
+ },
7694
+ });
7491
7695
  }
7492
7696
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoCatalog, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7493
7697
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoCatalog, providedIn: 'root' });
@@ -7506,7 +7710,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
7506
7710
  function provideRobinA2ui() {
7507
7711
  return makeEnvironmentProviders([
7508
7712
  AoCatalog,
7509
- provideMarkdownRenderer(),
7713
+ provideMarkdownRenderer((markdown) => renderMarkdown(markdown).catch(renderFallbackMarkdown)),
7510
7714
  {
7511
7715
  provide: A2UI_RENDERER_CONFIG,
7512
7716
  useFactory: () => {
@@ -7523,6 +7727,24 @@ function provideRobinA2ui() {
7523
7727
  A2uiRendererService,
7524
7728
  ]);
7525
7729
  }
7730
+ function renderFallbackMarkdown(markdown) {
7731
+ return escapeHtml(markdown)
7732
+ .replace(/^#### (.*)$/gim, '<h4>$1</h4>')
7733
+ .replace(/^### (.*)$/gim, '<h3>$1</h3>')
7734
+ .replace(/^## (.*)$/gim, '<h2>$1</h2>')
7735
+ .replace(/^# (.*)$/gim, '<h1>$1</h1>')
7736
+ .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
7737
+ .replace(/\*(.*?)\*/g, '<em>$1</em>')
7738
+ .replace(/\n/g, '<br>');
7739
+ }
7740
+ function escapeHtml(value) {
7741
+ return value
7742
+ .replace(/&/g, '&amp;')
7743
+ .replace(/</g, '&lt;')
7744
+ .replace(/>/g, '&gt;')
7745
+ .replace(/"/g, '&quot;')
7746
+ .replace(/'/g, '&#39;');
7747
+ }
7526
7748
 
7527
7749
  /*
7528
7750
  * Public API Surface of design-system