@aakash58/chatbot 1.0.85 → 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 +461 -296
- package/fesm2022/aakash58-chatbot.mjs.map +1 -1
- package/index.d.ts +14 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, Output, Input, Component, ViewChild, HostListener, Directive, signal, Injectable, Inject, inject, InjectionToken, computed, effect, ElementRef,
|
|
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';
|
|
@@ -13,13 +13,14 @@ import * as i2 from '@angular/material/button';
|
|
|
13
13
|
import { MatButtonModule } from '@angular/material/button';
|
|
14
14
|
import * as i4 from '@angular/forms';
|
|
15
15
|
import { FormsModule } from '@angular/forms';
|
|
16
|
-
import { Subject, throwError, timer, of,
|
|
16
|
+
import { Subject, throwError, timer, of, delay, retry as retry$1, map as map$1, catchError as catchError$1, firstValueFrom, Observable, tap } from 'rxjs';
|
|
17
17
|
import * as i1$4 from '@angular/common/http';
|
|
18
|
-
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
|
|
18
|
+
import { HttpClient, HttpHeaders, HttpErrorResponse, provideHttpClient, HTTP_INTERCEPTORS, withInterceptorsFromDi } from '@angular/common/http';
|
|
19
19
|
import { timeout, map, catchError, retry } from 'rxjs/operators';
|
|
20
20
|
import * as CryptoJS from 'crypto-js';
|
|
21
21
|
import { JwtHelperService } from '@auth0/angular-jwt';
|
|
22
22
|
import * as i1$5 from '@angular/router';
|
|
23
|
+
import { bootstrapApplication } from '@angular/platform-browser';
|
|
23
24
|
|
|
24
25
|
const appConst = {
|
|
25
26
|
//LIVE ASSETS
|
|
@@ -95,11 +96,11 @@ class ChatButtonComponent {
|
|
|
95
96
|
this.toggle.emit();
|
|
96
97
|
}
|
|
97
98
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
98
|
-
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 }] });
|
|
99
100
|
}
|
|
100
101
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatButtonComponent, decorators: [{
|
|
101
102
|
type: Component,
|
|
102
|
-
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"] }]
|
|
103
104
|
}], propDecorators: { buttonStyle: [{
|
|
104
105
|
type: Input
|
|
105
106
|
}], isChatOpen: [{
|
|
@@ -954,11 +955,16 @@ class ChatWindowComponent {
|
|
|
954
955
|
continueAsGuest = new EventEmitter();
|
|
955
956
|
loginClick = new EventEmitter();
|
|
956
957
|
loginSubmit = new EventEmitter();
|
|
958
|
+
logout = new EventEmitter();
|
|
957
959
|
themeService = inject(ThemeService);
|
|
958
960
|
// Login form state
|
|
959
961
|
loginUsername = '';
|
|
960
962
|
loginPassword = '';
|
|
961
963
|
showLoginForm = false;
|
|
964
|
+
showPassword = false;
|
|
965
|
+
togglePasswordVisibility() {
|
|
966
|
+
this.showPassword = !this.showPassword;
|
|
967
|
+
}
|
|
962
968
|
onToggleChat() {
|
|
963
969
|
this.toggleChat.emit();
|
|
964
970
|
}
|
|
@@ -997,9 +1003,15 @@ class ChatWindowComponent {
|
|
|
997
1003
|
this.messageError = null;
|
|
998
1004
|
this.clearMessageError.emit();
|
|
999
1005
|
}
|
|
1006
|
+
onClearAuthError() {
|
|
1007
|
+
this.clearMessageError.emit();
|
|
1008
|
+
}
|
|
1000
1009
|
onClearChat() {
|
|
1001
1010
|
this.clearChat.emit();
|
|
1002
1011
|
}
|
|
1012
|
+
onLogout() {
|
|
1013
|
+
this.logout.emit();
|
|
1014
|
+
}
|
|
1003
1015
|
onSessionSelected(session) {
|
|
1004
1016
|
this.sessionSelected.emit(session);
|
|
1005
1017
|
}
|
|
@@ -1025,18 +1037,14 @@ class ChatWindowComponent {
|
|
|
1025
1037
|
// Initialization logic if needed
|
|
1026
1038
|
}
|
|
1027
1039
|
ngOnChanges(changes) {
|
|
1028
|
-
|
|
1029
|
-
if (changes['
|
|
1030
|
-
this.
|
|
1031
|
-
}
|
|
1032
|
-
// If authSuccess input changes, update messageError (used for all snackbar messages currently) to show success
|
|
1033
|
-
if (changes['authSuccess'] && this.authSuccess) {
|
|
1034
|
-
this.messageError = this.authSuccess;
|
|
1040
|
+
//? Handle authentication status changes
|
|
1041
|
+
if (changes['isAuthenticated'] && this.isAuthenticated) {
|
|
1042
|
+
this.showLoginForm = false;
|
|
1035
1043
|
}
|
|
1036
1044
|
}
|
|
1037
1045
|
ngOnDestroy() { }
|
|
1038
1046
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatWindowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1039
|
-
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" }, 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 <!-- Inline error message -->\r\n <app-snackbar\r\n *ngIf=\"messageError\"\r\n [message]=\"messageError\"\r\n [show]=\"true\"\r\n (closed)=\"onClearMessageError()\"\r\n ></app-snackbar>\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 <input\r\n type=\"password\"\r\n [(ngModel)]=\"loginPassword\"\r\n placeholder=\"Password\"\r\n class=\"login-input\"\r\n (keydown.enter)=\"onLoginSubmit()\"\r\n />\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 <!-- 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: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-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"] }] });
|
|
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"] }] });
|
|
1040
1048
|
}
|
|
1041
1049
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChatWindowComponent, decorators: [{
|
|
1042
1050
|
type: Component,
|
|
@@ -1052,7 +1060,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
1052
1060
|
ResizableDialogDirective,
|
|
1053
1061
|
ChatHistorySidebarComponent,
|
|
1054
1062
|
FormsModule,
|
|
1055
|
-
], 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 <!-- Inline error message -->\r\n <app-snackbar\r\n *ngIf=\"messageError\"\r\n [message]=\"messageError\"\r\n [show]=\"true\"\r\n (closed)=\"onClearMessageError()\"\r\n ></app-snackbar>\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 <input\r\n type=\"password\"\r\n [(ngModel)]=\"loginPassword\"\r\n placeholder=\"Password\"\r\n class=\"login-input\"\r\n (keydown.enter)=\"onLoginSubmit()\"\r\n />\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 <!-- 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: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-actions{display:flex;justify-content:center;gap:10px;margin-top:10px}\n"] }]
|
|
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"] }]
|
|
1056
1064
|
}], propDecorators: { isChatOpen: [{
|
|
1057
1065
|
type: Input
|
|
1058
1066
|
}], enableDrag: [{
|
|
@@ -1145,6 +1153,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
1145
1153
|
type: Output
|
|
1146
1154
|
}], loginSubmit: [{
|
|
1147
1155
|
type: Output
|
|
1156
|
+
}], logout: [{
|
|
1157
|
+
type: Output
|
|
1148
1158
|
}] } });
|
|
1149
1159
|
|
|
1150
1160
|
class FullscreenDirective {
|
|
@@ -1214,6 +1224,7 @@ const environment = {
|
|
|
1214
1224
|
production: false,
|
|
1215
1225
|
apiBaseUrl: '',
|
|
1216
1226
|
loginEndpoint: '',
|
|
1227
|
+
apiSegment: 'api/v1/',
|
|
1217
1228
|
};
|
|
1218
1229
|
|
|
1219
1230
|
class AppConst {
|
|
@@ -1222,9 +1233,11 @@ class AppConst {
|
|
|
1222
1233
|
async load() {
|
|
1223
1234
|
const filePath = `../assets/${environment.production ? environment.config : environment.config}?t=${new Date().getTime()}`;
|
|
1224
1235
|
const response = await fetch(filePath);
|
|
1236
|
+
console.error('============================ AppConst ============================', filePath);
|
|
1225
1237
|
if (response.ok) {
|
|
1226
1238
|
try {
|
|
1227
1239
|
AppConst.data = await response.json();
|
|
1240
|
+
console.error('============================ AppConst ============================', AppConst.data);
|
|
1228
1241
|
// Override apiBaseUrl if present in environment
|
|
1229
1242
|
// if (environment.apiBaseUrl) {
|
|
1230
1243
|
// AppConst.data.apiBaseUrl = environment.apiBaseUrl;
|
|
@@ -1788,240 +1801,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
1788
1801
|
}]
|
|
1789
1802
|
}], ctorParameters: () => [] });
|
|
1790
1803
|
|
|
1791
|
-
class MessageService {
|
|
1792
|
-
// Context-aware message storage
|
|
1793
|
-
currentContextKey = signal('default', ...(ngDevMode ? [{ debugName: "currentContextKey" }] : []));
|
|
1794
|
-
// Public messages signal for current context
|
|
1795
|
-
messages = signal([], ...(ngDevMode ? [{ debugName: "messages" }] : []));
|
|
1796
|
-
audioUnlocked = false;
|
|
1797
|
-
// Active session
|
|
1798
|
-
activeSession = null;
|
|
1799
|
-
// API service (optional)
|
|
1800
|
-
apiService = inject(ChatbotApiService, { optional: true });
|
|
1801
|
-
chatHistoryService = inject(ChatHistoryService);
|
|
1802
|
-
// User context for backend proxy mode
|
|
1803
|
-
userContext;
|
|
1804
|
-
// API state signals
|
|
1805
|
-
isLoadingApi = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingApi" }] : []));
|
|
1806
|
-
apiError = signal(null, ...(ngDevMode ? [{ debugName: "apiError" }] : []));
|
|
1807
|
-
isBotTyping = signal(false, ...(ngDevMode ? [{ debugName: "isBotTyping" }] : []));
|
|
1808
|
-
isGuestMode = signal(false, ...(ngDevMode ? [{ debugName: "isGuestMode" }] : []));
|
|
1809
|
-
constructor() {
|
|
1810
|
-
// Start with empty messages - no auto-load
|
|
1811
|
-
}
|
|
1812
|
-
setGuestMode(isGuest) {
|
|
1813
|
-
this.isGuestMode.set(isGuest);
|
|
1814
|
-
}
|
|
1815
|
-
/**
|
|
1816
|
-
* Switch to a new context
|
|
1817
|
-
*/
|
|
1818
|
-
switchContext(contextKey) {
|
|
1819
|
-
this.currentContextKey.set(contextKey);
|
|
1820
|
-
// Start fresh - don't auto-load
|
|
1821
|
-
this.startNewSession();
|
|
1822
|
-
}
|
|
1823
|
-
/**
|
|
1824
|
-
* Start a new chat session
|
|
1825
|
-
*/
|
|
1826
|
-
startNewSession() {
|
|
1827
|
-
const contextKey = this.currentContextKey();
|
|
1828
|
-
const userId = this.userContext?.userId || 'anonymous';
|
|
1829
|
-
this.activeSession = this.chatHistoryService.createSession(contextKey, userId);
|
|
1830
|
-
this.messages.set([]);
|
|
1831
|
-
}
|
|
1832
|
-
/**
|
|
1833
|
-
* Load an existing session
|
|
1834
|
-
*/
|
|
1835
|
-
loadSession(session) {
|
|
1836
|
-
this.activeSession = session;
|
|
1837
|
-
this.messages.set([...session.messages]);
|
|
1838
|
-
}
|
|
1839
|
-
/**
|
|
1840
|
-
* Get current context key
|
|
1841
|
-
*/
|
|
1842
|
-
getCurrentContextKey() {
|
|
1843
|
-
return this.currentContextKey();
|
|
1844
|
-
}
|
|
1845
|
-
/**
|
|
1846
|
-
* Set user context for backend proxy mode
|
|
1847
|
-
*/
|
|
1848
|
-
setUserContext(context) {
|
|
1849
|
-
this.userContext = context;
|
|
1850
|
-
// Start fresh when user changes - don't auto-load
|
|
1851
|
-
this.startNewSession();
|
|
1852
|
-
}
|
|
1853
|
-
/**
|
|
1854
|
-
* Get current user context
|
|
1855
|
-
*/
|
|
1856
|
-
getUserContext() {
|
|
1857
|
-
return this.userContext;
|
|
1858
|
-
}
|
|
1859
|
-
/**
|
|
1860
|
-
* Get active session
|
|
1861
|
-
*/
|
|
1862
|
-
getActiveSession() {
|
|
1863
|
-
return this.activeSession;
|
|
1864
|
-
}
|
|
1865
|
-
/**
|
|
1866
|
-
* Clear messages for current session and start new one
|
|
1867
|
-
*/
|
|
1868
|
-
clearMessages() {
|
|
1869
|
-
this.messages.set([]);
|
|
1870
|
-
this.startNewSession();
|
|
1871
|
-
}
|
|
1872
|
-
/**
|
|
1873
|
-
* Add message to current session
|
|
1874
|
-
*/
|
|
1875
|
-
addMessage(message) {
|
|
1876
|
-
const newMessage = { ...message, timestamp: new Date() };
|
|
1877
|
-
// Update current messages signal
|
|
1878
|
-
this.messages.update((msgs) => [...msgs, newMessage]);
|
|
1879
|
-
// Save to active session
|
|
1880
|
-
if (this.activeSession) {
|
|
1881
|
-
console.log('Saving message to session:', this.activeSession.id);
|
|
1882
|
-
this.chatHistoryService.saveMessageToSession(this.activeSession, newMessage).subscribe(() => {
|
|
1883
|
-
console.log('Message saved, session title:', this.activeSession?.title);
|
|
1884
|
-
});
|
|
1885
|
-
}
|
|
1886
|
-
else {
|
|
1887
|
-
console.warn('No active session to save message to!');
|
|
1888
|
-
}
|
|
1889
|
-
if (message.sender === 'bot') {
|
|
1890
|
-
this.playBotSound();
|
|
1891
|
-
}
|
|
1892
|
-
}
|
|
1893
|
-
/**
|
|
1894
|
-
* Get bot reply - supports both API and local modes
|
|
1895
|
-
*/
|
|
1896
|
-
async getBotReply(userText) {
|
|
1897
|
-
// If in guest mode, force local logic
|
|
1898
|
-
if (this.isGuestMode()) {
|
|
1899
|
-
return this.getBotReplyLocal(userText);
|
|
1900
|
-
}
|
|
1901
|
-
// Check if API mode is enabled
|
|
1902
|
-
if (this.apiService?.isApiEnabled()) {
|
|
1903
|
-
return this.getBotReplyFromApi(userText);
|
|
1904
|
-
}
|
|
1905
|
-
// Fall back to local intent matching
|
|
1906
|
-
return this.getBotReplyLocal(userText);
|
|
1907
|
-
}
|
|
1908
|
-
/**
|
|
1909
|
-
* Get bot reply from API
|
|
1910
|
-
*/
|
|
1911
|
-
async getBotReplyFromApi(userText) {
|
|
1912
|
-
if (!this.apiService) {
|
|
1913
|
-
return this.getFallbackReply();
|
|
1914
|
-
}
|
|
1915
|
-
try {
|
|
1916
|
-
this.isLoadingApi.set(true);
|
|
1917
|
-
this.apiError.set(null);
|
|
1918
|
-
// Get message history if API config includes history
|
|
1919
|
-
const history = this.apiService.getConfig().includeHistory ? this.messages() : undefined;
|
|
1920
|
-
// Call API
|
|
1921
|
-
const response = await firstValueFrom(this.apiService.sendMessage(userText, history));
|
|
1922
|
-
this.isLoadingApi.set(false);
|
|
1923
|
-
return response.reply;
|
|
1924
|
-
}
|
|
1925
|
-
catch (error) {
|
|
1926
|
-
this.isLoadingApi.set(false);
|
|
1927
|
-
const apiError = error;
|
|
1928
|
-
this.apiError.set(apiError);
|
|
1929
|
-
console.error('API error, falling back to local mode:', apiError);
|
|
1930
|
-
// Fallback to local mode on API error
|
|
1931
|
-
return this.getBotReplyLocal(userText);
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
/**
|
|
1935
|
-
* Get bot reply using local intent matching
|
|
1936
|
-
*/
|
|
1937
|
-
getBotReplyLocal(userText) {
|
|
1938
|
-
const text = userText.toLowerCase();
|
|
1939
|
-
for (const intent of CHAT_INTENTS) {
|
|
1940
|
-
if (intent.patterns.some((pattern) => text.includes(pattern))) {
|
|
1941
|
-
return intent.response;
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
return this.getFallbackReply();
|
|
1945
|
-
}
|
|
1946
|
-
/**
|
|
1947
|
-
* Process a user message: add it, get bot reply, and add bot reply
|
|
1948
|
-
*/
|
|
1949
|
-
async processUserMessage(text) {
|
|
1950
|
-
this.addMessage({
|
|
1951
|
-
sender: 'user',
|
|
1952
|
-
text: text,
|
|
1953
|
-
id: Date.now().toString(),
|
|
1954
|
-
timestamp: new Date(),
|
|
1955
|
-
});
|
|
1956
|
-
this.isBotTyping.set(true);
|
|
1957
|
-
const minDelay = 1000;
|
|
1958
|
-
const start = Date.now();
|
|
1959
|
-
try {
|
|
1960
|
-
const botReply = await this.getBotReply(text);
|
|
1961
|
-
// Ensure minimum delay
|
|
1962
|
-
const elapsed = Date.now() - start;
|
|
1963
|
-
if (elapsed < minDelay) {
|
|
1964
|
-
await new Promise((resolve) => setTimeout(resolve, minDelay - elapsed));
|
|
1965
|
-
}
|
|
1966
|
-
const isFallback = botReply === this.getFallbackReply();
|
|
1967
|
-
this.addMessage({
|
|
1968
|
-
sender: 'bot',
|
|
1969
|
-
text: botReply,
|
|
1970
|
-
id: Date.now().toString(),
|
|
1971
|
-
showSuggestions: isFallback,
|
|
1972
|
-
});
|
|
1973
|
-
}
|
|
1974
|
-
catch (error) {
|
|
1975
|
-
console.error('Error getting bot reply:', error);
|
|
1976
|
-
this.addMessage({
|
|
1977
|
-
sender: 'bot',
|
|
1978
|
-
text: this.getFallbackReply(),
|
|
1979
|
-
id: Date.now().toString(),
|
|
1980
|
-
showSuggestions: true,
|
|
1981
|
-
});
|
|
1982
|
-
}
|
|
1983
|
-
finally {
|
|
1984
|
-
this.isBotTyping.set(false);
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
1987
|
-
getFallbackReply() {
|
|
1988
|
-
return "I'm sorry 😔, I didn't understand that.";
|
|
1989
|
-
}
|
|
1990
|
-
isFallbackIntent(userText) {
|
|
1991
|
-
const text = userText.toLowerCase();
|
|
1992
|
-
return !CHAT_INTENTS.some((intent) => intent.patterns.some((pattern) => text.includes(pattern)));
|
|
1993
|
-
}
|
|
1994
|
-
unlockAudio() {
|
|
1995
|
-
if (this.audioUnlocked)
|
|
1996
|
-
return;
|
|
1997
|
-
const audio = new Audio();
|
|
1998
|
-
audio.volume = 1.0;
|
|
1999
|
-
audio
|
|
2000
|
-
.play()
|
|
2001
|
-
.then(() => (this.audioUnlocked = true))
|
|
2002
|
-
.catch(() => { });
|
|
2003
|
-
}
|
|
2004
|
-
playBotSound() {
|
|
2005
|
-
if (!this.audioUnlocked)
|
|
2006
|
-
return;
|
|
2007
|
-
try {
|
|
2008
|
-
const audio = new Audio('assets/bot.mp3');
|
|
2009
|
-
audio.play();
|
|
2010
|
-
}
|
|
2011
|
-
catch (error) {
|
|
2012
|
-
console.error('Error playing bot sound:', error);
|
|
2013
|
-
}
|
|
2014
|
-
}
|
|
2015
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2016
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, providedIn: 'root' });
|
|
2017
|
-
}
|
|
2018
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MessageService, decorators: [{
|
|
2019
|
-
type: Injectable,
|
|
2020
|
-
args: [{
|
|
2021
|
-
providedIn: 'root',
|
|
2022
|
-
}]
|
|
2023
|
-
}], ctorParameters: () => [] });
|
|
2024
|
-
|
|
2025
1804
|
class HttpService {
|
|
2026
1805
|
http;
|
|
2027
1806
|
// @BlockUI() blockUI!: NgBlockUI;
|
|
@@ -2029,6 +1808,8 @@ class HttpService {
|
|
|
2029
1808
|
constructor(http) {
|
|
2030
1809
|
this.http = http;
|
|
2031
1810
|
this.apiUrl = `${AppConst?.data?.apiBaseUrl}${AppConst?.data?.apiSegment}`;
|
|
1811
|
+
// this.apiUrl = `${environment.apiBaseUrl}${environment.apiSegment}`;
|
|
1812
|
+
console.log('HttpService: Initialized', this.apiUrl);
|
|
2032
1813
|
}
|
|
2033
1814
|
get(url, param, nestedParam = false, showLoader = false, refresh = true) {
|
|
2034
1815
|
// if (showLoader && !this.blockUI.isActive) {
|
|
@@ -2091,7 +1872,22 @@ class AccountService {
|
|
|
2091
1872
|
this.http = http;
|
|
2092
1873
|
}
|
|
2093
1874
|
login(param, showLoader = false) {
|
|
2094
|
-
return this.http.post('
|
|
1875
|
+
return this.http.post('auth/login', param, showLoader);
|
|
1876
|
+
}
|
|
1877
|
+
logout(refreshToken, showLoader = false) {
|
|
1878
|
+
return this.http.post('auth/logout', { refresh_token: refreshToken }, showLoader);
|
|
1879
|
+
}
|
|
1880
|
+
startChat(param, showLoader = false) {
|
|
1881
|
+
return this.http.post('chat/ask', param, showLoader);
|
|
1882
|
+
}
|
|
1883
|
+
getChatHistory(param, showLoader = false) {
|
|
1884
|
+
return this.http.get('chat/history', param, showLoader);
|
|
1885
|
+
}
|
|
1886
|
+
deleteHistory(param, showLoader = false) {
|
|
1887
|
+
return this.http.post('chat/history', param, showLoader);
|
|
1888
|
+
}
|
|
1889
|
+
refreshLogin(param, showLoader = false) {
|
|
1890
|
+
return this.http.post('Account/RefreshToken', param, showLoader);
|
|
2095
1891
|
}
|
|
2096
1892
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AccountService, deps: [{ token: HttpService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2097
1893
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AccountService, providedIn: 'root' });
|
|
@@ -2294,25 +2090,266 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
2294
2090
|
}]
|
|
2295
2091
|
}], ctorParameters: () => [{ type: i1$5.Router }, { type: i1$4.HttpClient }, { type: CryptoHelperService }] });
|
|
2296
2092
|
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
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
|
+
|
|
2334
|
+
/**
|
|
2335
|
+
* ChatFacadeService - High-level orchestration service
|
|
2336
|
+
*
|
|
2337
|
+
* Coordinates operations between multiple services to provide simplified,
|
|
2338
|
+
* high-level operations for the chat component. This facade encapsulates
|
|
2339
|
+
* complex interactions and provides a clean API for common chat operations.
|
|
2340
|
+
*
|
|
2341
|
+
* Responsibilities:
|
|
2342
|
+
* - Session management (load, delete, switch sessions)
|
|
2343
|
+
* - Authentication orchestration
|
|
2344
|
+
* - Message operations coordination
|
|
2345
|
+
* - Context management
|
|
2346
|
+
*/
|
|
2347
|
+
class ChatFacadeService {
|
|
2348
|
+
messageService = inject(MessageService);
|
|
2349
|
+
chatHistoryService = inject(ChatHistoryService);
|
|
2350
|
+
accountService = inject(AccountService);
|
|
2351
|
+
authService = inject(AuthService);
|
|
2352
|
+
tenantContextService = inject(TenantContextService);
|
|
2316
2353
|
// Chat State
|
|
2317
2354
|
messages = this.messageService.messages;
|
|
2318
2355
|
isBotTyping = this.messageService.isBotTyping;
|
|
@@ -2334,6 +2371,13 @@ class ChatFacadeService {
|
|
|
2334
2371
|
this.isGuestMode.set(true);
|
|
2335
2372
|
}
|
|
2336
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';
|
|
2380
|
+
}
|
|
2337
2381
|
// ============================================================================
|
|
2338
2382
|
// SESSION MANAGEMENT
|
|
2339
2383
|
// ============================================================================
|
|
@@ -2415,6 +2459,8 @@ class ChatFacadeService {
|
|
|
2415
2459
|
*/
|
|
2416
2460
|
clearMessageError() {
|
|
2417
2461
|
this.messageError.set(null);
|
|
2462
|
+
this.authError.set(null);
|
|
2463
|
+
this.authSuccess.set(null);
|
|
2418
2464
|
}
|
|
2419
2465
|
// ============================================================================
|
|
2420
2466
|
// AUTHENTICATION
|
|
@@ -2436,22 +2482,31 @@ class ChatFacadeService {
|
|
|
2436
2482
|
/**
|
|
2437
2483
|
* Authenticate user with credentials
|
|
2438
2484
|
*/
|
|
2439
|
-
async login(credentials) {
|
|
2485
|
+
async login(credentials, silent = false) {
|
|
2440
2486
|
this.isLoggingIn.set(true);
|
|
2441
|
-
|
|
2442
|
-
|
|
2487
|
+
if (!silent) {
|
|
2488
|
+
this.authError.set(null);
|
|
2489
|
+
this.authSuccess.set(null);
|
|
2490
|
+
}
|
|
2443
2491
|
try {
|
|
2444
2492
|
const response = await firstValueFrom(this.accountService.login(credentials));
|
|
2493
|
+
console.log('>>>>>>>>>>>Login response<<<<<<<<<<:', response);
|
|
2494
|
+
console.log('>>>>>>>>>>Credentials used<<<<<<<<:', credentials);
|
|
2445
2495
|
if (response && response.success) {
|
|
2496
|
+
console.log('Login response (success):', response);
|
|
2446
2497
|
this.isAuthenticated.set(true);
|
|
2447
2498
|
this.disableGuestMode(); // Ensure guest mode is off
|
|
2448
|
-
|
|
2499
|
+
if (!silent) {
|
|
2500
|
+
this.authSuccess.set('Login successful!');
|
|
2501
|
+
}
|
|
2449
2502
|
this.isLoggingIn.set(false);
|
|
2450
2503
|
return true;
|
|
2451
2504
|
}
|
|
2452
2505
|
else {
|
|
2453
2506
|
this.isAuthenticated.set(false);
|
|
2454
|
-
|
|
2507
|
+
if (!silent) {
|
|
2508
|
+
this.authError.set('Login failed. Please check your credentials.');
|
|
2509
|
+
}
|
|
2455
2510
|
this.isLoggingIn.set(false);
|
|
2456
2511
|
return false;
|
|
2457
2512
|
}
|
|
@@ -2459,7 +2514,9 @@ class ChatFacadeService {
|
|
|
2459
2514
|
catch (error) {
|
|
2460
2515
|
console.error('Login failed:', error);
|
|
2461
2516
|
this.isAuthenticated.set(false);
|
|
2462
|
-
|
|
2517
|
+
if (!silent) {
|
|
2518
|
+
this.authError.set('An error occurred during login.');
|
|
2519
|
+
}
|
|
2463
2520
|
this.isLoggingIn.set(false);
|
|
2464
2521
|
return false;
|
|
2465
2522
|
}
|
|
@@ -2470,6 +2527,59 @@ class ChatFacadeService {
|
|
|
2470
2527
|
checkAuthentication() {
|
|
2471
2528
|
return this.authService.isAuthenticated();
|
|
2472
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
|
+
}
|
|
2473
2583
|
// ============================================================================
|
|
2474
2584
|
// CONTEXT MANAGEMENT
|
|
2475
2585
|
// ============================================================================
|
|
@@ -2720,6 +2830,43 @@ const appEmoji = {
|
|
|
2720
2830
|
redHeart: '\u{2764}\u{FE0F}',
|
|
2721
2831
|
};
|
|
2722
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
|
+
|
|
2723
2870
|
class Doohbot extends DoohbotInput {
|
|
2724
2871
|
elementRef;
|
|
2725
2872
|
renderer;
|
|
@@ -2807,6 +2954,17 @@ class Doohbot extends DoohbotInput {
|
|
|
2807
2954
|
this.renderer.addClass(host, activeTheme);
|
|
2808
2955
|
this.themeService.applyCssVariables(host, this.themeConfig);
|
|
2809
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
|
+
});
|
|
2810
2968
|
}
|
|
2811
2969
|
// ============================================================================
|
|
2812
2970
|
// LIFECYCLE HOOKS
|
|
@@ -2820,7 +2978,7 @@ class Doohbot extends DoohbotInput {
|
|
|
2820
2978
|
this.uiState.closeChat();
|
|
2821
2979
|
// Close history sidebar when user is switched
|
|
2822
2980
|
this.uiState.closeHistorySidebar();
|
|
2823
|
-
this.performLogin();
|
|
2981
|
+
// this.performLogin();
|
|
2824
2982
|
// Load sessions for new user
|
|
2825
2983
|
this.loadUserSessions();
|
|
2826
2984
|
}
|
|
@@ -2867,10 +3025,11 @@ class Doohbot extends DoohbotInput {
|
|
|
2867
3025
|
username: this.config.username || AppConst.data?.username,
|
|
2868
3026
|
password: this.config.password || AppConst.data?.password,
|
|
2869
3027
|
};
|
|
2870
|
-
|
|
3028
|
+
console.log('performLogin:', credentials.username, credentials.password);
|
|
3029
|
+
this.chatFacade.login(credentials, true);
|
|
2871
3030
|
}
|
|
2872
3031
|
performLoginWithCredentials(credentials) {
|
|
2873
|
-
this.chatFacade.login(credentials);
|
|
3032
|
+
this.chatFacade.login(credentials, false);
|
|
2874
3033
|
}
|
|
2875
3034
|
continueAsGuest() {
|
|
2876
3035
|
this.chatFacade.enableGuestMode();
|
|
@@ -2878,6 +3037,9 @@ class Doohbot extends DoohbotInput {
|
|
|
2878
3037
|
disableGuestMode() {
|
|
2879
3038
|
this.chatFacade.disableGuestMode();
|
|
2880
3039
|
}
|
|
3040
|
+
performLogout() {
|
|
3041
|
+
this.chatFacade.logout();
|
|
3042
|
+
}
|
|
2881
3043
|
// ============================================================================
|
|
2882
3044
|
// CHAT OPERATIONS
|
|
2883
3045
|
// ============================================================================
|
|
@@ -2932,27 +3094,11 @@ class Doohbot extends DoohbotInput {
|
|
|
2932
3094
|
return item.id || index.toString();
|
|
2933
3095
|
}
|
|
2934
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 });
|
|
2935
|
-
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" },
|
|
2936
|
-
AppConst,
|
|
2937
|
-
{
|
|
2938
|
-
provide: APP_INITIALIZER,
|
|
2939
|
-
useFactory: (appConst) => () => appConst.load(),
|
|
2940
|
-
deps: [AppConst],
|
|
2941
|
-
multi: true,
|
|
2942
|
-
},
|
|
2943
|
-
], 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></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"] }, { 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 });
|
|
2944
3098
|
}
|
|
2945
3099
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: Doohbot, decorators: [{
|
|
2946
3100
|
type: Component,
|
|
2947
|
-
args: [{ selector: 'app-doohbot', standalone: true, imports: [CommonModule, ChatButtonComponent, ChatWindowComponent, FullscreenDirective], changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2948
|
-
AppConst,
|
|
2949
|
-
{
|
|
2950
|
-
provide: APP_INITIALIZER,
|
|
2951
|
-
useFactory: (appConst) => () => appConst.load(),
|
|
2952
|
-
deps: [AppConst],
|
|
2953
|
-
multi: true,
|
|
2954
|
-
},
|
|
2955
|
-
], 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></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"] }]
|
|
2956
3102
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { config: [{
|
|
2957
3103
|
type: Input
|
|
2958
3104
|
}], platformTenant: [{
|
|
@@ -2980,6 +3126,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
2980
3126
|
type: ViewChild,
|
|
2981
3127
|
args: [FullscreenDirective]
|
|
2982
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
|
+
});
|
|
2983
3148
|
|
|
2984
3149
|
const DOOHBOT_API_URL = new InjectionToken('DOOHBOT_API_URL');
|
|
2985
3150
|
|
|
@@ -2992,5 +3157,5 @@ const DOOHBOT_API_URL = new InjectionToken('DOOHBOT_API_URL');
|
|
|
2992
3157
|
* Generated bundle index. Do not edit.
|
|
2993
3158
|
*/
|
|
2994
3159
|
|
|
2995
|
-
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 };
|
|
2996
3161
|
//# sourceMappingURL=aakash58-chatbot.mjs.map
|