@aakash58/chatbot 1.0.84 → 1.0.86
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.
- package/fesm2022/aakash58-chatbot.mjs +633 -561
- package/fesm2022/aakash58-chatbot.mjs.map +1 -1
- package/index.d.ts +52 -11
- package/package.json +2 -2
- package/aakash58-chatbot-1.0.84.tgz +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, Output, Input, Component, ViewChild, HostListener, Directive, signal, Injectable, Inject,
|
|
2
|
+
import { EventEmitter, Output, Input, Component, ViewChild, HostListener, Directive, signal, Injectable, Inject, inject, InjectionToken, computed, effect, ElementRef, ChangeDetectionStrategy, provideAppInitializer } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i1$1 from '@angular/material/icon';
|
|
@@ -11,13 +11,16 @@ import * as i1$3 from '@angular/material/dialog';
|
|
|
11
11
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
12
12
|
import * as i2 from '@angular/material/button';
|
|
13
13
|
import { MatButtonModule } from '@angular/material/button';
|
|
14
|
-
import
|
|
14
|
+
import * as i4 from '@angular/forms';
|
|
15
|
+
import { FormsModule } from '@angular/forms';
|
|
16
|
+
import { Subject, throwError, timer, of, delay, retry as retry$1, map as map$1, catchError as catchError$1, firstValueFrom, Observable, tap } from 'rxjs';
|
|
15
17
|
import * as i1$4 from '@angular/common/http';
|
|
16
|
-
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
|
|
18
|
+
import { HttpClient, HttpHeaders, HttpErrorResponse, provideHttpClient, HTTP_INTERCEPTORS, withInterceptorsFromDi } from '@angular/common/http';
|
|
17
19
|
import { timeout, map, catchError, retry } from 'rxjs/operators';
|
|
18
20
|
import * as CryptoJS from 'crypto-js';
|
|
19
21
|
import { JwtHelperService } from '@auth0/angular-jwt';
|
|
20
22
|
import * as i1$5 from '@angular/router';
|
|
23
|
+
import { bootstrapApplication } from '@angular/platform-browser';
|
|
21
24
|
|
|
22
25
|
const appConst = {
|
|
23
26
|
//LIVE ASSETS
|
|
@@ -45,7 +48,6 @@ class DoohbotInput {
|
|
|
45
48
|
password = '';
|
|
46
49
|
authToken;
|
|
47
50
|
DOOHBOT_API_URL;
|
|
48
|
-
skipAuthentication;
|
|
49
51
|
// inputs
|
|
50
52
|
userAvatarUrl = appConst.USER_AVATAR;
|
|
51
53
|
// Application Constants Text
|
|
@@ -94,11 +96,11 @@ class ChatButtonComponent {
|
|
|
94
96
|
this.toggle.emit();
|
|
95
97
|
}
|
|
96
98
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
97
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: ChatButtonComponent, isStandalone: true, selector: "app-chat-button", inputs: { buttonStyle: "buttonStyle", isChatOpen: "isChatOpen", unreadCount: "unreadCount", chatIcon: "chatIcon", appTitle: "appTitle", appLogoUrl: "appLogoUrl", appTextLogoUrl: "appTextLogoUrl" }, outputs: { toggle: "toggle" }, ngImport: i0, template: "<!-- fab -->\r\n<button class=\"chat-fab\" (click)=\"onToggle()\" *ngIf=\"buttonStyle === 'fab' && !isChatOpen\">\r\n <!-- <mat-icon>{{ chatIcon }}</mat-icon> -->\r\n <img style=\"width: 30px; height: 30px\" [src]=\"appLogoUrl\" />\r\n <!-- <div class=\"chat-logo\"></div> -->\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n\r\n<!-- sidebar button -->\r\n<button\r\n class=\"chat-sidebar\"\r\n (click)=\"onToggle()\"\r\n *ngIf=\"isSidebar && !isChatOpen\"\r\n [ngClass]=\"sidebarPosition\"\r\n>\r\n <!-- <h2 style=\"transform: rotate(-90deg); font-size: 16px\">{{ appTitle }}</h2> -->\r\n <img style=\"transform: rotate(-90deg); width: 100px; height: 45px\" [src]=\"appTextLogoUrl\" />\r\n\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n", styles: [".chat-sidebar{position:fixed;right:0;width:40px;height:120px;border-radius:16px 0 0 16px;background:var(--background-color);color:var(--white);border:none;box-shadow:var(--border-shadow-color);display:flex;justify-content:center;align-items:center;cursor:pointer;z-index:1000}.chat-sidebar.disabled{background:transparent;border-radius:0}.chat-sidebar h2{margin:0;font-size:12px;transform:rotate(-90deg);white-space:nowrap}.chat-sidebar .alert-badge{position:absolute;bottom:15px;right:30px;width:18px;height:18px;border-radius:50%;background:var(--red);color:var(--white);font-size:10px;display:flex;align-items:center;justify-content:center}.chat-sidebar.center{top:50%;transform:translateY(-50%)}.chat-sidebar.top{top:calc(50% - 45vh);transform:none}.chat-sidebar.bottom{top:calc(50% + 30vh);transform:none}.chat-fab{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background:var(--background-color);color:var(--white);box-shadow:0 6px 16px #0003;border:none;cursor:pointer;z-index:1000;display:flex;align-items:center;justify-content:center}.chat-fab svg,.chat-fab mat-icon{width:24px;height:24px}.chat-fab:hover{transform:scale(1.1)}.alert-badge{position:absolute;top:-4px;right:-4px;background:var(--red);color:var(--white);border-radius:50%;min-width:18px;height:18px;font-size:11px;display:flex;align-items:center;justify-content:center;font-weight:700;line-height:1}.chat-logo{width:45px;height:45px;mask:url(/assets/logo.svg) no-repeat center;-webkit-mask-size:contain;mask-size:contain;background-color:
|
|
99
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: ChatButtonComponent, isStandalone: true, selector: "app-chat-button", inputs: { buttonStyle: "buttonStyle", isChatOpen: "isChatOpen", unreadCount: "unreadCount", chatIcon: "chatIcon", appTitle: "appTitle", appLogoUrl: "appLogoUrl", appTextLogoUrl: "appTextLogoUrl" }, outputs: { toggle: "toggle" }, ngImport: i0, template: "<!-- fab -->\r\n<button class=\"chat-fab\" (click)=\"onToggle()\" *ngIf=\"buttonStyle === 'fab' && !isChatOpen\">\r\n <!-- <mat-icon>{{ chatIcon }}</mat-icon> -->\r\n <img style=\"width: 30px; height: 30px\" [src]=\"appLogoUrl\" />\r\n <!-- <div class=\"chat-logo\"></div> -->\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n\r\n<!-- sidebar button -->\r\n<button\r\n class=\"chat-sidebar\"\r\n (click)=\"onToggle()\"\r\n *ngIf=\"isSidebar && !isChatOpen\"\r\n [ngClass]=\"sidebarPosition\"\r\n>\r\n <!-- <h2 style=\"transform: rotate(-90deg); font-size: 16px\">{{ appTitle }}</h2> -->\r\n <img style=\"transform: rotate(-90deg); width: 100px; height: 45px\" [src]=\"appTextLogoUrl\" />\r\n\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n", styles: [".chat-sidebar{position:fixed;right:0;width:40px;height:120px;border-radius:16px 0 0 16px;background:var(--background-color);color:var(--white);border:none;box-shadow:var(--border-shadow-color);display:flex;justify-content:center;align-items:center;cursor:pointer;z-index:1000}.chat-sidebar.disabled{background:transparent;border-radius:0}.chat-sidebar h2{margin:0;font-size:12px;transform:rotate(-90deg);white-space:nowrap}.chat-sidebar .alert-badge{position:absolute;bottom:15px;right:30px;width:18px;height:18px;border-radius:50%;background:var(--red);color:var(--white);font-size:10px;display:flex;align-items:center;justify-content:center}.chat-sidebar.center{top:50%;transform:translateY(-50%)}.chat-sidebar.top{top:calc(50% - 45vh);transform:none}.chat-sidebar.bottom{top:calc(50% + 30vh);transform:none}.chat-fab{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background:var(--background-color);color:var(--white);box-shadow:0 6px 16px #0003;border:none;cursor:pointer;z-index:1000;display:flex;align-items:center;justify-content:center}.chat-fab svg,.chat-fab mat-icon{width:24px;height:24px}.chat-fab:hover{transform:scale(1.1)}.alert-badge{position:absolute;top:-4px;right:-4px;background:var(--red);color:var(--white);border-radius:50%;min-width:18px;height:18px;font-size:11px;display:flex;align-items:center;justify-content:center;font-weight:700;line-height:1}.chat-logo{width:45px;height:45px;mask:url(/assets/logo.svg) no-repeat center;-webkit-mask-size:contain;mask-size:contain;background-color:var(--white)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }] });
|
|
98
100
|
}
|
|
99
101
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatButtonComponent, decorators: [{
|
|
100
102
|
type: Component,
|
|
101
|
-
args: [{ selector: 'app-chat-button', standalone: true, imports: [CommonModule, MatIconModule], template: "<!-- fab -->\r\n<button class=\"chat-fab\" (click)=\"onToggle()\" *ngIf=\"buttonStyle === 'fab' && !isChatOpen\">\r\n <!-- <mat-icon>{{ chatIcon }}</mat-icon> -->\r\n <img style=\"width: 30px; height: 30px\" [src]=\"appLogoUrl\" />\r\n <!-- <div class=\"chat-logo\"></div> -->\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n\r\n<!-- sidebar button -->\r\n<button\r\n class=\"chat-sidebar\"\r\n (click)=\"onToggle()\"\r\n *ngIf=\"isSidebar && !isChatOpen\"\r\n [ngClass]=\"sidebarPosition\"\r\n>\r\n <!-- <h2 style=\"transform: rotate(-90deg); font-size: 16px\">{{ appTitle }}</h2> -->\r\n <img style=\"transform: rotate(-90deg); width: 100px; height: 45px\" [src]=\"appTextLogoUrl\" />\r\n\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n", styles: [".chat-sidebar{position:fixed;right:0;width:40px;height:120px;border-radius:16px 0 0 16px;background:var(--background-color);color:var(--white);border:none;box-shadow:var(--border-shadow-color);display:flex;justify-content:center;align-items:center;cursor:pointer;z-index:1000}.chat-sidebar.disabled{background:transparent;border-radius:0}.chat-sidebar h2{margin:0;font-size:12px;transform:rotate(-90deg);white-space:nowrap}.chat-sidebar .alert-badge{position:absolute;bottom:15px;right:30px;width:18px;height:18px;border-radius:50%;background:var(--red);color:var(--white);font-size:10px;display:flex;align-items:center;justify-content:center}.chat-sidebar.center{top:50%;transform:translateY(-50%)}.chat-sidebar.top{top:calc(50% - 45vh);transform:none}.chat-sidebar.bottom{top:calc(50% + 30vh);transform:none}.chat-fab{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background:var(--background-color);color:var(--white);box-shadow:0 6px 16px #0003;border:none;cursor:pointer;z-index:1000;display:flex;align-items:center;justify-content:center}.chat-fab svg,.chat-fab mat-icon{width:24px;height:24px}.chat-fab:hover{transform:scale(1.1)}.alert-badge{position:absolute;top:-4px;right:-4px;background:var(--red);color:var(--white);border-radius:50%;min-width:18px;height:18px;font-size:11px;display:flex;align-items:center;justify-content:center;font-weight:700;line-height:1}.chat-logo{width:45px;height:45px;mask:url(/assets/logo.svg) no-repeat center;-webkit-mask-size:contain;mask-size:contain;background-color:
|
|
103
|
+
args: [{ selector: 'app-chat-button', standalone: true, imports: [CommonModule, MatIconModule], template: "<!-- fab -->\r\n<button class=\"chat-fab\" (click)=\"onToggle()\" *ngIf=\"buttonStyle === 'fab' && !isChatOpen\">\r\n <!-- <mat-icon>{{ chatIcon }}</mat-icon> -->\r\n <img style=\"width: 30px; height: 30px\" [src]=\"appLogoUrl\" />\r\n <!-- <div class=\"chat-logo\"></div> -->\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n\r\n<!-- sidebar button -->\r\n<button\r\n class=\"chat-sidebar\"\r\n (click)=\"onToggle()\"\r\n *ngIf=\"isSidebar && !isChatOpen\"\r\n [ngClass]=\"sidebarPosition\"\r\n>\r\n <!-- <h2 style=\"transform: rotate(-90deg); font-size: 16px\">{{ appTitle }}</h2> -->\r\n <img style=\"transform: rotate(-90deg); width: 100px; height: 45px\" [src]=\"appTextLogoUrl\" />\r\n\r\n <span class=\"alert-badge\" *ngIf=\"unreadCount > 0\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n</button>\r\n", styles: [".chat-sidebar{position:fixed;right:0;width:40px;height:120px;border-radius:16px 0 0 16px;background:var(--background-color);color:var(--white);border:none;box-shadow:var(--border-shadow-color);display:flex;justify-content:center;align-items:center;cursor:pointer;z-index:1000}.chat-sidebar.disabled{background:transparent;border-radius:0}.chat-sidebar h2{margin:0;font-size:12px;transform:rotate(-90deg);white-space:nowrap}.chat-sidebar .alert-badge{position:absolute;bottom:15px;right:30px;width:18px;height:18px;border-radius:50%;background:var(--red);color:var(--white);font-size:10px;display:flex;align-items:center;justify-content:center}.chat-sidebar.center{top:50%;transform:translateY(-50%)}.chat-sidebar.top{top:calc(50% - 45vh);transform:none}.chat-sidebar.bottom{top:calc(50% + 30vh);transform:none}.chat-fab{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background:var(--background-color);color:var(--white);box-shadow:0 6px 16px #0003;border:none;cursor:pointer;z-index:1000;display:flex;align-items:center;justify-content:center}.chat-fab svg,.chat-fab mat-icon{width:24px;height:24px}.chat-fab:hover{transform:scale(1.1)}.alert-badge{position:absolute;top:-4px;right:-4px;background:var(--red);color:var(--white);border-radius:50%;min-width:18px;height:18px;font-size:11px;display:flex;align-items:center;justify-content:center;font-weight:700;line-height:1}.chat-logo{width:45px;height:45px;mask:url(/assets/logo.svg) no-repeat center;-webkit-mask-size:contain;mask-size:contain;background-color:var(--white)}\n"] }]
|
|
102
104
|
}], propDecorators: { buttonStyle: [{
|
|
103
105
|
type: Input
|
|
104
106
|
}], isChatOpen: [{
|
|
@@ -151,8 +153,11 @@ class MessageListComponent {
|
|
|
151
153
|
userAvatarUrl = '';
|
|
152
154
|
userName = '';
|
|
153
155
|
isAuthenticated = false;
|
|
156
|
+
isGuestMode = false;
|
|
154
157
|
trackByMessageId = (index, item) => item.id ?? index;
|
|
155
158
|
suggestionClick = new EventEmitter();
|
|
159
|
+
loginClick = new EventEmitter();
|
|
160
|
+
continueAsGuest = new EventEmitter();
|
|
156
161
|
chatMessagesContainer;
|
|
157
162
|
mutationObserver;
|
|
158
163
|
appEmoji = {
|
|
@@ -187,11 +192,11 @@ class MessageListComponent {
|
|
|
187
192
|
this.suggestionClick.emit(text);
|
|
188
193
|
}
|
|
189
194
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
190
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: MessageListComponent, isStandalone: true, selector: "app-message-list", inputs: { messages: "messages", isBotTyping: "isBotTyping", appLogoUrl: "appLogoUrl", appSubtitle: "appSubtitle", welcomeDesc: "welcomeDesc", predefinedMessages: "predefinedMessages", botAvatarUrl: "botAvatarUrl", userAvatarUrl: "userAvatarUrl", userName: "userName", isAuthenticated: "isAuthenticated", trackByMessageId: "trackByMessageId" }, outputs: { suggestionClick: "suggestionClick" }, viewQueries: [{ propertyName: "chatMessagesContainer", first: true, predicate: ["chatMessages"], descendants: true }], ngImport: i0, template: "<div #chatMessages class=\"chat-messages\">\r\n <!-- Welcome Screen -->\r\n <div class=\"welcome-screen\" *ngIf=\"messages.length === 0 && !isBotTyping\">\r\n <img [src]=\"appLogoUrl\" alt=\"Welcome\" class=\"welcome-image\" style=\"border-radius: 0px\" />\r\n\r\n <!-- Only show greeting if authenticated -->\r\n <h2 class=\"welcome-greeting\" *ngIf=\"userName && isAuthenticated\">\r\n Hi, {{ userName }}!\r\n <!-- <span class=\"emoji\">👋</span> -->\r\n <span class=\"emoji\">{{ appEmoji.waveHand }}</span>\r\n </h2>\r\n\r\n <h3>{{ appSubtitle }}</h3>\r\n <p>{{ welcomeDesc }}</p>\r\n\r\n <!-- Predefined messages chips: Only show when authenticated -->\r\n <app-chips\r\n *ngIf=\"isAuthenticated\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onPredefinedClick($event)\"\r\n ></app-chips>\r\n </div>\r\n\r\n <!-- Chat Messages -->\r\n <div\r\n *ngFor=\"let message of messages; trackBy: trackByMessageId\"\r\n class=\"message-wrapper\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n <!-- Bot Avatar -->\r\n <img\r\n *ngIf=\"message.sender === 'bot'\"\r\n class=\"bot-avatar\"\r\n [src]=\"botAvatarUrl\"\r\n alt=\"Bot Avatar\"\r\n />\r\n\r\n <!-- Message Bubble -->\r\n <div\r\n class=\"message\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n {{ message.text }}\r\n <!-- Show time below message -->\r\n <div *ngIf=\"message.sender === 'bot'\" class=\"message-time\">\r\n {{ message.timestamp | date: 'shortTime' }}\r\n </div>\r\n </div>\r\n\r\n <!-- User Avatar -->\r\n <div class=\"user-avatar-container\" *ngIf=\"message.sender === 'user'\">\r\n <img class=\"user-avatar\" [src]=\"userAvatarUrl\" alt=\"User Avatar\" />\r\n <!-- <span class=\"user-name\" *ngIf=\"userName\">{{ userName }}</span> -->\r\n </div>\r\n </div>\r\n\r\n <!-- Typing Indicator -->\r\n <div class=\"message-wrapper bot\" *ngIf=\"isBotTyping\">\r\n <img class=\"bot-avatar\" [src]=\"botAvatarUrl\" alt=\"Bot Avatar\" />\r\n <div class=\"message bot\">\r\n <div class=\"typing-indicator\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.chat-messages{flex-grow:1;padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px;scroll-behavior:smooth}.chat-messages::-webkit-scrollbar{width:8px}.chat-messages::-webkit-scrollbar-track{background:var(--grey);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb{background-color:var(--primary-color);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb:hover{background-color:var(--primary-color)}.chat-messages{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--background-color)}.welcome-screen{display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;height:100%;padding:0 20px}.welcome-image{width:80px;margin-bottom:30px}.welcome-greeting{margin:0 0 12px;color:var(--text-color);font-family:var(--font-family);font-size:24px;font-weight:600;background:var(--text-color);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.welcome-greeting .emoji{background:none;-webkit-background-clip:initial;-webkit-text-fill-color:initial;background-clip:initial}.welcome-screen h3{margin:0 0 5px;color:var(--text-color);font-family:var(--font-family);font-size:18px}.welcome-screen p{margin:0 0 30px;color:var(--secondary-text-color);font-size:14px;font-family:var(--font-family)}.message-wrapper{display:flex;align-items:flex-end;gap:8px;margin-bottom:6px}.message-wrapper.user{justify-content:flex-end}.message-wrapper.bot{justify-content:flex-start}.message{padding:10px 15px;max-width:80%;overflow-y:auto;word-wrap:break-word;font-family:var(--font-family)}.message .message-time{font-size:11px;color:var(--grey);text-align:right;margin-top:4px}.message.user{background-color:var(--primary-color);color:var(--user-text-color);align-self:flex-end;border-radius:20px 20px 0}.message.bot{background-color:var(--bot-message-color);color:var(--bot-text-color);align-self:flex-start;border-radius:20px 20px 20px 0}.bot-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color);filter:var(--avatar-filter)}.user-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color)}.user-avatar.placeholder{filter:var(--avatar-filter)}.user-avatar-container{display:flex;flex-direction:column;align-items:center;gap:4px}.user-name{font-size:10px;color:var(--secondary-text-color);font-family:var(--font-family);text-align:center;max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.typing-indicator{display:flex;align-items:center;justify-content:center;gap:4px}.typing-indicator span{width:8px;height:8px;background-color:var(--typing-indicator-color);border-radius:50%;animation:blink 1.4s infinite both}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes blink{0%,80%,to{opacity:.2}40%{opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: Chips, selector: "app-chips", inputs: ["messages", "disabled"], outputs: ["chipClick"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] });
|
|
195
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: MessageListComponent, isStandalone: true, selector: "app-message-list", inputs: { messages: "messages", isBotTyping: "isBotTyping", appLogoUrl: "appLogoUrl", appSubtitle: "appSubtitle", welcomeDesc: "welcomeDesc", predefinedMessages: "predefinedMessages", botAvatarUrl: "botAvatarUrl", userAvatarUrl: "userAvatarUrl", userName: "userName", isAuthenticated: "isAuthenticated", isGuestMode: "isGuestMode", trackByMessageId: "trackByMessageId" }, outputs: { suggestionClick: "suggestionClick", loginClick: "loginClick", continueAsGuest: "continueAsGuest" }, viewQueries: [{ propertyName: "chatMessagesContainer", first: true, predicate: ["chatMessages"], descendants: true }], ngImport: i0, template: "<div #chatMessages class=\"chat-messages\">\r\n <!-- Welcome Screen -->\r\n <div class=\"welcome-screen\" *ngIf=\"messages.length === 0 && !isBotTyping\">\r\n <img [src]=\"appLogoUrl\" alt=\"Welcome\" class=\"welcome-image\" style=\"border-radius: 0px\" />\r\n\r\n <!-- Only show greeting if authenticated -->\r\n <h2 class=\"welcome-greeting\" *ngIf=\"userName && isAuthenticated\">\r\n Hi, {{ userName }}!\r\n <!-- <span class=\"emoji\">👋</span> -->\r\n <span class=\"emoji\">{{ appEmoji.waveHand }}</span>\r\n </h2>\r\n\r\n <h3>{{ appSubtitle }}</h3>\r\n <p>{{ welcomeDesc }}</p>\r\n\r\n <!-- Predefined messages chips: Only show when authenticated -->\r\n <app-chips\r\n *ngIf=\"isAuthenticated\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onPredefinedClick($event)\"\r\n ></app-chips>\r\n\r\n <!-- Guest Mode Login Button -->\r\n <div *ngIf=\"isGuestMode\" style=\"margin-top: 10px\">\r\n <button class=\"login-btn\" (click)=\"loginClick.emit()\">Login</button>\r\n </div>\r\n\r\n <!-- Fallback / Login Prompts (Below Welcome Text) -->\r\n <div\r\n *ngIf=\"!isAuthenticated && !isGuestMode\"\r\n class=\"auth-buttons-container\"\r\n style=\"margin-top: 20px\"\r\n >\r\n <button (click)=\"loginClick.emit()\" class=\"auth-btn primary\" style=\"margin-right: 10px\">\r\n Login\r\n </button>\r\n <button (click)=\"continueAsGuest.emit()\" class=\"auth-btn secondary\">Continue as Guest</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Chat Messages -->\r\n <div\r\n *ngFor=\"let message of messages; trackBy: trackByMessageId\"\r\n class=\"message-wrapper\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n <!-- Bot Avatar -->\r\n <img\r\n *ngIf=\"message.sender === 'bot'\"\r\n class=\"bot-avatar\"\r\n [src]=\"botAvatarUrl\"\r\n alt=\"Bot Avatar\"\r\n />\r\n\r\n <!-- Message Bubble -->\r\n <div\r\n class=\"message\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n {{ message.text }}\r\n <!-- Show time below message -->\r\n <div *ngIf=\"message.sender === 'bot'\" class=\"message-time\">\r\n {{ message.timestamp | date: 'shortTime' }}\r\n </div>\r\n </div>\r\n\r\n <!-- User Avatar -->\r\n <div class=\"user-avatar-container\" *ngIf=\"message.sender === 'user'\">\r\n <img class=\"user-avatar\" [src]=\"userAvatarUrl\" alt=\"User Avatar\" />\r\n <!-- <span class=\"user-name\" *ngIf=\"userName\">{{ userName }}</span> -->\r\n </div>\r\n </div>\r\n\r\n <!-- Typing Indicator -->\r\n <div class=\"message-wrapper bot\" *ngIf=\"isBotTyping\">\r\n <img class=\"bot-avatar\" [src]=\"botAvatarUrl\" alt=\"Bot Avatar\" />\r\n <div class=\"message bot\">\r\n <div class=\"typing-indicator\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.login-btn{padding:10px 15px;border:none;border-radius:20px;background-color:var(--primary-color);color:var(--user-text-color);font-size:1em;cursor:pointer;transition:background-color .2s ease}.chat-messages{flex-grow:1;padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px;scroll-behavior:smooth}.chat-messages::-webkit-scrollbar{width:8px}.chat-messages::-webkit-scrollbar-track{background:var(--grey);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb{background-color:var(--primary-color);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb:hover{background-color:var(--primary-color)}.chat-messages{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--background-color)}.welcome-screen{display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;height:100%;padding:0 20px}.welcome-image{width:80px;margin-bottom:30px}.welcome-greeting{margin:0 0 12px;color:var(--text-color);font-family:var(--font-family);font-size:24px;font-weight:600;background:var(--text-color);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.welcome-greeting .emoji{background:none;-webkit-background-clip:initial;-webkit-text-fill-color:initial;background-clip:initial}.welcome-screen h3{margin:0 0 5px;color:var(--text-color);font-family:var(--font-family);font-size:18px}.welcome-screen p{margin:0 0 30px;color:var(--secondary-text-color);font-size:14px;font-family:var(--font-family)}.message-wrapper{display:flex;align-items:flex-end;gap:8px;margin-bottom:6px}.message-wrapper.user{justify-content:flex-end}.message-wrapper.bot{justify-content:flex-start}.message{padding:10px 15px;max-width:80%;overflow-y:auto;word-wrap:break-word;font-family:var(--font-family)}.message .message-time{font-size:11px;color:var(--grey);text-align:right;margin-top:4px}.message.user{background-color:var(--primary-color);color:var(--user-text-color);align-self:flex-end;border-radius:20px 20px 0}.message.bot{background-color:var(--bot-message-color);color:var(--bot-text-color);align-self:flex-start;border-radius:20px 20px 20px 0}.bot-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color);filter:var(--avatar-filter)}.user-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color)}.user-avatar.placeholder{filter:var(--avatar-filter)}.user-avatar-container{display:flex;flex-direction:column;align-items:center;gap:4px}.user-name{font-size:10px;color:var(--secondary-text-color);font-family:var(--font-family);text-align:center;max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.typing-indicator{display:flex;align-items:center;justify-content:center;gap:4px}.typing-indicator span{width:8px;height:8px;background-color:var(--typing-indicator-color);border-radius:50%;animation:blink 1.4s infinite both}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes blink{0%,80%,to{opacity:.2}40%{opacity:1}}.auth-buttons-container{display:flex;flex-direction:row;justify-content:center;gap:10px}.auth-btn{padding:8px 16px;border-radius:20px;font-size:.9em;font-weight:500;cursor:pointer;transition:all .2s ease}.auth-btn.primary{background:var(--primary-color);color:var(--white);border:1px solid var(--primary-color)}.auth-btn.primary:hover{opacity:.9}.auth-btn.primary:disabled{opacity:.5;cursor:not-allowed}.auth-btn.secondary{background:transparent;color:var(--primary-color);border:1px solid var(--primary-color)}.auth-btn.secondary:hover{opacity:.9}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: Chips, selector: "app-chips", inputs: ["messages", "disabled"], outputs: ["chipClick"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] });
|
|
191
196
|
}
|
|
192
197
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
193
198
|
type: Component,
|
|
194
|
-
args: [{ selector: 'app-message-list', standalone: true, imports: [CommonModule, Chips], template: "<div #chatMessages class=\"chat-messages\">\r\n <!-- Welcome Screen -->\r\n <div class=\"welcome-screen\" *ngIf=\"messages.length === 0 && !isBotTyping\">\r\n <img [src]=\"appLogoUrl\" alt=\"Welcome\" class=\"welcome-image\" style=\"border-radius: 0px\" />\r\n\r\n <!-- Only show greeting if authenticated -->\r\n <h2 class=\"welcome-greeting\" *ngIf=\"userName && isAuthenticated\">\r\n Hi, {{ userName }}!\r\n <!-- <span class=\"emoji\">👋</span> -->\r\n <span class=\"emoji\">{{ appEmoji.waveHand }}</span>\r\n </h2>\r\n\r\n <h3>{{ appSubtitle }}</h3>\r\n <p>{{ welcomeDesc }}</p>\r\n\r\n <!-- Predefined messages chips: Only show when authenticated -->\r\n <app-chips\r\n *ngIf=\"isAuthenticated\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onPredefinedClick($event)\"\r\n ></app-chips>\r\n </div>\r\n\r\n <!-- Chat Messages -->\r\n <div\r\n *ngFor=\"let message of messages; trackBy: trackByMessageId\"\r\n class=\"message-wrapper\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n <!-- Bot Avatar -->\r\n <img\r\n *ngIf=\"message.sender === 'bot'\"\r\n class=\"bot-avatar\"\r\n [src]=\"botAvatarUrl\"\r\n alt=\"Bot Avatar\"\r\n />\r\n\r\n <!-- Message Bubble -->\r\n <div\r\n class=\"message\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n {{ message.text }}\r\n <!-- Show time below message -->\r\n <div *ngIf=\"message.sender === 'bot'\" class=\"message-time\">\r\n {{ message.timestamp | date: 'shortTime' }}\r\n </div>\r\n </div>\r\n\r\n <!-- User Avatar -->\r\n <div class=\"user-avatar-container\" *ngIf=\"message.sender === 'user'\">\r\n <img class=\"user-avatar\" [src]=\"userAvatarUrl\" alt=\"User Avatar\" />\r\n <!-- <span class=\"user-name\" *ngIf=\"userName\">{{ userName }}</span> -->\r\n </div>\r\n </div>\r\n\r\n <!-- Typing Indicator -->\r\n <div class=\"message-wrapper bot\" *ngIf=\"isBotTyping\">\r\n <img class=\"bot-avatar\" [src]=\"botAvatarUrl\" alt=\"Bot Avatar\" />\r\n <div class=\"message bot\">\r\n <div class=\"typing-indicator\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.chat-messages{flex-grow:1;padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px;scroll-behavior:smooth}.chat-messages::-webkit-scrollbar{width:8px}.chat-messages::-webkit-scrollbar-track{background:var(--grey);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb{background-color:var(--primary-color);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb:hover{background-color:var(--primary-color)}.chat-messages{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--background-color)}.welcome-screen{display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;height:100%;padding:0 20px}.welcome-image{width:80px;margin-bottom:30px}.welcome-greeting{margin:0 0 12px;color:var(--text-color);font-family:var(--font-family);font-size:24px;font-weight:600;background:var(--text-color);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.welcome-greeting .emoji{background:none;-webkit-background-clip:initial;-webkit-text-fill-color:initial;background-clip:initial}.welcome-screen h3{margin:0 0 5px;color:var(--text-color);font-family:var(--font-family);font-size:18px}.welcome-screen p{margin:0 0 30px;color:var(--secondary-text-color);font-size:14px;font-family:var(--font-family)}.message-wrapper{display:flex;align-items:flex-end;gap:8px;margin-bottom:6px}.message-wrapper.user{justify-content:flex-end}.message-wrapper.bot{justify-content:flex-start}.message{padding:10px 15px;max-width:80%;overflow-y:auto;word-wrap:break-word;font-family:var(--font-family)}.message .message-time{font-size:11px;color:var(--grey);text-align:right;margin-top:4px}.message.user{background-color:var(--primary-color);color:var(--user-text-color);align-self:flex-end;border-radius:20px 20px 0}.message.bot{background-color:var(--bot-message-color);color:var(--bot-text-color);align-self:flex-start;border-radius:20px 20px 20px 0}.bot-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color);filter:var(--avatar-filter)}.user-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color)}.user-avatar.placeholder{filter:var(--avatar-filter)}.user-avatar-container{display:flex;flex-direction:column;align-items:center;gap:4px}.user-name{font-size:10px;color:var(--secondary-text-color);font-family:var(--font-family);text-align:center;max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.typing-indicator{display:flex;align-items:center;justify-content:center;gap:4px}.typing-indicator span{width:8px;height:8px;background-color:var(--typing-indicator-color);border-radius:50%;animation:blink 1.4s infinite both}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes blink{0%,80%,to{opacity:.2}40%{opacity:1}}\n"] }]
|
|
199
|
+
args: [{ selector: 'app-message-list', standalone: true, imports: [CommonModule, Chips], template: "<div #chatMessages class=\"chat-messages\">\r\n <!-- Welcome Screen -->\r\n <div class=\"welcome-screen\" *ngIf=\"messages.length === 0 && !isBotTyping\">\r\n <img [src]=\"appLogoUrl\" alt=\"Welcome\" class=\"welcome-image\" style=\"border-radius: 0px\" />\r\n\r\n <!-- Only show greeting if authenticated -->\r\n <h2 class=\"welcome-greeting\" *ngIf=\"userName && isAuthenticated\">\r\n Hi, {{ userName }}!\r\n <!-- <span class=\"emoji\">👋</span> -->\r\n <span class=\"emoji\">{{ appEmoji.waveHand }}</span>\r\n </h2>\r\n\r\n <h3>{{ appSubtitle }}</h3>\r\n <p>{{ welcomeDesc }}</p>\r\n\r\n <!-- Predefined messages chips: Only show when authenticated -->\r\n <app-chips\r\n *ngIf=\"isAuthenticated\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onPredefinedClick($event)\"\r\n ></app-chips>\r\n\r\n <!-- Guest Mode Login Button -->\r\n <div *ngIf=\"isGuestMode\" style=\"margin-top: 10px\">\r\n <button class=\"login-btn\" (click)=\"loginClick.emit()\">Login</button>\r\n </div>\r\n\r\n <!-- Fallback / Login Prompts (Below Welcome Text) -->\r\n <div\r\n *ngIf=\"!isAuthenticated && !isGuestMode\"\r\n class=\"auth-buttons-container\"\r\n style=\"margin-top: 20px\"\r\n >\r\n <button (click)=\"loginClick.emit()\" class=\"auth-btn primary\" style=\"margin-right: 10px\">\r\n Login\r\n </button>\r\n <button (click)=\"continueAsGuest.emit()\" class=\"auth-btn secondary\">Continue as Guest</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Chat Messages -->\r\n <div\r\n *ngFor=\"let message of messages; trackBy: trackByMessageId\"\r\n class=\"message-wrapper\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n <!-- Bot Avatar -->\r\n <img\r\n *ngIf=\"message.sender === 'bot'\"\r\n class=\"bot-avatar\"\r\n [src]=\"botAvatarUrl\"\r\n alt=\"Bot Avatar\"\r\n />\r\n\r\n <!-- Message Bubble -->\r\n <div\r\n class=\"message\"\r\n [class.user]=\"message.sender === 'user'\"\r\n [class.bot]=\"message.sender === 'bot'\"\r\n >\r\n {{ message.text }}\r\n <!-- Show time below message -->\r\n <div *ngIf=\"message.sender === 'bot'\" class=\"message-time\">\r\n {{ message.timestamp | date: 'shortTime' }}\r\n </div>\r\n </div>\r\n\r\n <!-- User Avatar -->\r\n <div class=\"user-avatar-container\" *ngIf=\"message.sender === 'user'\">\r\n <img class=\"user-avatar\" [src]=\"userAvatarUrl\" alt=\"User Avatar\" />\r\n <!-- <span class=\"user-name\" *ngIf=\"userName\">{{ userName }}</span> -->\r\n </div>\r\n </div>\r\n\r\n <!-- Typing Indicator -->\r\n <div class=\"message-wrapper bot\" *ngIf=\"isBotTyping\">\r\n <img class=\"bot-avatar\" [src]=\"botAvatarUrl\" alt=\"Bot Avatar\" />\r\n <div class=\"message bot\">\r\n <div class=\"typing-indicator\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.login-btn{padding:10px 15px;border:none;border-radius:20px;background-color:var(--primary-color);color:var(--user-text-color);font-size:1em;cursor:pointer;transition:background-color .2s ease}.chat-messages{flex-grow:1;padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px;scroll-behavior:smooth}.chat-messages::-webkit-scrollbar{width:8px}.chat-messages::-webkit-scrollbar-track{background:var(--grey);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb{background-color:var(--primary-color);border-radius:4px}.chat-messages::-webkit-scrollbar-thumb:hover{background-color:var(--primary-color)}.chat-messages{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--background-color)}.welcome-screen{display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;height:100%;padding:0 20px}.welcome-image{width:80px;margin-bottom:30px}.welcome-greeting{margin:0 0 12px;color:var(--text-color);font-family:var(--font-family);font-size:24px;font-weight:600;background:var(--text-color);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.welcome-greeting .emoji{background:none;-webkit-background-clip:initial;-webkit-text-fill-color:initial;background-clip:initial}.welcome-screen h3{margin:0 0 5px;color:var(--text-color);font-family:var(--font-family);font-size:18px}.welcome-screen p{margin:0 0 30px;color:var(--secondary-text-color);font-size:14px;font-family:var(--font-family)}.message-wrapper{display:flex;align-items:flex-end;gap:8px;margin-bottom:6px}.message-wrapper.user{justify-content:flex-end}.message-wrapper.bot{justify-content:flex-start}.message{padding:10px 15px;max-width:80%;overflow-y:auto;word-wrap:break-word;font-family:var(--font-family)}.message .message-time{font-size:11px;color:var(--grey);text-align:right;margin-top:4px}.message.user{background-color:var(--primary-color);color:var(--user-text-color);align-self:flex-end;border-radius:20px 20px 0}.message.bot{background-color:var(--bot-message-color);color:var(--bot-text-color);align-self:flex-start;border-radius:20px 20px 20px 0}.bot-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color);filter:var(--avatar-filter)}.user-avatar{width:24px;height:24px;border-radius:50%;object-fit:cover;border:1px solid var(--border-color)}.user-avatar.placeholder{filter:var(--avatar-filter)}.user-avatar-container{display:flex;flex-direction:column;align-items:center;gap:4px}.user-name{font-size:10px;color:var(--secondary-text-color);font-family:var(--font-family);text-align:center;max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.typing-indicator{display:flex;align-items:center;justify-content:center;gap:4px}.typing-indicator span{width:8px;height:8px;background-color:var(--typing-indicator-color);border-radius:50%;animation:blink 1.4s infinite both}.typing-indicator span:nth-child(2){animation-delay:.2s}.typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes blink{0%,80%,to{opacity:.2}40%{opacity:1}}.auth-buttons-container{display:flex;flex-direction:row;justify-content:center;gap:10px}.auth-btn{padding:8px 16px;border-radius:20px;font-size:.9em;font-weight:500;cursor:pointer;transition:all .2s ease}.auth-btn.primary{background:var(--primary-color);color:var(--white);border:1px solid var(--primary-color)}.auth-btn.primary:hover{opacity:.9}.auth-btn.primary:disabled{opacity:.5;cursor:not-allowed}.auth-btn.secondary{background:transparent;color:var(--primary-color);border:1px solid var(--primary-color)}.auth-btn.secondary:hover{opacity:.9}\n"] }]
|
|
195
200
|
}], propDecorators: { messages: [{
|
|
196
201
|
type: Input
|
|
197
202
|
}], isBotTyping: [{
|
|
@@ -212,10 +217,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
212
217
|
type: Input
|
|
213
218
|
}], isAuthenticated: [{
|
|
214
219
|
type: Input
|
|
220
|
+
}], isGuestMode: [{
|
|
221
|
+
type: Input
|
|
215
222
|
}], trackByMessageId: [{
|
|
216
223
|
type: Input
|
|
217
224
|
}], suggestionClick: [{
|
|
218
225
|
type: Output
|
|
226
|
+
}], loginClick: [{
|
|
227
|
+
type: Output
|
|
228
|
+
}], continueAsGuest: [{
|
|
229
|
+
type: Output
|
|
219
230
|
}], chatMessagesContainer: [{
|
|
220
231
|
type: ViewChild,
|
|
221
232
|
args: ['chatMessages']
|
|
@@ -528,31 +539,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
528
539
|
args: ['document:mouseup']
|
|
529
540
|
}] } });
|
|
530
541
|
|
|
531
|
-
const DEFAULT_THEME_CONFIG = {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
};
|
|
542
|
+
// const DEFAULT_THEME_CONFIG: DoohbotThemeConfig = {
|
|
543
|
+
// fontFamily: "'Roboto', Arial, sans-serif",
|
|
544
|
+
// primaryColor: '#2800ff',
|
|
545
|
+
// secondaryColor: '#08dacf',
|
|
546
|
+
// backgroundColor: '#f8f9fa, #1a1717',
|
|
547
|
+
// chatInputColor: '#f8f9fa, #1a1717',
|
|
548
|
+
// textAltColor: '#000000, #ffffff',
|
|
549
|
+
// buttonColor: '#000000, #ffffff',
|
|
550
|
+
// textColor: '#333, #f5f5f5',
|
|
551
|
+
// secondaryTextColor: '#858585, #a1a1a1',
|
|
552
|
+
// hintTextColor: '#858585, #a1a1a1',
|
|
553
|
+
// userMessageColor: '#2800ff',
|
|
554
|
+
// botMessageColor: '#e9ecef, #333',
|
|
555
|
+
// userTextColor: '#fff',
|
|
556
|
+
// botTextColor: '#333, #fff',
|
|
557
|
+
// borderColor: '#ccc, #444',
|
|
558
|
+
// borderShadowColor: '0 4px 16px rgba(0, 0, 0, 0.25), 0 4px 16px rgba(0, 0, 0, 0.75)',
|
|
559
|
+
// borderTopColor: '#dddddd00, #44444400',
|
|
560
|
+
// typingIndicatorColor: '#999, #bbb',
|
|
561
|
+
// white: '#ffffff',
|
|
562
|
+
// black: '#000000',
|
|
563
|
+
// grey: '#6c757d, #9ca3af',
|
|
564
|
+
// red: '#ff0000',
|
|
565
|
+
// lightRed: '#f28b8b',
|
|
566
|
+
// };
|
|
556
567
|
class ThemeService {
|
|
557
568
|
overlay;
|
|
558
569
|
renderer;
|
|
@@ -897,215 +908,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
897
908
|
type: Output
|
|
898
909
|
}] } });
|
|
899
910
|
|
|
900
|
-
class MenuItem {
|
|
901
|
-
href = '#';
|
|
902
|
-
selected = new EventEmitter();
|
|
903
|
-
onClick(event) {
|
|
904
|
-
// Optional: prevent default if used for actions, not navigation
|
|
905
|
-
// event.preventDefault();
|
|
906
|
-
this.selected.emit();
|
|
907
|
-
}
|
|
908
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
909
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: MenuItem, isStandalone: true, selector: "app-menu-item", inputs: { href: "href" }, outputs: { selected: "selected" }, ngImport: i0, template: "<li>\r\n <a [href]=\"href\" (click)=\"onClick($event)\">\r\n <ng-content></ng-content>\r\n </a>\r\n</li>\r\n", styles: [""] });
|
|
910
|
-
}
|
|
911
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MenuItem, decorators: [{
|
|
912
|
-
type: Component,
|
|
913
|
-
args: [{ selector: 'app-menu-item', imports: [], template: "<li>\r\n <a [href]=\"href\" (click)=\"onClick($event)\">\r\n <ng-content></ng-content>\r\n </a>\r\n</li>\r\n" }]
|
|
914
|
-
}], propDecorators: { href: [{
|
|
915
|
-
type: Input
|
|
916
|
-
}], selected: [{
|
|
917
|
-
type: Output
|
|
918
|
-
}] } });
|
|
919
|
-
|
|
920
|
-
class DropdownMenu {
|
|
921
|
-
detailsRef;
|
|
922
|
-
menuItems;
|
|
923
|
-
ngAfterContentInit() {
|
|
924
|
-
// Subscribe to all menu item selections
|
|
925
|
-
this.menuItems.forEach((item) => {
|
|
926
|
-
item.selected.subscribe(() => {
|
|
927
|
-
this.close();
|
|
928
|
-
});
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
close() {
|
|
932
|
-
this.detailsRef.nativeElement.open = false;
|
|
933
|
-
}
|
|
934
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DropdownMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
935
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: DropdownMenu, isStandalone: true, selector: "app-dropdown-menu", queries: [{ propertyName: "menuItems", predicate: MenuItem }], viewQueries: [{ propertyName: "detailsRef", first: true, predicate: ["details"], descendants: true }], ngImport: i0, template: "<details class=\"dropdown-menu\" #details>\r\n <summary role=\"button\" class=\"dropdown-trigger\">\r\n <ng-content select=\"[trigger]\"></ng-content>\r\n </summary>\r\n <ul class=\"dropdown-list\">\r\n <ng-content></ng-content>\r\n </ul>\r\n</details>\r\n\r\n<!-- ussage example:\r\n<app-dropdown-menu>\r\n <span trigger>\u2630 Menu</span>\r\n\r\n <app-menu-item href=\"/profile\" (selected)=\"doSomething('profile')\">\r\n My Profile\r\n </app-menu-item>\r\n \r\n <app-menu-item href=\"/settings\" (selected)=\"doSomething('settings')\">\r\n Settings\r\n </app-menu-item>\r\n \r\n <app-menu-item href=\"#\" (selected)=\"logout()\">\r\n Logout\r\n </app-menu-item>\r\n</app-dropdown-menu> -->\r\n\r\n<!-- \r\n Note: The above usage example is commented out to avoid rendering issues.\r\n It demonstrates how to use the DropdownMenu component with MenuItem components as options.\r\n-->\r\n", styles: [".dropdown-menu{position:relative;display:inline-block;margin:0;padding:0}.dropdown-menu summary{list-style:none;cursor:pointer;outline:none}.dropdown-menu summary::-webkit-details-marker{display:none}.dropdown-list{position:absolute;top:100%;left:0;margin:8px 0 0;padding:8px 0;width:180px;background:var(--background-color);border-radius:6px;box-shadow:var(--border-shadow-color);z-index:1000;list-style:none}.dropdown-list:before{content:\"\";position:absolute;top:-6px;left:16px;width:0;height:0;border:6px solid transparent;border-bottom-color:var(--background-color)}.dropdown-list li a{display:block;padding:8px 16px;color:var(--primary-color);text-decoration:none}.dropdown-list li a:hover{background:var(--red);color:var(--secondary-color)}\n"] });
|
|
936
|
-
}
|
|
937
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DropdownMenu, decorators: [{
|
|
938
|
-
type: Component,
|
|
939
|
-
args: [{ selector: 'app-dropdown-menu', imports: [], template: "<details class=\"dropdown-menu\" #details>\r\n <summary role=\"button\" class=\"dropdown-trigger\">\r\n <ng-content select=\"[trigger]\"></ng-content>\r\n </summary>\r\n <ul class=\"dropdown-list\">\r\n <ng-content></ng-content>\r\n </ul>\r\n</details>\r\n\r\n<!-- ussage example:\r\n<app-dropdown-menu>\r\n <span trigger>\u2630 Menu</span>\r\n\r\n <app-menu-item href=\"/profile\" (selected)=\"doSomething('profile')\">\r\n My Profile\r\n </app-menu-item>\r\n \r\n <app-menu-item href=\"/settings\" (selected)=\"doSomething('settings')\">\r\n Settings\r\n </app-menu-item>\r\n \r\n <app-menu-item href=\"#\" (selected)=\"logout()\">\r\n Logout\r\n </app-menu-item>\r\n</app-dropdown-menu> -->\r\n\r\n<!-- \r\n Note: The above usage example is commented out to avoid rendering issues.\r\n It demonstrates how to use the DropdownMenu component with MenuItem components as options.\r\n-->\r\n", styles: [".dropdown-menu{position:relative;display:inline-block;margin:0;padding:0}.dropdown-menu summary{list-style:none;cursor:pointer;outline:none}.dropdown-menu summary::-webkit-details-marker{display:none}.dropdown-list{position:absolute;top:100%;left:0;margin:8px 0 0;padding:8px 0;width:180px;background:var(--background-color);border-radius:6px;box-shadow:var(--border-shadow-color);z-index:1000;list-style:none}.dropdown-list:before{content:\"\";position:absolute;top:-6px;left:16px;width:0;height:0;border:6px solid transparent;border-bottom-color:var(--background-color)}.dropdown-list li a{display:block;padding:8px 16px;color:var(--primary-color);text-decoration:none}.dropdown-list li a:hover{background:var(--red);color:var(--secondary-color)}\n"] }]
|
|
940
|
-
}], propDecorators: { detailsRef: [{
|
|
941
|
-
type: ViewChild,
|
|
942
|
-
args: ['details']
|
|
943
|
-
}], menuItems: [{
|
|
944
|
-
type: ContentChildren,
|
|
945
|
-
args: [MenuItem]
|
|
946
|
-
}] } });
|
|
947
|
-
|
|
948
|
-
class PopoutWindowDirective {
|
|
949
|
-
renderer2;
|
|
950
|
-
elementRef;
|
|
951
|
-
innerWrapper;
|
|
952
|
-
windowWidth = 400;
|
|
953
|
-
windowHeight = 400;
|
|
954
|
-
windowLeft = 200;
|
|
955
|
-
windowTop = 200;
|
|
956
|
-
windowTitle = 'Popout Window';
|
|
957
|
-
windowStyle = '';
|
|
958
|
-
windowStyleUrl = '';
|
|
959
|
-
suppressCloneStyles = false;
|
|
960
|
-
get isPoppedOut() {
|
|
961
|
-
return this.isOut;
|
|
962
|
-
}
|
|
963
|
-
closed = new EventEmitter();
|
|
964
|
-
shown = new EventEmitter();
|
|
965
|
-
popoutWindow = null;
|
|
966
|
-
isOut = false;
|
|
967
|
-
observer;
|
|
968
|
-
beforeunloadHandler() {
|
|
969
|
-
this.close();
|
|
970
|
-
}
|
|
971
|
-
constructor(renderer2, elementRef) {
|
|
972
|
-
this.renderer2 = renderer2;
|
|
973
|
-
this.elementRef = elementRef;
|
|
974
|
-
}
|
|
975
|
-
ngOnDestroy() {
|
|
976
|
-
this.observer?.disconnect();
|
|
977
|
-
this.close();
|
|
978
|
-
}
|
|
979
|
-
close() {
|
|
980
|
-
if (this.popoutWindow) {
|
|
981
|
-
this.popoutWindow.close();
|
|
982
|
-
this.popoutWindow = null;
|
|
983
|
-
this.isOut = false;
|
|
984
|
-
this.closed.next(true);
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
popIn() {
|
|
988
|
-
if (this.elementRef.nativeElement && this.innerWrapper.nativeElement) {
|
|
989
|
-
this.renderer2.appendChild(this.elementRef.nativeElement, this.innerWrapper.nativeElement);
|
|
990
|
-
this.close();
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
popOut() {
|
|
994
|
-
if (!this.popoutWindow) {
|
|
995
|
-
const elmRect = this.innerWrapper.nativeElement.getBoundingClientRect();
|
|
996
|
-
const navHeight = window.outerHeight - window.innerHeight;
|
|
997
|
-
const navWidth = window.outerWidth - window.innerWidth;
|
|
998
|
-
const winLeft = this.windowLeft || window.screenX + navWidth + elmRect.left;
|
|
999
|
-
const winTop = this.windowTop || window.screenY + navHeight + elmRect.top - 60;
|
|
1000
|
-
this.popoutWindow = window.open('', `popoutWindow${Date.now()}`, `width=${this.windowWidth > 99 ? this.windowWidth : elmRect.width},
|
|
1001
|
-
height=${this.windowHeight > 99 ? this.windowHeight : elmRect.height + 1},
|
|
1002
|
-
left=${winLeft},
|
|
1003
|
-
top=${winTop}`);
|
|
1004
|
-
if (!this.popoutWindow) {
|
|
1005
|
-
console.error('Popup blocked or failed to open');
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
this.popoutWindow.document.title = this.windowTitle
|
|
1009
|
-
? this.windowTitle
|
|
1010
|
-
: window.document.title;
|
|
1011
|
-
this.popoutWindow.document.body.style.margin = '0';
|
|
1012
|
-
if (!this.suppressCloneStyles) {
|
|
1013
|
-
document.head.querySelectorAll('style').forEach((node) => {
|
|
1014
|
-
this.popoutWindow?.document.head.appendChild(node.cloneNode(true));
|
|
1015
|
-
});
|
|
1016
|
-
this.observeStyleChanges();
|
|
1017
|
-
document.head.querySelectorAll('link[rel="stylesheet"]').forEach((node) => {
|
|
1018
|
-
this.popoutWindow?.document.head.insertAdjacentHTML('beforeend', `<link rel="stylesheet" type="${node.type}" href="${node.href}">`);
|
|
1019
|
-
});
|
|
1020
|
-
// Safe check for document.fonts
|
|
1021
|
-
const doc = document;
|
|
1022
|
-
const targetDoc = this.popoutWindow.document;
|
|
1023
|
-
if (doc.fonts && targetDoc.fonts) {
|
|
1024
|
-
doc.fonts.forEach((node) => {
|
|
1025
|
-
targetDoc.fonts.add(node);
|
|
1026
|
-
});
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
if (this.windowStyleUrl) {
|
|
1030
|
-
this.popoutWindow.document.head.insertAdjacentHTML('beforeend', `<link rel="stylesheet" type="text/css" href="${window.location.origin}/${this.windowStyleUrl}">`);
|
|
1031
|
-
}
|
|
1032
|
-
if (this.windowStyle) {
|
|
1033
|
-
this.popoutWindow.document.head.insertAdjacentHTML('beforeend', `<style>${this.windowStyle}</style>`);
|
|
1034
|
-
}
|
|
1035
|
-
this.renderer2.appendChild(this.popoutWindow.document.body, this.innerWrapper.nativeElement);
|
|
1036
|
-
this.isOut = true;
|
|
1037
|
-
this.shown.emit(this.popoutWindow);
|
|
1038
|
-
this.popoutWindow.addEventListener('unload', () => {
|
|
1039
|
-
this.popIn();
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
else {
|
|
1043
|
-
this.popoutWindow.focus();
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
observeStyleChanges() {
|
|
1047
|
-
const docHead = document.querySelector('head');
|
|
1048
|
-
if (!docHead)
|
|
1049
|
-
return;
|
|
1050
|
-
this.observer?.disconnect();
|
|
1051
|
-
this.observer = new MutationObserver((mutations) => {
|
|
1052
|
-
mutations.forEach((mutation) => {
|
|
1053
|
-
mutation.addedNodes.forEach((node) => {
|
|
1054
|
-
if (node.nodeName === 'STYLE' && this.popoutWindow) {
|
|
1055
|
-
this.popoutWindow.document.head.appendChild(node.cloneNode(true));
|
|
1056
|
-
}
|
|
1057
|
-
});
|
|
1058
|
-
});
|
|
1059
|
-
});
|
|
1060
|
-
this.observer.observe(docHead, { childList: true });
|
|
1061
|
-
}
|
|
1062
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: PopoutWindowDirective, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1063
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: PopoutWindowDirective, isStandalone: true, selector: "popout-window", inputs: { windowWidth: "windowWidth", windowHeight: "windowHeight", windowLeft: "windowLeft", windowTop: "windowTop", windowTitle: "windowTitle", windowStyle: "windowStyle", windowStyleUrl: "windowStyleUrl", suppressCloneStyles: "suppressCloneStyles", isPoppedOut: "isPoppedOut" }, outputs: { closed: "closed", shown: "shown" }, host: { listeners: { "window:beforeunload": "beforeunloadHandler()" } }, viewQueries: [{ propertyName: "innerWrapper", first: true, predicate: ["innerWrapper"], descendants: true }], ngImport: i0, template: `
|
|
1064
|
-
<div #innerWrapper style="width: 100%; height: 100%; overflow: auto;">
|
|
1065
|
-
<ng-content></ng-content>
|
|
1066
|
-
</div>
|
|
1067
|
-
`, isInline: true });
|
|
1068
|
-
}
|
|
1069
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: PopoutWindowDirective, decorators: [{
|
|
1070
|
-
type: Component,
|
|
1071
|
-
args: [{
|
|
1072
|
-
selector: 'popout-window',
|
|
1073
|
-
template: `
|
|
1074
|
-
<div #innerWrapper style="width: 100%; height: 100%; overflow: auto;">
|
|
1075
|
-
<ng-content></ng-content>
|
|
1076
|
-
</div>
|
|
1077
|
-
`,
|
|
1078
|
-
}]
|
|
1079
|
-
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { innerWrapper: [{
|
|
1080
|
-
type: ViewChild,
|
|
1081
|
-
args: ['innerWrapper']
|
|
1082
|
-
}], windowWidth: [{
|
|
1083
|
-
type: Input
|
|
1084
|
-
}], windowHeight: [{
|
|
1085
|
-
type: Input
|
|
1086
|
-
}], windowLeft: [{
|
|
1087
|
-
type: Input
|
|
1088
|
-
}], windowTop: [{
|
|
1089
|
-
type: Input
|
|
1090
|
-
}], windowTitle: [{
|
|
1091
|
-
type: Input
|
|
1092
|
-
}], windowStyle: [{
|
|
1093
|
-
type: Input
|
|
1094
|
-
}], windowStyleUrl: [{
|
|
1095
|
-
type: Input
|
|
1096
|
-
}], suppressCloneStyles: [{
|
|
1097
|
-
type: Input
|
|
1098
|
-
}], isPoppedOut: [{
|
|
1099
|
-
type: Input
|
|
1100
|
-
}], closed: [{
|
|
1101
|
-
type: Output
|
|
1102
|
-
}], shown: [{
|
|
1103
|
-
type: Output
|
|
1104
|
-
}], beforeunloadHandler: [{
|
|
1105
|
-
type: HostListener,
|
|
1106
|
-
args: ['window:beforeunload']
|
|
1107
|
-
}] } });
|
|
1108
|
-
|
|
1109
911
|
class ChatWindowComponent {
|
|
1110
912
|
isChatOpen = false;
|
|
1111
913
|
enableDrag = false;
|
|
@@ -1135,6 +937,10 @@ class ChatWindowComponent {
|
|
|
1135
937
|
chatSessions = [];
|
|
1136
938
|
chatHistoryUserName = 'User';
|
|
1137
939
|
isGuestUser = false;
|
|
940
|
+
isGuestMode = false;
|
|
941
|
+
isLoggingIn = false;
|
|
942
|
+
authError = null;
|
|
943
|
+
authSuccess = null;
|
|
1138
944
|
themeConfig;
|
|
1139
945
|
toggleChat = new EventEmitter();
|
|
1140
946
|
toggleFullScreen = new EventEmitter();
|
|
@@ -1146,7 +952,19 @@ class ChatWindowComponent {
|
|
|
1146
952
|
clearChat = new EventEmitter();
|
|
1147
953
|
sessionSelected = new EventEmitter();
|
|
1148
954
|
sessionDeleted = new EventEmitter();
|
|
955
|
+
continueAsGuest = new EventEmitter();
|
|
956
|
+
loginClick = new EventEmitter();
|
|
957
|
+
loginSubmit = new EventEmitter();
|
|
958
|
+
logout = new EventEmitter();
|
|
1149
959
|
themeService = inject(ThemeService);
|
|
960
|
+
// Login form state
|
|
961
|
+
loginUsername = '';
|
|
962
|
+
loginPassword = '';
|
|
963
|
+
showLoginForm = false;
|
|
964
|
+
showPassword = false;
|
|
965
|
+
togglePasswordVisibility() {
|
|
966
|
+
this.showPassword = !this.showPassword;
|
|
967
|
+
}
|
|
1150
968
|
onToggleChat() {
|
|
1151
969
|
this.toggleChat.emit();
|
|
1152
970
|
}
|
|
@@ -1154,6 +972,21 @@ class ChatWindowComponent {
|
|
|
1154
972
|
console.log('History button clicked!');
|
|
1155
973
|
this.toggleHistorySidebar.emit();
|
|
1156
974
|
}
|
|
975
|
+
onLoginClick() {
|
|
976
|
+
this.loginClick.emit();
|
|
977
|
+
this.showLoginForm = true;
|
|
978
|
+
}
|
|
979
|
+
onLoginSubmit() {
|
|
980
|
+
if (this.loginUsername && this.loginPassword) {
|
|
981
|
+
this.loginSubmit.emit({
|
|
982
|
+
username: this.loginUsername,
|
|
983
|
+
password: this.loginPassword,
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
onCancelLogin() {
|
|
988
|
+
this.showLoginForm = false;
|
|
989
|
+
}
|
|
1157
990
|
onToggleFullScreen() {
|
|
1158
991
|
this.toggleFullScreen.emit();
|
|
1159
992
|
}
|
|
@@ -1167,17 +1000,27 @@ class ChatWindowComponent {
|
|
|
1167
1000
|
this.send.emit(text);
|
|
1168
1001
|
}
|
|
1169
1002
|
onClearMessageError() {
|
|
1003
|
+
this.messageError = null;
|
|
1004
|
+
this.clearMessageError.emit();
|
|
1005
|
+
}
|
|
1006
|
+
onClearAuthError() {
|
|
1170
1007
|
this.clearMessageError.emit();
|
|
1171
1008
|
}
|
|
1172
1009
|
onClearChat() {
|
|
1173
1010
|
this.clearChat.emit();
|
|
1174
1011
|
}
|
|
1012
|
+
onLogout() {
|
|
1013
|
+
this.logout.emit();
|
|
1014
|
+
}
|
|
1175
1015
|
onSessionSelected(session) {
|
|
1176
1016
|
this.sessionSelected.emit(session);
|
|
1177
1017
|
}
|
|
1178
1018
|
onSessionDeleted(sessionId) {
|
|
1179
1019
|
this.sessionDeleted.emit(sessionId);
|
|
1180
1020
|
}
|
|
1021
|
+
onContinueAsGuest() {
|
|
1022
|
+
this.continueAsGuest.emit();
|
|
1023
|
+
}
|
|
1181
1024
|
onPopoutShown(win) {
|
|
1182
1025
|
// Apply theme classes
|
|
1183
1026
|
const activeTheme = this.themeService.activeTheme();
|
|
@@ -1190,8 +1033,18 @@ class ChatWindowComponent {
|
|
|
1190
1033
|
// Apply CSS variables
|
|
1191
1034
|
this.themeService.applyCssVariables(body, this.themeConfig);
|
|
1192
1035
|
}
|
|
1036
|
+
ngOnInit() {
|
|
1037
|
+
// Initialization logic if needed
|
|
1038
|
+
}
|
|
1039
|
+
ngOnChanges(changes) {
|
|
1040
|
+
//? Handle authentication status changes
|
|
1041
|
+
if (changes['isAuthenticated'] && this.isAuthenticated) {
|
|
1042
|
+
this.showLoginForm = false;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
ngOnDestroy() { }
|
|
1193
1046
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatWindowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1194
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: ChatWindowComponent, isStandalone: true, selector: "app-chat-window", inputs: { isChatOpen: "isChatOpen", enableDrag: "enableDrag", enableResize: "enableResize", isFullScreen: "isFullScreen", isAuthenticated: "isAuthenticated", appTitle: "appTitle", appLogoUrl: "appLogoUrl", appTextLogoUrl: "appTextLogoUrl", appHeaderLogoUrl: "appHeaderLogoUrl", moreIcon: "moreIcon", minimizeIcon: "minimizeIcon", messages: "messages", isBotTyping: "isBotTyping", appSubtitle: "appSubtitle", welcomeDesc: "welcomeDesc", predefinedMessages: "predefinedMessages", botAvatarUrl: "botAvatarUrl", userAvatarUrl: "userAvatarUrl", userName: "userName", trackByMessageId: "trackByMessageId", hintText: "hintText", sendIcon: "sendIcon", messageError: "messageError", showSuggestionChips: "showSuggestionChips", isHistorySidebarOpen: "isHistorySidebarOpen", chatSessions: "chatSessions", chatHistoryUserName: "chatHistoryUserName", isGuestUser: "isGuestUser", themeConfig: "themeConfig" }, outputs: { toggleChat: "toggleChat", toggleFullScreen: "toggleFullScreen", toggleHistorySidebar: "toggleHistorySidebar", openSettings: "openSettings", suggestionClick: "suggestionClick", send: "send", clearMessageError: "clearMessageError", clearChat: "clearChat", sessionSelected: "sessionSelected", sessionDeleted: "sessionDeleted" }, ngImport: i0, template: "<div\r\n *ngIf=\"isChatOpen\"\r\n draggableDialog\r\n [enableDrag]=\"enableDrag\"\r\n [dragHandle]=\"'.chat-header'\"\r\n resizableDialog\r\n [enableResize]=\"enableResize\"\r\n class=\"chat-window\"\r\n [class.fullscreen]=\"isFullScreen\"\r\n>\r\n <!-- chat window -->\r\n <div class=\"chat-header\">\r\n <div class=\"chat-title\">\r\n <img\r\n class=\"chat-logo\"\r\n style=\"width: 150px; height: 50px; margin-left: 0px\"\r\n [src]=\"appHeaderLogoUrl\"\r\n alt=\"Text-Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"chat-header-buttons\">\r\n <!-- New Chat Button -->\r\n <!-- <button class=\"header-button\" (click)=\"createNewChat()\">\r\n <mat-icon>add</mat-icon>\r\n </button> -->\r\n\r\n <!-- <app-dropdown-menu>\r\n <span trigger>\u2630</span>\r\n\r\n <app-menu-item (selected)=\"onToggleFullScreen()\"> My Profile </app-menu-item>\r\n\r\n <app-menu-item> Settings </app-menu-item>\r\n\r\n <app-menu-item> Logout </app-menu-item>\r\n </app-dropdown-menu> -->\r\n\r\n <!-- History Button -->\r\n <button\r\n class=\"header-button\"\r\n *ngIf=\"isAuthenticated\"\r\n (click)=\"onToggleHistorySidebar()\"\r\n title=\"Chat History\"\r\n >\r\n <mat-icon>history</mat-icon>\r\n </button>\r\n\r\n <!-- settings Button -->\r\n <button class=\"header-button\" [matMenuTriggerFor]=\"settingsMenu\">\r\n <mat-icon>{{ moreIcon }}</mat-icon>\r\n </button>\r\n\r\n <!-- minimize Button -->\r\n <button class=\"header-button\" (click)=\"onToggleChat()\">\r\n <mat-icon>{{ minimizeIcon }}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Main Content Area: Toggle between Messages and History -->\r\n <!-- <popout-window\r\n #popout\r\n [windowTitle]=\"appTitle || 'Chat'\"\r\n [windowWidth]=\"400\"\r\n [windowHeight]=\"620\"\r\n (shown)=\"onPopoutShown($event)\"\r\n > -->\r\n <div class=\"chat-content-wrapper\">\r\n <!-- Chat History View -->\r\n <app-chat-history-sidebar\r\n [sessions]=\"chatSessions\"\r\n [isOpen]=\"isHistorySidebarOpen\"\r\n [userName]=\"chatHistoryUserName\"\r\n (sessionSelected)=\"onSessionSelected($event)\"\r\n (sessionDeleted)=\"onSessionDeleted($event)\"\r\n (closed)=\"onToggleHistorySidebar()\"\r\n >\r\n </app-chat-history-sidebar>\r\n\r\n <!-- Messages View -->\r\n <div class=\"messages-view\" [class.hidden]=\"isHistorySidebarOpen\">\r\n <!-- Messages / Welcome Screen -->\r\n <app-message-list\r\n [messages]=\"messages\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [appLogoUrl]=\"appLogoUrl\"\r\n [appSubtitle]=\"appSubtitle\"\r\n [welcomeDesc]=\"welcomeDesc\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [isAuthenticated]=\"isAuthenticated\"\r\n (suggestionClick)=\"onSuggestionClick($event)\"\r\n ></app-message-list>\r\n\r\n <!-- SUGGESTED CHIPS: Show only if last bot message was fallback AND user is authenticated -->\r\n <app-chips\r\n *ngIf=\"showSuggestionChips && isAuthenticated\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onSuggestionClick($event)\"\r\n ></app-chips>\r\n\r\n <!-- Inline error message -->\r\n <app-snackbar\r\n *ngIf=\"messageError\"\r\n [message]=\"messageError\"\r\n [show]=\"!messageError\"\r\n (closed)=\"onClearMessageError()\"\r\n ></app-snackbar>\r\n\r\n <!-- Chat Input: Only show when authenticated -->\r\n <app-message-input\r\n *ngIf=\"isAuthenticated\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [hintText]=\"hintText\"\r\n [sendIcon]=\"sendIcon\"\r\n (send)=\"onSend($event)\"\r\n ></app-message-input>\r\n\r\n <!-- footer -->\r\n <div class=\"terms-conditions\">\r\n <a href=\"#\">Terms and Conditions</a>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- </popout-window> -->\r\n</div>\r\n\r\n<mat-menu #settingsMenu=\"matMenu\">\r\n <!-- Change Theme -->\r\n <div class=\"theme-selector\">\r\n <!-- Auto Theme (inherits from parent app) -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'auto'\"\r\n (click)=\"themeService.setTheme('auto')\"\r\n >\r\n <mat-icon>brightness_auto</mat-icon>\r\n </button>\r\n\r\n <!-- Light Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'light'\"\r\n (click)=\"themeService.setTheme('light')\"\r\n >\r\n <mat-icon>light_mode</mat-icon>\r\n </button>\r\n\r\n <!-- Dark Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'dark'\"\r\n (click)=\"themeService.setTheme('dark')\"\r\n >\r\n <mat-icon>dark_mode</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Popout Button -->\r\n <!-- <button mat-menu-item (click)=\"popout.popOut()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>open_in_new</mat-icon>\r\n <span>Popout Widget</span>\r\n </button> -->\r\n\r\n <!-- Full-Screen Button -->\r\n <button mat-menu-item (click)=\"onToggleFullScreen()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>{{ isFullScreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\r\n <span> {{ isFullScreen ? 'Minimize' : 'Expand' }}</span>\r\n </button>\r\n\r\n <!-- Clear Chat -->\r\n <button mat-menu-item (click)=\"onClearChat()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>clear_all</mat-icon>\r\n <span>Clear Chat</span>\r\n </button>\r\n</mat-menu>\r\n", styles: ["::ng-deep .mat-mdc-menu-panel{background-color:#8b8b8b!important;color:#fff!important;border-radius:8px!important;padding:4px 0!important;box-shadow:0 4px 16px #00000040!important;border-color:#ccc!important;font-family:Roboto,Arial,sans-serif!important;font-size:14px!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item mat-icon{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover{background-color:#5c5c5c!important;color:#f5f5f5!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover mat-icon{color:#f5f5f5!important}.doohbot-container{position:fixed;bottom:20px;right:20px;z-index:1000}.chat-window{width:clamp(400px,30vw,450px);height:clamp(620px,70vh,660px);background-color:var(--background-color);border-radius:20px;border-color:var(--border-color);box-shadow:var(--border-shadow-color);display:flex;flex-direction:column;overflow:hidden;animation:slide-in .5s ease;position:fixed;right:20px;bottom:20px;-webkit-user-select:none;user-select:none}@media (max-width: 768px){.chat-window{width:95%;height:calc(100vh - 20px)}}@media (max-width: 480px){.chat-window{width:90%;height:calc(100vh - 40px)}}.chat-window.fullscreen{width:98vw;height:96vh;border-radius:20px;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-webkit-user-select:none;user-select:none}@keyframes slide-in{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}.chat-header{display:flex;justify-content:space-between;align-items:center;padding:10px 20px;background-color:var(--background-color);color:var(--text-alt-color);cursor:move;-webkit-user-select:none;user-select:none}.chat-header:active{cursor:grabbing}.chat-title{display:flex;align-items:center;gap:6px;font-family:var(--font-family)}.chat-logo{width:45px;height:45px;object-fit:contain}.chat-header h2{margin:0;font-size:1.2rem;color:var(--text-alt-color);font-family:var(--font-family);font-weight:700}.header-button{background:none;border:none;color:var(--button-color);cursor:pointer;font-size:1.5rem}.header-button :hover{transform:scale(1.1)}.terms-conditions{font-size:.8rem;color:var(--text-color);margin-top:5px;margin-bottom:10px;display:flex;justify-content:center;align-items:center}.terms-conditions a{color:var(--grey);text-decoration:underline;font-family:var(--font-family)}.terms-conditions a:hover{color:var(--primary-color)}.chat-content-wrapper{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative}.messages-view{display:flex;flex-direction:column;height:100%;width:100%}.messages-view.hidden{display:none}.theme-selector{display:flex;align-items:center;padding:4px 12px;gap:8px}.theme-btn{background:none;border:none;color:#fff;transition:color .2s ease}.theme-btn.selected{color:#000}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: Chips, selector: "app-chips", inputs: ["messages", "disabled"], outputs: ["chipClick"] }, { kind: "component", type: MessageListComponent, selector: "app-message-list", inputs: ["messages", "isBotTyping", "appLogoUrl", "appSubtitle", "welcomeDesc", "predefinedMessages", "botAvatarUrl", "userAvatarUrl", "userName", "isAuthenticated", "trackByMessageId"], outputs: ["suggestionClick"] }, { kind: "component", type: MessageInputComponent, selector: "app-message-input", inputs: ["isBotTyping", "hintText", "sendIcon"], outputs: ["send"] }, { kind: "component", type: SnackBar, selector: "app-snackbar", inputs: ["message", "autoDismiss", "dismissDelay", "show"], outputs: ["closed"] }, { kind: "directive", type: DraggableDialogDirective, selector: "[draggableDialog]", inputs: ["dragHandle", "enableDrag"] }, { kind: "directive", type: ResizableDialogDirective, selector: "[resizableDialog]", inputs: ["enableResize"] }, { kind: "component", type: ChatHistorySidebarComponent, selector: "app-chat-history-sidebar", inputs: ["sessions", "isOpen", "userName"], outputs: ["sessionSelected", "sessionDeleted", "closed"] }] });
|
|
1047
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: ChatWindowComponent, isStandalone: true, selector: "app-chat-window", inputs: { isChatOpen: "isChatOpen", enableDrag: "enableDrag", enableResize: "enableResize", isFullScreen: "isFullScreen", isAuthenticated: "isAuthenticated", appTitle: "appTitle", appLogoUrl: "appLogoUrl", appTextLogoUrl: "appTextLogoUrl", appHeaderLogoUrl: "appHeaderLogoUrl", moreIcon: "moreIcon", minimizeIcon: "minimizeIcon", messages: "messages", isBotTyping: "isBotTyping", appSubtitle: "appSubtitle", welcomeDesc: "welcomeDesc", predefinedMessages: "predefinedMessages", botAvatarUrl: "botAvatarUrl", userAvatarUrl: "userAvatarUrl", userName: "userName", trackByMessageId: "trackByMessageId", hintText: "hintText", sendIcon: "sendIcon", messageError: "messageError", showSuggestionChips: "showSuggestionChips", isHistorySidebarOpen: "isHistorySidebarOpen", chatSessions: "chatSessions", chatHistoryUserName: "chatHistoryUserName", isGuestUser: "isGuestUser", isGuestMode: "isGuestMode", isLoggingIn: "isLoggingIn", authError: "authError", authSuccess: "authSuccess", themeConfig: "themeConfig" }, outputs: { toggleChat: "toggleChat", toggleFullScreen: "toggleFullScreen", toggleHistorySidebar: "toggleHistorySidebar", openSettings: "openSettings", suggestionClick: "suggestionClick", send: "send", clearMessageError: "clearMessageError", clearChat: "clearChat", sessionSelected: "sessionSelected", sessionDeleted: "sessionDeleted", continueAsGuest: "continueAsGuest", loginClick: "loginClick", loginSubmit: "loginSubmit", logout: "logout" }, usesOnChanges: true, ngImport: i0, template: "<div\r\n *ngIf=\"isChatOpen\"\r\n draggableDialog\r\n [enableDrag]=\"enableDrag\"\r\n [dragHandle]=\"'.chat-header'\"\r\n resizableDialog\r\n [enableResize]=\"enableResize\"\r\n class=\"chat-window\"\r\n [class.fullscreen]=\"isFullScreen\"\r\n>\r\n <!-- chat window -->\r\n <div class=\"chat-header\">\r\n <div class=\"chat-title\">\r\n <img\r\n class=\"chat-logo\"\r\n style=\"width: 150px; height: 50px; margin-left: 0px\"\r\n [src]=\"appHeaderLogoUrl\"\r\n alt=\"Text-Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"chat-header-buttons\">\r\n <!-- New Chat Button -->\r\n <!-- <button class=\"header-button\" (click)=\"createNewChat()\">\r\n <mat-icon>add</mat-icon>\r\n </button> -->\r\n\r\n <!-- <app-dropdown-menu>\r\n <span trigger>\u2630</span>\r\n\r\n <app-menu-item (selected)=\"onToggleFullScreen()\"> My Profile </app-menu-item>\r\n\r\n <app-menu-item> Settings </app-menu-item>\r\n\r\n <app-menu-item> Logout </app-menu-item>\r\n </app-dropdown-menu> -->\r\n\r\n <!-- History Button -->\r\n <button\r\n class=\"header-button\"\r\n *ngIf=\"isAuthenticated\"\r\n (click)=\"onToggleHistorySidebar()\"\r\n title=\"Chat History\"\r\n >\r\n <mat-icon>history</mat-icon>\r\n </button>\r\n\r\n <!-- settings Button -->\r\n <button class=\"header-button\" [matMenuTriggerFor]=\"settingsMenu\">\r\n <mat-icon>{{ moreIcon }}</mat-icon>\r\n </button>\r\n\r\n <!-- minimize Button -->\r\n <button class=\"header-button\" (click)=\"onToggleChat()\">\r\n <mat-icon>{{ minimizeIcon }}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Main Content Area: Toggle between Messages and History -->\r\n <!-- <popout-window\r\n #popout\r\n [windowTitle]=\"appTitle || 'Chat'\"\r\n [windowWidth]=\"400\"\r\n [windowHeight]=\"620\"\r\n (shown)=\"onPopoutShown($event)\"\r\n > -->\r\n <div class=\"chat-content-wrapper\">\r\n <!-- Chat History View -->\r\n <app-chat-history-sidebar\r\n [sessions]=\"chatSessions\"\r\n [isOpen]=\"isHistorySidebarOpen\"\r\n [userName]=\"chatHistoryUserName\"\r\n (sessionSelected)=\"onSessionSelected($event)\"\r\n (sessionDeleted)=\"onSessionDeleted($event)\"\r\n (closed)=\"onToggleHistorySidebar()\"\r\n >\r\n </app-chat-history-sidebar>\r\n\r\n <!-- Messages View -->\r\n <div class=\"messages-view\" [class.hidden]=\"isHistorySidebarOpen\">\r\n <!-- Messages / Welcome Screen -->\r\n <app-message-list\r\n *ngIf=\"!showLoginForm\"\r\n [messages]=\"messages\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [appLogoUrl]=\"appLogoUrl\"\r\n [appSubtitle]=\"appSubtitle\"\r\n [welcomeDesc]=\"welcomeDesc\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [isAuthenticated]=\"isAuthenticated\"\r\n [isGuestMode]=\"isGuestMode\"\r\n (suggestionClick)=\"onSuggestionClick($event)\"\r\n (loginClick)=\"onLoginClick()\"\r\n (continueAsGuest)=\"onContinueAsGuest()\"\r\n ></app-message-list>\r\n\r\n <!-- SUGGESTED CHIPS: Show only if last bot message was fallback AND user is authenticated -->\r\n <app-chips\r\n *ngIf=\"showSuggestionChips && (isAuthenticated || isGuestMode)\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onSuggestionClick($event)\"\r\n ></app-chips>\r\n\r\n <!-- Chat Input: Only show when authenticated or guest mode -->\r\n <app-message-input\r\n *ngIf=\"isAuthenticated || isGuestMode\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [hintText]=\"hintText\"\r\n [sendIcon]=\"sendIcon\"\r\n (send)=\"onSend($event)\"\r\n ></app-message-input>\r\n\r\n <!-- Login Form -->\r\n <div *ngIf=\"showLoginForm && !isAuthenticated\" class=\"login-form-container\">\r\n <h3 class=\"login-title\">Login</h3>\r\n <div class=\"login-fields\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"loginUsername\"\r\n placeholder=\"Username\"\r\n class=\"login-input\"\r\n />\r\n <div class=\"password-wrapper\">\r\n <input\r\n [type]=\"showPassword ? 'text' : 'password'\"\r\n [(ngModel)]=\"loginPassword\"\r\n placeholder=\"Password\"\r\n class=\"login-input password-input\"\r\n (keydown.enter)=\"onLoginSubmit()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"password-toggle-btn\"\r\n (click)=\"togglePasswordVisibility()\"\r\n tabindex=\"-1\"\r\n >\r\n <mat-icon>{{ showPassword ? 'visibility' : 'visibility_off' }}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"login-actions\">\r\n <button (click)=\"onCancelLogin()\" class=\"auth-btn secondary\">Cancel</button>\r\n <button\r\n (click)=\"onLoginSubmit()\"\r\n class=\"auth-btn primary\"\r\n [disabled]=\"!loginUsername || !loginPassword || isLoggingIn\"\r\n >\r\n {{ isLoggingIn ? 'Logging in...' : 'Submit' }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Auth error snackbar (login/logout errors only) -->\r\n <app-snackbar\r\n *ngIf=\"authError\"\r\n [message]=\"authError\"\r\n (closed)=\"onClearAuthError()\"\r\n ></app-snackbar>\r\n\r\n <!-- footer -->\r\n <div class=\"terms-conditions\">\r\n <a href=\"#\">Terms and Conditions</a>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- </popout-window> -->\r\n</div>\r\n\r\n<mat-menu #settingsMenu=\"matMenu\">\r\n <!-- Change Theme -->\r\n <div class=\"theme-selector\">\r\n <!-- Auto Theme (inherits from parent app) -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'auto'\"\r\n (click)=\"themeService.setTheme('auto')\"\r\n >\r\n <mat-icon>brightness_auto</mat-icon>\r\n </button>\r\n\r\n <!-- Light Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'light'\"\r\n (click)=\"themeService.setTheme('light')\"\r\n >\r\n <mat-icon>light_mode</mat-icon>\r\n </button>\r\n\r\n <!-- Dark Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'dark'\"\r\n (click)=\"themeService.setTheme('dark')\"\r\n >\r\n <mat-icon>dark_mode</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Popout Button -->\r\n <!-- <button mat-menu-item (click)=\"popout.popOut()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>open_in_new</mat-icon>\r\n <span>Popout Widget</span>\r\n </button> -->\r\n\r\n <!-- Full-Screen Button -->\r\n <button mat-menu-item (click)=\"onToggleFullScreen()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>{{ isFullScreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\r\n <span> {{ isFullScreen ? 'Minimize' : 'Expand' }}</span>\r\n </button>\r\n\r\n <!-- Clear Chat -->\r\n <button mat-menu-item (click)=\"onClearChat()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>clear_all</mat-icon>\r\n <span>Clear Chat</span>\r\n </button>\r\n\r\n <!-- Logout -->\r\n <button\r\n mat-menu-item\r\n *ngIf=\"isAuthenticated\"\r\n (click)=\"onLogout()\"\r\n style=\"display: flex; align-items: center\"\r\n >\r\n <mat-icon>logout</mat-icon>\r\n <span>Logout</span>\r\n </button>\r\n</mat-menu>\r\n", styles: ["::ng-deep .mat-mdc-menu-panel{background-color:#8b8b8b!important;color:#fff!important;border-radius:8px!important;padding:4px 0!important;box-shadow:0 4px 16px #00000040!important;border-color:#ccc!important;font-family:Roboto,Arial,sans-serif!important;font-size:14px!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item mat-icon{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover{background-color:#5c5c5c!important;color:#f5f5f5!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover mat-icon{color:#f5f5f5!important}.doohbot-container{position:fixed;bottom:20px;right:20px;z-index:1000}.chat-window{width:clamp(400px,30vw,450px);height:clamp(620px,70vh,660px);background-color:var(--background-color);border-radius:20px;border-color:var(--border-color);box-shadow:var(--border-shadow-color);display:flex;flex-direction:column;overflow:hidden;animation:slide-in .5s ease;position:fixed;right:20px;bottom:20px;-webkit-user-select:none;user-select:none}@media (max-width: 768px){.chat-window{width:95%;height:calc(100vh - 20px)}}@media (max-width: 480px){.chat-window{width:90%;height:calc(100vh - 40px)}}.chat-window.fullscreen{width:98vw;height:96vh;border-radius:20px;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-webkit-user-select:none;user-select:none}@keyframes slide-in{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}.chat-header{display:flex;justify-content:space-between;align-items:center;padding:10px 20px;background-color:var(--background-color);color:var(--text-alt-color);cursor:move;-webkit-user-select:none;user-select:none}.chat-header:active{cursor:grabbing}.chat-title{display:flex;align-items:center;gap:6px;font-family:var(--font-family)}.chat-logo{width:45px;height:45px;object-fit:contain}.chat-header h2{margin:0;font-size:1.2rem;color:var(--text-alt-color);font-family:var(--font-family);font-weight:700}.header-button{background:none;border:none;color:var(--button-color);cursor:pointer;font-size:1.5rem}.header-button :hover{transform:scale(1.1)}.terms-conditions{font-size:.8rem;color:var(--text-color);margin-top:5px;margin-bottom:10px;display:flex;justify-content:center;align-items:center}.terms-conditions a{color:var(--grey);text-decoration:underline;font-family:var(--font-family)}.terms-conditions a:hover{color:var(--primary-color)}.chat-content-wrapper{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative}.messages-view{display:flex;flex-direction:column;height:100%;width:100%}.messages-view.hidden{display:none}.messages-view app-message-list{flex:1;min-height:0}.messages-view app-snackbar{flex-shrink:0;margin-top:auto}.messages-view app-message-input{flex-shrink:0}.theme-selector{display:flex;align-items:center;padding:4px 12px;gap:8px}.theme-btn{background:none;border:none;color:var(--white);transition:color .2s ease}.theme-btn.selected{color:var(--black)}.auth-prompt-container{padding:20px;display:flex;justify-content:center;align-items:center;flex-direction:column;gap:15px;text-align:center;height:100%}.auth-prompt-container .auth-prompt-text{margin:0;font-size:.95em;opacity:.8;color:var(--text-color)}.auth-prompt-container .auth-buttons{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}.auth-btn{padding:8px 18px;border-radius:20px;cursor:pointer;font-size:.9em;font-weight:500;transition:all .2s ease}.auth-btn.primary{background:var(--primary-color);color:var(--white);border:1px solid var(--primary-color)}.auth-btn.primary:hover{opacity:.9}.auth-btn.primary:disabled{opacity:.5;cursor:not-allowed}.auth-btn.secondary{background:transparent;color:var(--re);border:1px solid var(--primary-color)}.auth-btn.secondary:hover{opacity:.9}.login-form-container{padding:20px;display:flex;flex-direction:column;gap:15px;height:100%;justify-content:center}.login-form-container .login-title{text-align:center;margin:0 0 10px;font-size:1.2em;color:var(--text-color);font-family:var(--font-family)}.login-form-container .login-fields{display:flex;flex-direction:column;gap:10px}.login-form-container .login-fields .login-input{padding:10px 12px;border-radius:8px;border:1px solid var(--border-color);font-size:.9em;background:var(--background-color);color:var(--text-color)}.login-form-container .login-fields .login-input:focus{outline:none;border-color:var(--primary-color)}.login-form-container .login-fields .password-wrapper{position:relative;display:flex;align-items:center}.login-form-container .login-fields .password-wrapper .login-input{width:100%;padding-right:40px}.login-form-container .login-fields .password-wrapper .password-toggle-btn{position:absolute;right:8px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:4px;color:var(--text-color);opacity:.6;transition:opacity .2s}.login-form-container .login-fields .password-wrapper .password-toggle-btn:hover{opacity:1}.login-form-container .login-fields .password-wrapper .password-toggle-btn mat-icon{font-size:20px;width:20px;height:20px}.login-form-container .login-actions{display:flex;justify-content:center;gap:10px;margin-top:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: Chips, selector: "app-chips", inputs: ["messages", "disabled"], outputs: ["chipClick"] }, { kind: "component", type: MessageListComponent, selector: "app-message-list", inputs: ["messages", "isBotTyping", "appLogoUrl", "appSubtitle", "welcomeDesc", "predefinedMessages", "botAvatarUrl", "userAvatarUrl", "userName", "isAuthenticated", "isGuestMode", "trackByMessageId"], outputs: ["suggestionClick", "loginClick", "continueAsGuest"] }, { kind: "component", type: MessageInputComponent, selector: "app-message-input", inputs: ["isBotTyping", "hintText", "sendIcon"], outputs: ["send"] }, { kind: "component", type: SnackBar, selector: "app-snackbar", inputs: ["message", "autoDismiss", "dismissDelay", "show"], outputs: ["closed"] }, { kind: "directive", type: DraggableDialogDirective, selector: "[draggableDialog]", inputs: ["dragHandle", "enableDrag"] }, { kind: "directive", type: ResizableDialogDirective, selector: "[resizableDialog]", inputs: ["enableResize"] }, { kind: "component", type: ChatHistorySidebarComponent, selector: "app-chat-history-sidebar", inputs: ["sessions", "isOpen", "userName"], outputs: ["sessionSelected", "sessionDeleted", "closed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
1195
1048
|
}
|
|
1196
1049
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatWindowComponent, decorators: [{
|
|
1197
1050
|
type: Component,
|
|
@@ -1206,10 +1059,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
1206
1059
|
DraggableDialogDirective,
|
|
1207
1060
|
ResizableDialogDirective,
|
|
1208
1061
|
ChatHistorySidebarComponent,
|
|
1209
|
-
|
|
1210
|
-
MenuItem,
|
|
1211
|
-
PopoutWindowDirective,
|
|
1212
|
-
], template: "<div\r\n *ngIf=\"isChatOpen\"\r\n draggableDialog\r\n [enableDrag]=\"enableDrag\"\r\n [dragHandle]=\"'.chat-header'\"\r\n resizableDialog\r\n [enableResize]=\"enableResize\"\r\n class=\"chat-window\"\r\n [class.fullscreen]=\"isFullScreen\"\r\n>\r\n <!-- chat window -->\r\n <div class=\"chat-header\">\r\n <div class=\"chat-title\">\r\n <img\r\n class=\"chat-logo\"\r\n style=\"width: 150px; height: 50px; margin-left: 0px\"\r\n [src]=\"appHeaderLogoUrl\"\r\n alt=\"Text-Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"chat-header-buttons\">\r\n <!-- New Chat Button -->\r\n <!-- <button class=\"header-button\" (click)=\"createNewChat()\">\r\n <mat-icon>add</mat-icon>\r\n </button> -->\r\n\r\n <!-- <app-dropdown-menu>\r\n <span trigger>\u2630</span>\r\n\r\n <app-menu-item (selected)=\"onToggleFullScreen()\"> My Profile </app-menu-item>\r\n\r\n <app-menu-item> Settings </app-menu-item>\r\n\r\n <app-menu-item> Logout </app-menu-item>\r\n </app-dropdown-menu> -->\r\n\r\n <!-- History Button -->\r\n <button\r\n class=\"header-button\"\r\n *ngIf=\"isAuthenticated\"\r\n (click)=\"onToggleHistorySidebar()\"\r\n title=\"Chat History\"\r\n >\r\n <mat-icon>history</mat-icon>\r\n </button>\r\n\r\n <!-- settings Button -->\r\n <button class=\"header-button\" [matMenuTriggerFor]=\"settingsMenu\">\r\n <mat-icon>{{ moreIcon }}</mat-icon>\r\n </button>\r\n\r\n <!-- minimize Button -->\r\n <button class=\"header-button\" (click)=\"onToggleChat()\">\r\n <mat-icon>{{ minimizeIcon }}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Main Content Area: Toggle between Messages and History -->\r\n <!-- <popout-window\r\n #popout\r\n [windowTitle]=\"appTitle || 'Chat'\"\r\n [windowWidth]=\"400\"\r\n [windowHeight]=\"620\"\r\n (shown)=\"onPopoutShown($event)\"\r\n > -->\r\n <div class=\"chat-content-wrapper\">\r\n <!-- Chat History View -->\r\n <app-chat-history-sidebar\r\n [sessions]=\"chatSessions\"\r\n [isOpen]=\"isHistorySidebarOpen\"\r\n [userName]=\"chatHistoryUserName\"\r\n (sessionSelected)=\"onSessionSelected($event)\"\r\n (sessionDeleted)=\"onSessionDeleted($event)\"\r\n (closed)=\"onToggleHistorySidebar()\"\r\n >\r\n </app-chat-history-sidebar>\r\n\r\n <!-- Messages View -->\r\n <div class=\"messages-view\" [class.hidden]=\"isHistorySidebarOpen\">\r\n <!-- Messages / Welcome Screen -->\r\n <app-message-list\r\n [messages]=\"messages\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [appLogoUrl]=\"appLogoUrl\"\r\n [appSubtitle]=\"appSubtitle\"\r\n [welcomeDesc]=\"welcomeDesc\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [isAuthenticated]=\"isAuthenticated\"\r\n (suggestionClick)=\"onSuggestionClick($event)\"\r\n ></app-message-list>\r\n\r\n <!-- SUGGESTED CHIPS: Show only if last bot message was fallback AND user is authenticated -->\r\n <app-chips\r\n *ngIf=\"showSuggestionChips && isAuthenticated\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onSuggestionClick($event)\"\r\n ></app-chips>\r\n\r\n <!-- Inline error message -->\r\n <app-snackbar\r\n *ngIf=\"messageError\"\r\n [message]=\"messageError\"\r\n [show]=\"!messageError\"\r\n (closed)=\"onClearMessageError()\"\r\n ></app-snackbar>\r\n\r\n <!-- Chat Input: Only show when authenticated -->\r\n <app-message-input\r\n *ngIf=\"isAuthenticated\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [hintText]=\"hintText\"\r\n [sendIcon]=\"sendIcon\"\r\n (send)=\"onSend($event)\"\r\n ></app-message-input>\r\n\r\n <!-- footer -->\r\n <div class=\"terms-conditions\">\r\n <a href=\"#\">Terms and Conditions</a>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- </popout-window> -->\r\n</div>\r\n\r\n<mat-menu #settingsMenu=\"matMenu\">\r\n <!-- Change Theme -->\r\n <div class=\"theme-selector\">\r\n <!-- Auto Theme (inherits from parent app) -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'auto'\"\r\n (click)=\"themeService.setTheme('auto')\"\r\n >\r\n <mat-icon>brightness_auto</mat-icon>\r\n </button>\r\n\r\n <!-- Light Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'light'\"\r\n (click)=\"themeService.setTheme('light')\"\r\n >\r\n <mat-icon>light_mode</mat-icon>\r\n </button>\r\n\r\n <!-- Dark Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'dark'\"\r\n (click)=\"themeService.setTheme('dark')\"\r\n >\r\n <mat-icon>dark_mode</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Popout Button -->\r\n <!-- <button mat-menu-item (click)=\"popout.popOut()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>open_in_new</mat-icon>\r\n <span>Popout Widget</span>\r\n </button> -->\r\n\r\n <!-- Full-Screen Button -->\r\n <button mat-menu-item (click)=\"onToggleFullScreen()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>{{ isFullScreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\r\n <span> {{ isFullScreen ? 'Minimize' : 'Expand' }}</span>\r\n </button>\r\n\r\n <!-- Clear Chat -->\r\n <button mat-menu-item (click)=\"onClearChat()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>clear_all</mat-icon>\r\n <span>Clear Chat</span>\r\n </button>\r\n</mat-menu>\r\n", styles: ["::ng-deep .mat-mdc-menu-panel{background-color:#8b8b8b!important;color:#fff!important;border-radius:8px!important;padding:4px 0!important;box-shadow:0 4px 16px #00000040!important;border-color:#ccc!important;font-family:Roboto,Arial,sans-serif!important;font-size:14px!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item mat-icon{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover{background-color:#5c5c5c!important;color:#f5f5f5!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover mat-icon{color:#f5f5f5!important}.doohbot-container{position:fixed;bottom:20px;right:20px;z-index:1000}.chat-window{width:clamp(400px,30vw,450px);height:clamp(620px,70vh,660px);background-color:var(--background-color);border-radius:20px;border-color:var(--border-color);box-shadow:var(--border-shadow-color);display:flex;flex-direction:column;overflow:hidden;animation:slide-in .5s ease;position:fixed;right:20px;bottom:20px;-webkit-user-select:none;user-select:none}@media (max-width: 768px){.chat-window{width:95%;height:calc(100vh - 20px)}}@media (max-width: 480px){.chat-window{width:90%;height:calc(100vh - 40px)}}.chat-window.fullscreen{width:98vw;height:96vh;border-radius:20px;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-webkit-user-select:none;user-select:none}@keyframes slide-in{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}.chat-header{display:flex;justify-content:space-between;align-items:center;padding:10px 20px;background-color:var(--background-color);color:var(--text-alt-color);cursor:move;-webkit-user-select:none;user-select:none}.chat-header:active{cursor:grabbing}.chat-title{display:flex;align-items:center;gap:6px;font-family:var(--font-family)}.chat-logo{width:45px;height:45px;object-fit:contain}.chat-header h2{margin:0;font-size:1.2rem;color:var(--text-alt-color);font-family:var(--font-family);font-weight:700}.header-button{background:none;border:none;color:var(--button-color);cursor:pointer;font-size:1.5rem}.header-button :hover{transform:scale(1.1)}.terms-conditions{font-size:.8rem;color:var(--text-color);margin-top:5px;margin-bottom:10px;display:flex;justify-content:center;align-items:center}.terms-conditions a{color:var(--grey);text-decoration:underline;font-family:var(--font-family)}.terms-conditions a:hover{color:var(--primary-color)}.chat-content-wrapper{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative}.messages-view{display:flex;flex-direction:column;height:100%;width:100%}.messages-view.hidden{display:none}.theme-selector{display:flex;align-items:center;padding:4px 12px;gap:8px}.theme-btn{background:none;border:none;color:#fff;transition:color .2s ease}.theme-btn.selected{color:#000}\n"] }]
|
|
1062
|
+
FormsModule,
|
|
1063
|
+
], template: "<div\r\n *ngIf=\"isChatOpen\"\r\n draggableDialog\r\n [enableDrag]=\"enableDrag\"\r\n [dragHandle]=\"'.chat-header'\"\r\n resizableDialog\r\n [enableResize]=\"enableResize\"\r\n class=\"chat-window\"\r\n [class.fullscreen]=\"isFullScreen\"\r\n>\r\n <!-- chat window -->\r\n <div class=\"chat-header\">\r\n <div class=\"chat-title\">\r\n <img\r\n class=\"chat-logo\"\r\n style=\"width: 150px; height: 50px; margin-left: 0px\"\r\n [src]=\"appHeaderLogoUrl\"\r\n alt=\"Text-Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"chat-header-buttons\">\r\n <!-- New Chat Button -->\r\n <!-- <button class=\"header-button\" (click)=\"createNewChat()\">\r\n <mat-icon>add</mat-icon>\r\n </button> -->\r\n\r\n <!-- <app-dropdown-menu>\r\n <span trigger>\u2630</span>\r\n\r\n <app-menu-item (selected)=\"onToggleFullScreen()\"> My Profile </app-menu-item>\r\n\r\n <app-menu-item> Settings </app-menu-item>\r\n\r\n <app-menu-item> Logout </app-menu-item>\r\n </app-dropdown-menu> -->\r\n\r\n <!-- History Button -->\r\n <button\r\n class=\"header-button\"\r\n *ngIf=\"isAuthenticated\"\r\n (click)=\"onToggleHistorySidebar()\"\r\n title=\"Chat History\"\r\n >\r\n <mat-icon>history</mat-icon>\r\n </button>\r\n\r\n <!-- settings Button -->\r\n <button class=\"header-button\" [matMenuTriggerFor]=\"settingsMenu\">\r\n <mat-icon>{{ moreIcon }}</mat-icon>\r\n </button>\r\n\r\n <!-- minimize Button -->\r\n <button class=\"header-button\" (click)=\"onToggleChat()\">\r\n <mat-icon>{{ minimizeIcon }}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Main Content Area: Toggle between Messages and History -->\r\n <!-- <popout-window\r\n #popout\r\n [windowTitle]=\"appTitle || 'Chat'\"\r\n [windowWidth]=\"400\"\r\n [windowHeight]=\"620\"\r\n (shown)=\"onPopoutShown($event)\"\r\n > -->\r\n <div class=\"chat-content-wrapper\">\r\n <!-- Chat History View -->\r\n <app-chat-history-sidebar\r\n [sessions]=\"chatSessions\"\r\n [isOpen]=\"isHistorySidebarOpen\"\r\n [userName]=\"chatHistoryUserName\"\r\n (sessionSelected)=\"onSessionSelected($event)\"\r\n (sessionDeleted)=\"onSessionDeleted($event)\"\r\n (closed)=\"onToggleHistorySidebar()\"\r\n >\r\n </app-chat-history-sidebar>\r\n\r\n <!-- Messages View -->\r\n <div class=\"messages-view\" [class.hidden]=\"isHistorySidebarOpen\">\r\n <!-- Messages / Welcome Screen -->\r\n <app-message-list\r\n *ngIf=\"!showLoginForm\"\r\n [messages]=\"messages\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [appLogoUrl]=\"appLogoUrl\"\r\n [appSubtitle]=\"appSubtitle\"\r\n [welcomeDesc]=\"welcomeDesc\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [isAuthenticated]=\"isAuthenticated\"\r\n [isGuestMode]=\"isGuestMode\"\r\n (suggestionClick)=\"onSuggestionClick($event)\"\r\n (loginClick)=\"onLoginClick()\"\r\n (continueAsGuest)=\"onContinueAsGuest()\"\r\n ></app-message-list>\r\n\r\n <!-- SUGGESTED CHIPS: Show only if last bot message was fallback AND user is authenticated -->\r\n <app-chips\r\n *ngIf=\"showSuggestionChips && (isAuthenticated || isGuestMode)\"\r\n [messages]=\"predefinedMessages\"\r\n [disabled]=\"isBotTyping\"\r\n (chipClick)=\"onSuggestionClick($event)\"\r\n ></app-chips>\r\n\r\n <!-- Chat Input: Only show when authenticated or guest mode -->\r\n <app-message-input\r\n *ngIf=\"isAuthenticated || isGuestMode\"\r\n [isBotTyping]=\"isBotTyping\"\r\n [hintText]=\"hintText\"\r\n [sendIcon]=\"sendIcon\"\r\n (send)=\"onSend($event)\"\r\n ></app-message-input>\r\n\r\n <!-- Login Form -->\r\n <div *ngIf=\"showLoginForm && !isAuthenticated\" class=\"login-form-container\">\r\n <h3 class=\"login-title\">Login</h3>\r\n <div class=\"login-fields\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"loginUsername\"\r\n placeholder=\"Username\"\r\n class=\"login-input\"\r\n />\r\n <div class=\"password-wrapper\">\r\n <input\r\n [type]=\"showPassword ? 'text' : 'password'\"\r\n [(ngModel)]=\"loginPassword\"\r\n placeholder=\"Password\"\r\n class=\"login-input password-input\"\r\n (keydown.enter)=\"onLoginSubmit()\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"password-toggle-btn\"\r\n (click)=\"togglePasswordVisibility()\"\r\n tabindex=\"-1\"\r\n >\r\n <mat-icon>{{ showPassword ? 'visibility' : 'visibility_off' }}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"login-actions\">\r\n <button (click)=\"onCancelLogin()\" class=\"auth-btn secondary\">Cancel</button>\r\n <button\r\n (click)=\"onLoginSubmit()\"\r\n class=\"auth-btn primary\"\r\n [disabled]=\"!loginUsername || !loginPassword || isLoggingIn\"\r\n >\r\n {{ isLoggingIn ? 'Logging in...' : 'Submit' }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Auth error snackbar (login/logout errors only) -->\r\n <app-snackbar\r\n *ngIf=\"authError\"\r\n [message]=\"authError\"\r\n (closed)=\"onClearAuthError()\"\r\n ></app-snackbar>\r\n\r\n <!-- footer -->\r\n <div class=\"terms-conditions\">\r\n <a href=\"#\">Terms and Conditions</a>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- </popout-window> -->\r\n</div>\r\n\r\n<mat-menu #settingsMenu=\"matMenu\">\r\n <!-- Change Theme -->\r\n <div class=\"theme-selector\">\r\n <!-- Auto Theme (inherits from parent app) -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'auto'\"\r\n (click)=\"themeService.setTheme('auto')\"\r\n >\r\n <mat-icon>brightness_auto</mat-icon>\r\n </button>\r\n\r\n <!-- Light Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'light'\"\r\n (click)=\"themeService.setTheme('light')\"\r\n >\r\n <mat-icon>light_mode</mat-icon>\r\n </button>\r\n\r\n <!-- Dark Theme -->\r\n <button\r\n mat-icon-button\r\n class=\"theme-btn\"\r\n [class.selected]=\"themeService.theme() === 'dark'\"\r\n (click)=\"themeService.setTheme('dark')\"\r\n >\r\n <mat-icon>dark_mode</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Popout Button -->\r\n <!-- <button mat-menu-item (click)=\"popout.popOut()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>open_in_new</mat-icon>\r\n <span>Popout Widget</span>\r\n </button> -->\r\n\r\n <!-- Full-Screen Button -->\r\n <button mat-menu-item (click)=\"onToggleFullScreen()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>{{ isFullScreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\r\n <span> {{ isFullScreen ? 'Minimize' : 'Expand' }}</span>\r\n </button>\r\n\r\n <!-- Clear Chat -->\r\n <button mat-menu-item (click)=\"onClearChat()\" style=\"display: flex; align-items: center\">\r\n <mat-icon>clear_all</mat-icon>\r\n <span>Clear Chat</span>\r\n </button>\r\n\r\n <!-- Logout -->\r\n <button\r\n mat-menu-item\r\n *ngIf=\"isAuthenticated\"\r\n (click)=\"onLogout()\"\r\n style=\"display: flex; align-items: center\"\r\n >\r\n <mat-icon>logout</mat-icon>\r\n <span>Logout</span>\r\n </button>\r\n</mat-menu>\r\n", styles: ["::ng-deep .mat-mdc-menu-panel{background-color:#8b8b8b!important;color:#fff!important;border-radius:8px!important;padding:4px 0!important;box-shadow:0 4px 16px #00000040!important;border-color:#ccc!important;font-family:Roboto,Arial,sans-serif!important;font-size:14px!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item mat-icon{color:#fff!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover{background-color:#5c5c5c!important;color:#f5f5f5!important}::ng-deep .mat-mdc-menu-panel .mat-mdc-menu-item:hover mat-icon{color:#f5f5f5!important}.doohbot-container{position:fixed;bottom:20px;right:20px;z-index:1000}.chat-window{width:clamp(400px,30vw,450px);height:clamp(620px,70vh,660px);background-color:var(--background-color);border-radius:20px;border-color:var(--border-color);box-shadow:var(--border-shadow-color);display:flex;flex-direction:column;overflow:hidden;animation:slide-in .5s ease;position:fixed;right:20px;bottom:20px;-webkit-user-select:none;user-select:none}@media (max-width: 768px){.chat-window{width:95%;height:calc(100vh - 20px)}}@media (max-width: 480px){.chat-window{width:90%;height:calc(100vh - 40px)}}.chat-window.fullscreen{width:98vw;height:96vh;border-radius:20px;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-webkit-user-select:none;user-select:none}@keyframes slide-in{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}.chat-header{display:flex;justify-content:space-between;align-items:center;padding:10px 20px;background-color:var(--background-color);color:var(--text-alt-color);cursor:move;-webkit-user-select:none;user-select:none}.chat-header:active{cursor:grabbing}.chat-title{display:flex;align-items:center;gap:6px;font-family:var(--font-family)}.chat-logo{width:45px;height:45px;object-fit:contain}.chat-header h2{margin:0;font-size:1.2rem;color:var(--text-alt-color);font-family:var(--font-family);font-weight:700}.header-button{background:none;border:none;color:var(--button-color);cursor:pointer;font-size:1.5rem}.header-button :hover{transform:scale(1.1)}.terms-conditions{font-size:.8rem;color:var(--text-color);margin-top:5px;margin-bottom:10px;display:flex;justify-content:center;align-items:center}.terms-conditions a{color:var(--grey);text-decoration:underline;font-family:var(--font-family)}.terms-conditions a:hover{color:var(--primary-color)}.chat-content-wrapper{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative}.messages-view{display:flex;flex-direction:column;height:100%;width:100%}.messages-view.hidden{display:none}.messages-view app-message-list{flex:1;min-height:0}.messages-view app-snackbar{flex-shrink:0;margin-top:auto}.messages-view app-message-input{flex-shrink:0}.theme-selector{display:flex;align-items:center;padding:4px 12px;gap:8px}.theme-btn{background:none;border:none;color:var(--white);transition:color .2s ease}.theme-btn.selected{color:var(--black)}.auth-prompt-container{padding:20px;display:flex;justify-content:center;align-items:center;flex-direction:column;gap:15px;text-align:center;height:100%}.auth-prompt-container .auth-prompt-text{margin:0;font-size:.95em;opacity:.8;color:var(--text-color)}.auth-prompt-container .auth-buttons{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}.auth-btn{padding:8px 18px;border-radius:20px;cursor:pointer;font-size:.9em;font-weight:500;transition:all .2s ease}.auth-btn.primary{background:var(--primary-color);color:var(--white);border:1px solid var(--primary-color)}.auth-btn.primary:hover{opacity:.9}.auth-btn.primary:disabled{opacity:.5;cursor:not-allowed}.auth-btn.secondary{background:transparent;color:var(--re);border:1px solid var(--primary-color)}.auth-btn.secondary:hover{opacity:.9}.login-form-container{padding:20px;display:flex;flex-direction:column;gap:15px;height:100%;justify-content:center}.login-form-container .login-title{text-align:center;margin:0 0 10px;font-size:1.2em;color:var(--text-color);font-family:var(--font-family)}.login-form-container .login-fields{display:flex;flex-direction:column;gap:10px}.login-form-container .login-fields .login-input{padding:10px 12px;border-radius:8px;border:1px solid var(--border-color);font-size:.9em;background:var(--background-color);color:var(--text-color)}.login-form-container .login-fields .login-input:focus{outline:none;border-color:var(--primary-color)}.login-form-container .login-fields .password-wrapper{position:relative;display:flex;align-items:center}.login-form-container .login-fields .password-wrapper .login-input{width:100%;padding-right:40px}.login-form-container .login-fields .password-wrapper .password-toggle-btn{position:absolute;right:8px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:4px;color:var(--text-color);opacity:.6;transition:opacity .2s}.login-form-container .login-fields .password-wrapper .password-toggle-btn:hover{opacity:1}.login-form-container .login-fields .password-wrapper .password-toggle-btn mat-icon{font-size:20px;width:20px;height:20px}.login-form-container .login-actions{display:flex;justify-content:center;gap:10px;margin-top:10px}\n"] }]
|
|
1213
1064
|
}], propDecorators: { isChatOpen: [{
|
|
1214
1065
|
type: Input
|
|
1215
1066
|
}], enableDrag: [{
|
|
@@ -1266,6 +1117,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
1266
1117
|
type: Input
|
|
1267
1118
|
}], isGuestUser: [{
|
|
1268
1119
|
type: Input
|
|
1120
|
+
}], isGuestMode: [{
|
|
1121
|
+
type: Input
|
|
1122
|
+
}], isLoggingIn: [{
|
|
1123
|
+
type: Input
|
|
1124
|
+
}], authError: [{
|
|
1125
|
+
type: Input
|
|
1126
|
+
}], authSuccess: [{
|
|
1127
|
+
type: Input
|
|
1269
1128
|
}], themeConfig: [{
|
|
1270
1129
|
type: Input
|
|
1271
1130
|
}], toggleChat: [{
|
|
@@ -1288,6 +1147,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
1288
1147
|
type: Output
|
|
1289
1148
|
}], sessionDeleted: [{
|
|
1290
1149
|
type: Output
|
|
1150
|
+
}], continueAsGuest: [{
|
|
1151
|
+
type: Output
|
|
1152
|
+
}], loginClick: [{
|
|
1153
|
+
type: Output
|
|
1154
|
+
}], loginSubmit: [{
|
|
1155
|
+
type: Output
|
|
1156
|
+
}], logout: [{
|
|
1157
|
+
type: Output
|
|
1291
1158
|
}] } });
|
|
1292
1159
|
|
|
1293
1160
|
class FullscreenDirective {
|
|
@@ -1357,6 +1224,7 @@ const environment = {
|
|
|
1357
1224
|
production: false,
|
|
1358
1225
|
apiBaseUrl: '',
|
|
1359
1226
|
loginEndpoint: '',
|
|
1227
|
+
apiSegment: 'api/v1/',
|
|
1360
1228
|
};
|
|
1361
1229
|
|
|
1362
1230
|
class AppConst {
|
|
@@ -1365,9 +1233,11 @@ class AppConst {
|
|
|
1365
1233
|
async load() {
|
|
1366
1234
|
const filePath = `../assets/${environment.production ? environment.config : environment.config}?t=${new Date().getTime()}`;
|
|
1367
1235
|
const response = await fetch(filePath);
|
|
1236
|
+
console.error('============================ AppConst ============================', filePath);
|
|
1368
1237
|
if (response.ok) {
|
|
1369
1238
|
try {
|
|
1370
1239
|
AppConst.data = await response.json();
|
|
1240
|
+
console.error('============================ AppConst ============================', AppConst.data);
|
|
1371
1241
|
// Override apiBaseUrl if present in environment
|
|
1372
1242
|
// if (environment.apiBaseUrl) {
|
|
1373
1243
|
// AppConst.data.apiBaseUrl = environment.apiBaseUrl;
|
|
@@ -1931,302 +1801,93 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
1931
1801
|
}]
|
|
1932
1802
|
}], ctorParameters: () => [] });
|
|
1933
1803
|
|
|
1934
|
-
class
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
apiService = inject(ChatbotApiService, { optional: true });
|
|
1944
|
-
chatHistoryService = inject(ChatHistoryService);
|
|
1945
|
-
// User context for backend proxy mode
|
|
1946
|
-
userContext;
|
|
1947
|
-
// API state signals
|
|
1948
|
-
isLoadingApi = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingApi" }] : []));
|
|
1949
|
-
apiError = signal(null, ...(ngDevMode ? [{ debugName: "apiError" }] : []));
|
|
1950
|
-
isBotTyping = signal(false, ...(ngDevMode ? [{ debugName: "isBotTyping" }] : []));
|
|
1951
|
-
constructor() {
|
|
1952
|
-
// Start with empty messages - no auto-load
|
|
1804
|
+
class HttpService {
|
|
1805
|
+
http;
|
|
1806
|
+
// @BlockUI() blockUI!: NgBlockUI;
|
|
1807
|
+
apiUrl;
|
|
1808
|
+
constructor(http) {
|
|
1809
|
+
this.http = http;
|
|
1810
|
+
this.apiUrl = `${AppConst?.data?.apiBaseUrl}${AppConst?.data?.apiSegment}`;
|
|
1811
|
+
// this.apiUrl = `${environment.apiBaseUrl}${environment.apiSegment}`;
|
|
1812
|
+
console.log('HttpService: Initialized', this.apiUrl);
|
|
1953
1813
|
}
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1814
|
+
get(url, param, nestedParam = false, showLoader = false, refresh = true) {
|
|
1815
|
+
// if (showLoader && !this.blockUI.isActive) {
|
|
1816
|
+
// this.blockUI.start();
|
|
1817
|
+
// }
|
|
1818
|
+
let params = {};
|
|
1819
|
+
if (nestedParam) {
|
|
1820
|
+
this.buildHttpParams(params, param, '');
|
|
1821
|
+
}
|
|
1822
|
+
else {
|
|
1823
|
+
params = param;
|
|
1824
|
+
}
|
|
1825
|
+
return this.http.get(`${this.apiUrl}${url}`, { params: params, withCredentials: true }).pipe(delay(100), retry$1(0), map$1((response) => this.returnResponse(response, showLoader)), catchError$1((error) => {
|
|
1826
|
+
// if (this.blockUI.isActive) {
|
|
1827
|
+
// this.blockUI.stop();
|
|
1828
|
+
// }
|
|
1829
|
+
return of(error);
|
|
1830
|
+
}));
|
|
1961
1831
|
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1832
|
+
buildHttpParams(params, data, currentPath) {
|
|
1833
|
+
Object.keys(data).forEach((key) => {
|
|
1834
|
+
if (data[key] instanceof Object && !(data[key] instanceof Array)) {
|
|
1835
|
+
this.buildHttpParams(params, data[key], `${currentPath}${key}.`);
|
|
1836
|
+
}
|
|
1837
|
+
else {
|
|
1838
|
+
params[`${currentPath}${key}`] = data[key];
|
|
1839
|
+
}
|
|
1840
|
+
});
|
|
1970
1841
|
}
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
this.
|
|
1976
|
-
|
|
1842
|
+
post(url, param, showLoader = false) {
|
|
1843
|
+
// if (showLoader && !this.blockUI.isActive) {
|
|
1844
|
+
// this.blockUI.start();
|
|
1845
|
+
// }
|
|
1846
|
+
return this.http.post(`${this.apiUrl}${url}`, param).pipe(delay(100), retry$1(0), map$1((response) => this.returnResponse(response, showLoader)), catchError$1((error) => {
|
|
1847
|
+
// if (this.blockUI.isActive) {
|
|
1848
|
+
// this.blockUI.stop();
|
|
1849
|
+
// }
|
|
1850
|
+
return of(error);
|
|
1851
|
+
}));
|
|
1977
1852
|
}
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
return
|
|
1853
|
+
returnResponse(value, showLoader = true) {
|
|
1854
|
+
// if (showLoader && this.blockUI.isActive) {
|
|
1855
|
+
// this.blockUI.reset();
|
|
1856
|
+
// }
|
|
1857
|
+
return value;
|
|
1983
1858
|
}
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1859
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: HttpService, deps: [{ token: i1$4.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1860
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: HttpService, providedIn: 'root' });
|
|
1861
|
+
}
|
|
1862
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: HttpService, decorators: [{
|
|
1863
|
+
type: Injectable,
|
|
1864
|
+
args: [{
|
|
1865
|
+
providedIn: 'root',
|
|
1866
|
+
}]
|
|
1867
|
+
}], ctorParameters: () => [{ type: i1$4.HttpClient }] });
|
|
1868
|
+
|
|
1869
|
+
class AccountService {
|
|
1870
|
+
http;
|
|
1871
|
+
constructor(http) {
|
|
1872
|
+
this.http = http;
|
|
1991
1873
|
}
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
*/
|
|
1995
|
-
getUserContext() {
|
|
1996
|
-
return this.userContext;
|
|
1874
|
+
login(param, showLoader = false) {
|
|
1875
|
+
return this.http.post('auth/login', param, showLoader);
|
|
1997
1876
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
*/
|
|
2001
|
-
getActiveSession() {
|
|
2002
|
-
return this.activeSession;
|
|
1877
|
+
logout(refreshToken, showLoader = false) {
|
|
1878
|
+
return this.http.post('auth/logout', { refresh_token: refreshToken }, showLoader);
|
|
2003
1879
|
}
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
*/
|
|
2007
|
-
clearMessages() {
|
|
2008
|
-
this.messages.set([]);
|
|
2009
|
-
this.startNewSession();
|
|
1880
|
+
startChat(param, showLoader = false) {
|
|
1881
|
+
return this.http.post('chat/ask', param, showLoader);
|
|
2010
1882
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
*/
|
|
2014
|
-
addMessage(message) {
|
|
2015
|
-
const newMessage = { ...message, timestamp: new Date() };
|
|
2016
|
-
// Update current messages signal
|
|
2017
|
-
this.messages.update((msgs) => [...msgs, newMessage]);
|
|
2018
|
-
// Save to active session
|
|
2019
|
-
if (this.activeSession) {
|
|
2020
|
-
console.log('Saving message to session:', this.activeSession.id);
|
|
2021
|
-
this.chatHistoryService.saveMessageToSession(this.activeSession, newMessage).subscribe(() => {
|
|
2022
|
-
console.log('Message saved, session title:', this.activeSession?.title);
|
|
2023
|
-
});
|
|
2024
|
-
}
|
|
2025
|
-
else {
|
|
2026
|
-
console.warn('No active session to save message to!');
|
|
2027
|
-
}
|
|
2028
|
-
if (message.sender === 'bot') {
|
|
2029
|
-
this.playBotSound();
|
|
2030
|
-
}
|
|
1883
|
+
getChatHistory(param, showLoader = false) {
|
|
1884
|
+
return this.http.get('chat/history', param, showLoader);
|
|
2031
1885
|
}
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
*/
|
|
2035
|
-
async getBotReply(userText) {
|
|
2036
|
-
// Check if API mode is enabled
|
|
2037
|
-
if (this.apiService?.isApiEnabled()) {
|
|
2038
|
-
return this.getBotReplyFromApi(userText);
|
|
2039
|
-
}
|
|
2040
|
-
// Fall back to local intent matching
|
|
2041
|
-
return this.getBotReplyLocal(userText);
|
|
1886
|
+
deleteHistory(param, showLoader = false) {
|
|
1887
|
+
return this.http.post('chat/history', param, showLoader);
|
|
2042
1888
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
*/
|
|
2046
|
-
async getBotReplyFromApi(userText) {
|
|
2047
|
-
if (!this.apiService) {
|
|
2048
|
-
return this.getFallbackReply();
|
|
2049
|
-
}
|
|
2050
|
-
try {
|
|
2051
|
-
this.isLoadingApi.set(true);
|
|
2052
|
-
this.apiError.set(null);
|
|
2053
|
-
// Get message history if API config includes history
|
|
2054
|
-
const history = this.apiService.getConfig().includeHistory ? this.messages() : undefined;
|
|
2055
|
-
// Call API
|
|
2056
|
-
const response = await firstValueFrom(this.apiService.sendMessage(userText, history));
|
|
2057
|
-
this.isLoadingApi.set(false);
|
|
2058
|
-
return response.reply;
|
|
2059
|
-
}
|
|
2060
|
-
catch (error) {
|
|
2061
|
-
this.isLoadingApi.set(false);
|
|
2062
|
-
const apiError = error;
|
|
2063
|
-
this.apiError.set(apiError);
|
|
2064
|
-
console.error('API error, falling back to local mode:', apiError);
|
|
2065
|
-
// Fallback to local mode on API error
|
|
2066
|
-
return this.getBotReplyLocal(userText);
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
/**
|
|
2070
|
-
* Get bot reply using local intent matching
|
|
2071
|
-
*/
|
|
2072
|
-
getBotReplyLocal(userText) {
|
|
2073
|
-
const text = userText.toLowerCase();
|
|
2074
|
-
for (const intent of CHAT_INTENTS) {
|
|
2075
|
-
if (intent.patterns.some((pattern) => text.includes(pattern))) {
|
|
2076
|
-
return intent.response;
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
2079
|
-
return this.getFallbackReply();
|
|
2080
|
-
}
|
|
2081
|
-
/**
|
|
2082
|
-
* Process a user message: add it, get bot reply, and add bot reply
|
|
2083
|
-
*/
|
|
2084
|
-
async processUserMessage(text) {
|
|
2085
|
-
this.addMessage({
|
|
2086
|
-
sender: 'user',
|
|
2087
|
-
text: text,
|
|
2088
|
-
id: Date.now().toString(),
|
|
2089
|
-
timestamp: new Date(),
|
|
2090
|
-
});
|
|
2091
|
-
this.isBotTyping.set(true);
|
|
2092
|
-
const minDelay = 1000;
|
|
2093
|
-
const start = Date.now();
|
|
2094
|
-
try {
|
|
2095
|
-
const botReply = await this.getBotReply(text);
|
|
2096
|
-
// Ensure minimum delay
|
|
2097
|
-
const elapsed = Date.now() - start;
|
|
2098
|
-
if (elapsed < minDelay) {
|
|
2099
|
-
await new Promise((resolve) => setTimeout(resolve, minDelay - elapsed));
|
|
2100
|
-
}
|
|
2101
|
-
const isFallback = botReply === this.getFallbackReply();
|
|
2102
|
-
this.addMessage({
|
|
2103
|
-
sender: 'bot',
|
|
2104
|
-
text: botReply,
|
|
2105
|
-
id: Date.now().toString(),
|
|
2106
|
-
showSuggestions: isFallback,
|
|
2107
|
-
});
|
|
2108
|
-
}
|
|
2109
|
-
catch (error) {
|
|
2110
|
-
console.error('Error getting bot reply:', error);
|
|
2111
|
-
this.addMessage({
|
|
2112
|
-
sender: 'bot',
|
|
2113
|
-
text: this.getFallbackReply(),
|
|
2114
|
-
id: Date.now().toString(),
|
|
2115
|
-
showSuggestions: true,
|
|
2116
|
-
});
|
|
2117
|
-
}
|
|
2118
|
-
finally {
|
|
2119
|
-
this.isBotTyping.set(false);
|
|
2120
|
-
}
|
|
2121
|
-
}
|
|
2122
|
-
getFallbackReply() {
|
|
2123
|
-
return "I'm sorry 😔, I didn't understand that.";
|
|
2124
|
-
}
|
|
2125
|
-
isFallbackIntent(userText) {
|
|
2126
|
-
const text = userText.toLowerCase();
|
|
2127
|
-
return !CHAT_INTENTS.some((intent) => intent.patterns.some((pattern) => text.includes(pattern)));
|
|
2128
|
-
}
|
|
2129
|
-
unlockAudio() {
|
|
2130
|
-
if (this.audioUnlocked)
|
|
2131
|
-
return;
|
|
2132
|
-
const audio = new Audio();
|
|
2133
|
-
audio.volume = 1.0;
|
|
2134
|
-
audio
|
|
2135
|
-
.play()
|
|
2136
|
-
.then(() => (this.audioUnlocked = true))
|
|
2137
|
-
.catch(() => { });
|
|
2138
|
-
}
|
|
2139
|
-
playBotSound() {
|
|
2140
|
-
if (!this.audioUnlocked)
|
|
2141
|
-
return;
|
|
2142
|
-
try {
|
|
2143
|
-
const audio = new Audio('assets/bot.mp3');
|
|
2144
|
-
audio.play();
|
|
2145
|
-
}
|
|
2146
|
-
catch (error) {
|
|
2147
|
-
console.error('Error playing bot sound:', error);
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2151
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, providedIn: 'root' });
|
|
2152
|
-
}
|
|
2153
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, decorators: [{
|
|
2154
|
-
type: Injectable,
|
|
2155
|
-
args: [{
|
|
2156
|
-
providedIn: 'root',
|
|
2157
|
-
}]
|
|
2158
|
-
}], ctorParameters: () => [] });
|
|
2159
|
-
|
|
2160
|
-
class HttpService {
|
|
2161
|
-
http;
|
|
2162
|
-
// @BlockUI() blockUI!: NgBlockUI;
|
|
2163
|
-
apiUrl;
|
|
2164
|
-
constructor(http) {
|
|
2165
|
-
this.http = http;
|
|
2166
|
-
this.apiUrl = `${AppConst?.data?.apiBaseUrl}${AppConst?.data?.apiSegment}`;
|
|
2167
|
-
}
|
|
2168
|
-
get(url, param, nestedParam = false, showLoader = false, refresh = true) {
|
|
2169
|
-
// if (showLoader && !this.blockUI.isActive) {
|
|
2170
|
-
// this.blockUI.start();
|
|
2171
|
-
// }
|
|
2172
|
-
let params = {};
|
|
2173
|
-
if (nestedParam) {
|
|
2174
|
-
this.buildHttpParams(params, param, '');
|
|
2175
|
-
}
|
|
2176
|
-
else {
|
|
2177
|
-
params = param;
|
|
2178
|
-
}
|
|
2179
|
-
return this.http.get(`${this.apiUrl}${url}`, { params: params, withCredentials: true }).pipe(delay(100), retry$1(0), map$1((response) => this.returnResponse(response, showLoader)), catchError$1((error) => {
|
|
2180
|
-
// if (this.blockUI.isActive) {
|
|
2181
|
-
// this.blockUI.stop();
|
|
2182
|
-
// }
|
|
2183
|
-
return of(error);
|
|
2184
|
-
}));
|
|
2185
|
-
}
|
|
2186
|
-
buildHttpParams(params, data, currentPath) {
|
|
2187
|
-
Object.keys(data).forEach((key) => {
|
|
2188
|
-
if (data[key] instanceof Object && !(data[key] instanceof Array)) {
|
|
2189
|
-
this.buildHttpParams(params, data[key], `${currentPath}${key}.`);
|
|
2190
|
-
}
|
|
2191
|
-
else {
|
|
2192
|
-
params[`${currentPath}${key}`] = data[key];
|
|
2193
|
-
}
|
|
2194
|
-
});
|
|
2195
|
-
}
|
|
2196
|
-
post(url, param, showLoader = false) {
|
|
2197
|
-
// if (showLoader && !this.blockUI.isActive) {
|
|
2198
|
-
// this.blockUI.start();
|
|
2199
|
-
// }
|
|
2200
|
-
return this.http.post(`${this.apiUrl}${url}`, param).pipe(delay(100), retry$1(0), map$1((response) => this.returnResponse(response, showLoader)), catchError$1((error) => {
|
|
2201
|
-
// if (this.blockUI.isActive) {
|
|
2202
|
-
// this.blockUI.stop();
|
|
2203
|
-
// }
|
|
2204
|
-
return of(error);
|
|
2205
|
-
}));
|
|
2206
|
-
}
|
|
2207
|
-
returnResponse(value, showLoader = true) {
|
|
2208
|
-
// if (showLoader && this.blockUI.isActive) {
|
|
2209
|
-
// this.blockUI.reset();
|
|
2210
|
-
// }
|
|
2211
|
-
return value;
|
|
2212
|
-
}
|
|
2213
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: HttpService, deps: [{ token: i1$4.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2214
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: HttpService, providedIn: 'root' });
|
|
2215
|
-
}
|
|
2216
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: HttpService, decorators: [{
|
|
2217
|
-
type: Injectable,
|
|
2218
|
-
args: [{
|
|
2219
|
-
providedIn: 'root',
|
|
2220
|
-
}]
|
|
2221
|
-
}], ctorParameters: () => [{ type: i1$4.HttpClient }] });
|
|
2222
|
-
|
|
2223
|
-
class AccountService {
|
|
2224
|
-
http;
|
|
2225
|
-
constructor(http) {
|
|
2226
|
-
this.http = http;
|
|
2227
|
-
}
|
|
2228
|
-
login(param, showLoader = false) {
|
|
2229
|
-
return this.http.post('Account/Login', param, showLoader);
|
|
1889
|
+
refreshLogin(param, showLoader = false) {
|
|
1890
|
+
return this.http.post('Account/RefreshToken', param, showLoader);
|
|
2230
1891
|
}
|
|
2231
1892
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AccountService, deps: [{ token: HttpService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2232
1893
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AccountService, providedIn: 'root' });
|
|
@@ -2429,6 +2090,247 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
2429
2090
|
}]
|
|
2430
2091
|
}], ctorParameters: () => [{ type: i1$5.Router }, { type: i1$4.HttpClient }, { type: CryptoHelperService }] });
|
|
2431
2092
|
|
|
2093
|
+
class MessageService {
|
|
2094
|
+
// Context-aware message storage
|
|
2095
|
+
currentContextKey = signal('default', ...(ngDevMode ? [{ debugName: "currentContextKey" }] : []));
|
|
2096
|
+
// Public messages signal for current context
|
|
2097
|
+
messages = signal([], ...(ngDevMode ? [{ debugName: "messages" }] : []));
|
|
2098
|
+
audioUnlocked = false;
|
|
2099
|
+
// Active session
|
|
2100
|
+
activeSession = null;
|
|
2101
|
+
// API service (optional)
|
|
2102
|
+
apiService = inject(ChatbotApiService, { optional: true });
|
|
2103
|
+
chatHistoryService = inject(ChatHistoryService);
|
|
2104
|
+
// User context for backend proxy mode
|
|
2105
|
+
userContext;
|
|
2106
|
+
// API state signals
|
|
2107
|
+
isLoadingApi = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingApi" }] : []));
|
|
2108
|
+
apiError = signal(null, ...(ngDevMode ? [{ debugName: "apiError" }] : []));
|
|
2109
|
+
isBotTyping = signal(false, ...(ngDevMode ? [{ debugName: "isBotTyping" }] : []));
|
|
2110
|
+
isGuestMode = signal(false, ...(ngDevMode ? [{ debugName: "isGuestMode" }] : []));
|
|
2111
|
+
constructor() {
|
|
2112
|
+
// Start with empty messages - no auto-load
|
|
2113
|
+
}
|
|
2114
|
+
setGuestMode(isGuest) {
|
|
2115
|
+
this.isGuestMode.set(isGuest);
|
|
2116
|
+
}
|
|
2117
|
+
/**
|
|
2118
|
+
* Switch to a new context
|
|
2119
|
+
*/
|
|
2120
|
+
switchContext(contextKey) {
|
|
2121
|
+
this.currentContextKey.set(contextKey);
|
|
2122
|
+
// Start fresh - don't auto-load
|
|
2123
|
+
this.startNewSession();
|
|
2124
|
+
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Start a new chat session
|
|
2127
|
+
*/
|
|
2128
|
+
startNewSession() {
|
|
2129
|
+
const contextKey = this.currentContextKey();
|
|
2130
|
+
const userId = this.userContext?.userId || 'anonymous';
|
|
2131
|
+
this.activeSession = this.chatHistoryService.createSession(contextKey, userId);
|
|
2132
|
+
this.messages.set([]);
|
|
2133
|
+
}
|
|
2134
|
+
/**
|
|
2135
|
+
* Load an existing session
|
|
2136
|
+
*/
|
|
2137
|
+
loadSession(session) {
|
|
2138
|
+
this.activeSession = session;
|
|
2139
|
+
this.messages.set([...session.messages]);
|
|
2140
|
+
}
|
|
2141
|
+
/**
|
|
2142
|
+
* Get current context key
|
|
2143
|
+
*/
|
|
2144
|
+
getCurrentContextKey() {
|
|
2145
|
+
return this.currentContextKey();
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Set user context for backend proxy mode
|
|
2149
|
+
*/
|
|
2150
|
+
setUserContext(context) {
|
|
2151
|
+
this.userContext = context;
|
|
2152
|
+
// Start fresh when user changes - don't auto-load
|
|
2153
|
+
this.startNewSession();
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Get current user context
|
|
2157
|
+
*/
|
|
2158
|
+
getUserContext() {
|
|
2159
|
+
return this.userContext;
|
|
2160
|
+
}
|
|
2161
|
+
/**
|
|
2162
|
+
* Get active session
|
|
2163
|
+
*/
|
|
2164
|
+
getActiveSession() {
|
|
2165
|
+
return this.activeSession;
|
|
2166
|
+
}
|
|
2167
|
+
/**
|
|
2168
|
+
* Clear messages for current session and start new one
|
|
2169
|
+
*/
|
|
2170
|
+
clearMessages() {
|
|
2171
|
+
this.messages.set([]);
|
|
2172
|
+
this.startNewSession();
|
|
2173
|
+
}
|
|
2174
|
+
/**
|
|
2175
|
+
* Add message to current session
|
|
2176
|
+
*/
|
|
2177
|
+
addMessage(message) {
|
|
2178
|
+
const newMessage = { ...message, timestamp: new Date() };
|
|
2179
|
+
// Update current messages signal
|
|
2180
|
+
this.messages.update((msgs) => [...msgs, newMessage]);
|
|
2181
|
+
// Save to active session
|
|
2182
|
+
if (this.activeSession) {
|
|
2183
|
+
console.log('Saving message to session:', this.activeSession.id);
|
|
2184
|
+
this.chatHistoryService.saveMessageToSession(this.activeSession, newMessage).subscribe(() => {
|
|
2185
|
+
console.log('Message saved, session title:', this.activeSession?.title);
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
else {
|
|
2189
|
+
console.warn('No active session to save message to!');
|
|
2190
|
+
}
|
|
2191
|
+
if (message.sender === 'bot') {
|
|
2192
|
+
this.playBotSound();
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
/**
|
|
2196
|
+
* Get bot reply - supports both API and local modes
|
|
2197
|
+
*/
|
|
2198
|
+
async getBotReply(userText) {
|
|
2199
|
+
// If in guest mode, force local logic
|
|
2200
|
+
if (this.isGuestMode()) {
|
|
2201
|
+
return this.getBotReplyLocal(userText);
|
|
2202
|
+
}
|
|
2203
|
+
// Get auth service to check if user is authenticated
|
|
2204
|
+
const authService = inject(AuthService, { optional: true });
|
|
2205
|
+
const isAuthenticated = authService?.isAuthenticated() || false;
|
|
2206
|
+
// Call API if user is authenticated
|
|
2207
|
+
if (isAuthenticated) {
|
|
2208
|
+
return this.getBotReplyFromApi(userText);
|
|
2209
|
+
}
|
|
2210
|
+
// Fall back to local intent matching
|
|
2211
|
+
return this.getBotReplyLocal(userText);
|
|
2212
|
+
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Get bot reply from API
|
|
2215
|
+
*/
|
|
2216
|
+
async getBotReplyFromApi(userText) {
|
|
2217
|
+
// Inject AccountService dynamically
|
|
2218
|
+
const accountService = inject(AccountService, { optional: true });
|
|
2219
|
+
if (!accountService) {
|
|
2220
|
+
console.error('AccountService not available, falling back to local');
|
|
2221
|
+
return this.getBotReplyLocal(userText);
|
|
2222
|
+
}
|
|
2223
|
+
try {
|
|
2224
|
+
this.isLoadingApi.set(true);
|
|
2225
|
+
this.apiError.set(null);
|
|
2226
|
+
// Call chat API endpoint
|
|
2227
|
+
const response = await firstValueFrom(accountService.startChat({ message: userText }));
|
|
2228
|
+
this.isLoadingApi.set(false);
|
|
2229
|
+
if (response && response.success && response.data) {
|
|
2230
|
+
return response.data.reply || response.data.message || this.getFallbackReply();
|
|
2231
|
+
}
|
|
2232
|
+
return this.getFallbackReply();
|
|
2233
|
+
}
|
|
2234
|
+
catch (error) {
|
|
2235
|
+
this.isLoadingApi.set(false);
|
|
2236
|
+
const apiError = error;
|
|
2237
|
+
this.apiError.set(apiError);
|
|
2238
|
+
console.error('API error, falling back to local mode:', apiError);
|
|
2239
|
+
// Fallback to local mode on API error
|
|
2240
|
+
return this.getBotReplyLocal(userText);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Get bot reply using local intent matching
|
|
2245
|
+
*/
|
|
2246
|
+
getBotReplyLocal(userText) {
|
|
2247
|
+
const text = userText.toLowerCase();
|
|
2248
|
+
for (const intent of CHAT_INTENTS) {
|
|
2249
|
+
if (intent.patterns.some((pattern) => text.includes(pattern))) {
|
|
2250
|
+
return intent.response;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
return this.getFallbackReply();
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* Process a user message: add it, get bot reply, and add bot reply
|
|
2257
|
+
*/
|
|
2258
|
+
async processUserMessage(text) {
|
|
2259
|
+
this.addMessage({
|
|
2260
|
+
sender: 'user',
|
|
2261
|
+
text: text,
|
|
2262
|
+
id: Date.now().toString(),
|
|
2263
|
+
timestamp: new Date(),
|
|
2264
|
+
});
|
|
2265
|
+
this.isBotTyping.set(true);
|
|
2266
|
+
const minDelay = 1000;
|
|
2267
|
+
const start = Date.now();
|
|
2268
|
+
try {
|
|
2269
|
+
const botReply = await this.getBotReply(text);
|
|
2270
|
+
// Ensure minimum delay
|
|
2271
|
+
const elapsed = Date.now() - start;
|
|
2272
|
+
if (elapsed < minDelay) {
|
|
2273
|
+
await new Promise((resolve) => setTimeout(resolve, minDelay - elapsed));
|
|
2274
|
+
}
|
|
2275
|
+
const isFallback = botReply === this.getFallbackReply();
|
|
2276
|
+
this.addMessage({
|
|
2277
|
+
sender: 'bot',
|
|
2278
|
+
text: botReply,
|
|
2279
|
+
id: Date.now().toString(),
|
|
2280
|
+
showSuggestions: isFallback,
|
|
2281
|
+
});
|
|
2282
|
+
}
|
|
2283
|
+
catch (error) {
|
|
2284
|
+
console.error('Error getting bot reply:', error);
|
|
2285
|
+
this.addMessage({
|
|
2286
|
+
sender: 'bot',
|
|
2287
|
+
text: this.getFallbackReply(),
|
|
2288
|
+
id: Date.now().toString(),
|
|
2289
|
+
showSuggestions: true,
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
finally {
|
|
2293
|
+
this.isBotTyping.set(false);
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
getFallbackReply() {
|
|
2297
|
+
return "I'm sorry 😔, I didn't understand that.";
|
|
2298
|
+
}
|
|
2299
|
+
isFallbackIntent(userText) {
|
|
2300
|
+
const text = userText.toLowerCase();
|
|
2301
|
+
return !CHAT_INTENTS.some((intent) => intent.patterns.some((pattern) => text.includes(pattern)));
|
|
2302
|
+
}
|
|
2303
|
+
unlockAudio() {
|
|
2304
|
+
if (this.audioUnlocked)
|
|
2305
|
+
return;
|
|
2306
|
+
const audio = new Audio();
|
|
2307
|
+
audio.volume = 1.0;
|
|
2308
|
+
audio
|
|
2309
|
+
.play()
|
|
2310
|
+
.then(() => (this.audioUnlocked = true))
|
|
2311
|
+
.catch(() => { });
|
|
2312
|
+
}
|
|
2313
|
+
playBotSound() {
|
|
2314
|
+
if (!this.audioUnlocked)
|
|
2315
|
+
return;
|
|
2316
|
+
try {
|
|
2317
|
+
const audio = new Audio('assets/bot.mp3');
|
|
2318
|
+
audio.play();
|
|
2319
|
+
}
|
|
2320
|
+
catch (error) {
|
|
2321
|
+
console.error('Error playing bot sound:', error);
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2325
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, providedIn: 'root' });
|
|
2326
|
+
}
|
|
2327
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, decorators: [{
|
|
2328
|
+
type: Injectable,
|
|
2329
|
+
args: [{
|
|
2330
|
+
providedIn: 'root',
|
|
2331
|
+
}]
|
|
2332
|
+
}], ctorParameters: () => [] });
|
|
2333
|
+
|
|
2432
2334
|
/**
|
|
2433
2335
|
* ChatFacadeService - High-level orchestration service
|
|
2434
2336
|
*
|
|
@@ -2448,15 +2350,33 @@ class ChatFacadeService {
|
|
|
2448
2350
|
accountService = inject(AccountService);
|
|
2449
2351
|
authService = inject(AuthService);
|
|
2450
2352
|
tenantContextService = inject(TenantContextService);
|
|
2451
|
-
//
|
|
2353
|
+
// Chat State
|
|
2452
2354
|
messages = this.messageService.messages;
|
|
2453
2355
|
isBotTyping = this.messageService.isBotTyping;
|
|
2454
2356
|
chatSessions = signal([], ...(ngDevMode ? [{ debugName: "chatSessions" }] : []));
|
|
2455
2357
|
isAuthenticated = signal(false, ...(ngDevMode ? [{ debugName: "isAuthenticated" }] : []));
|
|
2358
|
+
isGuestMode = signal(false, ...(ngDevMode ? [{ debugName: "isGuestMode" }] : []));
|
|
2456
2359
|
messageError = signal(null, ...(ngDevMode ? [{ debugName: "messageError" }] : []));
|
|
2360
|
+
// API / Auth State
|
|
2361
|
+
apiError = signal(null, ...(ngDevMode ? [{ debugName: "apiError" }] : []));
|
|
2362
|
+
authError = signal(null, ...(ngDevMode ? [{ debugName: "authError" }] : []));
|
|
2363
|
+
authSuccess = signal(null, ...(ngDevMode ? [{ debugName: "authSuccess" }] : []));
|
|
2364
|
+
isLoggingIn = signal(false, ...(ngDevMode ? [{ debugName: "isLoggingIn" }] : []));
|
|
2457
2365
|
constructor() {
|
|
2458
2366
|
// Set initial authentication status
|
|
2459
2367
|
this.isAuthenticated.set(this.authService.isAuthenticated());
|
|
2368
|
+
// Check if we should default to guest mode (missing API config)
|
|
2369
|
+
if (!this.authService.apiUrl || !this.authService.companyCode) {
|
|
2370
|
+
console.log('ChatFacade: No API config detected, defaulting to Guest Mode');
|
|
2371
|
+
this.isGuestMode.set(true);
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
/**
|
|
2375
|
+
* Get logged-in user's name from auth token
|
|
2376
|
+
*/
|
|
2377
|
+
getLoggedInUserName() {
|
|
2378
|
+
const username = this.authService.getLocalStorage('username');
|
|
2379
|
+
return username || 'User';
|
|
2460
2380
|
}
|
|
2461
2381
|
// ============================================================================
|
|
2462
2382
|
// SESSION MANAGEMENT
|
|
@@ -2539,34 +2459,65 @@ class ChatFacadeService {
|
|
|
2539
2459
|
*/
|
|
2540
2460
|
clearMessageError() {
|
|
2541
2461
|
this.messageError.set(null);
|
|
2462
|
+
this.authError.set(null);
|
|
2463
|
+
this.authSuccess.set(null);
|
|
2542
2464
|
}
|
|
2543
2465
|
// ============================================================================
|
|
2544
2466
|
// AUTHENTICATION
|
|
2545
2467
|
// ============================================================================
|
|
2546
2468
|
/**
|
|
2547
|
-
*
|
|
2469
|
+
* Enable guest mode explicitly
|
|
2548
2470
|
*/
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2471
|
+
enableGuestMode() {
|
|
2472
|
+
this.isGuestMode.set(true);
|
|
2473
|
+
this.messageService.setGuestMode(true);
|
|
2474
|
+
}
|
|
2475
|
+
/**
|
|
2476
|
+
* Disable guest mode explicitly
|
|
2477
|
+
*/
|
|
2478
|
+
disableGuestMode() {
|
|
2479
|
+
this.isGuestMode.set(false);
|
|
2480
|
+
this.messageService.setGuestMode(false);
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* Authenticate user with credentials
|
|
2484
|
+
*/
|
|
2485
|
+
async login(credentials, silent = false) {
|
|
2486
|
+
this.isLoggingIn.set(true);
|
|
2487
|
+
if (!silent) {
|
|
2488
|
+
this.authError.set(null);
|
|
2489
|
+
this.authSuccess.set(null);
|
|
2555
2490
|
}
|
|
2556
2491
|
try {
|
|
2557
2492
|
const response = await firstValueFrom(this.accountService.login(credentials));
|
|
2493
|
+
console.log('>>>>>>>>>>>Login response<<<<<<<<<<:', response);
|
|
2494
|
+
console.log('>>>>>>>>>>Credentials used<<<<<<<<:', credentials);
|
|
2558
2495
|
if (response && response.success) {
|
|
2496
|
+
console.log('Login response (success):', response);
|
|
2559
2497
|
this.isAuthenticated.set(true);
|
|
2498
|
+
this.disableGuestMode(); // Ensure guest mode is off
|
|
2499
|
+
if (!silent) {
|
|
2500
|
+
this.authSuccess.set('Login successful!');
|
|
2501
|
+
}
|
|
2502
|
+
this.isLoggingIn.set(false);
|
|
2560
2503
|
return true;
|
|
2561
2504
|
}
|
|
2562
2505
|
else {
|
|
2563
2506
|
this.isAuthenticated.set(false);
|
|
2507
|
+
if (!silent) {
|
|
2508
|
+
this.authError.set('Login failed. Please check your credentials.');
|
|
2509
|
+
}
|
|
2510
|
+
this.isLoggingIn.set(false);
|
|
2564
2511
|
return false;
|
|
2565
2512
|
}
|
|
2566
2513
|
}
|
|
2567
2514
|
catch (error) {
|
|
2568
2515
|
console.error('Login failed:', error);
|
|
2569
2516
|
this.isAuthenticated.set(false);
|
|
2517
|
+
if (!silent) {
|
|
2518
|
+
this.authError.set('An error occurred during login.');
|
|
2519
|
+
}
|
|
2520
|
+
this.isLoggingIn.set(false);
|
|
2570
2521
|
return false;
|
|
2571
2522
|
}
|
|
2572
2523
|
}
|
|
@@ -2576,6 +2527,59 @@ class ChatFacadeService {
|
|
|
2576
2527
|
checkAuthentication() {
|
|
2577
2528
|
return this.authService.isAuthenticated();
|
|
2578
2529
|
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Logout the current user
|
|
2532
|
+
*/
|
|
2533
|
+
async logout() {
|
|
2534
|
+
try {
|
|
2535
|
+
// Get refresh token from auth service
|
|
2536
|
+
const refreshToken = this.authService.getLocalStorage('refresh_token');
|
|
2537
|
+
if (!refreshToken) {
|
|
2538
|
+
console.warn('No refresh token found, clearing local state only');
|
|
2539
|
+
this.clearAuthState();
|
|
2540
|
+
return;
|
|
2541
|
+
}
|
|
2542
|
+
// Call the backend logout endpoint with refresh token
|
|
2543
|
+
const response = await firstValueFrom(this.accountService.logout(refreshToken));
|
|
2544
|
+
if (response && response.success) {
|
|
2545
|
+
this.clearAuthState();
|
|
2546
|
+
console.log('User logged out successfully');
|
|
2547
|
+
}
|
|
2548
|
+
else {
|
|
2549
|
+
throw new Error('Logout failed');
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
catch (error) {
|
|
2553
|
+
console.error('Logout failed:', error);
|
|
2554
|
+
// Even if backend logout fails, clear local state
|
|
2555
|
+
this.clearAuthState();
|
|
2556
|
+
this.authError.set('Logout completed with errors.');
|
|
2557
|
+
setTimeout(() => {
|
|
2558
|
+
this.authError.set(null);
|
|
2559
|
+
}, 5000);
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
/**
|
|
2563
|
+
* Clear authentication state and reset UI
|
|
2564
|
+
*/
|
|
2565
|
+
clearAuthState() {
|
|
2566
|
+
// Clear auth storage via AuthService
|
|
2567
|
+
this.authService.clearAuth();
|
|
2568
|
+
// Update authentication state
|
|
2569
|
+
this.isAuthenticated.set(false);
|
|
2570
|
+
this.isGuestMode.set(false);
|
|
2571
|
+
// Clear messages and start new session
|
|
2572
|
+
this.messageService.clearMessages();
|
|
2573
|
+
this.messageService.startNewSession();
|
|
2574
|
+
// Clear sessions
|
|
2575
|
+
this.chatSessions.set([]);
|
|
2576
|
+
// Show success message
|
|
2577
|
+
this.authSuccess.set('Logged out successfully!');
|
|
2578
|
+
// Clear success message after 3 seconds
|
|
2579
|
+
setTimeout(() => {
|
|
2580
|
+
this.authSuccess.set(null);
|
|
2581
|
+
}, 3000);
|
|
2582
|
+
}
|
|
2579
2583
|
// ============================================================================
|
|
2580
2584
|
// CONTEXT MANAGEMENT
|
|
2581
2585
|
// ============================================================================
|
|
@@ -2826,6 +2830,43 @@ const appEmoji = {
|
|
|
2826
2830
|
redHeart: '\u{2764}\u{FE0F}',
|
|
2827
2831
|
};
|
|
2828
2832
|
|
|
2833
|
+
class AuthInterceptor {
|
|
2834
|
+
auth;
|
|
2835
|
+
constructor(auth) {
|
|
2836
|
+
this.auth = auth;
|
|
2837
|
+
}
|
|
2838
|
+
intercept(req, next) {
|
|
2839
|
+
const authReq = this.getRequestWithHeaders(req);
|
|
2840
|
+
return this.sendRequest(authReq, next);
|
|
2841
|
+
}
|
|
2842
|
+
sendRequest(req, next) {
|
|
2843
|
+
return next.handle(req).pipe(tap((event) => {
|
|
2844
|
+
// if (event instanceof HttpResponse) {
|
|
2845
|
+
// this.ngxCache.setHttpResponse(req.urlWithParams
|
|
2846
|
+
// .replace('refresh=true', '')
|
|
2847
|
+
// .replace('refresh=false', '')
|
|
2848
|
+
// .replace('refresh=undefined', ''), event, AppConst.data.timeToLeave || 60);
|
|
2849
|
+
// }
|
|
2850
|
+
}));
|
|
2851
|
+
}
|
|
2852
|
+
getRequestWithHeaders(req) {
|
|
2853
|
+
let headers = req.headers;
|
|
2854
|
+
const token = this.auth.getLocalStorage('access_token') ?? '';
|
|
2855
|
+
if (token != '') {
|
|
2856
|
+
headers = headers.set('Authorization', `Bearer ${token}`);
|
|
2857
|
+
}
|
|
2858
|
+
return req.clone({ headers });
|
|
2859
|
+
}
|
|
2860
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AuthInterceptor, deps: [{ token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2861
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AuthInterceptor, providedIn: 'root' });
|
|
2862
|
+
}
|
|
2863
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AuthInterceptor, decorators: [{
|
|
2864
|
+
type: Injectable,
|
|
2865
|
+
args: [{
|
|
2866
|
+
providedIn: 'root',
|
|
2867
|
+
}]
|
|
2868
|
+
}], ctorParameters: () => [{ type: AuthService }] });
|
|
2869
|
+
|
|
2829
2870
|
class Doohbot extends DoohbotInput {
|
|
2830
2871
|
elementRef;
|
|
2831
2872
|
renderer;
|
|
@@ -2864,6 +2905,10 @@ class Doohbot extends DoohbotInput {
|
|
|
2864
2905
|
chatSessions = this.chatFacade.chatSessions;
|
|
2865
2906
|
messageError = this.chatFacade.messageError;
|
|
2866
2907
|
showSuggestionChips = this.chatFacade.showSuggestionChips;
|
|
2908
|
+
isGuestMode = this.chatFacade.isGuestMode;
|
|
2909
|
+
isLoggingIn = this.chatFacade.isLoggingIn;
|
|
2910
|
+
authError = this.chatFacade.authError;
|
|
2911
|
+
authSuccess = this.chatFacade.authSuccess;
|
|
2867
2912
|
// ============================================================================
|
|
2868
2913
|
// COMPONENT-SPECIFIC STATE
|
|
2869
2914
|
// ============================================================================
|
|
@@ -2909,6 +2954,17 @@ class Doohbot extends DoohbotInput {
|
|
|
2909
2954
|
this.renderer.addClass(host, activeTheme);
|
|
2910
2955
|
this.themeService.applyCssVariables(host, this.themeConfig);
|
|
2911
2956
|
});
|
|
2957
|
+
// Update userName when authentication status changes
|
|
2958
|
+
effect(() => {
|
|
2959
|
+
const isAuth = this.chatFacade.isAuthenticated();
|
|
2960
|
+
if (isAuth) {
|
|
2961
|
+
const loggedInName = this.chatFacade.getLoggedInUserName();
|
|
2962
|
+
if (loggedInName !== 'User') {
|
|
2963
|
+
this.userName = loggedInName;
|
|
2964
|
+
console.log('Updated userName from auth token:', this.userName);
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
});
|
|
2912
2968
|
}
|
|
2913
2969
|
// ============================================================================
|
|
2914
2970
|
// LIFECYCLE HOOKS
|
|
@@ -2922,7 +2978,7 @@ class Doohbot extends DoohbotInput {
|
|
|
2922
2978
|
this.uiState.closeChat();
|
|
2923
2979
|
// Close history sidebar when user is switched
|
|
2924
2980
|
this.uiState.closeHistorySidebar();
|
|
2925
|
-
this.performLogin();
|
|
2981
|
+
// this.performLogin();
|
|
2926
2982
|
// Load sessions for new user
|
|
2927
2983
|
this.loadUserSessions();
|
|
2928
2984
|
}
|
|
@@ -2969,7 +3025,20 @@ class Doohbot extends DoohbotInput {
|
|
|
2969
3025
|
username: this.config.username || AppConst.data?.username,
|
|
2970
3026
|
password: this.config.password || AppConst.data?.password,
|
|
2971
3027
|
};
|
|
2972
|
-
|
|
3028
|
+
console.log('performLogin:', credentials.username, credentials.password);
|
|
3029
|
+
this.chatFacade.login(credentials, true);
|
|
3030
|
+
}
|
|
3031
|
+
performLoginWithCredentials(credentials) {
|
|
3032
|
+
this.chatFacade.login(credentials, false);
|
|
3033
|
+
}
|
|
3034
|
+
continueAsGuest() {
|
|
3035
|
+
this.chatFacade.enableGuestMode();
|
|
3036
|
+
}
|
|
3037
|
+
disableGuestMode() {
|
|
3038
|
+
this.chatFacade.disableGuestMode();
|
|
3039
|
+
}
|
|
3040
|
+
performLogout() {
|
|
3041
|
+
this.chatFacade.logout();
|
|
2973
3042
|
}
|
|
2974
3043
|
// ============================================================================
|
|
2975
3044
|
// CHAT OPERATIONS
|
|
@@ -3025,27 +3094,11 @@ class Doohbot extends DoohbotInput {
|
|
|
3025
3094
|
return item.id || index.toString();
|
|
3026
3095
|
}
|
|
3027
3096
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: Doohbot, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
3028
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: Doohbot, isStandalone: true, selector: "app-doohbot", inputs: { config: "config", platformTenant: "platformTenant", subTenant: "subTenant", agent: "agent", buttonStyle: "buttonStyle", enableDrag: "enableDrag", enableResize: "enableResize", apiConfig: "apiConfig", userContext: "userContext", themeConfig: "themeConfig" },
|
|
3029
|
-
AppConst,
|
|
3030
|
-
{
|
|
3031
|
-
provide: APP_INITIALIZER,
|
|
3032
|
-
useFactory: (appConst) => () => appConst.load(),
|
|
3033
|
-
deps: [AppConst],
|
|
3034
|
-
multi: true,
|
|
3035
|
-
},
|
|
3036
|
-
], viewQueries: [{ propertyName: "chatWindowRef", first: true, predicate: ChatWindowComponent, descendants: true, read: ElementRef }, { propertyName: "fullscreenDirective", first: true, predicate: FullscreenDirective, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<app-chat-button\r\n [buttonStyle]=\"buttonStyle\"\r\n [isChatOpen]=\"isChatOpen()\"\r\n [unreadCount]=\"unreadCount()\"\r\n [chatIcon]=\"chatIcon ?? ''\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n (toggle)=\"toggleChat()\"\r\n></app-chat-button>\r\n\r\n<app-chat-window\r\n *ngIf=\"isChatOpen()\"\r\n appFullscreen\r\n [isChatOpen]=\"isChatOpen()\"\r\n [enableDrag]=\"enableDrag\"\r\n [enableResize]=\"enableResize\"\r\n [isFullScreen]=\"isFullScreen()\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n [appHeaderLogoUrl]=\"appHeaderLogoUrl ?? ''\"\r\n [moreIcon]=\"moreIcon ?? ''\"\r\n [minimizeIcon]=\"minimizeIcon ?? ''\"\r\n [messages]=\"messages()\"\r\n [isBotTyping]=\"isBotTyping()\"\r\n [isAuthenticated]=\"isAuthenticated()\"\r\n [appSubtitle]=\"appSubtitle ?? ''\"\r\n [welcomeDesc]=\"welcomeDesc ?? ''\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl ?? ''\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [hintText]=\"hintText ?? ''\"\r\n [sendIcon]=\"sendIcon ?? ''\"\r\n [messageError]=\"messageError()\"\r\n [showSuggestionChips]=\"showSuggestionChips()\"\r\n [isHistorySidebarOpen]=\"isHistorySidebarOpen()\"\r\n [chatSessions]=\"chatSessions()\"\r\n [chatHistoryUserName]=\"userName\"\r\n [isGuestUser]=\"isGuestUser()\"\r\n (toggleChat)=\"toggleChat()\"\r\n (toggleFullScreen)=\"toggleFullScreen()\"\r\n (toggleHistorySidebar)=\"toggleHistorySidebar()\"\r\n (sessionSelected)=\"loadChatSession($event)\"\r\n (sessionDeleted)=\"deleteSession($event)\"\r\n (suggestionClick)=\"sendMessage($event)\"\r\n (send)=\"sendMessage($event)\"\r\n (clearMessageError)=\"clearMessageError()\"\r\n (clearChat)=\"clearChat()\"\r\n></app-chat-window>\r\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap\";@import\"https://fonts.googleapis.com/icon?family=Material+Icons\";:host(.light-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #f8f9fa;--chat-input-color: var(--background-color);--text-alt-color: #000000;--button-color: #000000;--text-color: #333;--secondary-text-color: #858585;--hint-text-color: #858585;--user-message-color: var(--primary-color);--bot-message-color: #e9ecef;--user-text-color: #fff;--bot-text-color: #333;--border-color: #ccc;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .25);--border-top-color: #dddddd00;--typing-indicator-color: #999;--avatar-filter: invert(48%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(96%) contrast(91%);--white: #ffffff;--black: #000000;--grey: #6c757d;--red: #ff0000;--light-red: #f28b8b}:host(.dark-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #1a1717;--chat-input-color: var(--background-color);--text-alt-color: #ffffff;--button-color: #ffffff;--text-color: #f5f5f5;--secondary-text-color: #a1a1a1;--hint-text-color: #a1a1a1;--user-message-color: var(--primary-color);--bot-message-color: #333;--user-text-color: #fff;--bot-text-color: #fff;--border-color: #444;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .75);--border-top-color: #44444400;--typing-indicator-color: #bbb;--avatar-filter: invert(100%) brightness(100%);--white: #ffffff;--black: #000000;--grey: #9ca3af;--red: #ff0000;--light-red: #f28b8b}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChatButtonComponent, selector: "app-chat-button", inputs: ["buttonStyle", "isChatOpen", "unreadCount", "chatIcon", "appTitle", "appLogoUrl", "appTextLogoUrl"], outputs: ["toggle"] }, { kind: "component", type: ChatWindowComponent, selector: "app-chat-window", inputs: ["isChatOpen", "enableDrag", "enableResize", "isFullScreen", "isAuthenticated", "appTitle", "appLogoUrl", "appTextLogoUrl", "appHeaderLogoUrl", "moreIcon", "minimizeIcon", "messages", "isBotTyping", "appSubtitle", "welcomeDesc", "predefinedMessages", "botAvatarUrl", "userAvatarUrl", "userName", "trackByMessageId", "hintText", "sendIcon", "messageError", "showSuggestionChips", "isHistorySidebarOpen", "chatSessions", "chatHistoryUserName", "isGuestUser", "themeConfig"], outputs: ["toggleChat", "toggleFullScreen", "toggleHistorySidebar", "openSettings", "suggestionClick", "send", "clearMessageError", "clearChat", "sessionSelected", "sessionDeleted"] }, { kind: "directive", type: FullscreenDirective, selector: "[appFullscreen]", inputs: ["fullscreenTarget"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3097
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: Doohbot, isStandalone: true, selector: "app-doohbot", inputs: { config: "config", platformTenant: "platformTenant", subTenant: "subTenant", agent: "agent", buttonStyle: "buttonStyle", enableDrag: "enableDrag", enableResize: "enableResize", apiConfig: "apiConfig", userContext: "userContext", themeConfig: "themeConfig" }, viewQueries: [{ propertyName: "chatWindowRef", first: true, predicate: ChatWindowComponent, descendants: true, read: ElementRef }, { propertyName: "fullscreenDirective", first: true, predicate: FullscreenDirective, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<app-chat-button\r\n [buttonStyle]=\"buttonStyle\"\r\n [isChatOpen]=\"isChatOpen()\"\r\n [unreadCount]=\"unreadCount()\"\r\n [chatIcon]=\"chatIcon ?? ''\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n (toggle)=\"toggleChat()\"\r\n></app-chat-button>\r\n\r\n<app-chat-window\r\n *ngIf=\"isChatOpen()\"\r\n appFullscreen\r\n [isChatOpen]=\"isChatOpen()\"\r\n [enableDrag]=\"enableDrag\"\r\n [enableResize]=\"enableResize\"\r\n [isFullScreen]=\"isFullScreen()\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n [appHeaderLogoUrl]=\"appHeaderLogoUrl ?? ''\"\r\n [moreIcon]=\"moreIcon ?? ''\"\r\n [minimizeIcon]=\"minimizeIcon ?? ''\"\r\n [messages]=\"messages()\"\r\n [isBotTyping]=\"isBotTyping()\"\r\n [isAuthenticated]=\"isAuthenticated()\"\r\n [appSubtitle]=\"appSubtitle ?? ''\"\r\n [welcomeDesc]=\"welcomeDesc ?? ''\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl ?? ''\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [hintText]=\"hintText ?? ''\"\r\n [sendIcon]=\"sendIcon ?? ''\"\r\n [messageError]=\"messageError()\"\r\n [showSuggestionChips]=\"showSuggestionChips()\"\r\n [isHistorySidebarOpen]=\"isHistorySidebarOpen()\"\r\n [chatSessions]=\"chatSessions()\"\r\n [chatHistoryUserName]=\"userName\"\r\n [isGuestUser]=\"isGuestUser()\"\r\n [isGuestMode]=\"isGuestMode()\"\r\n [isLoggingIn]=\"isLoggingIn()\"\r\n [authError]=\"authError()\"\r\n [authSuccess]=\"authSuccess()\"\r\n (toggleChat)=\"toggleChat()\"\r\n (continueAsGuest)=\"continueAsGuest()\"\r\n (loginClick)=\"disableGuestMode()\"\r\n (loginSubmit)=\"performLoginWithCredentials($event)\"\r\n (toggleFullScreen)=\"toggleFullScreen()\"\r\n (toggleHistorySidebar)=\"toggleHistorySidebar()\"\r\n (sessionSelected)=\"loadChatSession($event)\"\r\n (sessionDeleted)=\"deleteSession($event)\"\r\n (suggestionClick)=\"sendMessage($event)\"\r\n (send)=\"sendMessage($event)\"\r\n (clearMessageError)=\"clearMessageError()\"\r\n (clearChat)=\"clearChat()\"\r\n (logout)=\"performLogout()\"\r\n></app-chat-window>\r\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap\";@import\"https://fonts.googleapis.com/icon?family=Material+Icons\";:host(.light-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #f8f9fa;--chat-input-color: var(--background-color);--text-alt-color: #000000;--button-color: #000000;--text-color: #333;--secondary-text-color: #858585;--hint-text-color: #858585;--user-message-color: var(--primary-color);--bot-message-color: #e9ecef;--user-text-color: #fff;--bot-text-color: #333;--border-color: #ccc;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .25);--border-top-color: #dddddd00;--typing-indicator-color: #999;--avatar-filter: invert(48%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(96%) contrast(91%);--white: #ffffff;--black: #000000;--grey: #6c757d;--red: #ff0000;--light-red: #f28b8b}:host(.dark-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #1a1717;--chat-input-color: var(--background-color);--text-alt-color: #ffffff;--button-color: #ffffff;--text-color: #f5f5f5;--secondary-text-color: #a1a1a1;--hint-text-color: #a1a1a1;--user-message-color: var(--primary-color);--bot-message-color: #333;--user-text-color: #fff;--bot-text-color: #fff;--border-color: #444;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .75);--border-top-color: #44444400;--typing-indicator-color: #bbb;--avatar-filter: invert(100%) brightness(100%);--white: #ffffff;--black: #000000;--grey: #9ca3af;--red: #ff0000;--light-red: #f28b8b}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChatButtonComponent, selector: "app-chat-button", inputs: ["buttonStyle", "isChatOpen", "unreadCount", "chatIcon", "appTitle", "appLogoUrl", "appTextLogoUrl"], outputs: ["toggle"] }, { kind: "component", type: ChatWindowComponent, selector: "app-chat-window", inputs: ["isChatOpen", "enableDrag", "enableResize", "isFullScreen", "isAuthenticated", "appTitle", "appLogoUrl", "appTextLogoUrl", "appHeaderLogoUrl", "moreIcon", "minimizeIcon", "messages", "isBotTyping", "appSubtitle", "welcomeDesc", "predefinedMessages", "botAvatarUrl", "userAvatarUrl", "userName", "trackByMessageId", "hintText", "sendIcon", "messageError", "showSuggestionChips", "isHistorySidebarOpen", "chatSessions", "chatHistoryUserName", "isGuestUser", "isGuestMode", "isLoggingIn", "authError", "authSuccess", "themeConfig"], outputs: ["toggleChat", "toggleFullScreen", "toggleHistorySidebar", "openSettings", "suggestionClick", "send", "clearMessageError", "clearChat", "sessionSelected", "sessionDeleted", "continueAsGuest", "loginClick", "loginSubmit", "logout"] }, { kind: "directive", type: FullscreenDirective, selector: "[appFullscreen]", inputs: ["fullscreenTarget"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3037
3098
|
}
|
|
3038
3099
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: Doohbot, decorators: [{
|
|
3039
3100
|
type: Component,
|
|
3040
|
-
args: [{ selector: 'app-doohbot', standalone: true, imports: [CommonModule, ChatButtonComponent, ChatWindowComponent, FullscreenDirective], changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3041
|
-
AppConst,
|
|
3042
|
-
{
|
|
3043
|
-
provide: APP_INITIALIZER,
|
|
3044
|
-
useFactory: (appConst) => () => appConst.load(),
|
|
3045
|
-
deps: [AppConst],
|
|
3046
|
-
multi: true,
|
|
3047
|
-
},
|
|
3048
|
-
], template: "<app-chat-button\r\n [buttonStyle]=\"buttonStyle\"\r\n [isChatOpen]=\"isChatOpen()\"\r\n [unreadCount]=\"unreadCount()\"\r\n [chatIcon]=\"chatIcon ?? ''\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n (toggle)=\"toggleChat()\"\r\n></app-chat-button>\r\n\r\n<app-chat-window\r\n *ngIf=\"isChatOpen()\"\r\n appFullscreen\r\n [isChatOpen]=\"isChatOpen()\"\r\n [enableDrag]=\"enableDrag\"\r\n [enableResize]=\"enableResize\"\r\n [isFullScreen]=\"isFullScreen()\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n [appHeaderLogoUrl]=\"appHeaderLogoUrl ?? ''\"\r\n [moreIcon]=\"moreIcon ?? ''\"\r\n [minimizeIcon]=\"minimizeIcon ?? ''\"\r\n [messages]=\"messages()\"\r\n [isBotTyping]=\"isBotTyping()\"\r\n [isAuthenticated]=\"isAuthenticated()\"\r\n [appSubtitle]=\"appSubtitle ?? ''\"\r\n [welcomeDesc]=\"welcomeDesc ?? ''\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl ?? ''\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [hintText]=\"hintText ?? ''\"\r\n [sendIcon]=\"sendIcon ?? ''\"\r\n [messageError]=\"messageError()\"\r\n [showSuggestionChips]=\"showSuggestionChips()\"\r\n [isHistorySidebarOpen]=\"isHistorySidebarOpen()\"\r\n [chatSessions]=\"chatSessions()\"\r\n [chatHistoryUserName]=\"userName\"\r\n [isGuestUser]=\"isGuestUser()\"\r\n (toggleChat)=\"toggleChat()\"\r\n (toggleFullScreen)=\"toggleFullScreen()\"\r\n (toggleHistorySidebar)=\"toggleHistorySidebar()\"\r\n (sessionSelected)=\"loadChatSession($event)\"\r\n (sessionDeleted)=\"deleteSession($event)\"\r\n (suggestionClick)=\"sendMessage($event)\"\r\n (send)=\"sendMessage($event)\"\r\n (clearMessageError)=\"clearMessageError()\"\r\n (clearChat)=\"clearChat()\"\r\n></app-chat-window>\r\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap\";@import\"https://fonts.googleapis.com/icon?family=Material+Icons\";:host(.light-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #f8f9fa;--chat-input-color: var(--background-color);--text-alt-color: #000000;--button-color: #000000;--text-color: #333;--secondary-text-color: #858585;--hint-text-color: #858585;--user-message-color: var(--primary-color);--bot-message-color: #e9ecef;--user-text-color: #fff;--bot-text-color: #333;--border-color: #ccc;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .25);--border-top-color: #dddddd00;--typing-indicator-color: #999;--avatar-filter: invert(48%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(96%) contrast(91%);--white: #ffffff;--black: #000000;--grey: #6c757d;--red: #ff0000;--light-red: #f28b8b}:host(.dark-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #1a1717;--chat-input-color: var(--background-color);--text-alt-color: #ffffff;--button-color: #ffffff;--text-color: #f5f5f5;--secondary-text-color: #a1a1a1;--hint-text-color: #a1a1a1;--user-message-color: var(--primary-color);--bot-message-color: #333;--user-text-color: #fff;--bot-text-color: #fff;--border-color: #444;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .75);--border-top-color: #44444400;--typing-indicator-color: #bbb;--avatar-filter: invert(100%) brightness(100%);--white: #ffffff;--black: #000000;--grey: #9ca3af;--red: #ff0000;--light-red: #f28b8b}\n"] }]
|
|
3101
|
+
args: [{ selector: 'app-doohbot', standalone: true, imports: [CommonModule, ChatButtonComponent, ChatWindowComponent, FullscreenDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-chat-button\r\n [buttonStyle]=\"buttonStyle\"\r\n [isChatOpen]=\"isChatOpen()\"\r\n [unreadCount]=\"unreadCount()\"\r\n [chatIcon]=\"chatIcon ?? ''\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n (toggle)=\"toggleChat()\"\r\n></app-chat-button>\r\n\r\n<app-chat-window\r\n *ngIf=\"isChatOpen()\"\r\n appFullscreen\r\n [isChatOpen]=\"isChatOpen()\"\r\n [enableDrag]=\"enableDrag\"\r\n [enableResize]=\"enableResize\"\r\n [isFullScreen]=\"isFullScreen()\"\r\n [appTitle]=\"appTitle ?? ''\"\r\n [appLogoUrl]=\"appLogoUrl ?? ''\"\r\n [appTextLogoUrl]=\"appTextLogoUrl ?? ''\"\r\n [appHeaderLogoUrl]=\"appHeaderLogoUrl ?? ''\"\r\n [moreIcon]=\"moreIcon ?? ''\"\r\n [minimizeIcon]=\"minimizeIcon ?? ''\"\r\n [messages]=\"messages()\"\r\n [isBotTyping]=\"isBotTyping()\"\r\n [isAuthenticated]=\"isAuthenticated()\"\r\n [appSubtitle]=\"appSubtitle ?? ''\"\r\n [welcomeDesc]=\"welcomeDesc ?? ''\"\r\n [predefinedMessages]=\"predefinedMessages\"\r\n [botAvatarUrl]=\"botAvatarUrl ?? ''\"\r\n [userAvatarUrl]=\"userAvatarUrl\"\r\n [userName]=\"userName\"\r\n [trackByMessageId]=\"trackByMessageId\"\r\n [hintText]=\"hintText ?? ''\"\r\n [sendIcon]=\"sendIcon ?? ''\"\r\n [messageError]=\"messageError()\"\r\n [showSuggestionChips]=\"showSuggestionChips()\"\r\n [isHistorySidebarOpen]=\"isHistorySidebarOpen()\"\r\n [chatSessions]=\"chatSessions()\"\r\n [chatHistoryUserName]=\"userName\"\r\n [isGuestUser]=\"isGuestUser()\"\r\n [isGuestMode]=\"isGuestMode()\"\r\n [isLoggingIn]=\"isLoggingIn()\"\r\n [authError]=\"authError()\"\r\n [authSuccess]=\"authSuccess()\"\r\n (toggleChat)=\"toggleChat()\"\r\n (continueAsGuest)=\"continueAsGuest()\"\r\n (loginClick)=\"disableGuestMode()\"\r\n (loginSubmit)=\"performLoginWithCredentials($event)\"\r\n (toggleFullScreen)=\"toggleFullScreen()\"\r\n (toggleHistorySidebar)=\"toggleHistorySidebar()\"\r\n (sessionSelected)=\"loadChatSession($event)\"\r\n (sessionDeleted)=\"deleteSession($event)\"\r\n (suggestionClick)=\"sendMessage($event)\"\r\n (send)=\"sendMessage($event)\"\r\n (clearMessageError)=\"clearMessageError()\"\r\n (clearChat)=\"clearChat()\"\r\n (logout)=\"performLogout()\"\r\n></app-chat-window>\r\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap\";@import\"https://fonts.googleapis.com/icon?family=Material+Icons\";:host(.light-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #f8f9fa;--chat-input-color: var(--background-color);--text-alt-color: #000000;--button-color: #000000;--text-color: #333;--secondary-text-color: #858585;--hint-text-color: #858585;--user-message-color: var(--primary-color);--bot-message-color: #e9ecef;--user-text-color: #fff;--bot-text-color: #333;--border-color: #ccc;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .25);--border-top-color: #dddddd00;--typing-indicator-color: #999;--avatar-filter: invert(48%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(96%) contrast(91%);--white: #ffffff;--black: #000000;--grey: #6c757d;--red: #ff0000;--light-red: #f28b8b}:host(.dark-theme){--font-family: \"Roboto\", Arial, sans-serif;--primary-color: #2800ff;--secondary-color: #08dacf;--background-color: #1a1717;--chat-input-color: var(--background-color);--text-alt-color: #ffffff;--button-color: #ffffff;--text-color: #f5f5f5;--secondary-text-color: #a1a1a1;--hint-text-color: #a1a1a1;--user-message-color: var(--primary-color);--bot-message-color: #333;--user-text-color: #fff;--bot-text-color: #fff;--border-color: #444;--border-shadow-color: 0 4px 16px rgba(0, 0, 0, .75);--border-top-color: #44444400;--typing-indicator-color: #bbb;--avatar-filter: invert(100%) brightness(100%);--white: #ffffff;--black: #000000;--grey: #9ca3af;--red: #ff0000;--light-red: #f28b8b}\n"] }]
|
|
3049
3102
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { config: [{
|
|
3050
3103
|
type: Input
|
|
3051
3104
|
}], platformTenant: [{
|
|
@@ -3073,6 +3126,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
3073
3126
|
type: ViewChild,
|
|
3074
3127
|
args: [FullscreenDirective]
|
|
3075
3128
|
}] } });
|
|
3129
|
+
// ============================================================================
|
|
3130
|
+
// APP INITIALIZATION
|
|
3131
|
+
// ============================================================================
|
|
3132
|
+
function initializeApp() {
|
|
3133
|
+
const appConst = inject(AppConst);
|
|
3134
|
+
return appConst.load(); // Returns a Promise
|
|
3135
|
+
}
|
|
3136
|
+
bootstrapApplication(Doohbot, {
|
|
3137
|
+
providers: [
|
|
3138
|
+
provideHttpClient(withInterceptorsFromDi()),
|
|
3139
|
+
AppConst,
|
|
3140
|
+
provideAppInitializer(initializeApp),
|
|
3141
|
+
{
|
|
3142
|
+
provide: HTTP_INTERCEPTORS,
|
|
3143
|
+
useClass: AuthInterceptor,
|
|
3144
|
+
multi: true,
|
|
3145
|
+
},
|
|
3146
|
+
],
|
|
3147
|
+
});
|
|
3076
3148
|
|
|
3077
3149
|
const DOOHBOT_API_URL = new InjectionToken('DOOHBOT_API_URL');
|
|
3078
3150
|
|
|
@@ -3085,5 +3157,5 @@ const DOOHBOT_API_URL = new InjectionToken('DOOHBOT_API_URL');
|
|
|
3085
3157
|
* Generated bundle index. Do not edit.
|
|
3086
3158
|
*/
|
|
3087
3159
|
|
|
3088
|
-
export { AccountService, AuthService, ChatWindowComponent, ChatbotApiService, DOOHBOT_API_CONFIG, DOOHBOT_API_URL, DialogComponent, DialogService, Doohbot, DoohbotInput, MessageListComponent, appConst };
|
|
3160
|
+
export { AccountService, AuthService, ChatWindowComponent, ChatbotApiService, DOOHBOT_API_CONFIG, DOOHBOT_API_URL, DialogComponent, DialogService, Doohbot, DoohbotInput, MessageListComponent, appConst, initializeApp };
|
|
3089
3161
|
//# sourceMappingURL=aakash58-chatbot.mjs.map
|