@ah-oh/ao-workspaces-design-system 0.0.54 → 0.0.56
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 });
|
|
@@ -6937,8 +6939,7 @@ class ChatMessageComponent {
|
|
|
6937
6939
|
normalisedParts = computed(() => this.parts().map(part => (part.kind === 'error' ? this.toTextPart(part.fallback) : part)), ...(ngDevMode ? [{ debugName: "normalisedParts" }] : /* istanbul ignore next */ []));
|
|
6938
6940
|
router = inject(Router);
|
|
6939
6941
|
/**
|
|
6940
|
-
* Hook for in-app navigation triggered from markdown links.
|
|
6941
|
-
* template via (load) on <markdown>.
|
|
6942
|
+
* Hook for in-app navigation triggered from rendered markdown links.
|
|
6942
6943
|
*/
|
|
6943
6944
|
onMarkdownReady(element) {
|
|
6944
6945
|
this.convertLinks(element);
|
|
@@ -6947,48 +6948,61 @@ class ChatMessageComponent {
|
|
|
6947
6948
|
return { kind: 'text', content: fallback };
|
|
6948
6949
|
}
|
|
6949
6950
|
convertLinks(element) {
|
|
6950
|
-
if (element
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6951
|
+
if (!element)
|
|
6952
|
+
return;
|
|
6953
|
+
const currentUrl = new URL(window.location.href);
|
|
6954
|
+
const anchors = Array.from(element.querySelectorAll('a[href]'));
|
|
6955
|
+
for (const anchor of anchors) {
|
|
6956
|
+
if (anchor.dataset['robinRouterLink'] === 'true')
|
|
6957
|
+
continue;
|
|
6958
|
+
const linkUrl = this.parseUrl(anchor.getAttribute('href') ?? '', currentUrl);
|
|
6959
|
+
if (!linkUrl)
|
|
6960
|
+
continue;
|
|
6961
|
+
if (currentUrl.host !== linkUrl.host)
|
|
6962
|
+
continue;
|
|
6963
|
+
anchor.dataset['robinRouterLink'] = 'true';
|
|
6964
|
+
anchor.addEventListener('click', event => {
|
|
6965
|
+
void this.router.navigateByUrl(`${linkUrl.pathname}${linkUrl.search}`);
|
|
6966
|
+
event.stopPropagation();
|
|
6967
|
+
event.preventDefault();
|
|
6968
|
+
});
|
|
6964
6969
|
}
|
|
6965
|
-
|
|
6966
|
-
|
|
6970
|
+
}
|
|
6971
|
+
parseUrl(value, base) {
|
|
6972
|
+
try {
|
|
6973
|
+
return new URL(value, base);
|
|
6974
|
+
}
|
|
6975
|
+
catch {
|
|
6976
|
+
return undefined;
|
|
6967
6977
|
}
|
|
6968
6978
|
}
|
|
6969
6979
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6970
|
-
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
|
|
6980
|
+
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 <div #markdownHost class=\"message__markdown\">\n <markdown\n [data]=\"part.content\"\n (ready)=\"onMarkdownReady(markdownHost)\"\n ></markdown>\n </div>\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 .message__markdown{display:block}.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"] }] });
|
|
6971
6981
|
}
|
|
6972
6982
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatMessageComponent, decorators: [{
|
|
6973
6983
|
type: Component,
|
|
6974
|
-
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
|
|
6984
|
+
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 <div #markdownHost class=\"message__markdown\">\n <markdown\n [data]=\"part.content\"\n (ready)=\"onMarkdownReady(markdownHost)\"\n ></markdown>\n </div>\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 .message__markdown{display:block}.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"] }]
|
|
6975
6985
|
}], 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 }] }] } });
|
|
6976
6986
|
|
|
6977
6987
|
class RobinChatService {
|
|
6978
6988
|
http = inject(HttpClient);
|
|
6979
6989
|
baseUrl = inject(ROBIN_API_BASE_URL);
|
|
6990
|
+
requestOptions = { withCredentials: true };
|
|
6980
6991
|
sendMessage(req) {
|
|
6981
|
-
return firstValueFrom(this.http.post(this.url('/chat/message'), req));
|
|
6992
|
+
return firstValueFrom(this.http.post(this.url('/chat/message'), req, this.requestOptions));
|
|
6982
6993
|
}
|
|
6983
6994
|
sendAction(req) {
|
|
6984
|
-
return firstValueFrom(this.http.post(this.url('/chat/action'), req));
|
|
6995
|
+
return firstValueFrom(this.http.post(this.url('/chat/action'), req, this.requestOptions));
|
|
6985
6996
|
}
|
|
6986
6997
|
listThreads(product) {
|
|
6987
6998
|
const params = new HttpParams().set('product', product);
|
|
6988
|
-
return firstValueFrom(this.http.get(this.url('/chat/threads'), {
|
|
6999
|
+
return firstValueFrom(this.http.get(this.url('/chat/threads'), {
|
|
7000
|
+
...this.requestOptions,
|
|
7001
|
+
params,
|
|
7002
|
+
}));
|
|
6989
7003
|
}
|
|
6990
7004
|
loadHistory(threadId) {
|
|
6991
|
-
return firstValueFrom(this.http.get(this.url(`/chat/history/${threadId}`)));
|
|
7005
|
+
return firstValueFrom(this.http.get(this.url(`/chat/history/${threadId}`), this.requestOptions));
|
|
6992
7006
|
}
|
|
6993
7007
|
url(path) {
|
|
6994
7008
|
return `${this.baseUrl}${path}`;
|
|
@@ -7070,12 +7084,11 @@ class ChatComponent {
|
|
|
7070
7084
|
dispatcher = inject(RobinChatActionDispatcher);
|
|
7071
7085
|
authService = inject(WorkspaceNavbarService);
|
|
7072
7086
|
destroyRef = inject(DestroyRef);
|
|
7087
|
+
appName = inject(ROBIN_SEARCH_APP_NAME);
|
|
7073
7088
|
product;
|
|
7074
|
-
handbookType;
|
|
7075
7089
|
currentThreadId;
|
|
7076
7090
|
ngOnInit() {
|
|
7077
7091
|
this.product = this.resolveProduct();
|
|
7078
|
-
this.handbookType = this.product;
|
|
7079
7092
|
this.dispatcher.responses$
|
|
7080
7093
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
7081
7094
|
.subscribe(response => this.handleResponse(response));
|
|
@@ -7165,7 +7178,7 @@ class ChatComponent {
|
|
|
7165
7178
|
question: 'Bitte begrüße den User kurz und biete Hilfe an.',
|
|
7166
7179
|
threadId: this.currentThreadId,
|
|
7167
7180
|
product: this.product,
|
|
7168
|
-
|
|
7181
|
+
appName: this.appName,
|
|
7169
7182
|
type: this.searchType ?? null,
|
|
7170
7183
|
})
|
|
7171
7184
|
.then(response => this.handleResponse(response))
|
|
@@ -7179,7 +7192,7 @@ class ChatComponent {
|
|
|
7179
7192
|
question,
|
|
7180
7193
|
threadId: this.currentThreadId,
|
|
7181
7194
|
product: this.product,
|
|
7182
|
-
|
|
7195
|
+
appName: this.appName,
|
|
7183
7196
|
type: this.searchType ?? null,
|
|
7184
7197
|
})
|
|
7185
7198
|
.then(response => this.handleResponse(response))
|
|
@@ -7284,11 +7297,11 @@ class ChatComponent {
|
|
|
7284
7297
|
}
|
|
7285
7298
|
}
|
|
7286
7299
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7287
|
-
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:
|
|
7300
|
+
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" }] });
|
|
7288
7301
|
}
|
|
7289
7302
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ChatComponent, decorators: [{
|
|
7290
7303
|
type: Component,
|
|
7291
|
-
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:
|
|
7304
|
+
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"] }]
|
|
7292
7305
|
}], propDecorators: { historyElement: [{
|
|
7293
7306
|
type: ViewChild,
|
|
7294
7307
|
args: ['conversation']
|
|
@@ -7531,6 +7544,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
7531
7544
|
}, 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"] }]
|
|
7532
7545
|
}], 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"] }] } });
|
|
7533
7546
|
|
|
7547
|
+
/**
|
|
7548
|
+
* Robin-flavoured ChoicePicker that keeps the basic A2UI look but turns chip
|
|
7549
|
+
* selections into server actions so quick-reply chips behave like chat buttons.
|
|
7550
|
+
*/
|
|
7551
|
+
class AoChoicePickerComponent extends CatalogComponent {
|
|
7552
|
+
displayStyle = computed(() => this.readString('displayStyle') ?? 'checkbox', ...(ngDevMode ? [{ debugName: "displayStyle" }] : /* istanbul ignore next */ []));
|
|
7553
|
+
options = computed(() => this.readOptions(), ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
7554
|
+
selectedValue = computed(() => this.readSelectedValues(), ...(ngDevMode ? [{ debugName: "selectedValue" }] : /* istanbul ignore next */ []));
|
|
7555
|
+
renderer = inject(A2uiRendererService);
|
|
7556
|
+
isMultiple() {
|
|
7557
|
+
return this.readString('variant') === 'multipleSelection';
|
|
7558
|
+
}
|
|
7559
|
+
isSelected(value) {
|
|
7560
|
+
return this.selectedValue().includes(value);
|
|
7561
|
+
}
|
|
7562
|
+
selectOption(option) {
|
|
7563
|
+
const nextValue = this.getNextValue(option.value);
|
|
7564
|
+
this.props()['value']?.onUpdate([...nextValue]);
|
|
7565
|
+
if (this.displayStyle() === 'chips')
|
|
7566
|
+
this.dispatchSelection(option, nextValue);
|
|
7567
|
+
}
|
|
7568
|
+
getNextValue(value) {
|
|
7569
|
+
if (!this.isMultiple())
|
|
7570
|
+
return [value];
|
|
7571
|
+
if (this.isSelected(value))
|
|
7572
|
+
return this.selectedValue().filter(item => item !== value);
|
|
7573
|
+
return [...this.selectedValue(), value];
|
|
7574
|
+
}
|
|
7575
|
+
dispatchSelection(option, selectedValues) {
|
|
7576
|
+
const surface = this.renderer.surfaceGroup.getSurface(this.surfaceId());
|
|
7577
|
+
if (!surface)
|
|
7578
|
+
return;
|
|
7579
|
+
void surface.dispatchAction({
|
|
7580
|
+
event: {
|
|
7581
|
+
name: 'choiceSelected',
|
|
7582
|
+
context: {
|
|
7583
|
+
componentId: this.componentId(),
|
|
7584
|
+
label: option.label,
|
|
7585
|
+
selectedValue: option.value,
|
|
7586
|
+
selectedValues: [...selectedValues],
|
|
7587
|
+
},
|
|
7588
|
+
},
|
|
7589
|
+
}, this.componentId());
|
|
7590
|
+
}
|
|
7591
|
+
readString(key) {
|
|
7592
|
+
const value = this.props()[key]?.value();
|
|
7593
|
+
return typeof value === 'string' ? value : undefined;
|
|
7594
|
+
}
|
|
7595
|
+
readSelectedValues() {
|
|
7596
|
+
const value = this.props()['value']?.value();
|
|
7597
|
+
if (!Array.isArray(value))
|
|
7598
|
+
return [];
|
|
7599
|
+
return value.filter((item) => typeof item === 'string');
|
|
7600
|
+
}
|
|
7601
|
+
readOptions() {
|
|
7602
|
+
const value = this.props()['options']?.value();
|
|
7603
|
+
if (!Array.isArray(value))
|
|
7604
|
+
return [];
|
|
7605
|
+
return value.filter(this.isChoicePickerOption);
|
|
7606
|
+
}
|
|
7607
|
+
isChoicePickerOption(value) {
|
|
7608
|
+
if (!value || typeof value !== 'object')
|
|
7609
|
+
return false;
|
|
7610
|
+
const option = value;
|
|
7611
|
+
return typeof option['label'] === 'string' && typeof option['value'] === 'string';
|
|
7612
|
+
}
|
|
7613
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoChoicePickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
7614
|
+
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: `
|
|
7615
|
+
<div class="a2ui-choice-picker">
|
|
7616
|
+
@if (displayStyle() === 'chips') {
|
|
7617
|
+
<div class="a2ui-chips-group">
|
|
7618
|
+
@for (option of options(); track option.value) {
|
|
7619
|
+
<button
|
|
7620
|
+
type="button"
|
|
7621
|
+
class="a2ui-chip"
|
|
7622
|
+
[class.active]="isSelected(option.value)"
|
|
7623
|
+
(click)="selectOption(option)"
|
|
7624
|
+
>
|
|
7625
|
+
{{ option.label }}
|
|
7626
|
+
</button>
|
|
7627
|
+
}
|
|
7628
|
+
</div>
|
|
7629
|
+
} @else {
|
|
7630
|
+
<div class="a2ui-options-group">
|
|
7631
|
+
@for (option of options(); track option.value) {
|
|
7632
|
+
<label class="a2ui-option-label">
|
|
7633
|
+
<input
|
|
7634
|
+
[type]="isMultiple() ? 'checkbox' : 'radio'"
|
|
7635
|
+
[name]="componentId()"
|
|
7636
|
+
[value]="option.value"
|
|
7637
|
+
[checked]="isSelected(option.value)"
|
|
7638
|
+
(change)="selectOption(option)"
|
|
7639
|
+
class="a2ui-option-input"
|
|
7640
|
+
/>
|
|
7641
|
+
<span class="a2ui-option-text">{{ option.label }}</span>
|
|
7642
|
+
</label>
|
|
7643
|
+
}
|
|
7644
|
+
</div>
|
|
7645
|
+
}
|
|
7646
|
+
</div>
|
|
7647
|
+
`, 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 });
|
|
7648
|
+
}
|
|
7649
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoChoicePickerComponent, decorators: [{
|
|
7650
|
+
type: Component,
|
|
7651
|
+
args: [{ selector: 'lib-ao-choice-picker', template: `
|
|
7652
|
+
<div class="a2ui-choice-picker">
|
|
7653
|
+
@if (displayStyle() === 'chips') {
|
|
7654
|
+
<div class="a2ui-chips-group">
|
|
7655
|
+
@for (option of options(); track option.value) {
|
|
7656
|
+
<button
|
|
7657
|
+
type="button"
|
|
7658
|
+
class="a2ui-chip"
|
|
7659
|
+
[class.active]="isSelected(option.value)"
|
|
7660
|
+
(click)="selectOption(option)"
|
|
7661
|
+
>
|
|
7662
|
+
{{ option.label }}
|
|
7663
|
+
</button>
|
|
7664
|
+
}
|
|
7665
|
+
</div>
|
|
7666
|
+
} @else {
|
|
7667
|
+
<div class="a2ui-options-group">
|
|
7668
|
+
@for (option of options(); track option.value) {
|
|
7669
|
+
<label class="a2ui-option-label">
|
|
7670
|
+
<input
|
|
7671
|
+
[type]="isMultiple() ? 'checkbox' : 'radio'"
|
|
7672
|
+
[name]="componentId()"
|
|
7673
|
+
[value]="option.value"
|
|
7674
|
+
[checked]="isSelected(option.value)"
|
|
7675
|
+
(change)="selectOption(option)"
|
|
7676
|
+
class="a2ui-option-input"
|
|
7677
|
+
/>
|
|
7678
|
+
<span class="a2ui-option-text">{{ option.label }}</span>
|
|
7679
|
+
</label>
|
|
7680
|
+
}
|
|
7681
|
+
</div>
|
|
7682
|
+
}
|
|
7683
|
+
</div>
|
|
7684
|
+
`, 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"] }]
|
|
7685
|
+
}] });
|
|
7686
|
+
|
|
7534
7687
|
const AO_CATALOG_ID = 'ah-oh.com:robin-v1';
|
|
7535
7688
|
/**
|
|
7536
7689
|
* Robin's design-system catalog. Phase 1 delegates entirely to the upstream
|
|
@@ -7545,7 +7698,12 @@ const AO_CATALOG_ID = 'ah-oh.com:robin-v1';
|
|
|
7545
7698
|
*/
|
|
7546
7699
|
class AoCatalog extends BasicCatalogBase {
|
|
7547
7700
|
constructor() {
|
|
7548
|
-
super({
|
|
7701
|
+
super({
|
|
7702
|
+
id: AO_CATALOG_ID,
|
|
7703
|
+
components: {
|
|
7704
|
+
choicePicker: { ...ChoicePickerApi, component: AoChoicePickerComponent },
|
|
7705
|
+
},
|
|
7706
|
+
});
|
|
7549
7707
|
}
|
|
7550
7708
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoCatalog, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7551
7709
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AoCatalog, providedIn: 'root' });
|
|
@@ -7564,7 +7722,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
7564
7722
|
function provideRobinA2ui() {
|
|
7565
7723
|
return makeEnvironmentProviders([
|
|
7566
7724
|
AoCatalog,
|
|
7567
|
-
provideMarkdownRenderer(),
|
|
7725
|
+
provideMarkdownRenderer((markdown) => renderMarkdown(markdown).catch(renderFallbackMarkdown)),
|
|
7568
7726
|
{
|
|
7569
7727
|
provide: A2UI_RENDERER_CONFIG,
|
|
7570
7728
|
useFactory: () => {
|
|
@@ -7581,6 +7739,24 @@ function provideRobinA2ui() {
|
|
|
7581
7739
|
A2uiRendererService,
|
|
7582
7740
|
]);
|
|
7583
7741
|
}
|
|
7742
|
+
function renderFallbackMarkdown(markdown) {
|
|
7743
|
+
return escapeHtml(markdown)
|
|
7744
|
+
.replace(/^#### (.*)$/gim, '<h4>$1</h4>')
|
|
7745
|
+
.replace(/^### (.*)$/gim, '<h3>$1</h3>')
|
|
7746
|
+
.replace(/^## (.*)$/gim, '<h2>$1</h2>')
|
|
7747
|
+
.replace(/^# (.*)$/gim, '<h1>$1</h1>')
|
|
7748
|
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|
7749
|
+
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
|
7750
|
+
.replace(/\n/g, '<br>');
|
|
7751
|
+
}
|
|
7752
|
+
function escapeHtml(value) {
|
|
7753
|
+
return value
|
|
7754
|
+
.replace(/&/g, '&')
|
|
7755
|
+
.replace(/</g, '<')
|
|
7756
|
+
.replace(/>/g, '>')
|
|
7757
|
+
.replace(/"/g, '"')
|
|
7758
|
+
.replace(/'/g, ''');
|
|
7759
|
+
}
|
|
7584
7760
|
|
|
7585
7761
|
/*
|
|
7586
7762
|
* Public API Surface of design-system
|