@aslaluroba/help-center 1.1.4 → 1.1.6
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/aslaluroba-help-center.mjs +1421 -0
- package/fesm2022/aslaluroba-help-center.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/tailwind.css +1 -0
- package/package.json +15 -31
- package/public_api.d.ts +8 -0
- package/src/app/chat/chat.component.d.ts +39 -0
- package/src/app/help-center-widget/help-center-widget.component.d.ts +106 -0
- package/src/app/help-screen-data/help-screen-data.component.d.ts +52 -0
- package/src/app/pipes/translate.pipe.d.ts +11 -0
- package/src/app/services/api.service.d.ts +11 -0
- package/src/app/services/signalrService.service.d.ts +13 -0
- package/src/app/services/token.service.d.ts +12 -0
- package/src/app/services/translation.service.d.ts +32 -0
- package/src/app/shared/components/button/button.component.d.ts +34 -0
- package/src/app/shared/components/button/index.d.ts +1 -0
- package/src/app/shared/components/card/card.component.d.ts +38 -0
- package/src/app/shared/components/card/index.d.ts +1 -0
- package/src/app/shared/components/confirmation-dialog/confirmation-dialog.component.d.ts +12 -0
- package/src/app/shared/components/header/header.component.d.ts +29 -0
- package/src/app/shared/components/header/index.d.ts +1 -0
- package/src/app/shared/components/loading/loading.component.d.ts +5 -0
- package/src/app/shared/utils/class-utils.d.ts +5 -0
- package/src/app/styles/styles.module.d.ts +8 -0
- package/src/app/types/index.d.ts +1 -0
- package/.editorconfig +0 -17
- package/angular.json +0 -106
- package/generate-styles.js +0 -19
- package/ng-package.json +0 -47
- package/package-lock.json +0 -16479
- package/postcss.config.js +0 -6
- package/proxy.conf.json +0 -4
- package/public/Shape.png +0 -0
- package/public/favicon.ico +0 -0
- package/public_api.ts +0 -14
- package/src/app/app.component.ts +0 -59
- package/src/app/app.config.ts +0 -23
- package/src/app/app.routes.ts +0 -3
- package/src/app/chat/chat.component.html +0 -102
- package/src/app/chat/chat.component.ts +0 -88
- package/src/app/help-center-widget/help-center-widget.component.html +0 -220
- package/src/app/help-center-widget/help-center-widget.component.scss +0 -427
- package/src/app/help-center-widget/help-center-widget.component.spec.ts +0 -23
- package/src/app/help-center-widget/help-center-widget.component.ts +0 -460
- package/src/app/help-center-widget/help-center.module.ts +0 -18
- package/src/app/help-screen-data/help-screen-data.component.html +0 -48
- package/src/app/help-screen-data/help-screen-data.component.ts +0 -81
- package/src/app/language.service.ts +0 -19
- package/src/app/pipes/translate.pipe.ts +0 -16
- package/src/app/services/api.service.ts +0 -89
- package/src/app/services/help-center-config.service.ts +0 -16
- package/src/app/services/signalrService.service.ts +0 -104
- package/src/app/services/token.service.ts +0 -44
- package/src/app/services/translation.service.ts +0 -86
- package/src/app/shared/components/button/button.component.ts +0 -80
- package/src/app/shared/components/button/index.ts +0 -1
- package/src/app/shared/components/card/card.component.ts +0 -106
- package/src/app/shared/components/card/index.ts +0 -1
- package/src/app/shared/components/confirmation-dialog/confirmation-dialog.component.ts +0 -39
- package/src/app/shared/components/header/header.component.ts +0 -118
- package/src/app/shared/components/header/index.ts +0 -1
- package/src/app/shared/components/loading/loading.component.ts +0 -14
- package/src/app/shared/utils/class-utils.ts +0 -9
- package/src/app/types/index.ts +0 -1
- package/src/index.html +0 -13
- package/src/lib/tailwind.css +0 -1
- package/src/main.ts +0 -5
- package/src/styles.css +0 -8
- package/src/styles.scss +0 -38
- package/tailwind.config.ts +0 -175
- package/tsconfig.app.json +0 -15
- package/tsconfig.json +0 -33
- package/tsconfig.spec.json +0 -15
- /package/{src/assets → assets}/i18n/ar.json +0 -0
- /package/{src/assets → assets}/i18n/en.json +0 -0
- /package/{src/assets → assets}/icons/arrow-stripped-colored.svg +0 -0
- /package/{src/assets → assets}/icons/arrow-stripped.svg +0 -0
- /package/{src/assets → assets}/icons/chat.svg +0 -0
- /package/{src/assets → assets}/icons/close-circle.svg +0 -0
- /package/{src/assets → assets}/icons/menu.svg +0 -0
- /package/{src/assets → assets}/icons/person.svg +0 -0
- /package/{src/assets → assets}/icons/send.svg +0 -0
- /package/{src/assets → assets}/images/animatedLogo.gif +0 -0
- /package/{src/assets → assets}/images/seperator.svg +0 -0
- /package/{src/assets → assets}/images/stars.svg +0 -0
- /package/{src/assets → assets}/logo-primary.svg +0 -0
- /package/{src/assets → assets}/logo-white.svg +0 -0
|
@@ -0,0 +1,1421 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { HostBinding, Input, ViewEncapsulation, Component, EventEmitter, Output, Injectable, Pipe, HostListener, ViewChild, NgModule } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as i2 from '@angular/forms';
|
|
6
|
+
import { FormsModule } from '@angular/forms';
|
|
7
|
+
import { clsx } from 'clsx';
|
|
8
|
+
import { twMerge } from 'tailwind-merge';
|
|
9
|
+
import { BehaviorSubject } from 'rxjs';
|
|
10
|
+
import { MarkdownComponent } from 'ngx-markdown';
|
|
11
|
+
import 'prismjs';
|
|
12
|
+
import 'prismjs/components/prism-typescript';
|
|
13
|
+
import 'prismjs/components/prism-javascript';
|
|
14
|
+
import 'prismjs/components/prism-css';
|
|
15
|
+
import 'prismjs/components/prism-json';
|
|
16
|
+
import 'prismjs/components/prism-markdown';
|
|
17
|
+
import 'prismjs/themes/prism-okaidia.css';
|
|
18
|
+
import * as signalR from '@microsoft/signalr';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Utility function to conditionally join CSS class names
|
|
22
|
+
*/
|
|
23
|
+
function cn(...inputs) {
|
|
24
|
+
return twMerge(clsx(inputs));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class CardComponent {
|
|
28
|
+
variant = 'default';
|
|
29
|
+
class = '';
|
|
30
|
+
get hostClasses() {
|
|
31
|
+
const variantStyles = {
|
|
32
|
+
default: 'babylai-rounded-xl babylai-border babylai-bg-card babylai-text-card-foreground babylai-shadow',
|
|
33
|
+
rounded: 'babylai-rounded-3xl babylai-bg-black-white-50 babylai-py-4 babylai-px-[24px] babylai-w-full babylai-block',
|
|
34
|
+
shadowed: 'babylai-rounded-xl babylai-border babylai-bg-card babylai-text-card-foreground babylai-shadow-lg'
|
|
35
|
+
};
|
|
36
|
+
return cn(variantStyles[this.variant], this.class);
|
|
37
|
+
}
|
|
38
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
39
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: CardComponent, isStandalone: true, selector: "app-card", inputs: { variant: "variant", class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
40
|
+
}
|
|
41
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardComponent, decorators: [{
|
|
42
|
+
type: Component,
|
|
43
|
+
args: [{
|
|
44
|
+
selector: 'app-card',
|
|
45
|
+
standalone: true,
|
|
46
|
+
imports: [CommonModule],
|
|
47
|
+
template: `<ng-content></ng-content>`,
|
|
48
|
+
encapsulation: ViewEncapsulation.None
|
|
49
|
+
}]
|
|
50
|
+
}], propDecorators: { variant: [{
|
|
51
|
+
type: Input
|
|
52
|
+
}], class: [{
|
|
53
|
+
type: Input
|
|
54
|
+
}], hostClasses: [{
|
|
55
|
+
type: HostBinding,
|
|
56
|
+
args: ['class']
|
|
57
|
+
}] } });
|
|
58
|
+
class CardHeaderComponent {
|
|
59
|
+
class = '';
|
|
60
|
+
get hostClasses() {
|
|
61
|
+
return cn('babylai-flex babylai-flex-col babylai-space-y-1.5 babylai-p-6', this.class);
|
|
62
|
+
}
|
|
63
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
64
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: CardHeaderComponent, isStandalone: true, selector: "app-card-header", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
65
|
+
}
|
|
66
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardHeaderComponent, decorators: [{
|
|
67
|
+
type: Component,
|
|
68
|
+
args: [{
|
|
69
|
+
selector: 'app-card-header',
|
|
70
|
+
standalone: true,
|
|
71
|
+
imports: [CommonModule],
|
|
72
|
+
template: `<ng-content></ng-content>`,
|
|
73
|
+
encapsulation: ViewEncapsulation.None
|
|
74
|
+
}]
|
|
75
|
+
}], propDecorators: { class: [{
|
|
76
|
+
type: Input
|
|
77
|
+
}], hostClasses: [{
|
|
78
|
+
type: HostBinding,
|
|
79
|
+
args: ['class']
|
|
80
|
+
}] } });
|
|
81
|
+
class CardTitleComponent {
|
|
82
|
+
class = '';
|
|
83
|
+
get hostClasses() {
|
|
84
|
+
return cn('babylai-font-semibold babylai-leading-none babylai-tracking-tight', this.class);
|
|
85
|
+
}
|
|
86
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
87
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: CardTitleComponent, isStandalone: true, selector: "app-card-title", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
88
|
+
}
|
|
89
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardTitleComponent, decorators: [{
|
|
90
|
+
type: Component,
|
|
91
|
+
args: [{
|
|
92
|
+
selector: 'app-card-title',
|
|
93
|
+
standalone: true,
|
|
94
|
+
imports: [CommonModule],
|
|
95
|
+
template: `<ng-content></ng-content>`,
|
|
96
|
+
encapsulation: ViewEncapsulation.None
|
|
97
|
+
}]
|
|
98
|
+
}], propDecorators: { class: [{
|
|
99
|
+
type: Input
|
|
100
|
+
}], hostClasses: [{
|
|
101
|
+
type: HostBinding,
|
|
102
|
+
args: ['class']
|
|
103
|
+
}] } });
|
|
104
|
+
class CardDescriptionComponent {
|
|
105
|
+
class = '';
|
|
106
|
+
get hostClasses() {
|
|
107
|
+
return cn('babylai-text-sm babylai-text-muted-foreground', this.class);
|
|
108
|
+
}
|
|
109
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardDescriptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
110
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: CardDescriptionComponent, isStandalone: true, selector: "app-card-description", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
111
|
+
}
|
|
112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardDescriptionComponent, decorators: [{
|
|
113
|
+
type: Component,
|
|
114
|
+
args: [{
|
|
115
|
+
selector: 'app-card-description',
|
|
116
|
+
standalone: true,
|
|
117
|
+
imports: [CommonModule],
|
|
118
|
+
template: `<ng-content></ng-content>`,
|
|
119
|
+
encapsulation: ViewEncapsulation.None
|
|
120
|
+
}]
|
|
121
|
+
}], propDecorators: { class: [{
|
|
122
|
+
type: Input
|
|
123
|
+
}], hostClasses: [{
|
|
124
|
+
type: HostBinding,
|
|
125
|
+
args: ['class']
|
|
126
|
+
}] } });
|
|
127
|
+
class CardContentComponent {
|
|
128
|
+
class = '';
|
|
129
|
+
get hostClasses() {
|
|
130
|
+
return cn('babylai-p-0 babylai-pt-0', this.class);
|
|
131
|
+
}
|
|
132
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
133
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: CardContentComponent, isStandalone: true, selector: "app-card-content", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
134
|
+
}
|
|
135
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardContentComponent, decorators: [{
|
|
136
|
+
type: Component,
|
|
137
|
+
args: [{
|
|
138
|
+
selector: 'app-card-content',
|
|
139
|
+
standalone: true,
|
|
140
|
+
imports: [CommonModule],
|
|
141
|
+
template: `<ng-content></ng-content>`,
|
|
142
|
+
encapsulation: ViewEncapsulation.None
|
|
143
|
+
}]
|
|
144
|
+
}], propDecorators: { class: [{
|
|
145
|
+
type: Input
|
|
146
|
+
}], hostClasses: [{
|
|
147
|
+
type: HostBinding,
|
|
148
|
+
args: ['class']
|
|
149
|
+
}] } });
|
|
150
|
+
class CardFooterComponent {
|
|
151
|
+
class = '';
|
|
152
|
+
get hostClasses() {
|
|
153
|
+
return cn('babylai-flex babylai-items-center babylai-p-6 babylai-pt-0', this.class);
|
|
154
|
+
}
|
|
155
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
156
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: CardFooterComponent, isStandalone: true, selector: "app-card-footer", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
157
|
+
}
|
|
158
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: CardFooterComponent, decorators: [{
|
|
159
|
+
type: Component,
|
|
160
|
+
args: [{
|
|
161
|
+
selector: 'app-card-footer',
|
|
162
|
+
standalone: true,
|
|
163
|
+
imports: [CommonModule],
|
|
164
|
+
template: `<ng-content></ng-content>`,
|
|
165
|
+
encapsulation: ViewEncapsulation.None
|
|
166
|
+
}]
|
|
167
|
+
}], propDecorators: { class: [{
|
|
168
|
+
type: Input
|
|
169
|
+
}], hostClasses: [{
|
|
170
|
+
type: HostBinding,
|
|
171
|
+
args: ['class']
|
|
172
|
+
}] } });
|
|
173
|
+
|
|
174
|
+
class ButtonComponent {
|
|
175
|
+
variant = 'default';
|
|
176
|
+
type = 'button';
|
|
177
|
+
disabled = false;
|
|
178
|
+
fullWidth = false;
|
|
179
|
+
className = '';
|
|
180
|
+
onClick = new EventEmitter();
|
|
181
|
+
getButtonClasses() {
|
|
182
|
+
const baseClasses = 'babylai-cursor-pointer babylai-transition-all babylai-duration-200 ';
|
|
183
|
+
const variantClasses = {
|
|
184
|
+
default: 'babylai-bg-primary babylai-text-white babylai-py-2 babylai-px-4 babylai-rounded-full hover:babylai-bg-primary-700',
|
|
185
|
+
'icon-bg': 'babylai-bg-primary babylai-text-white babylai-py-2 babylai-px-4 babylai-rounded-full babylai-w-12 babylai-h-12 babylai-flex babylai-items-center babylai-justify-center hover:babylai-bg-primary-700',
|
|
186
|
+
'icon-only': 'babylai-bg-transparent babylai-border-none babylai-p-1 babylai-flex babylai-items-center babylai-justify-center'
|
|
187
|
+
};
|
|
188
|
+
const widthClass = this.fullWidth ? 'babylai-w-full' : '';
|
|
189
|
+
const disabledClass = this.disabled ? 'babylai-opacity-50 babylai-cursor-not-allowed' : '';
|
|
190
|
+
return `${baseClasses} ${variantClasses[this.variant]} ${widthClass} ${disabledClass} ${this.className}`;
|
|
191
|
+
}
|
|
192
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
193
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: ButtonComponent, isStandalone: true, selector: "app-button", inputs: { variant: "variant", type: "type", disabled: "disabled", fullWidth: "fullWidth", className: "className" }, outputs: { onClick: "onClick" }, ngImport: i0, template: `
|
|
194
|
+
<button [type]="type" [disabled]="disabled" [ngClass]="getButtonClasses()" (click)="onClick.emit($event)">
|
|
195
|
+
<ng-content></ng-content>
|
|
196
|
+
</button>
|
|
197
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
198
|
+
}
|
|
199
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
200
|
+
type: Component,
|
|
201
|
+
args: [{
|
|
202
|
+
selector: 'app-button',
|
|
203
|
+
standalone: true,
|
|
204
|
+
imports: [CommonModule],
|
|
205
|
+
template: `
|
|
206
|
+
<button [type]="type" [disabled]="disabled" [ngClass]="getButtonClasses()" (click)="onClick.emit($event)">
|
|
207
|
+
<ng-content></ng-content>
|
|
208
|
+
</button>
|
|
209
|
+
`
|
|
210
|
+
}]
|
|
211
|
+
}], propDecorators: { variant: [{
|
|
212
|
+
type: Input
|
|
213
|
+
}], type: [{
|
|
214
|
+
type: Input
|
|
215
|
+
}], disabled: [{
|
|
216
|
+
type: Input
|
|
217
|
+
}], fullWidth: [{
|
|
218
|
+
type: Input
|
|
219
|
+
}], className: [{
|
|
220
|
+
type: Input
|
|
221
|
+
}], onClick: [{
|
|
222
|
+
type: Output
|
|
223
|
+
}] } });
|
|
224
|
+
class ButtonContentComponent {
|
|
225
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ButtonContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
226
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: ButtonContentComponent, isStandalone: true, selector: "app-button-content", ngImport: i0, template: ` <ng-content></ng-content> `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
227
|
+
}
|
|
228
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ButtonContentComponent, decorators: [{
|
|
229
|
+
type: Component,
|
|
230
|
+
args: [{
|
|
231
|
+
selector: 'app-button-content',
|
|
232
|
+
standalone: true,
|
|
233
|
+
imports: [CommonModule],
|
|
234
|
+
template: ` <ng-content></ng-content> `
|
|
235
|
+
}]
|
|
236
|
+
}] });
|
|
237
|
+
class IconButtonComponent {
|
|
238
|
+
className = '';
|
|
239
|
+
disabled = false;
|
|
240
|
+
onClick = new EventEmitter();
|
|
241
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: IconButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
242
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: IconButtonComponent, isStandalone: true, selector: "app-icon-button", inputs: { className: "className", disabled: "disabled" }, outputs: { onClick: "onClick" }, ngImport: i0, template: `
|
|
243
|
+
<app-button [variant]="'icon-bg'" [className]="className" [disabled]="disabled" (onClick)="onClick.emit($event)">
|
|
244
|
+
<ng-content></ng-content>
|
|
245
|
+
</app-button>
|
|
246
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }] });
|
|
247
|
+
}
|
|
248
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: IconButtonComponent, decorators: [{
|
|
249
|
+
type: Component,
|
|
250
|
+
args: [{
|
|
251
|
+
selector: 'app-icon-button',
|
|
252
|
+
standalone: true,
|
|
253
|
+
imports: [CommonModule, ButtonComponent],
|
|
254
|
+
template: `
|
|
255
|
+
<app-button [variant]="'icon-bg'" [className]="className" [disabled]="disabled" (onClick)="onClick.emit($event)">
|
|
256
|
+
<ng-content></ng-content>
|
|
257
|
+
</app-button>
|
|
258
|
+
`
|
|
259
|
+
}]
|
|
260
|
+
}], propDecorators: { className: [{
|
|
261
|
+
type: Input
|
|
262
|
+
}], disabled: [{
|
|
263
|
+
type: Input
|
|
264
|
+
}], onClick: [{
|
|
265
|
+
type: Output
|
|
266
|
+
}] } });
|
|
267
|
+
class TransparentIconButtonComponent {
|
|
268
|
+
className = '';
|
|
269
|
+
disabled = false;
|
|
270
|
+
onClick = new EventEmitter();
|
|
271
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TransparentIconButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
272
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: TransparentIconButtonComponent, isStandalone: true, selector: "app-transparent-icon-button", inputs: { className: "className", disabled: "disabled" }, outputs: { onClick: "onClick" }, ngImport: i0, template: `
|
|
273
|
+
<app-button [variant]="'icon-only'" [className]="className" [disabled]="disabled" (onClick)="onClick.emit($event)">
|
|
274
|
+
<ng-content></ng-content>
|
|
275
|
+
</app-button>
|
|
276
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }] });
|
|
277
|
+
}
|
|
278
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TransparentIconButtonComponent, decorators: [{
|
|
279
|
+
type: Component,
|
|
280
|
+
args: [{
|
|
281
|
+
selector: 'app-transparent-icon-button',
|
|
282
|
+
standalone: true,
|
|
283
|
+
imports: [CommonModule, ButtonComponent],
|
|
284
|
+
template: `
|
|
285
|
+
<app-button [variant]="'icon-only'" [className]="className" [disabled]="disabled" (onClick)="onClick.emit($event)">
|
|
286
|
+
<ng-content></ng-content>
|
|
287
|
+
</app-button>
|
|
288
|
+
`
|
|
289
|
+
}]
|
|
290
|
+
}], propDecorators: { className: [{
|
|
291
|
+
type: Input
|
|
292
|
+
}], disabled: [{
|
|
293
|
+
type: Input
|
|
294
|
+
}], onClick: [{
|
|
295
|
+
type: Output
|
|
296
|
+
}] } });
|
|
297
|
+
|
|
298
|
+
// src/app/services/translation.service.ts
|
|
299
|
+
const defaultTranslations = {
|
|
300
|
+
ChatIntroMessage: '',
|
|
301
|
+
BabylaiTitle: '',
|
|
302
|
+
BabylaiDescription: '',
|
|
303
|
+
ChatNow: '',
|
|
304
|
+
TryBableAI: '',
|
|
305
|
+
ContactUs: '',
|
|
306
|
+
PickTopicTitle: '',
|
|
307
|
+
BabylAI: '',
|
|
308
|
+
ChatPlaceholder: '',
|
|
309
|
+
PoweredByBabylAI: '',
|
|
310
|
+
EndChat: '',
|
|
311
|
+
LeavingDialogTitle: '',
|
|
312
|
+
LeavingDialogBody: '',
|
|
313
|
+
Confirm: '',
|
|
314
|
+
Cancel: '',
|
|
315
|
+
title: ''
|
|
316
|
+
};
|
|
317
|
+
class TranslationService {
|
|
318
|
+
translations = {
|
|
319
|
+
en: {
|
|
320
|
+
ChatIntroMessage: 'Chat with BabylAI 🚀',
|
|
321
|
+
BabylaiTitle: 'BabylAI',
|
|
322
|
+
BabylaiDescription: "Hey there! 👋 I'm BabylAI, here to assist you.",
|
|
323
|
+
ChatNow: 'Chat Now',
|
|
324
|
+
TryBableAI: 'Try BabylAI for Free 🎉',
|
|
325
|
+
ContactUs: "Contact us, Let's Talk! 💬",
|
|
326
|
+
PickTopicTitle: 'Pick a Topic to Get Started',
|
|
327
|
+
BabylAI: 'BabylAI',
|
|
328
|
+
ChatPlaceholder: 'Type your message...',
|
|
329
|
+
PoweredByBabylAI: 'Powered by BabylAI',
|
|
330
|
+
EndChat: 'End Chat',
|
|
331
|
+
LeavingDialogTitle: 'Leaving so soon? 👋',
|
|
332
|
+
LeavingDialogBody: "Don't worry, you can come back anytime. We're always here if you need help or have questions.",
|
|
333
|
+
Confirm: 'Confirm',
|
|
334
|
+
Cancel: 'Cancel',
|
|
335
|
+
title: 'Help Center'
|
|
336
|
+
},
|
|
337
|
+
ar: {
|
|
338
|
+
ChatIntroMessage: 'دردش مع BabylAI 🚀',
|
|
339
|
+
BabylaiTitle: 'BabylAI',
|
|
340
|
+
BabylaiDescription: 'مرحبا! 👋 أنا BabylAI، هنا لتساعدك.',
|
|
341
|
+
ChatNow: 'دردش الآن',
|
|
342
|
+
TryBableAI: 'جرب BabylAI مجانا 🎉',
|
|
343
|
+
ContactUs: 'تواصل معنا, دعنا نتحدث! 💬',
|
|
344
|
+
PickTopicTitle: 'اختر موضوع للبدء',
|
|
345
|
+
BabylAI: 'BabylAI',
|
|
346
|
+
ChatPlaceholder: 'اكتب رسالتك...',
|
|
347
|
+
PoweredByBabylAI: 'مدعوم من BabylAI',
|
|
348
|
+
EndChat: 'إنهاء الدردشة',
|
|
349
|
+
LeavingDialogTitle: 'هل تغادر بالفعل؟ 👋',
|
|
350
|
+
LeavingDialogBody: 'لا تقلق، يمكنك العودة في أي وقت. نحن دائماً هنا إذا كنت بحاجة إلى مساعدة أو لديك أسئلة.',
|
|
351
|
+
Confirm: 'تأكيد',
|
|
352
|
+
Cancel: 'إلغاء',
|
|
353
|
+
title: 'مركز المساعدة'
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
currentLang = new BehaviorSubject('en');
|
|
357
|
+
constructor() { }
|
|
358
|
+
translate(key) {
|
|
359
|
+
const lang = this.currentLang.value;
|
|
360
|
+
return this.translations[lang][key] || key;
|
|
361
|
+
}
|
|
362
|
+
setLanguage(lang) {
|
|
363
|
+
this.currentLang.next(lang);
|
|
364
|
+
}
|
|
365
|
+
getCurrentLang() {
|
|
366
|
+
return this.currentLang.value;
|
|
367
|
+
}
|
|
368
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TranslationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
369
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TranslationService, providedIn: 'root' });
|
|
370
|
+
}
|
|
371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TranslationService, decorators: [{
|
|
372
|
+
type: Injectable,
|
|
373
|
+
args: [{
|
|
374
|
+
providedIn: 'root'
|
|
375
|
+
}]
|
|
376
|
+
}], ctorParameters: () => [] });
|
|
377
|
+
|
|
378
|
+
// src/app/pipes/translate.pipe.ts
|
|
379
|
+
class TranslatePipe {
|
|
380
|
+
translationService;
|
|
381
|
+
constructor(translationService) {
|
|
382
|
+
this.translationService = translationService;
|
|
383
|
+
}
|
|
384
|
+
transform(key) {
|
|
385
|
+
return this.translationService.translate(key);
|
|
386
|
+
}
|
|
387
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TranslatePipe, deps: [{ token: TranslationService }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
388
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.11", ngImport: i0, type: TranslatePipe, isStandalone: true, name: "translate" });
|
|
389
|
+
}
|
|
390
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TranslatePipe, decorators: [{
|
|
391
|
+
type: Pipe,
|
|
392
|
+
args: [{
|
|
393
|
+
name: 'translate',
|
|
394
|
+
standalone: true
|
|
395
|
+
}]
|
|
396
|
+
}], ctorParameters: () => [{ type: TranslationService }] });
|
|
397
|
+
|
|
398
|
+
class HelpScreenDataComponent {
|
|
399
|
+
helpScreenData = null;
|
|
400
|
+
title = '';
|
|
401
|
+
handleStartNewChat = new EventEmitter();
|
|
402
|
+
expandedItemId = null;
|
|
403
|
+
ngOnInit() { }
|
|
404
|
+
toggleExpand(itemId) {
|
|
405
|
+
if (this.expandedItemId === itemId) {
|
|
406
|
+
this.expandedItemId = null;
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
this.expandedItemId = itemId;
|
|
410
|
+
setTimeout(() => {
|
|
411
|
+
const element = document.getElementById(itemId);
|
|
412
|
+
if (element) {
|
|
413
|
+
element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
414
|
+
}
|
|
415
|
+
}, 100);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
startNewChat(option) {
|
|
419
|
+
this.handleStartNewChat.emit(option);
|
|
420
|
+
}
|
|
421
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: HelpScreenDataComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
422
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: HelpScreenDataComponent, isStandalone: true, selector: "app-help-screen-data", inputs: { helpScreenData: "helpScreenData", title: "title" }, outputs: { handleStartNewChat: "handleStartNewChat" }, ngImport: i0, template: "<div class=\"babylai-flex babylai-flex-col babylai-gap-4\">\n <h1 class=\"babylai-text-4xl babylai-font-bold babylai-text-black-white-600 babylai-mb-3 babylai-max-w-56\">\n {{ 'PickTopicTitle' | translate }}\n </h1>\n <img\n src=\"/images/stars.svg\"\n alt=\"help-center-widget-icon\"\n class=\"babylai-absolute babylai-top-0 babylai-end-0 babylai-w-[15.42rem] babylai-h-[13.49rem] babylai-opacity-50 babylai-z-[-1]\"\n />\n <ng-container *ngFor=\"let item of helpScreenData?.options\">\n <app-card\n [id]=\"item.id\"\n variant=\"rounded\"\n class=\"babylai-cursor-pointer babylai-transition-all babylai-hover:babylai-shadow-md !babylai-px-2 !babylai-py-2 babylai-bg-black-white-100\"\n (click)=\"toggleExpand(item.id)\"\n >\n <app-card-content>\n <!-- Header section (always visible) -->\n <div class=\"babylai-flex babylai-items-center babylai-justify-between babylai-p-2\">\n <h4 class=\"babylai-text-base babylai-text-black-white-400 babylai-font-semibold\">{{ item.title }}</h4>\n <div\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-8 babylai-h-8 babylai-rounded-full babylai-text-primary babylai-transition-transform\"\n [ngClass]=\"{\n 'babylai-rotate-90': expandedItemId === item.id,\n 'babylai-rotate-[270deg]': expandedItemId !== item.id\n }\"\n >\n <img src=\"/icons/arrow-stripped-colored.svg\" alt=\"arrow-down\" class=\"babylai-w-4 babylai-h-4\" />\n </div>\n </div>\n\n <!-- Expanded content (visible only when expanded) -->\n <div\n *ngIf=\"expandedItemId === item.id\"\n class=\"babylai-transition-all babylai-duration-300 babylai-ease-in-out babylai-flex babylai-flex-col babylai-gap-2 babylai-mt-4 babylai-p-2\"\n >\n <ng-container>\n <div *ngFor=\"let paragraph of item.paragraphs\" class=\"babylai-text-base babylai-text-black-white-800 babylai-mb-2\">\n {{ paragraph }}\n </div>\n </ng-container>\n\n <app-button variant=\"default\" className=\"babylai-w-full\" (click)=\"startNewChat(item)\">{{ 'ChatNow' | translate }} </app-button>\n </div>\n </app-card-content>\n </app-card>\n </ng-container>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CardComponent, selector: "app-card", inputs: ["variant", "class"] }, { kind: "component", type: CardContentComponent, selector: "app-card-content", inputs: ["class"] }, { kind: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
423
|
+
}
|
|
424
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: HelpScreenDataComponent, decorators: [{
|
|
425
|
+
type: Component,
|
|
426
|
+
args: [{ selector: 'app-help-screen-data', standalone: true, imports: [CommonModule, CardComponent, CardContentComponent, ButtonComponent, TranslatePipe], template: "<div class=\"babylai-flex babylai-flex-col babylai-gap-4\">\n <h1 class=\"babylai-text-4xl babylai-font-bold babylai-text-black-white-600 babylai-mb-3 babylai-max-w-56\">\n {{ 'PickTopicTitle' | translate }}\n </h1>\n <img\n src=\"/images/stars.svg\"\n alt=\"help-center-widget-icon\"\n class=\"babylai-absolute babylai-top-0 babylai-end-0 babylai-w-[15.42rem] babylai-h-[13.49rem] babylai-opacity-50 babylai-z-[-1]\"\n />\n <ng-container *ngFor=\"let item of helpScreenData?.options\">\n <app-card\n [id]=\"item.id\"\n variant=\"rounded\"\n class=\"babylai-cursor-pointer babylai-transition-all babylai-hover:babylai-shadow-md !babylai-px-2 !babylai-py-2 babylai-bg-black-white-100\"\n (click)=\"toggleExpand(item.id)\"\n >\n <app-card-content>\n <!-- Header section (always visible) -->\n <div class=\"babylai-flex babylai-items-center babylai-justify-between babylai-p-2\">\n <h4 class=\"babylai-text-base babylai-text-black-white-400 babylai-font-semibold\">{{ item.title }}</h4>\n <div\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-8 babylai-h-8 babylai-rounded-full babylai-text-primary babylai-transition-transform\"\n [ngClass]=\"{\n 'babylai-rotate-90': expandedItemId === item.id,\n 'babylai-rotate-[270deg]': expandedItemId !== item.id\n }\"\n >\n <img src=\"/icons/arrow-stripped-colored.svg\" alt=\"arrow-down\" class=\"babylai-w-4 babylai-h-4\" />\n </div>\n </div>\n\n <!-- Expanded content (visible only when expanded) -->\n <div\n *ngIf=\"expandedItemId === item.id\"\n class=\"babylai-transition-all babylai-duration-300 babylai-ease-in-out babylai-flex babylai-flex-col babylai-gap-2 babylai-mt-4 babylai-p-2\"\n >\n <ng-container>\n <div *ngFor=\"let paragraph of item.paragraphs\" class=\"babylai-text-base babylai-text-black-white-800 babylai-mb-2\">\n {{ paragraph }}\n </div>\n </ng-container>\n\n <app-button variant=\"default\" className=\"babylai-w-full\" (click)=\"startNewChat(item)\">{{ 'ChatNow' | translate }} </app-button>\n </div>\n </app-card-content>\n </app-card>\n </ng-container>\n</div>\n" }]
|
|
427
|
+
}], propDecorators: { helpScreenData: [{
|
|
428
|
+
type: Input
|
|
429
|
+
}], title: [{
|
|
430
|
+
type: Input
|
|
431
|
+
}], handleStartNewChat: [{
|
|
432
|
+
type: Output
|
|
433
|
+
}] } });
|
|
434
|
+
|
|
435
|
+
class HeaderComponent {
|
|
436
|
+
headerType = 'standard';
|
|
437
|
+
showBackButton = false;
|
|
438
|
+
showLogo = true;
|
|
439
|
+
logoSrc = '/logo-white.svg';
|
|
440
|
+
logoAlt = 'BabylAI Logo';
|
|
441
|
+
language = 'en';
|
|
442
|
+
onBack = new EventEmitter();
|
|
443
|
+
onClose = new EventEmitter();
|
|
444
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
445
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: HeaderComponent, isStandalone: true, selector: "app-header", inputs: { headerType: "headerType", showBackButton: "showBackButton", showLogo: "showLogo", logoSrc: "logoSrc", logoAlt: "logoAlt", language: "language" }, outputs: { onBack: "onBack", onClose: "onClose" }, ngImport: i0, template: `
|
|
446
|
+
<div class="babylai-p-4 babylai-flex babylai-items-center babylai-justify-between">
|
|
447
|
+
<app-button *ngIf="showBackButton" variant="icon-bg" className="!babylai-bg-black-white-50" (click)="onBack.emit()">
|
|
448
|
+
<img
|
|
449
|
+
src="/icons/arrow-stripped-colored.svg"
|
|
450
|
+
alt="Back"
|
|
451
|
+
class="babylai-w-6 babylai-h-6"
|
|
452
|
+
[ngClass]="{ 'babylai-rotate-180': language === 'ar' }"
|
|
453
|
+
/>
|
|
454
|
+
</app-button>
|
|
455
|
+
<img *ngIf="showLogo" [src]="logoSrc" [alt]="logoAlt" class="babylai-w-10 babylai-h-10" />
|
|
456
|
+
<app-button *ngIf="!showBackButton" variant="icon-only" (click)="onClose.emit()">
|
|
457
|
+
<img src="/icons/close-circle.svg" alt="Close" class="babylai-w-10 babylai-h-10" />
|
|
458
|
+
</app-button>
|
|
459
|
+
</div>
|
|
460
|
+
`, isInline: true, 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: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }] });
|
|
461
|
+
}
|
|
462
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
463
|
+
type: Component,
|
|
464
|
+
args: [{
|
|
465
|
+
selector: 'app-header',
|
|
466
|
+
standalone: true,
|
|
467
|
+
imports: [CommonModule, ButtonComponent],
|
|
468
|
+
template: `
|
|
469
|
+
<div class="babylai-p-4 babylai-flex babylai-items-center babylai-justify-between">
|
|
470
|
+
<app-button *ngIf="showBackButton" variant="icon-bg" className="!babylai-bg-black-white-50" (click)="onBack.emit()">
|
|
471
|
+
<img
|
|
472
|
+
src="/icons/arrow-stripped-colored.svg"
|
|
473
|
+
alt="Back"
|
|
474
|
+
class="babylai-w-6 babylai-h-6"
|
|
475
|
+
[ngClass]="{ 'babylai-rotate-180': language === 'ar' }"
|
|
476
|
+
/>
|
|
477
|
+
</app-button>
|
|
478
|
+
<img *ngIf="showLogo" [src]="logoSrc" [alt]="logoAlt" class="babylai-w-10 babylai-h-10" />
|
|
479
|
+
<app-button *ngIf="!showBackButton" variant="icon-only" (click)="onClose.emit()">
|
|
480
|
+
<img src="/icons/close-circle.svg" alt="Close" class="babylai-w-10 babylai-h-10" />
|
|
481
|
+
</app-button>
|
|
482
|
+
</div>
|
|
483
|
+
`
|
|
484
|
+
}]
|
|
485
|
+
}], propDecorators: { headerType: [{
|
|
486
|
+
type: Input
|
|
487
|
+
}], showBackButton: [{
|
|
488
|
+
type: Input
|
|
489
|
+
}], showLogo: [{
|
|
490
|
+
type: Input
|
|
491
|
+
}], logoSrc: [{
|
|
492
|
+
type: Input
|
|
493
|
+
}], logoAlt: [{
|
|
494
|
+
type: Input
|
|
495
|
+
}], language: [{
|
|
496
|
+
type: Input
|
|
497
|
+
}], onBack: [{
|
|
498
|
+
type: Output
|
|
499
|
+
}], onClose: [{
|
|
500
|
+
type: Output
|
|
501
|
+
}] } });
|
|
502
|
+
class ChatHeaderComponent {
|
|
503
|
+
isMenuOpen = false;
|
|
504
|
+
showBackButton = false;
|
|
505
|
+
showLogo = true;
|
|
506
|
+
logoSrc = '/logo-white.svg';
|
|
507
|
+
logoAlt = 'BabylAI Logo';
|
|
508
|
+
language = 'en';
|
|
509
|
+
onBack = new EventEmitter();
|
|
510
|
+
onClose = new EventEmitter();
|
|
511
|
+
onDocumentClick(event) {
|
|
512
|
+
const target = event.target;
|
|
513
|
+
const menuContainer = target.closest('[data-menu-container]');
|
|
514
|
+
if (!menuContainer && this.isMenuOpen) {
|
|
515
|
+
this.isMenuOpen = false;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ChatHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
519
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: ChatHeaderComponent, isStandalone: true, selector: "app-chat-header", inputs: { showBackButton: "showBackButton", showLogo: "showLogo", logoSrc: "logoSrc", logoAlt: "logoAlt", language: "language" }, outputs: { onBack: "onBack", onClose: "onClose" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: `
|
|
520
|
+
<div
|
|
521
|
+
class="babylai-p-4 babylai-flex babylai-items-center babylai-justify-between babylai-bg-black-white-50 babylai-rounded-t-3xl babylai-relative"
|
|
522
|
+
>
|
|
523
|
+
<div class="babylai-flex babylai-items-center babylai-gap-2">
|
|
524
|
+
<app-button
|
|
525
|
+
variant="icon-bg"
|
|
526
|
+
className="!babylai-bg-primary-500/10 babylai-w-8 babylai-h-8 !babylai-p-2 hover:!babylai-bg-primary-700/10"
|
|
527
|
+
(click)="onBack.emit()"
|
|
528
|
+
>
|
|
529
|
+
<img
|
|
530
|
+
src="/icons/arrow-stripped-colored.svg"
|
|
531
|
+
alt="Back"
|
|
532
|
+
class="babylai-w-full babylai-h-full"
|
|
533
|
+
[ngClass]="{ 'babylai-rotate-180': language === 'ar' }"
|
|
534
|
+
/>
|
|
535
|
+
</app-button>
|
|
536
|
+
<div class="babylai-relative" data-menu-container>
|
|
537
|
+
<app-button
|
|
538
|
+
variant="icon-bg"
|
|
539
|
+
className="!babylai-bg-primary-500/10 babylai-w-8 babylai-h-8 !babylai-p-2 hover:!babylai-bg-primary-700/10"
|
|
540
|
+
(click)="$event.stopPropagation(); isMenuOpen = !isMenuOpen"
|
|
541
|
+
>
|
|
542
|
+
<img
|
|
543
|
+
src="/icons/menu.svg"
|
|
544
|
+
alt="Menu"
|
|
545
|
+
class="babylai-w-full babylai-h-full"
|
|
546
|
+
[ngClass]="{ 'babylai-rotate-180': language === 'ar' }"
|
|
547
|
+
/>
|
|
548
|
+
</app-button>
|
|
549
|
+
<div
|
|
550
|
+
*ngIf="isMenuOpen"
|
|
551
|
+
class="babylai-absolute babylai-mt-2 babylai-w-48 babylai-rounded-md babylai-shadow-lg babylai-bg-white babylai-ring-1 babylai-ring-black babylai-ring-opacity-5 babylai-z-50"
|
|
552
|
+
[ngClass]="{ 'babylai-right-0': language === 'ar', 'babylai-left-0': language === 'en' }"
|
|
553
|
+
>
|
|
554
|
+
<div class="babylai-py-1">
|
|
555
|
+
<button
|
|
556
|
+
(click)="onClose.emit(); isMenuOpen = false"
|
|
557
|
+
class="babylai-block babylai-w-full babylai-text-left babylai-px-4 babylai-py-2 babylai-text-sm babylai-text-gray-700 hover:babylai-bg-gray-100"
|
|
558
|
+
[ngClass]="{ 'babylai-text-left': language === 'en', 'babylai-text-right': language === 'ar' }"
|
|
559
|
+
>
|
|
560
|
+
{{ 'EndChat' | translate }}
|
|
561
|
+
</button>
|
|
562
|
+
</div>
|
|
563
|
+
</div>
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
<div
|
|
567
|
+
class="babylai-flex babylai-items-center babylai-gap-1 babylai-absolute babylai-left-1/2 babylai-transform babylai--translate-x-1/2"
|
|
568
|
+
>
|
|
569
|
+
<img src="/logo-primary.svg" [alt]="logoAlt" class="babylai-w-10 babylai-h-10" />
|
|
570
|
+
<p class="babylai-text-base babylai-font-bold babylai-text-black-white-600">{{ 'BabylAI' | translate }}</p>
|
|
571
|
+
</div>
|
|
572
|
+
</div>
|
|
573
|
+
`, isInline: true, 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: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
574
|
+
}
|
|
575
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ChatHeaderComponent, decorators: [{
|
|
576
|
+
type: Component,
|
|
577
|
+
args: [{
|
|
578
|
+
selector: 'app-chat-header',
|
|
579
|
+
standalone: true,
|
|
580
|
+
imports: [CommonModule, ButtonComponent, TranslatePipe],
|
|
581
|
+
template: `
|
|
582
|
+
<div
|
|
583
|
+
class="babylai-p-4 babylai-flex babylai-items-center babylai-justify-between babylai-bg-black-white-50 babylai-rounded-t-3xl babylai-relative"
|
|
584
|
+
>
|
|
585
|
+
<div class="babylai-flex babylai-items-center babylai-gap-2">
|
|
586
|
+
<app-button
|
|
587
|
+
variant="icon-bg"
|
|
588
|
+
className="!babylai-bg-primary-500/10 babylai-w-8 babylai-h-8 !babylai-p-2 hover:!babylai-bg-primary-700/10"
|
|
589
|
+
(click)="onBack.emit()"
|
|
590
|
+
>
|
|
591
|
+
<img
|
|
592
|
+
src="/icons/arrow-stripped-colored.svg"
|
|
593
|
+
alt="Back"
|
|
594
|
+
class="babylai-w-full babylai-h-full"
|
|
595
|
+
[ngClass]="{ 'babylai-rotate-180': language === 'ar' }"
|
|
596
|
+
/>
|
|
597
|
+
</app-button>
|
|
598
|
+
<div class="babylai-relative" data-menu-container>
|
|
599
|
+
<app-button
|
|
600
|
+
variant="icon-bg"
|
|
601
|
+
className="!babylai-bg-primary-500/10 babylai-w-8 babylai-h-8 !babylai-p-2 hover:!babylai-bg-primary-700/10"
|
|
602
|
+
(click)="$event.stopPropagation(); isMenuOpen = !isMenuOpen"
|
|
603
|
+
>
|
|
604
|
+
<img
|
|
605
|
+
src="/icons/menu.svg"
|
|
606
|
+
alt="Menu"
|
|
607
|
+
class="babylai-w-full babylai-h-full"
|
|
608
|
+
[ngClass]="{ 'babylai-rotate-180': language === 'ar' }"
|
|
609
|
+
/>
|
|
610
|
+
</app-button>
|
|
611
|
+
<div
|
|
612
|
+
*ngIf="isMenuOpen"
|
|
613
|
+
class="babylai-absolute babylai-mt-2 babylai-w-48 babylai-rounded-md babylai-shadow-lg babylai-bg-white babylai-ring-1 babylai-ring-black babylai-ring-opacity-5 babylai-z-50"
|
|
614
|
+
[ngClass]="{ 'babylai-right-0': language === 'ar', 'babylai-left-0': language === 'en' }"
|
|
615
|
+
>
|
|
616
|
+
<div class="babylai-py-1">
|
|
617
|
+
<button
|
|
618
|
+
(click)="onClose.emit(); isMenuOpen = false"
|
|
619
|
+
class="babylai-block babylai-w-full babylai-text-left babylai-px-4 babylai-py-2 babylai-text-sm babylai-text-gray-700 hover:babylai-bg-gray-100"
|
|
620
|
+
[ngClass]="{ 'babylai-text-left': language === 'en', 'babylai-text-right': language === 'ar' }"
|
|
621
|
+
>
|
|
622
|
+
{{ 'EndChat' | translate }}
|
|
623
|
+
</button>
|
|
624
|
+
</div>
|
|
625
|
+
</div>
|
|
626
|
+
</div>
|
|
627
|
+
</div>
|
|
628
|
+
<div
|
|
629
|
+
class="babylai-flex babylai-items-center babylai-gap-1 babylai-absolute babylai-left-1/2 babylai-transform babylai--translate-x-1/2"
|
|
630
|
+
>
|
|
631
|
+
<img src="/logo-primary.svg" [alt]="logoAlt" class="babylai-w-10 babylai-h-10" />
|
|
632
|
+
<p class="babylai-text-base babylai-font-bold babylai-text-black-white-600">{{ 'BabylAI' | translate }}</p>
|
|
633
|
+
</div>
|
|
634
|
+
</div>
|
|
635
|
+
`
|
|
636
|
+
}]
|
|
637
|
+
}], propDecorators: { showBackButton: [{
|
|
638
|
+
type: Input
|
|
639
|
+
}], showLogo: [{
|
|
640
|
+
type: Input
|
|
641
|
+
}], logoSrc: [{
|
|
642
|
+
type: Input
|
|
643
|
+
}], logoAlt: [{
|
|
644
|
+
type: Input
|
|
645
|
+
}], language: [{
|
|
646
|
+
type: Input
|
|
647
|
+
}], onBack: [{
|
|
648
|
+
type: Output
|
|
649
|
+
}], onClose: [{
|
|
650
|
+
type: Output
|
|
651
|
+
}], onDocumentClick: [{
|
|
652
|
+
type: HostListener,
|
|
653
|
+
args: ['document:click', ['$event']]
|
|
654
|
+
}] } });
|
|
655
|
+
|
|
656
|
+
class LoadingComponent {
|
|
657
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: LoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
658
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: LoadingComponent, isStandalone: true, selector: "app-loading", ngImport: i0, template: `
|
|
659
|
+
<div
|
|
660
|
+
class="babylai-flex babylai-flex-col babylai-items-center babylai-justify-center babylai-w-full babylai-h-full babylai-py-16 md:babylai-py-28"
|
|
661
|
+
>
|
|
662
|
+
<img src="/images/animatedLogo.gif" alt="Animated Logo" class="babylai-w-20 babylai-h-20" />
|
|
663
|
+
</div>
|
|
664
|
+
`, isInline: true });
|
|
665
|
+
}
|
|
666
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: LoadingComponent, decorators: [{
|
|
667
|
+
type: Component,
|
|
668
|
+
args: [{
|
|
669
|
+
selector: 'app-loading',
|
|
670
|
+
template: `
|
|
671
|
+
<div
|
|
672
|
+
class="babylai-flex babylai-flex-col babylai-items-center babylai-justify-center babylai-w-full babylai-h-full babylai-py-16 md:babylai-py-28"
|
|
673
|
+
>
|
|
674
|
+
<img src="/images/animatedLogo.gif" alt="Animated Logo" class="babylai-w-20 babylai-h-20" />
|
|
675
|
+
</div>
|
|
676
|
+
`,
|
|
677
|
+
standalone: true
|
|
678
|
+
}]
|
|
679
|
+
}] });
|
|
680
|
+
|
|
681
|
+
class ChatComponent {
|
|
682
|
+
messages = [];
|
|
683
|
+
needsAgent = false;
|
|
684
|
+
assistantStatus = 'idle';
|
|
685
|
+
isSignalRConnected = false;
|
|
686
|
+
isChatClosed = false;
|
|
687
|
+
sendMessageEvent = new EventEmitter();
|
|
688
|
+
chatMessagesContainer;
|
|
689
|
+
currentLang = 'en';
|
|
690
|
+
loading = false;
|
|
691
|
+
messageText = '';
|
|
692
|
+
get firstAgentMessageIndex() {
|
|
693
|
+
return this.messages.findIndex((message) => message.senderType === 2);
|
|
694
|
+
}
|
|
695
|
+
cleanMessageContent(content) {
|
|
696
|
+
// Remove excessive newlines (more than 2 consecutive newlines)
|
|
697
|
+
return content.replace(/\n{3,}/g, '\n\n').trim();
|
|
698
|
+
}
|
|
699
|
+
ngOnInit() {
|
|
700
|
+
// Initialize component
|
|
701
|
+
}
|
|
702
|
+
ngAfterViewChecked() {
|
|
703
|
+
this.scrollToBottom();
|
|
704
|
+
}
|
|
705
|
+
scrollToBottom() {
|
|
706
|
+
try {
|
|
707
|
+
this.chatMessagesContainer.nativeElement.scrollTop = this.chatMessagesContainer.nativeElement.scrollHeight;
|
|
708
|
+
}
|
|
709
|
+
catch (err) {
|
|
710
|
+
console.error('Error scrolling to bottom:', err);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
sendMessage() {
|
|
714
|
+
if (!this.messageText.trim() || !this.isSignalRConnected || this.isChatClosed)
|
|
715
|
+
return;
|
|
716
|
+
this.sendMessageEvent.emit(this.messageText);
|
|
717
|
+
this.messageText = '';
|
|
718
|
+
}
|
|
719
|
+
hasAgentMessageBeenSent(messages) {
|
|
720
|
+
return messages.some((message) => message.senderType === 2 || message.senderType === 3);
|
|
721
|
+
}
|
|
722
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
723
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: ChatComponent, isStandalone: true, selector: "app-chat", inputs: { messages: "messages", needsAgent: "needsAgent", assistantStatus: "assistantStatus", isSignalRConnected: "isSignalRConnected", isChatClosed: "isChatClosed", currentLang: "currentLang", loading: "loading" }, outputs: { sendMessageEvent: "sendMessageEvent" }, viewQueries: [{ propertyName: "chatMessagesContainer", first: true, predicate: ["chatMessagesContainer"], descendants: true }], ngImport: i0, template: "<div class=\"babylai-flex babylai-flex-col babylai-h-full babylai-overflow-hidden\">\n <div class=\"babylai-flex-1 babylai-overflow-y-auto babylai-pb-4 babylai-flex babylai-flex-col babylai-gap-2\" #chatMessagesContainer>\n <div *ngFor=\"let message of messages; let i = index\" class=\"babylai-flex babylai-flex-col babylai-gap-2\">\n <div class=\"babylai-w-full\" *ngIf=\"i === firstAgentMessageIndex && message.senderType === 2\">\n <img src=\"/images/seperator.svg\" class=\"babylai-w-full\" />\n </div>\n <div class=\"babylai-flex babylai-items-start babylai-gap-2\" [class.babylai-flex-row-reverse]=\"message.senderType === 1\">\n <div\n class=\"babylai-messageIcon babylai-mt-2\"\n [class.babylai-invisible]=\"i > 0 && messages[i - 1].senderType === message.senderType\"\n >\n @if (message.senderType === 3) {\n <span\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-10 babylai-h-10 babylai-rounded-full babylai-bg-primary babylai-p-[10px]\"\n >\n <img src=\"/logo-white.svg\" alt=\"robot\" class=\"babylai-w-full\" />\n </span>\n } @else if (needsAgent || message.senderType === 2) {\n <span\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-10 babylai-h-10 babylai-rounded-full babylai-bg-black-white-50 babylai-p-[10px]\"\n >\n <img src=\"/icons/person.svg\" alt=\"robot\" class=\"babylai-w-full\" />\n </span>\n }\n </div>\n <app-card\n variant=\"rounded\"\n [class]=\"\n 'babylai-max-w-[80%] babylai-relative ' +\n (message.senderType === 1\n ? 'babylai-self-start babylai-bg-primary babylai-text-white babylai-rtl'\n : 'babylai-self-end babylai-bg-black-white-100 babylai-text-black babylai-rtl')\n \"\n >\n <app-card-content>\n <div class=\"babylai-messageContent babylai-whitespace-pre-wrap\">\n <markdown\n [data]=\"cleanMessageContent(message.messageContent)\"\n ngPreserveWhitespaces\n [inline]=\"false\"\n class=\"babylai-prose babylai-max-w-none babylai-break-words [&>*:first-child]:babylai-mt-0 [&>*:last-child]:babylai-mb-0 [&>p]:babylai-my-2 [&>ul]:babylai-my-2 [&>ol]:babylai-my-2 [&>blockquote]:babylai-my-2\"\n [class.babylai-prose-invert]=\"message.senderType === 1\"\n >\n </markdown>\n </div>\n </app-card-content>\n </app-card>\n </div>\n </div>\n\n <div *ngIf=\"assistantStatus === 'typing' && firstAgentMessageIndex === -1\" class=\"babylai-flex babylai-items-start babylai-gap-2\">\n <div class=\"babylai-messageIcon babylai-mt-2\">\n <span\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-10 babylai-h-10 babylai-rounded-full babylai-bg-black-white-50 babylai-p-[10px]\"\n >\n <img src=\"/images/animatedLogo.gif\" alt=\"Loading\" class=\"babylai-w-full\" />\n </span>\n </div>\n <app-card\n variant=\"rounded\"\n class=\"babylai-max-w-[80%] babylai-relative babylai-self-end babylai-bg-black-white-100 babylai-text-black\"\n >\n <app-card-content>\n <div id=\"wave\">\n <span class=\"dot\"></span>\n <span class=\"dot\"></span>\n <span class=\"dot\"></span>\n </div>\n </app-card-content>\n </app-card>\n </div>\n <div *ngIf=\"loading\" class=\"babylai-flex babylai-items-center babylai-justify-center babylai-h-full\">\n <app-loading />\n </div>\n </div>\n\n <form (ngSubmit)=\"sendMessage()\" class=\"babylai-relative\">\n <div class=\"babylai-relative babylai-w-full\">\n <input\n type=\"text\"\n [(ngModel)]=\"messageText\"\n name=\"messageText\"\n [placeholder]=\"'ChatPlaceholder' | translate\"\n [disabled]=\"isChatClosed\"\n class=\"babylai-flex-1 babylai-min-h-16 babylai-w-full babylai-ps-3 babylai-pe-12 babylai-rounded-full focus:babylai-outline-none babylai-px-0 babylai-py-2 disabled:babylai-bg-black-white-200\"\n />\n <app-button\n type=\"submit\"\n [disabled]=\"!messageText.trim() || !isSignalRConnected || isChatClosed\"\n variant=\"icon-bg\"\n className=\"babylai-absolute babylai-end-1 babylai-top-1/2 babylai-transform -babylai-translate-y-1/2 babylai-w-10 babylai-h-10 babylai-opacity-100 babylai-py-0 babylai-px-0 !babylai-p-3 babylai-inline-flex babylai-items-center babylai-justify-center disabled:babylai-opacity-50 disabled:babylai-cursor-not-allowed\"\n >\n <img\n src=\"/icons/send.svg\"\n alt=\"send-message\"\n class=\"babylai-w-full\"\n [ngClass]=\"currentLang === 'ar' ? 'babylai-rotate-[270deg]' : ''\"\n />\n </app-button>\n </div>\n </form>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }, { kind: "component", type: CardComponent, selector: "app-card", inputs: ["variant", "class"] }, { kind: "component", type: CardContentComponent, selector: "app-card-content", inputs: ["class"] }, { kind: "component", type: LoadingComponent, selector: "app-loading" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
724
|
+
}
|
|
725
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ChatComponent, decorators: [{
|
|
726
|
+
type: Component,
|
|
727
|
+
args: [{ selector: 'app-chat', standalone: true, imports: [
|
|
728
|
+
CommonModule,
|
|
729
|
+
FormsModule,
|
|
730
|
+
MarkdownComponent,
|
|
731
|
+
ButtonComponent,
|
|
732
|
+
CardComponent,
|
|
733
|
+
CardContentComponent,
|
|
734
|
+
LoadingComponent,
|
|
735
|
+
TranslatePipe
|
|
736
|
+
], template: "<div class=\"babylai-flex babylai-flex-col babylai-h-full babylai-overflow-hidden\">\n <div class=\"babylai-flex-1 babylai-overflow-y-auto babylai-pb-4 babylai-flex babylai-flex-col babylai-gap-2\" #chatMessagesContainer>\n <div *ngFor=\"let message of messages; let i = index\" class=\"babylai-flex babylai-flex-col babylai-gap-2\">\n <div class=\"babylai-w-full\" *ngIf=\"i === firstAgentMessageIndex && message.senderType === 2\">\n <img src=\"/images/seperator.svg\" class=\"babylai-w-full\" />\n </div>\n <div class=\"babylai-flex babylai-items-start babylai-gap-2\" [class.babylai-flex-row-reverse]=\"message.senderType === 1\">\n <div\n class=\"babylai-messageIcon babylai-mt-2\"\n [class.babylai-invisible]=\"i > 0 && messages[i - 1].senderType === message.senderType\"\n >\n @if (message.senderType === 3) {\n <span\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-10 babylai-h-10 babylai-rounded-full babylai-bg-primary babylai-p-[10px]\"\n >\n <img src=\"/logo-white.svg\" alt=\"robot\" class=\"babylai-w-full\" />\n </span>\n } @else if (needsAgent || message.senderType === 2) {\n <span\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-10 babylai-h-10 babylai-rounded-full babylai-bg-black-white-50 babylai-p-[10px]\"\n >\n <img src=\"/icons/person.svg\" alt=\"robot\" class=\"babylai-w-full\" />\n </span>\n }\n </div>\n <app-card\n variant=\"rounded\"\n [class]=\"\n 'babylai-max-w-[80%] babylai-relative ' +\n (message.senderType === 1\n ? 'babylai-self-start babylai-bg-primary babylai-text-white babylai-rtl'\n : 'babylai-self-end babylai-bg-black-white-100 babylai-text-black babylai-rtl')\n \"\n >\n <app-card-content>\n <div class=\"babylai-messageContent babylai-whitespace-pre-wrap\">\n <markdown\n [data]=\"cleanMessageContent(message.messageContent)\"\n ngPreserveWhitespaces\n [inline]=\"false\"\n class=\"babylai-prose babylai-max-w-none babylai-break-words [&>*:first-child]:babylai-mt-0 [&>*:last-child]:babylai-mb-0 [&>p]:babylai-my-2 [&>ul]:babylai-my-2 [&>ol]:babylai-my-2 [&>blockquote]:babylai-my-2\"\n [class.babylai-prose-invert]=\"message.senderType === 1\"\n >\n </markdown>\n </div>\n </app-card-content>\n </app-card>\n </div>\n </div>\n\n <div *ngIf=\"assistantStatus === 'typing' && firstAgentMessageIndex === -1\" class=\"babylai-flex babylai-items-start babylai-gap-2\">\n <div class=\"babylai-messageIcon babylai-mt-2\">\n <span\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-w-10 babylai-h-10 babylai-rounded-full babylai-bg-black-white-50 babylai-p-[10px]\"\n >\n <img src=\"/images/animatedLogo.gif\" alt=\"Loading\" class=\"babylai-w-full\" />\n </span>\n </div>\n <app-card\n variant=\"rounded\"\n class=\"babylai-max-w-[80%] babylai-relative babylai-self-end babylai-bg-black-white-100 babylai-text-black\"\n >\n <app-card-content>\n <div id=\"wave\">\n <span class=\"dot\"></span>\n <span class=\"dot\"></span>\n <span class=\"dot\"></span>\n </div>\n </app-card-content>\n </app-card>\n </div>\n <div *ngIf=\"loading\" class=\"babylai-flex babylai-items-center babylai-justify-center babylai-h-full\">\n <app-loading />\n </div>\n </div>\n\n <form (ngSubmit)=\"sendMessage()\" class=\"babylai-relative\">\n <div class=\"babylai-relative babylai-w-full\">\n <input\n type=\"text\"\n [(ngModel)]=\"messageText\"\n name=\"messageText\"\n [placeholder]=\"'ChatPlaceholder' | translate\"\n [disabled]=\"isChatClosed\"\n class=\"babylai-flex-1 babylai-min-h-16 babylai-w-full babylai-ps-3 babylai-pe-12 babylai-rounded-full focus:babylai-outline-none babylai-px-0 babylai-py-2 disabled:babylai-bg-black-white-200\"\n />\n <app-button\n type=\"submit\"\n [disabled]=\"!messageText.trim() || !isSignalRConnected || isChatClosed\"\n variant=\"icon-bg\"\n className=\"babylai-absolute babylai-end-1 babylai-top-1/2 babylai-transform -babylai-translate-y-1/2 babylai-w-10 babylai-h-10 babylai-opacity-100 babylai-py-0 babylai-px-0 !babylai-p-3 babylai-inline-flex babylai-items-center babylai-justify-center disabled:babylai-opacity-50 disabled:babylai-cursor-not-allowed\"\n >\n <img\n src=\"/icons/send.svg\"\n alt=\"send-message\"\n class=\"babylai-w-full\"\n [ngClass]=\"currentLang === 'ar' ? 'babylai-rotate-[270deg]' : ''\"\n />\n </app-button>\n </div>\n </form>\n</div>\n" }]
|
|
737
|
+
}], propDecorators: { messages: [{
|
|
738
|
+
type: Input
|
|
739
|
+
}], needsAgent: [{
|
|
740
|
+
type: Input
|
|
741
|
+
}], assistantStatus: [{
|
|
742
|
+
type: Input
|
|
743
|
+
}], isSignalRConnected: [{
|
|
744
|
+
type: Input
|
|
745
|
+
}], isChatClosed: [{
|
|
746
|
+
type: Input
|
|
747
|
+
}], sendMessageEvent: [{
|
|
748
|
+
type: Output
|
|
749
|
+
}], chatMessagesContainer: [{
|
|
750
|
+
type: ViewChild,
|
|
751
|
+
args: ['chatMessagesContainer']
|
|
752
|
+
}], currentLang: [{
|
|
753
|
+
type: Input
|
|
754
|
+
}], loading: [{
|
|
755
|
+
type: Input
|
|
756
|
+
}] } });
|
|
757
|
+
|
|
758
|
+
class ConfirmationDialogComponent {
|
|
759
|
+
title = '';
|
|
760
|
+
body = '';
|
|
761
|
+
confirmText = 'Confirm';
|
|
762
|
+
cancelText = 'Cancel';
|
|
763
|
+
onConfirm = new EventEmitter();
|
|
764
|
+
onCancel = new EventEmitter();
|
|
765
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ConfirmationDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
766
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: ConfirmationDialogComponent, isStandalone: true, selector: "app-confirmation-dialog", inputs: { title: "title", body: "body", confirmText: "confirmText", cancelText: "cancelText" }, outputs: { onConfirm: "onConfirm", onCancel: "onCancel" }, ngImport: i0, template: `
|
|
767
|
+
<div
|
|
768
|
+
class="babylai-absolute babylai-inset-0 babylai-bg-black/50 babylai-z-[10] babylai-flex babylai-items-center babylai-justify-center babylai-rounded-3xl"
|
|
769
|
+
>
|
|
770
|
+
<div class="babylai-bg-white babylai-rounded-2xl babylai-p-6 babylai-max-w-sm babylai-w-full babylai-mx-4">
|
|
771
|
+
<h3 class="babylai-text-xl babylai-font-bold babylai-mb-2">{{ title }}</h3>
|
|
772
|
+
<p class="babylai-text-gray-600 babylai-mb-6">{{ body }}</p>
|
|
773
|
+
<div class="babylai-flex babylai-gap-3 babylai-justify-end">
|
|
774
|
+
<app-button
|
|
775
|
+
variant="default"
|
|
776
|
+
className="!babylai-bg-transparent !babylai-text-primary !babylai-border !babylai-border-primary hover:!babylai-bg-primary/10"
|
|
777
|
+
(click)="onCancel.emit()"
|
|
778
|
+
>
|
|
779
|
+
{{ cancelText }}
|
|
780
|
+
</app-button>
|
|
781
|
+
<app-button variant="default" (click)="onConfirm.emit()">
|
|
782
|
+
{{ confirmText }}
|
|
783
|
+
</app-button>
|
|
784
|
+
</div>
|
|
785
|
+
</div>
|
|
786
|
+
</div>
|
|
787
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }] });
|
|
788
|
+
}
|
|
789
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
|
|
790
|
+
type: Component,
|
|
791
|
+
args: [{
|
|
792
|
+
selector: 'app-confirmation-dialog',
|
|
793
|
+
standalone: true,
|
|
794
|
+
imports: [CommonModule, ButtonComponent],
|
|
795
|
+
template: `
|
|
796
|
+
<div
|
|
797
|
+
class="babylai-absolute babylai-inset-0 babylai-bg-black/50 babylai-z-[10] babylai-flex babylai-items-center babylai-justify-center babylai-rounded-3xl"
|
|
798
|
+
>
|
|
799
|
+
<div class="babylai-bg-white babylai-rounded-2xl babylai-p-6 babylai-max-w-sm babylai-w-full babylai-mx-4">
|
|
800
|
+
<h3 class="babylai-text-xl babylai-font-bold babylai-mb-2">{{ title }}</h3>
|
|
801
|
+
<p class="babylai-text-gray-600 babylai-mb-6">{{ body }}</p>
|
|
802
|
+
<div class="babylai-flex babylai-gap-3 babylai-justify-end">
|
|
803
|
+
<app-button
|
|
804
|
+
variant="default"
|
|
805
|
+
className="!babylai-bg-transparent !babylai-text-primary !babylai-border !babylai-border-primary hover:!babylai-bg-primary/10"
|
|
806
|
+
(click)="onCancel.emit()"
|
|
807
|
+
>
|
|
808
|
+
{{ cancelText }}
|
|
809
|
+
</app-button>
|
|
810
|
+
<app-button variant="default" (click)="onConfirm.emit()">
|
|
811
|
+
{{ confirmText }}
|
|
812
|
+
</app-button>
|
|
813
|
+
</div>
|
|
814
|
+
</div>
|
|
815
|
+
</div>
|
|
816
|
+
`
|
|
817
|
+
}]
|
|
818
|
+
}], propDecorators: { title: [{
|
|
819
|
+
type: Input
|
|
820
|
+
}], body: [{
|
|
821
|
+
type: Input
|
|
822
|
+
}], confirmText: [{
|
|
823
|
+
type: Input
|
|
824
|
+
}], cancelText: [{
|
|
825
|
+
type: Input
|
|
826
|
+
}], onConfirm: [{
|
|
827
|
+
type: Output
|
|
828
|
+
}], onCancel: [{
|
|
829
|
+
type: Output
|
|
830
|
+
}] } });
|
|
831
|
+
|
|
832
|
+
class ApiService {
|
|
833
|
+
getTokenFunction = null;
|
|
834
|
+
baseUrl = null;
|
|
835
|
+
initializeAPI(url, getToken) {
|
|
836
|
+
this.getTokenFunction = getToken;
|
|
837
|
+
this.baseUrl = url;
|
|
838
|
+
}
|
|
839
|
+
async getValidToken(forceRefresh = false) {
|
|
840
|
+
if (!this.getTokenFunction) {
|
|
841
|
+
throw new Error('API module not initialized. Call initializeAPI(getToken) first.');
|
|
842
|
+
}
|
|
843
|
+
let storedToken = localStorage.getItem('chatbot-token');
|
|
844
|
+
let storedExpiry = localStorage.getItem('chatbot-token-expiry');
|
|
845
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
846
|
+
if (!storedToken || !storedExpiry || currentTime >= Number(storedExpiry) || forceRefresh) {
|
|
847
|
+
const tokenResponse = await this.getTokenFunction();
|
|
848
|
+
if (!tokenResponse) {
|
|
849
|
+
throw new Error('Invalid token response from getTokenFunction');
|
|
850
|
+
}
|
|
851
|
+
storedToken = tokenResponse;
|
|
852
|
+
storedExpiry = String(currentTime + 900);
|
|
853
|
+
localStorage.setItem('chatbot-token', storedToken);
|
|
854
|
+
localStorage.setItem('chatbot-token-expiry', storedExpiry);
|
|
855
|
+
}
|
|
856
|
+
return storedToken;
|
|
857
|
+
}
|
|
858
|
+
async fetchWithAuth(url, options, retry = true) {
|
|
859
|
+
if (!options.headers) {
|
|
860
|
+
options.headers = {};
|
|
861
|
+
}
|
|
862
|
+
const headers = options.headers;
|
|
863
|
+
headers['Authorization'] = `Bearer ${await this.getValidToken()}`;
|
|
864
|
+
let response = await fetch(url, options);
|
|
865
|
+
if ((response.status === 401 || response.status === 403) && retry) {
|
|
866
|
+
console.warn('Token expired. Fetching new token...');
|
|
867
|
+
const newToken = await this.getValidToken(true);
|
|
868
|
+
headers['Authorization'] = `Bearer ${newToken}`;
|
|
869
|
+
response = await fetch(url, options);
|
|
870
|
+
}
|
|
871
|
+
return response;
|
|
872
|
+
}
|
|
873
|
+
async apiRequest(endpoint, method = 'GET', body = null, customHeaders = {}) {
|
|
874
|
+
if (!this.baseUrl) {
|
|
875
|
+
throw new Error('API not initialized. Call initializeAPI first.');
|
|
876
|
+
}
|
|
877
|
+
const url = `${this.baseUrl}/${endpoint}`;
|
|
878
|
+
const options = {
|
|
879
|
+
method,
|
|
880
|
+
headers: {
|
|
881
|
+
'Content-Type': 'application/json',
|
|
882
|
+
...customHeaders
|
|
883
|
+
},
|
|
884
|
+
body: body ? JSON.stringify(body) : null
|
|
885
|
+
};
|
|
886
|
+
const response = await this.fetchWithAuth(url, options);
|
|
887
|
+
if (!response.ok) {
|
|
888
|
+
const errorData = await response.json();
|
|
889
|
+
throw new Error(errorData.message || 'API request failed');
|
|
890
|
+
}
|
|
891
|
+
return response;
|
|
892
|
+
}
|
|
893
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
894
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ApiService, providedIn: 'root' });
|
|
895
|
+
}
|
|
896
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: ApiService, decorators: [{
|
|
897
|
+
type: Injectable,
|
|
898
|
+
args: [{
|
|
899
|
+
providedIn: 'root'
|
|
900
|
+
}]
|
|
901
|
+
}] });
|
|
902
|
+
|
|
903
|
+
class SignalRService {
|
|
904
|
+
connection = null;
|
|
905
|
+
isConnected = false;
|
|
906
|
+
baseURL = 'http://localhost:5086'; // Replace with your API URL
|
|
907
|
+
hubUrl = 'https://babylai.net'; // Replace with your SignalR hub URL
|
|
908
|
+
async startConnection(sessionId, apiKey, onMessageReceived) {
|
|
909
|
+
console.log('sessionId:', sessionId);
|
|
910
|
+
if (this.isConnected)
|
|
911
|
+
return;
|
|
912
|
+
this.connection = new signalR.HubConnectionBuilder()
|
|
913
|
+
.withUrl(`${this.hubUrl}/clientHub?access_token=${encodeURIComponent(apiKey)}`, {
|
|
914
|
+
withCredentials: true,
|
|
915
|
+
transport: signalR.HttpTransportType.WebSockets |
|
|
916
|
+
signalR.HttpTransportType.LongPolling,
|
|
917
|
+
headers: {
|
|
918
|
+
Authorization: `Bearer ${apiKey}`,
|
|
919
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
920
|
+
'X-SignalR-User-Agent': 'Microsoft SignalR/8.0 (8.0.7; Unknown OS; Browser; Unknown Runtime Version)',
|
|
921
|
+
},
|
|
922
|
+
skipNegotiation: false,
|
|
923
|
+
accessTokenFactory: () => apiKey,
|
|
924
|
+
})
|
|
925
|
+
.withAutomaticReconnect()
|
|
926
|
+
.configureLogging(signalR.LogLevel.Information)
|
|
927
|
+
.build();
|
|
928
|
+
this.connection.on('ReceiveMessage', (message, senderType, needsAgent) => {
|
|
929
|
+
console.log('Received message from SignalR:', message, senderType, needsAgent);
|
|
930
|
+
onMessageReceived(message, senderType, needsAgent);
|
|
931
|
+
});
|
|
932
|
+
try {
|
|
933
|
+
await this.connection.start();
|
|
934
|
+
console.log('SignalR connection started successfully.');
|
|
935
|
+
this.isConnected = true;
|
|
936
|
+
await this.joinGroup(sessionId);
|
|
937
|
+
console.log('SignalR group joined.');
|
|
938
|
+
}
|
|
939
|
+
catch (error) {
|
|
940
|
+
console.error('Error connecting to SignalR', error);
|
|
941
|
+
this.isConnected = false;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
async joinGroup(sessionId) {
|
|
945
|
+
if (this.connection) {
|
|
946
|
+
try {
|
|
947
|
+
console.log(`Attempting to join group with session ID: ${sessionId}`);
|
|
948
|
+
await this.connection.invoke('JoinGroup', sessionId);
|
|
949
|
+
console.log(`Joined group with session ID: ${sessionId}`);
|
|
950
|
+
}
|
|
951
|
+
catch (error) {
|
|
952
|
+
console.error('Error joining SignalR group:', error);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
async leaveGroup(sessionId) {
|
|
957
|
+
if (this.connection && this.isConnected) {
|
|
958
|
+
try {
|
|
959
|
+
await this.connection.invoke('LeaveGroup', sessionId);
|
|
960
|
+
console.log(`Left group with session ID: ${sessionId}`);
|
|
961
|
+
}
|
|
962
|
+
catch (error) {
|
|
963
|
+
console.error('Error leaving SignalR group:', error);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
async stopConnection() {
|
|
968
|
+
if (this.connection && this.isConnected) {
|
|
969
|
+
await this.connection.stop();
|
|
970
|
+
this.isConnected = false;
|
|
971
|
+
console.log('SignalR disconnected.');
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: SignalRService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
975
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: SignalRService, providedIn: 'root' });
|
|
976
|
+
}
|
|
977
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: SignalRService, decorators: [{
|
|
978
|
+
type: Injectable,
|
|
979
|
+
args: [{
|
|
980
|
+
providedIn: 'root',
|
|
981
|
+
}]
|
|
982
|
+
}] });
|
|
983
|
+
|
|
984
|
+
class TokenService {
|
|
985
|
+
baseUrl = null;
|
|
986
|
+
initializeService(baseUrl) {
|
|
987
|
+
this.baseUrl = baseUrl;
|
|
988
|
+
}
|
|
989
|
+
async getToken() {
|
|
990
|
+
if (!this.baseUrl) {
|
|
991
|
+
throw new Error('Token service not initialized. Call initializeService first.');
|
|
992
|
+
}
|
|
993
|
+
try {
|
|
994
|
+
const response = await fetch(`${this.baseUrl}/Auth/client/get-babylai-token`, {
|
|
995
|
+
method: 'POST',
|
|
996
|
+
headers: {
|
|
997
|
+
'Content-Type': 'application/json'
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
if (!response.ok) {
|
|
1001
|
+
throw new Error('Failed to fetch token');
|
|
1002
|
+
}
|
|
1003
|
+
const data = await response.json();
|
|
1004
|
+
return {
|
|
1005
|
+
token: data.token,
|
|
1006
|
+
expiresIn: data.expiresIn || 3600 // Default to 1 hour if not provided
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
catch (error) {
|
|
1010
|
+
throw new Error('Failed to get authentication token');
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1014
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TokenService, providedIn: 'root' });
|
|
1015
|
+
}
|
|
1016
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: TokenService, decorators: [{
|
|
1017
|
+
type: Injectable,
|
|
1018
|
+
args: [{
|
|
1019
|
+
providedIn: 'root'
|
|
1020
|
+
}]
|
|
1021
|
+
}] });
|
|
1022
|
+
|
|
1023
|
+
class HelpCenterWidgetComponent {
|
|
1024
|
+
apiService;
|
|
1025
|
+
signalRService;
|
|
1026
|
+
tokenService;
|
|
1027
|
+
translationService;
|
|
1028
|
+
getToken;
|
|
1029
|
+
helpScreenId;
|
|
1030
|
+
user;
|
|
1031
|
+
showArrow = true;
|
|
1032
|
+
messageLabel = null;
|
|
1033
|
+
currentLang = 'en';
|
|
1034
|
+
chatMessagesContainer;
|
|
1035
|
+
// State variables
|
|
1036
|
+
isPopupOpen = false;
|
|
1037
|
+
helpScreenData = null;
|
|
1038
|
+
status = 'idle';
|
|
1039
|
+
error = null;
|
|
1040
|
+
showArrowAnimation = false;
|
|
1041
|
+
isRTL = this.currentLang === 'en' ? false : true;
|
|
1042
|
+
showTooltip = false;
|
|
1043
|
+
sessionId = null;
|
|
1044
|
+
isSignalRConnected = false;
|
|
1045
|
+
isChatClosed = false;
|
|
1046
|
+
showChat = false;
|
|
1047
|
+
messageText = '';
|
|
1048
|
+
isTyping = false;
|
|
1049
|
+
messages = [];
|
|
1050
|
+
showHelpScreenData = false;
|
|
1051
|
+
chatIsLoading = false;
|
|
1052
|
+
isOpen = false;
|
|
1053
|
+
needsAgent = false;
|
|
1054
|
+
assistantStatus = 'idle';
|
|
1055
|
+
selectedOption = null;
|
|
1056
|
+
selectedNestedOption = null;
|
|
1057
|
+
baseUrl = 'https://babylai.net/api';
|
|
1058
|
+
showEndChatConfirmation = false;
|
|
1059
|
+
constructor(apiService, signalRService, tokenService, translationService) {
|
|
1060
|
+
this.apiService = apiService;
|
|
1061
|
+
this.signalRService = signalRService;
|
|
1062
|
+
this.tokenService = tokenService;
|
|
1063
|
+
this.translationService = translationService;
|
|
1064
|
+
}
|
|
1065
|
+
ngOnInit() {
|
|
1066
|
+
this.showArrowAnimation = this.showArrow;
|
|
1067
|
+
this.tokenService.initializeService(this.baseUrl);
|
|
1068
|
+
this.apiService.initializeAPI(this.baseUrl, this.getToken);
|
|
1069
|
+
}
|
|
1070
|
+
async handleTogglePopup() {
|
|
1071
|
+
this.isPopupOpen = !this.isPopupOpen;
|
|
1072
|
+
this.showArrowAnimation = this.isPopupOpen;
|
|
1073
|
+
if (this.isPopupOpen) {
|
|
1074
|
+
await this.fetchHelpScreenData();
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
async fetchHelpScreenData() {
|
|
1078
|
+
this.status = 'loading';
|
|
1079
|
+
this.error = null;
|
|
1080
|
+
try {
|
|
1081
|
+
const response = await this.apiService.apiRequest(`client/clientHelpScreen/${this.helpScreenId}`, 'GET');
|
|
1082
|
+
this.helpScreenData = await response.json();
|
|
1083
|
+
this.status = 'succeeded';
|
|
1084
|
+
}
|
|
1085
|
+
catch (error) {
|
|
1086
|
+
this.error = error.message;
|
|
1087
|
+
this.status = 'failed';
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
async createChatSession() {
|
|
1091
|
+
try {
|
|
1092
|
+
const chatSessionCreateDto = {
|
|
1093
|
+
optionId: this.selectedOption?.id,
|
|
1094
|
+
helpScreenId: this.helpScreenId
|
|
1095
|
+
};
|
|
1096
|
+
const response = await this.apiService.apiRequest('Client/ClientChatSession/create-session', 'POST', chatSessionCreateDto);
|
|
1097
|
+
const data = await response.json();
|
|
1098
|
+
this.sessionId = data.id;
|
|
1099
|
+
return data;
|
|
1100
|
+
}
|
|
1101
|
+
catch (error) {
|
|
1102
|
+
console.error('Error creating chat session:', error);
|
|
1103
|
+
throw error;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
async sendMessage(messageText) {
|
|
1107
|
+
const textToSend = messageText || this.messageText;
|
|
1108
|
+
if (!textToSend.trim() || !this.isSignalRConnected || this.isChatClosed)
|
|
1109
|
+
return;
|
|
1110
|
+
try {
|
|
1111
|
+
this.assistantStatus = 'typing';
|
|
1112
|
+
// Add user message
|
|
1113
|
+
this.messages.push({
|
|
1114
|
+
id: Date.now(),
|
|
1115
|
+
sender: 'user',
|
|
1116
|
+
senderType: 1,
|
|
1117
|
+
messageContent: textToSend,
|
|
1118
|
+
sentAt: new Date(),
|
|
1119
|
+
isSeen: false
|
|
1120
|
+
});
|
|
1121
|
+
if (!this.sessionId) {
|
|
1122
|
+
await this.createChatSession();
|
|
1123
|
+
}
|
|
1124
|
+
const messageDto = { messageContent: textToSend };
|
|
1125
|
+
await this.apiService.apiRequest(`Client/ClientChatSession/${this.sessionId}/send-message`, 'POST', messageDto);
|
|
1126
|
+
// Clear message input
|
|
1127
|
+
this.messageText = '';
|
|
1128
|
+
// Update message as seen
|
|
1129
|
+
this.messages = this.messages.map((msg) => (msg.senderType === 1 && !msg.isSeen ? { ...msg, isSeen: true } : msg));
|
|
1130
|
+
}
|
|
1131
|
+
catch (error) {
|
|
1132
|
+
console.error('Error sending message:', error);
|
|
1133
|
+
this.assistantStatus = 'idle';
|
|
1134
|
+
this.messages.push({
|
|
1135
|
+
id: Date.now(),
|
|
1136
|
+
sender: 'assistant',
|
|
1137
|
+
senderType: 3,
|
|
1138
|
+
messageContent: 'Failed to send the message. Please try again.\n لم يتم إرسال الرسالة. يرجى المحاولة مرة أخرى.',
|
|
1139
|
+
sentAt: new Date(),
|
|
1140
|
+
isSeen: true
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
async sendMessageToChatSession(chatSessionId, messageDto) {
|
|
1145
|
+
try {
|
|
1146
|
+
const response = await this.apiService.apiRequest(`Client/ClientChatSession/${chatSessionId}/send-message`, 'POST', messageDto);
|
|
1147
|
+
return await response.json();
|
|
1148
|
+
}
|
|
1149
|
+
catch (error) {
|
|
1150
|
+
console.error('Error sending message:', error);
|
|
1151
|
+
throw error;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
handleReceiveMessage(message, senderType, needsAgent) {
|
|
1155
|
+
if (needsAgent) {
|
|
1156
|
+
this.needsAgent = true;
|
|
1157
|
+
}
|
|
1158
|
+
const sender = this.getSenderType(parseInt(senderType));
|
|
1159
|
+
this.messages.push({
|
|
1160
|
+
id: Date.now(),
|
|
1161
|
+
sender: sender,
|
|
1162
|
+
senderType: parseInt(senderType),
|
|
1163
|
+
messageContent: message,
|
|
1164
|
+
sentAt: new Date(),
|
|
1165
|
+
isSeen: true
|
|
1166
|
+
});
|
|
1167
|
+
console.log(this.messages);
|
|
1168
|
+
this.assistantStatus = 'idle';
|
|
1169
|
+
this.scrollToBottom();
|
|
1170
|
+
}
|
|
1171
|
+
getSenderType(senderType) {
|
|
1172
|
+
switch (senderType) {
|
|
1173
|
+
case 1:
|
|
1174
|
+
return 'user';
|
|
1175
|
+
case 2:
|
|
1176
|
+
return 'agent';
|
|
1177
|
+
default:
|
|
1178
|
+
return 'assistant';
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
async handleStartNewChat(option) {
|
|
1182
|
+
this.selectedOption = option;
|
|
1183
|
+
this.chatIsLoading = true;
|
|
1184
|
+
if (!this.isSignalRConnected) {
|
|
1185
|
+
try {
|
|
1186
|
+
await this.createChatSession();
|
|
1187
|
+
const tokenResponse = await this.apiService.getValidToken();
|
|
1188
|
+
this.showChat = true;
|
|
1189
|
+
this.isChatClosed = false;
|
|
1190
|
+
this.showHelpScreenData = false;
|
|
1191
|
+
await this.signalRService.startConnection(this.sessionId, tokenResponse, this.handleReceiveMessage.bind(this));
|
|
1192
|
+
this.isSignalRConnected = true;
|
|
1193
|
+
// add greeting message
|
|
1194
|
+
this.messages.push({
|
|
1195
|
+
id: Date.now(),
|
|
1196
|
+
sender: 'assistant',
|
|
1197
|
+
senderType: 3,
|
|
1198
|
+
messageContent: option.assistant?.greeting ||
|
|
1199
|
+
(this.currentLang === 'en' ? 'Hello! How can I assist you today?' : 'مرحباً! كيف يمكنني مساعدتك اليوم؟'),
|
|
1200
|
+
sentAt: new Date(),
|
|
1201
|
+
isSeen: true
|
|
1202
|
+
});
|
|
1203
|
+
this.chatIsLoading = false;
|
|
1204
|
+
}
|
|
1205
|
+
catch (error) {
|
|
1206
|
+
console.error('Error connecting to SignalR:', error);
|
|
1207
|
+
this.chatIsLoading = false;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
else {
|
|
1211
|
+
this.showChat = true;
|
|
1212
|
+
this.isChatClosed = false;
|
|
1213
|
+
this.showHelpScreenData = false;
|
|
1214
|
+
this.chatIsLoading = false;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
async startNewChatSession(option) {
|
|
1218
|
+
try {
|
|
1219
|
+
this.status = 'loading';
|
|
1220
|
+
this.error = '';
|
|
1221
|
+
this.messages = [];
|
|
1222
|
+
const chatSessionCreateDto = {
|
|
1223
|
+
helpScreenId: this.helpScreenId,
|
|
1224
|
+
optionId: option.id,
|
|
1225
|
+
...(this.user && {
|
|
1226
|
+
user: {
|
|
1227
|
+
id: this.user.id,
|
|
1228
|
+
name: this.user.name,
|
|
1229
|
+
email: this.user.email
|
|
1230
|
+
}
|
|
1231
|
+
})
|
|
1232
|
+
};
|
|
1233
|
+
const response = await this.apiService.apiRequest('Client/ClientChatSession/create-session', 'POST', chatSessionCreateDto);
|
|
1234
|
+
const createdSession = await response.json();
|
|
1235
|
+
this.sessionId = createdSession.id;
|
|
1236
|
+
// Add greeting message
|
|
1237
|
+
this.messages.push({
|
|
1238
|
+
id: Date.now(),
|
|
1239
|
+
sender: 'assistant',
|
|
1240
|
+
senderType: 3,
|
|
1241
|
+
messageContent: option.assistant?.greeting || 'Hello! How can I assist you today?\nمرحباً! كيف يمكنني مساعدتك اليوم؟',
|
|
1242
|
+
sentAt: new Date(),
|
|
1243
|
+
isSeen: true
|
|
1244
|
+
});
|
|
1245
|
+
this.isSignalRConnected = true;
|
|
1246
|
+
this.isChatClosed = false;
|
|
1247
|
+
this.status = 'succeeded';
|
|
1248
|
+
}
|
|
1249
|
+
catch (error) {
|
|
1250
|
+
console.error('Chat start error:', error);
|
|
1251
|
+
this.error = error.message || 'Failed to start chat session';
|
|
1252
|
+
this.status = 'failed';
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
async handleStartChat(option) {
|
|
1256
|
+
this.showChat = true;
|
|
1257
|
+
await this.startNewChatSession(option);
|
|
1258
|
+
}
|
|
1259
|
+
async handleEndChat() {
|
|
1260
|
+
this.showEndChatConfirmation = true;
|
|
1261
|
+
}
|
|
1262
|
+
async confirmEndChat() {
|
|
1263
|
+
this.showEndChatConfirmation = false;
|
|
1264
|
+
if (this.sessionId) {
|
|
1265
|
+
await this.closeChatSession(this.sessionId);
|
|
1266
|
+
this.sessionId = null;
|
|
1267
|
+
}
|
|
1268
|
+
this.showChat = false;
|
|
1269
|
+
this.showHelpScreenData = true;
|
|
1270
|
+
this.messages = [];
|
|
1271
|
+
this.needsAgent = false;
|
|
1272
|
+
this.assistantStatus = 'idle';
|
|
1273
|
+
this.selectedOption = null;
|
|
1274
|
+
this.selectedNestedOption = null;
|
|
1275
|
+
}
|
|
1276
|
+
cancelEndChat() {
|
|
1277
|
+
this.showEndChatConfirmation = false;
|
|
1278
|
+
}
|
|
1279
|
+
async closeChatSession(chatSessionId) {
|
|
1280
|
+
try {
|
|
1281
|
+
const response = await this.apiService.apiRequest(`Client/ClientChatSession/${chatSessionId}/close`, 'POST');
|
|
1282
|
+
return await response.json();
|
|
1283
|
+
}
|
|
1284
|
+
catch (error) {
|
|
1285
|
+
console.error('Error closing chat session:', error);
|
|
1286
|
+
throw error;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
handleClosePopup() {
|
|
1290
|
+
if (this.showChat) {
|
|
1291
|
+
this.handleEndChat();
|
|
1292
|
+
}
|
|
1293
|
+
this.showHelpScreenData = false;
|
|
1294
|
+
this.showChat = false;
|
|
1295
|
+
this.isPopupOpen = false;
|
|
1296
|
+
this.selectedOption = null;
|
|
1297
|
+
this.selectedNestedOption = null;
|
|
1298
|
+
}
|
|
1299
|
+
handleCloseArrowAnimation() {
|
|
1300
|
+
this.showArrowAnimation = false;
|
|
1301
|
+
}
|
|
1302
|
+
handleBack() {
|
|
1303
|
+
if (this.showChat) {
|
|
1304
|
+
this.showChat = false;
|
|
1305
|
+
this.showHelpScreenData = true;
|
|
1306
|
+
}
|
|
1307
|
+
else if (this.selectedNestedOption) {
|
|
1308
|
+
this.selectedNestedOption = null;
|
|
1309
|
+
}
|
|
1310
|
+
else if (this.selectedOption) {
|
|
1311
|
+
this.selectedOption = null;
|
|
1312
|
+
}
|
|
1313
|
+
else if (this.showHelpScreenData) {
|
|
1314
|
+
this.showHelpScreenData = false;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
handleShowChat() {
|
|
1318
|
+
this.showChat = true;
|
|
1319
|
+
this.showHelpScreenData = false;
|
|
1320
|
+
}
|
|
1321
|
+
selectOption(option) {
|
|
1322
|
+
this.selectedOption = option;
|
|
1323
|
+
this.selectedNestedOption = null;
|
|
1324
|
+
}
|
|
1325
|
+
selectNestedOption(nestedOption) {
|
|
1326
|
+
this.selectedNestedOption = nestedOption;
|
|
1327
|
+
}
|
|
1328
|
+
handleShowHelpScreenData() {
|
|
1329
|
+
this.showHelpScreenData = true;
|
|
1330
|
+
}
|
|
1331
|
+
handleHideHelpScreenData() {
|
|
1332
|
+
this.showHelpScreenData = false;
|
|
1333
|
+
}
|
|
1334
|
+
scrollToBottom() {
|
|
1335
|
+
setTimeout(() => {
|
|
1336
|
+
if (this.chatMessagesContainer) {
|
|
1337
|
+
const element = this.chatMessagesContainer.nativeElement;
|
|
1338
|
+
element.scrollTop = element.scrollHeight;
|
|
1339
|
+
}
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
getDirection() {
|
|
1343
|
+
return this.currentLang === 'ar' ? 'rtl' : 'ltr';
|
|
1344
|
+
}
|
|
1345
|
+
get helpScreenDataList() {
|
|
1346
|
+
if (!this.helpScreenData?.options)
|
|
1347
|
+
return [];
|
|
1348
|
+
// Transform options to the format expected by HelpScreenDataComponent
|
|
1349
|
+
return this.helpScreenData.options.map((option) => ({
|
|
1350
|
+
icon: option.icon || '/icons/default.svg',
|
|
1351
|
+
title: option.title,
|
|
1352
|
+
description: option.paragraphs?.[0] || '',
|
|
1353
|
+
actionLabel: option.chatWithUs ? 'Chat Now' : '',
|
|
1354
|
+
action: option.chatWithUs ? () => this.handleStartChat(option) : null
|
|
1355
|
+
}));
|
|
1356
|
+
}
|
|
1357
|
+
navigateToUrl(url) {
|
|
1358
|
+
window.open(url, '_blank');
|
|
1359
|
+
}
|
|
1360
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: HelpCenterWidgetComponent, deps: [{ token: ApiService }, { token: SignalRService }, { token: TokenService }, { token: TranslationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1361
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.11", type: HelpCenterWidgetComponent, isStandalone: true, selector: "app-help-center-widget", inputs: { getToken: "getToken", helpScreenId: "helpScreenId", user: "user", showArrow: "showArrow", messageLabel: "messageLabel", currentLang: "currentLang" }, viewQueries: [{ propertyName: "chatMessagesContainer", first: true, predicate: ["chatMessagesContainer"], descendants: true }], ngImport: i0, template: "<div class=\"babylai-fixed babylai-bottom-5 babylai-right-5 babylai-z-[9999]\" [dir]=\"getDirection()\">\n <!-- Arrow Animation -->\n <div\n *ngIf=\"showArrowAnimation && !isPopupOpen\"\n class=\"babylai-fixed babylai-bottom-20 babylai-right-4 babylai-z-[1300] babylai-flex babylai-flex-col babylai-items-end babylai-animate-float\"\n >\n <div\n class=\"babylai-bg-primary babylai-text-white babylai-py-3 babylai-px-4 babylai-rounded-3xl babylai-shadow-lg babylai-mb-4 babylai-max-w-[200px] babylai-relative\"\n >\n <p class=\"babylai-text-xs babylai-font-bold babylai-m-0\">\n {{ messageLabel || 'Need assistance Or You want to try the Product? Click here' }}\n </p>\n <button\n class=\"babylai-absolute babylai-top-[-8px] babylai-right-[-8px] babylai-w-5 babylai-h-5 babylai-rounded-full babylai-bg-white babylai-border-none babylai-cursor-pointer babylai-flex babylai-items-center babylai-justify-center babylai-text-black babylai-p-[3px] hover:babylai-bg-primary-700 hover:babylai-text-white\"\n (click)=\"handleCloseArrowAnimation()\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\">\n <path d=\"M1 1L11 11M1 11L11 1\" stroke=\"currentColor\" strokeWidth=\"2\" />\n </svg>\n </button>\n <div\n class=\"babylai-absolute babylai-bottom-[-10px] babylai-right-5 babylai-w-0 babylai-h-0 babylai-border-l-[10px] babylai-border-r-[10px] babylai-border-t-[10px] babylai-border-l-transparent babylai-border-r-transparent babylai-border-t-primary\"\n ></div>\n </div>\n </div>\n\n <!-- Help Button -->\n <button\n class=\"babylai-w-14 babylai-h-14 babylai-rounded-full babylai-bg-primary babylai-text-white babylai-border-none babylai-cursor-pointer babylai-flex babylai-items-center babylai-justify-center babylai-shadow-md babylai-transition-transform babylai-duration-200 babylai-fixed babylai-bottom-5 babylai-right-5 babylai-z-[1000] hover:babylai-bg-primary-700 hover:babylai-scale-105 active:babylai-scale-95\"\n (click)=\"handleTogglePopup()\"\n >\n <span class=\"babylai-flex babylai-items-center babylai-justify-center\">\n <img src=\"/logo-white.svg\" alt=\"BabylAI Logo\" class=\"babylai-w-6 babylai-h-6\" />\n </span>\n </button>\n\n <!-- Help Popup -->\n <div\n *ngIf=\"isPopupOpen\"\n [ngClass]=\"{\n 'babylai-fixed babylai-bottom-20 babylai-right-5 babylai-w-[360px] babylai-h-[684px] babylai-rounded-3xl babylai-shadow-lg babylai-flex babylai-flex-col babylai-z-[1000] babylai-bg-black-white-100': true,\n 'babylai-w-[360px]': isPopupOpen,\n 'babylai-w-[60px]': !isPopupOpen,\n 'babylai-bg-gradient-to-b babylai-from-primary-500 babylai-to-primary-500/60': isPopupOpen && !showHelpScreenData && !showChat\n }\"\n >\n <app-confirmation-dialog\n *ngIf=\"showEndChatConfirmation\"\n [title]=\"'LeavingDialogTitle' | translate\"\n [body]=\"'LeavingDialogBody' | translate\"\n [confirmText]=\"'Confirm' | translate\"\n [cancelText]=\"'Cancel' | translate\"\n (onConfirm)=\"confirmEndChat()\"\n (onCancel)=\"cancelEndChat()\"\n ></app-confirmation-dialog>\n <!-- Loading State -->\n <div *ngIf=\"status === 'loading'\">\n <!-- Using existing header -->\n <ng-container *ngIf=\"!showHelpScreenData\">\n <app-header\n [showBackButton]=\"!!selectedOption || !!selectedNestedOption\"\n [showLogo]=\"true\"\n (onBack)=\"handleBack()\"\n (onClose)=\"handleClosePopup()\"\n >\n </app-header>\n </ng-container>\n <ng-container *ngIf=\"showHelpScreenData\">\n <app-header [showLogo]=\"false\" (onClose)=\"handleHideHelpScreenData()\"> </app-header>\n </ng-container>\n\n <!-- Animated Logo -->\n <app-loading></app-loading>\n </div>\n\n <!-- Error State -->\n <div\n *ngIf=\"status === 'failed'\"\n class=\"babylai-fixed babylai-bottom-[90px] babylai-right-5 babylai-p-4 babylai-bg-white babylai-rounded-xl babylai-shadow-lg\"\n >\n <span>Error: {{ error }}</span>\n </div>\n\n <!-- Content -->\n <ng-container *ngIf=\"status === 'succeeded'\">\n <!-- Header -->\n <ng-container *ngIf=\"!showHelpScreenData && !showChat\">\n <app-header\n [showBackButton]=\"!!selectedOption || !!selectedNestedOption\"\n [showLogo]=\"true\"\n (onBack)=\"handleBack()\"\n (onClose)=\"handleClosePopup()\"\n >\n </app-header>\n </ng-container>\n <ng-container *ngIf=\"showHelpScreenData && !showChat\">\n <app-header\n [showBackButton]=\"showHelpScreenData\"\n [showLogo]=\"false\"\n (onClose)=\"handleHideHelpScreenData()\"\n (onBack)=\"handleBack()\"\n [language]=\"currentLang\"\n >\n </app-header>\n\n <ng-container *ngIf=\"showHelpScreenData && sessionId\">\n <app-button\n variant=\"icon-bg\"\n (click)=\"handleShowChat()\"\n className=\"babylai-absolute babylai-bottom-5 babylai-right-5 !babylai-p-3\"\n >\n <img src=\"/icons/chat.svg\" alt=\"Close\" class=\"babylai-w-full\" />\n </app-button>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"showChat\">\n <app-chat-header\n [showBackButton]=\"showChat\"\n [showLogo]=\"false\"\n (onClose)=\"handleEndChat()\"\n (onBack)=\"handleBack()\"\n [language]=\"currentLang\"\n >\n </app-chat-header>\n\n <app-chat\n class=\"babylai-h-full babylai-mt-2 babylai-p-2 babylai-max-h-[85%]\"\n [messages]=\"messages\"\n [needsAgent]=\"needsAgent\"\n [assistantStatus]=\"assistantStatus\"\n [isSignalRConnected]=\"isSignalRConnected\"\n [isChatClosed]=\"isChatClosed\"\n (sendMessageEvent)=\"sendMessage($event)\"\n [currentLang]=\"currentLang\"\n [loading]=\"chatIsLoading\"\n >\n </app-chat>\n </ng-container>\n\n <!-- Content -->\n <div class=\"babylai-flex-1 babylai-flex babylai-flex-col babylai-gap-4 babylai-overflow-y-auto babylai-p-4\" *ngIf=\"!showChat\">\n <ng-container *ngIf=\"!showHelpScreenData\">\n <div class=\"babylai-flex babylai-flex-col babylai-gap-4\">\n <h1 class=\"babylai-text-6xl babylai-font-bold babylai-text-black-white-50\">{{ 'ChatIntroMessage' | translate }}</h1>\n </div>\n\n <div class=\"babylai-flex babylai-flex-col babylai-gap-4 babylai-mt-8\">\n <app-card variant=\"rounded\">\n <app-card-content>\n <div class=\"babylai-flex babylai-flex-col babylai-gap-4\">\n <div class=\"babylai-flex babylai-items-center babylai-justify-start babylai-gap-3\">\n <div\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-max-w-12 babylai-min-w-12 babylai-w-12 babylai-h-12 babylai-rounded-full babylai-bg-primary\"\n >\n <img src=\"/logo-white.svg\" alt=\"Chat\" class=\"babylai-w-5 babylai-h-5\" />\n </div>\n <div class=\"babylai-flex babylai-flex-col babylai-items-start babylai-justify-start babylai-gap-0\">\n <h4 class=\"babylai-text-base babylai-text-black-white-400 babylai-font-semibold\">\n {{ 'BabylaiTitle' | translate }}\n </h4>\n <p class=\"babylai-text-base babylai-text-black-white-800\">{{ 'BabylaiDescription' | translate }}</p>\n </div>\n </div>\n <app-button variant=\"default\" [fullWidth]=\"true\" (click)=\"handleShowHelpScreenData()\">\n {{ 'ChatNow' | translate }}\n </app-button>\n </div>\n </app-card-content>\n </app-card>\n\n <app-card variant=\"rounded\">\n <app-card-content>\n <div class=\"babylai-flex babylai-items-center babylai-justify-between babylai-gap-4\">\n <p class=\"babylai-text-base babylai-text-black-white-800\">{{ 'TryBableAI' | translate }}</p>\n <app-button variant=\"icon-bg\" (click)=\"navigateToUrl('https://babylai.net/signup')\">\n <img\n src=\"/icons/arrow-stripped.svg\"\n alt=\"Arrow Right\"\n [ngClass]=\"{ 'babylai-w-5 babylai-h-5': true, 'babylai-rotate-180': currentLang === 'ar' }\"\n />\n </app-button>\n </div>\n </app-card-content>\n </app-card>\n\n <app-card variant=\"rounded\">\n <app-card-content>\n <div class=\"babylai-flex babylai-items-center babylai-justify-between babylai-gap-4\">\n <p class=\"babylai-text-base babylai-text-black-white-800\">{{ 'ContactUs' | translate }}</p>\n <app-button variant=\"icon-bg\" (click)=\"navigateToUrl('https://babylai.net')\">\n <img\n src=\"/icons/arrow-stripped.svg\"\n alt=\"Arrow Right\"\n [ngClass]=\"{ 'babylai-w-5 babylai-h-5': true, 'babylai-rotate-180': currentLang === 'ar' }\"\n />\n </app-button>\n </div>\n </app-card-content>\n </app-card>\n </div>\n </ng-container>\n <ng-container *ngIf=\"showHelpScreenData\">\n <app-help-screen-data [helpScreenData]=\"helpScreenData\" (handleStartNewChat)=\"handleStartNewChat($event)\"></app-help-screen-data>\n </ng-container>\n </div>\n\n <!-- Footer -->\n <div class=\"babylai-flex babylai-justify-between babylai-items-center babylai-px-5 babylai-py-2.5\">\n <a\n href=\"https://babylai.net\"\n target=\"_blank\"\n class=\"babylai-text-xs babylai-text-black-white-300 babylai-w-full babylai-text-center\"\n [ngClass]=\"!showHelpScreenData && !showChat ? 'babylai-text-black-white-50' : ''\"\n >\n {{ 'PoweredByBabylAI' | translate }}\n </a>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".babylai-help-center-container{position:fixed;bottom:20px;right:20px;z-index:9999}.babylai-help-center-loadingContainer,.babylai-help-center-errorContainer{position:fixed;bottom:90px;right:20px;padding:16px;background:#fff;border-radius:12px;box-shadow:0 4px 20px #00000026}.babylai-help-center-popup{position:fixed;bottom:80px;right:20px;width:360px;max-height:600px;background:#fff;border-radius:12px;box-shadow:0 4px 20px #00000026;display:flex;flex-direction:column;z-index:1000}.babylai-help-center-header{padding:16px;border-bottom:1px solid #eee;display:flex;align-items:center;justify-content:space-between}.babylai-help-center-title{margin:0;font-size:18px;font-weight:500}.babylai-help-center-backButton{background:none;border:none;cursor:pointer;padding:4px;color:#666}.babylai-help-center-content{flex:1;overflow-y:auto;padding:16px}.babylai-help-center-optionsList{display:flex;flex-direction:column;gap:8px}.babylai-help-center-optionButton{padding:12px;background:#f5f5f5;border:none;border-radius:8px;cursor:pointer;text-align:left;font-size:14px}.babylai-help-center-optionButton:hover{background:#eee}.babylai-help-center-detailsContent{display:flex;flex-direction:column;gap:12px}.babylai-help-center-paragraph{margin:0;line-height:1.5}.babylai-help-center-chatButton{background-color:#f44;color:#fff;font-size:14px;margin-top:16px;padding:12px 24px;border:none;border-radius:12px;cursor:pointer;font-weight:500;transition:background-color .2s;align-self:center}.babylai-help-center-chatButton:hover{background-color:#c00}.babylai-help-center-chatContainer{display:flex;flex-direction:column;height:400px;overflow:hidden}.babylai-help-center-chatMessages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:8px}.babylai-help-center-message{max-width:80%;padding:8px 12px;border-radius:12px;position:relative}.babylai-help-center-userMessage{align-self:flex-start;background-color:#7a8ce9;color:#fff;direction:rtl}.babylai-help-center-assistantMessage{align-self:flex-end;background-color:#f1f1f1;color:#000;direction:rtl}.babylai-help-center-seenIndicator{position:absolute;bottom:-4px;right:4px;font-size:10px;color:#666}.babylai-help-center-chatInput{display:flex;gap:8px;padding:16px;border-top:1px solid #eee;background:#fff;position:relative}.babylai-help-center-chatInput input{flex:1;padding:8px 12px;border:1px solid #ddd;border-radius:20px;outline:none}.babylai-help-center-chatInput input:focus{border-color:#7a8ce9}.babylai-help-center-sendButton{width:40px;height:40px;border-radius:50%;background:#7a8ce9;border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background-color .2s}.babylai-help-center-sendButton:hover{background:#6675c3}.babylai-help-center-sendButton:disabled{background:#ccc;cursor:not-allowed}.babylai-help-center-footer{display:flex;justify-content:space-between;align-items:center;padding:10px 20px}.babylai-help-center-footerText{margin:0;font-size:12px;color:#999}.babylai-help-center-endChatButton{background-color:#f44;color:#fff;border:none;padding:5px 15px;border-radius:4px;cursor:pointer;font-size:14px}.babylai-help-center-endChatButton:hover{background-color:#c00}.babylai-help-center-typingIndicator{display:flex;gap:4px}.babylai-help-center-typingIndicator span{animation:bounce 1s infinite}.babylai-help-center-typingIndicator span:nth-child(2){animation-delay:.2s}.babylai-help-center-typingIndicator span:nth-child(3){animation-delay:.4s}.babylai-help-center-dialogOverlay{position:fixed;inset:0;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:1100}.babylai-help-center-dialog{background:#fff;border-radius:8px;padding:20px;width:90%;max-width:400px;box-shadow:0 4px 20px #00000026}.babylai-help-center-helpButton{width:56px;height:56px;border-radius:50%;background-color:#7a8ce9;color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px #00000026;transition:transform .2s,background-color .2s;position:fixed;bottom:20px;right:20px;z-index:1000}.babylai-help-center-helpButton:hover{background-color:#6270ba;transform:scale(1.05)}.babylai-help-center-helpButton:active{transform:scale(.95)}.babylai-help-center-helpIcon{display:flex;align-items:center;justify-content:center}.babylai-help-center-arrowBox{position:fixed;bottom:80px;right:15px;z-index:1300;display:flex;flex-direction:column;align-items:flex-end;animation:float 3s infinite ease-in-out}.babylai-help-center-messageBox{background-color:#7a8ce9;color:#fff;padding:12px 16px;border-radius:20px;box-shadow:0 4px 20px #00000026;margin-bottom:16px;max-width:200px;position:relative}.babylai-help-center-messageBox:after{content:\"\";position:absolute;bottom:-10px;right:20px;width:0;height:0;border-left:10px solid transparent;border-right:10px solid transparent;border-top:10px solid rgb(122,140,233)}.babylai-help-center-text{font-size:12px;font-weight:700;margin:0}.babylai-help-center-closeButton{position:absolute;top:-8px;right:-8px;width:20px;height:20px;border-radius:50%;background:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#000;padding:3px}.babylai-help-center-closeButton:hover{background-color:#6675c3;color:#fff}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-10px)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.05)}to{transform:scale(1)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.babylai-help-center-spinner{width:24px;height:24px;border:3px solid #f3f3f3;border-top:3px solid rgba(122,140,233,.7);border-radius:50%;animation:spin 1s linear infinite}\n", ":host{display:block;width:100%;height:100%}.help-center-container{width:100%;height:100%}\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: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: CardComponent, selector: "app-card", inputs: ["variant", "class"] }, { kind: "component", type: CardContentComponent, selector: "app-card-content", inputs: ["class"] }, { kind: "component", type: ButtonComponent, selector: "app-button", inputs: ["variant", "type", "disabled", "fullWidth", "className"], outputs: ["onClick"] }, { kind: "component", type: HelpScreenDataComponent, selector: "app-help-screen-data", inputs: ["helpScreenData", "title"], outputs: ["handleStartNewChat"] }, { kind: "component", type: HeaderComponent, selector: "app-header", inputs: ["headerType", "showBackButton", "showLogo", "logoSrc", "logoAlt", "language"], outputs: ["onBack", "onClose"] }, { kind: "component", type: ChatHeaderComponent, selector: "app-chat-header", inputs: ["showBackButton", "showLogo", "logoSrc", "logoAlt", "language"], outputs: ["onBack", "onClose"] }, { kind: "component", type: ChatComponent, selector: "app-chat", inputs: ["messages", "needsAgent", "assistantStatus", "isSignalRConnected", "isChatClosed", "currentLang", "loading"], outputs: ["sendMessageEvent"] }, { kind: "component", type: LoadingComponent, selector: "app-loading" }, { kind: "component", type: ConfirmationDialogComponent, selector: "app-confirmation-dialog", inputs: ["title", "body", "confirmText", "cancelText"], outputs: ["onConfirm", "onCancel"] }] });
|
|
1362
|
+
}
|
|
1363
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: HelpCenterWidgetComponent, decorators: [{
|
|
1364
|
+
type: Component,
|
|
1365
|
+
args: [{ selector: 'app-help-center-widget', standalone: true, imports: [
|
|
1366
|
+
CommonModule,
|
|
1367
|
+
FormsModule,
|
|
1368
|
+
TranslatePipe,
|
|
1369
|
+
CardComponent,
|
|
1370
|
+
CardContentComponent,
|
|
1371
|
+
ButtonComponent,
|
|
1372
|
+
HelpScreenDataComponent,
|
|
1373
|
+
HeaderComponent,
|
|
1374
|
+
ChatHeaderComponent,
|
|
1375
|
+
ChatComponent,
|
|
1376
|
+
LoadingComponent,
|
|
1377
|
+
ConfirmationDialogComponent
|
|
1378
|
+
], template: "<div class=\"babylai-fixed babylai-bottom-5 babylai-right-5 babylai-z-[9999]\" [dir]=\"getDirection()\">\n <!-- Arrow Animation -->\n <div\n *ngIf=\"showArrowAnimation && !isPopupOpen\"\n class=\"babylai-fixed babylai-bottom-20 babylai-right-4 babylai-z-[1300] babylai-flex babylai-flex-col babylai-items-end babylai-animate-float\"\n >\n <div\n class=\"babylai-bg-primary babylai-text-white babylai-py-3 babylai-px-4 babylai-rounded-3xl babylai-shadow-lg babylai-mb-4 babylai-max-w-[200px] babylai-relative\"\n >\n <p class=\"babylai-text-xs babylai-font-bold babylai-m-0\">\n {{ messageLabel || 'Need assistance Or You want to try the Product? Click here' }}\n </p>\n <button\n class=\"babylai-absolute babylai-top-[-8px] babylai-right-[-8px] babylai-w-5 babylai-h-5 babylai-rounded-full babylai-bg-white babylai-border-none babylai-cursor-pointer babylai-flex babylai-items-center babylai-justify-center babylai-text-black babylai-p-[3px] hover:babylai-bg-primary-700 hover:babylai-text-white\"\n (click)=\"handleCloseArrowAnimation()\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\">\n <path d=\"M1 1L11 11M1 11L11 1\" stroke=\"currentColor\" strokeWidth=\"2\" />\n </svg>\n </button>\n <div\n class=\"babylai-absolute babylai-bottom-[-10px] babylai-right-5 babylai-w-0 babylai-h-0 babylai-border-l-[10px] babylai-border-r-[10px] babylai-border-t-[10px] babylai-border-l-transparent babylai-border-r-transparent babylai-border-t-primary\"\n ></div>\n </div>\n </div>\n\n <!-- Help Button -->\n <button\n class=\"babylai-w-14 babylai-h-14 babylai-rounded-full babylai-bg-primary babylai-text-white babylai-border-none babylai-cursor-pointer babylai-flex babylai-items-center babylai-justify-center babylai-shadow-md babylai-transition-transform babylai-duration-200 babylai-fixed babylai-bottom-5 babylai-right-5 babylai-z-[1000] hover:babylai-bg-primary-700 hover:babylai-scale-105 active:babylai-scale-95\"\n (click)=\"handleTogglePopup()\"\n >\n <span class=\"babylai-flex babylai-items-center babylai-justify-center\">\n <img src=\"/logo-white.svg\" alt=\"BabylAI Logo\" class=\"babylai-w-6 babylai-h-6\" />\n </span>\n </button>\n\n <!-- Help Popup -->\n <div\n *ngIf=\"isPopupOpen\"\n [ngClass]=\"{\n 'babylai-fixed babylai-bottom-20 babylai-right-5 babylai-w-[360px] babylai-h-[684px] babylai-rounded-3xl babylai-shadow-lg babylai-flex babylai-flex-col babylai-z-[1000] babylai-bg-black-white-100': true,\n 'babylai-w-[360px]': isPopupOpen,\n 'babylai-w-[60px]': !isPopupOpen,\n 'babylai-bg-gradient-to-b babylai-from-primary-500 babylai-to-primary-500/60': isPopupOpen && !showHelpScreenData && !showChat\n }\"\n >\n <app-confirmation-dialog\n *ngIf=\"showEndChatConfirmation\"\n [title]=\"'LeavingDialogTitle' | translate\"\n [body]=\"'LeavingDialogBody' | translate\"\n [confirmText]=\"'Confirm' | translate\"\n [cancelText]=\"'Cancel' | translate\"\n (onConfirm)=\"confirmEndChat()\"\n (onCancel)=\"cancelEndChat()\"\n ></app-confirmation-dialog>\n <!-- Loading State -->\n <div *ngIf=\"status === 'loading'\">\n <!-- Using existing header -->\n <ng-container *ngIf=\"!showHelpScreenData\">\n <app-header\n [showBackButton]=\"!!selectedOption || !!selectedNestedOption\"\n [showLogo]=\"true\"\n (onBack)=\"handleBack()\"\n (onClose)=\"handleClosePopup()\"\n >\n </app-header>\n </ng-container>\n <ng-container *ngIf=\"showHelpScreenData\">\n <app-header [showLogo]=\"false\" (onClose)=\"handleHideHelpScreenData()\"> </app-header>\n </ng-container>\n\n <!-- Animated Logo -->\n <app-loading></app-loading>\n </div>\n\n <!-- Error State -->\n <div\n *ngIf=\"status === 'failed'\"\n class=\"babylai-fixed babylai-bottom-[90px] babylai-right-5 babylai-p-4 babylai-bg-white babylai-rounded-xl babylai-shadow-lg\"\n >\n <span>Error: {{ error }}</span>\n </div>\n\n <!-- Content -->\n <ng-container *ngIf=\"status === 'succeeded'\">\n <!-- Header -->\n <ng-container *ngIf=\"!showHelpScreenData && !showChat\">\n <app-header\n [showBackButton]=\"!!selectedOption || !!selectedNestedOption\"\n [showLogo]=\"true\"\n (onBack)=\"handleBack()\"\n (onClose)=\"handleClosePopup()\"\n >\n </app-header>\n </ng-container>\n <ng-container *ngIf=\"showHelpScreenData && !showChat\">\n <app-header\n [showBackButton]=\"showHelpScreenData\"\n [showLogo]=\"false\"\n (onClose)=\"handleHideHelpScreenData()\"\n (onBack)=\"handleBack()\"\n [language]=\"currentLang\"\n >\n </app-header>\n\n <ng-container *ngIf=\"showHelpScreenData && sessionId\">\n <app-button\n variant=\"icon-bg\"\n (click)=\"handleShowChat()\"\n className=\"babylai-absolute babylai-bottom-5 babylai-right-5 !babylai-p-3\"\n >\n <img src=\"/icons/chat.svg\" alt=\"Close\" class=\"babylai-w-full\" />\n </app-button>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"showChat\">\n <app-chat-header\n [showBackButton]=\"showChat\"\n [showLogo]=\"false\"\n (onClose)=\"handleEndChat()\"\n (onBack)=\"handleBack()\"\n [language]=\"currentLang\"\n >\n </app-chat-header>\n\n <app-chat\n class=\"babylai-h-full babylai-mt-2 babylai-p-2 babylai-max-h-[85%]\"\n [messages]=\"messages\"\n [needsAgent]=\"needsAgent\"\n [assistantStatus]=\"assistantStatus\"\n [isSignalRConnected]=\"isSignalRConnected\"\n [isChatClosed]=\"isChatClosed\"\n (sendMessageEvent)=\"sendMessage($event)\"\n [currentLang]=\"currentLang\"\n [loading]=\"chatIsLoading\"\n >\n </app-chat>\n </ng-container>\n\n <!-- Content -->\n <div class=\"babylai-flex-1 babylai-flex babylai-flex-col babylai-gap-4 babylai-overflow-y-auto babylai-p-4\" *ngIf=\"!showChat\">\n <ng-container *ngIf=\"!showHelpScreenData\">\n <div class=\"babylai-flex babylai-flex-col babylai-gap-4\">\n <h1 class=\"babylai-text-6xl babylai-font-bold babylai-text-black-white-50\">{{ 'ChatIntroMessage' | translate }}</h1>\n </div>\n\n <div class=\"babylai-flex babylai-flex-col babylai-gap-4 babylai-mt-8\">\n <app-card variant=\"rounded\">\n <app-card-content>\n <div class=\"babylai-flex babylai-flex-col babylai-gap-4\">\n <div class=\"babylai-flex babylai-items-center babylai-justify-start babylai-gap-3\">\n <div\n class=\"babylai-flex babylai-items-center babylai-justify-center babylai-max-w-12 babylai-min-w-12 babylai-w-12 babylai-h-12 babylai-rounded-full babylai-bg-primary\"\n >\n <img src=\"/logo-white.svg\" alt=\"Chat\" class=\"babylai-w-5 babylai-h-5\" />\n </div>\n <div class=\"babylai-flex babylai-flex-col babylai-items-start babylai-justify-start babylai-gap-0\">\n <h4 class=\"babylai-text-base babylai-text-black-white-400 babylai-font-semibold\">\n {{ 'BabylaiTitle' | translate }}\n </h4>\n <p class=\"babylai-text-base babylai-text-black-white-800\">{{ 'BabylaiDescription' | translate }}</p>\n </div>\n </div>\n <app-button variant=\"default\" [fullWidth]=\"true\" (click)=\"handleShowHelpScreenData()\">\n {{ 'ChatNow' | translate }}\n </app-button>\n </div>\n </app-card-content>\n </app-card>\n\n <app-card variant=\"rounded\">\n <app-card-content>\n <div class=\"babylai-flex babylai-items-center babylai-justify-between babylai-gap-4\">\n <p class=\"babylai-text-base babylai-text-black-white-800\">{{ 'TryBableAI' | translate }}</p>\n <app-button variant=\"icon-bg\" (click)=\"navigateToUrl('https://babylai.net/signup')\">\n <img\n src=\"/icons/arrow-stripped.svg\"\n alt=\"Arrow Right\"\n [ngClass]=\"{ 'babylai-w-5 babylai-h-5': true, 'babylai-rotate-180': currentLang === 'ar' }\"\n />\n </app-button>\n </div>\n </app-card-content>\n </app-card>\n\n <app-card variant=\"rounded\">\n <app-card-content>\n <div class=\"babylai-flex babylai-items-center babylai-justify-between babylai-gap-4\">\n <p class=\"babylai-text-base babylai-text-black-white-800\">{{ 'ContactUs' | translate }}</p>\n <app-button variant=\"icon-bg\" (click)=\"navigateToUrl('https://babylai.net')\">\n <img\n src=\"/icons/arrow-stripped.svg\"\n alt=\"Arrow Right\"\n [ngClass]=\"{ 'babylai-w-5 babylai-h-5': true, 'babylai-rotate-180': currentLang === 'ar' }\"\n />\n </app-button>\n </div>\n </app-card-content>\n </app-card>\n </div>\n </ng-container>\n <ng-container *ngIf=\"showHelpScreenData\">\n <app-help-screen-data [helpScreenData]=\"helpScreenData\" (handleStartNewChat)=\"handleStartNewChat($event)\"></app-help-screen-data>\n </ng-container>\n </div>\n\n <!-- Footer -->\n <div class=\"babylai-flex babylai-justify-between babylai-items-center babylai-px-5 babylai-py-2.5\">\n <a\n href=\"https://babylai.net\"\n target=\"_blank\"\n class=\"babylai-text-xs babylai-text-black-white-300 babylai-w-full babylai-text-center\"\n [ngClass]=\"!showHelpScreenData && !showChat ? 'babylai-text-black-white-50' : ''\"\n >\n {{ 'PoweredByBabylAI' | translate }}\n </a>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".babylai-help-center-container{position:fixed;bottom:20px;right:20px;z-index:9999}.babylai-help-center-loadingContainer,.babylai-help-center-errorContainer{position:fixed;bottom:90px;right:20px;padding:16px;background:#fff;border-radius:12px;box-shadow:0 4px 20px #00000026}.babylai-help-center-popup{position:fixed;bottom:80px;right:20px;width:360px;max-height:600px;background:#fff;border-radius:12px;box-shadow:0 4px 20px #00000026;display:flex;flex-direction:column;z-index:1000}.babylai-help-center-header{padding:16px;border-bottom:1px solid #eee;display:flex;align-items:center;justify-content:space-between}.babylai-help-center-title{margin:0;font-size:18px;font-weight:500}.babylai-help-center-backButton{background:none;border:none;cursor:pointer;padding:4px;color:#666}.babylai-help-center-content{flex:1;overflow-y:auto;padding:16px}.babylai-help-center-optionsList{display:flex;flex-direction:column;gap:8px}.babylai-help-center-optionButton{padding:12px;background:#f5f5f5;border:none;border-radius:8px;cursor:pointer;text-align:left;font-size:14px}.babylai-help-center-optionButton:hover{background:#eee}.babylai-help-center-detailsContent{display:flex;flex-direction:column;gap:12px}.babylai-help-center-paragraph{margin:0;line-height:1.5}.babylai-help-center-chatButton{background-color:#f44;color:#fff;font-size:14px;margin-top:16px;padding:12px 24px;border:none;border-radius:12px;cursor:pointer;font-weight:500;transition:background-color .2s;align-self:center}.babylai-help-center-chatButton:hover{background-color:#c00}.babylai-help-center-chatContainer{display:flex;flex-direction:column;height:400px;overflow:hidden}.babylai-help-center-chatMessages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:8px}.babylai-help-center-message{max-width:80%;padding:8px 12px;border-radius:12px;position:relative}.babylai-help-center-userMessage{align-self:flex-start;background-color:#7a8ce9;color:#fff;direction:rtl}.babylai-help-center-assistantMessage{align-self:flex-end;background-color:#f1f1f1;color:#000;direction:rtl}.babylai-help-center-seenIndicator{position:absolute;bottom:-4px;right:4px;font-size:10px;color:#666}.babylai-help-center-chatInput{display:flex;gap:8px;padding:16px;border-top:1px solid #eee;background:#fff;position:relative}.babylai-help-center-chatInput input{flex:1;padding:8px 12px;border:1px solid #ddd;border-radius:20px;outline:none}.babylai-help-center-chatInput input:focus{border-color:#7a8ce9}.babylai-help-center-sendButton{width:40px;height:40px;border-radius:50%;background:#7a8ce9;border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background-color .2s}.babylai-help-center-sendButton:hover{background:#6675c3}.babylai-help-center-sendButton:disabled{background:#ccc;cursor:not-allowed}.babylai-help-center-footer{display:flex;justify-content:space-between;align-items:center;padding:10px 20px}.babylai-help-center-footerText{margin:0;font-size:12px;color:#999}.babylai-help-center-endChatButton{background-color:#f44;color:#fff;border:none;padding:5px 15px;border-radius:4px;cursor:pointer;font-size:14px}.babylai-help-center-endChatButton:hover{background-color:#c00}.babylai-help-center-typingIndicator{display:flex;gap:4px}.babylai-help-center-typingIndicator span{animation:bounce 1s infinite}.babylai-help-center-typingIndicator span:nth-child(2){animation-delay:.2s}.babylai-help-center-typingIndicator span:nth-child(3){animation-delay:.4s}.babylai-help-center-dialogOverlay{position:fixed;inset:0;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:1100}.babylai-help-center-dialog{background:#fff;border-radius:8px;padding:20px;width:90%;max-width:400px;box-shadow:0 4px 20px #00000026}.babylai-help-center-helpButton{width:56px;height:56px;border-radius:50%;background-color:#7a8ce9;color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px #00000026;transition:transform .2s,background-color .2s;position:fixed;bottom:20px;right:20px;z-index:1000}.babylai-help-center-helpButton:hover{background-color:#6270ba;transform:scale(1.05)}.babylai-help-center-helpButton:active{transform:scale(.95)}.babylai-help-center-helpIcon{display:flex;align-items:center;justify-content:center}.babylai-help-center-arrowBox{position:fixed;bottom:80px;right:15px;z-index:1300;display:flex;flex-direction:column;align-items:flex-end;animation:float 3s infinite ease-in-out}.babylai-help-center-messageBox{background-color:#7a8ce9;color:#fff;padding:12px 16px;border-radius:20px;box-shadow:0 4px 20px #00000026;margin-bottom:16px;max-width:200px;position:relative}.babylai-help-center-messageBox:after{content:\"\";position:absolute;bottom:-10px;right:20px;width:0;height:0;border-left:10px solid transparent;border-right:10px solid transparent;border-top:10px solid rgb(122,140,233)}.babylai-help-center-text{font-size:12px;font-weight:700;margin:0}.babylai-help-center-closeButton{position:absolute;top:-8px;right:-8px;width:20px;height:20px;border-radius:50%;background:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#000;padding:3px}.babylai-help-center-closeButton:hover{background-color:#6675c3;color:#fff}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-10px)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.05)}to{transform:scale(1)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.babylai-help-center-spinner{width:24px;height:24px;border:3px solid #f3f3f3;border-top:3px solid rgba(122,140,233,.7);border-radius:50%;animation:spin 1s linear infinite}\n", ":host{display:block;width:100%;height:100%}.help-center-container{width:100%;height:100%}\n"] }]
|
|
1379
|
+
}], ctorParameters: () => [{ type: ApiService }, { type: SignalRService }, { type: TokenService }, { type: TranslationService }], propDecorators: { getToken: [{
|
|
1380
|
+
type: Input
|
|
1381
|
+
}], helpScreenId: [{
|
|
1382
|
+
type: Input
|
|
1383
|
+
}], user: [{
|
|
1384
|
+
type: Input
|
|
1385
|
+
}], showArrow: [{
|
|
1386
|
+
type: Input
|
|
1387
|
+
}], messageLabel: [{
|
|
1388
|
+
type: Input
|
|
1389
|
+
}], currentLang: [{
|
|
1390
|
+
type: Input
|
|
1391
|
+
}], chatMessagesContainer: [{
|
|
1392
|
+
type: ViewChild,
|
|
1393
|
+
args: ['chatMessagesContainer']
|
|
1394
|
+
}] } });
|
|
1395
|
+
|
|
1396
|
+
class StylesModule {
|
|
1397
|
+
constructor() {
|
|
1398
|
+
// Load Tailwind CSS
|
|
1399
|
+
require('../../lib/tailwind.css');
|
|
1400
|
+
}
|
|
1401
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: StylesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1402
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.11", ngImport: i0, type: StylesModule, imports: [CommonModule] });
|
|
1403
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: StylesModule, imports: [CommonModule] });
|
|
1404
|
+
}
|
|
1405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: StylesModule, decorators: [{
|
|
1406
|
+
type: NgModule,
|
|
1407
|
+
args: [{
|
|
1408
|
+
declarations: [],
|
|
1409
|
+
imports: [CommonModule],
|
|
1410
|
+
exports: []
|
|
1411
|
+
}]
|
|
1412
|
+
}], ctorParameters: () => [] });
|
|
1413
|
+
|
|
1414
|
+
// Components and Modules
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* Generated bundle index. Do not edit.
|
|
1418
|
+
*/
|
|
1419
|
+
|
|
1420
|
+
export { ApiService, HelpCenterWidgetComponent, SignalRService, StylesModule, TokenService, TranslatePipe, TranslationService };
|
|
1421
|
+
//# sourceMappingURL=aslaluroba-help-center.mjs.map
|