From 18cb2e12acf672a4fa5e8a52a99478367d6044a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Musia=C5=82?= Date: Thu, 8 Feb 2024 11:51:48 +0100 Subject: [PATCH] fix(AI-130): eslint fixes and styles improvements (#22) * feat(AI-130): added system notification when user added new files to the conversation * fix(AI-130): eslint fixes and styles improvements * feat(AI-130): format and unit test fixes --- README.md | 7 +-- apps/api/src/app/chat/chat.config.ts | 5 +- apps/spa/src/app/app.component.spec.ts | 9 ---- apps/spa/src/app/app.routes.ts | 2 +- .../chat/chat-audio/chat-audio.component.html | 17 +++---- .../chat-audio/chat-audio.component.spec.ts | 5 +- .../chat/chat-avatar/chat-avatar.component.ts | 4 +- .../chat-footer/chat-footer.component.html | 17 ++----- .../chat-footer/chat-footer.component.scss | 2 +- .../chat-footer/chat-footer.component.spec.ts | 3 +- .../chat/chat-footer/chat-footer.component.ts | 7 ++- .../chat-header/chat-header.component.html | 27 +++++----- .../chat-header/chat-header.component.scss | 2 +- .../chat-iframe/chat-iframe.component.html | 2 +- .../chat-iframe/chat-iframe.component.scss | 2 +- .../chat-message/chat-message.component.html | 7 +-- .../chat-message.component.spec.ts | 5 +- .../chat-messages.component.html | 11 ++--- .../chat-messages/chat-messages.component.ts | 6 ++- .../chat/chat-tip/chat-tip.component.html | 2 +- .../chat/chat-tip/chat-tip.component.scss | 2 +- .../chat/chat-tips/chat-tips.component.html | 6 +-- .../chat/chat-tips/chat-tips.component.scss | 2 +- .../chat/chat-tips/chat-tips.component.ts | 4 +- .../chat-trigger/chat-trigger.component.scss | 3 +- .../chat-typing/chat-typing.component.html | 12 ++--- .../controls/files/files.component.html | 18 +++---- .../controls/files/files.component.ts | 11 +++-- .../controls/files/files.directive.ts | 24 ++++++--- .../controls/files/files.service.ts | 4 +- .../controls/input/input.component.html | 6 +-- .../controls/input/input.component.spec.ts | 3 +- .../controls/recorder/recorder.component.html | 5 +- .../controls/recorder/recorder.component.scss | 2 - apps/spa/src/app/modules/+chat/chat.routes.ts | 6 +-- .../chat-example/chat-example.component.html | 49 +++++++++++-------- .../chat-example.component.spec.ts | 10 +++- .../chat-example/chat-example.component.ts | 10 ++-- .../+chat/containers/chat/chat.component.html | 31 ++++++------ .../containers/chat/chat.component.spec.ts | 8 ++- .../+chat/containers/chat/chat.component.ts | 9 +--- .../+chat/shared/chat-files.service.ts | 2 - .../app/modules/+chat/shared/chat.service.ts | 19 +++---- .../modules/+chat/shared/thread.service.ts | 4 +- .../configuration-form.component.html | 7 +-- .../configuration-form.component.scss | 2 +- .../configuration-form.component.spec.ts | 8 ++- apps/spa/src/index.html | 10 ++-- apps/spa/src/styles/_extends/_material.scss | 5 +- .../src/styles/_settings/_breakpoints.scss | 2 +- apps/spa/src/styles/_settings/_colors.scss | 2 +- apps/spa/src/styles/_settings/_shadow.scss | 9 ++-- apps/spa/src/styles/_settings/_sizes.scss | 49 +++++++++++++------ apps/spa/src/styles/settings.scss | 4 +- apps/spa/src/styles/styles.scss | 2 +- libs/ai-assistant/package.json | 11 ++++- .../src/lib/files/files.service.ts | 3 +- libs/ai-assistant/src/lib/run/run.service.ts | 1 + libs/ai-embedded/project.json | 2 +- .../src/lib/assistant-iframe.styles.ts | 3 +- libs/ai-embedded/src/lib/assistant-iframe.ts | 10 ++-- libs/ai-embedded/tsconfig.app.json | 10 +--- libs/ai-embedded/tsconfig.spec.json | 4 +- package.json | 9 ++-- 64 files changed, 287 insertions(+), 258 deletions(-) diff --git a/README.md b/README.md index 0a0a440..a70ab57 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # AI Assistant Install the dependencies: + ```bash $ npm install ``` @@ -25,11 +26,11 @@ $ npm run start:spa ``` Open your browser and navigate to: - * http://localhost:4200/ - spa - * http://localhost:3000/api/ - api -Happy coding! +- http://localhost:4200/ - spa +- http://localhost:3000/api/ - api +Happy coding! ## Ready to deploy? diff --git a/apps/api/src/app/chat/chat.config.ts b/apps/api/src/app/chat/chat.config.ts index 4ce2a72..ee0d1ff 100644 --- a/apps/api/src/app/chat/chat.config.ts +++ b/apps/api/src/app/chat/chat.config.ts @@ -5,10 +5,7 @@ import 'dotenv/config'; export const assistantParams: AssistantCreateParams = { name: '@boldare/ai-assistant', instructions: `You are a chatbot assistant. Use the general knowledge to answer questions. Speak briefly and clearly.`, - tools: [ - { type: 'code_interpreter' }, - { type: 'retrieval' }, - ], + tools: [{ type: 'code_interpreter' }, { type: 'retrieval' }], model: 'gpt-4-1106-preview', metadata: {}, }; diff --git a/apps/spa/src/app/app.component.spec.ts b/apps/spa/src/app/app.component.spec.ts index bda0acf..7cd488c 100644 --- a/apps/spa/src/app/app.component.spec.ts +++ b/apps/spa/src/app/app.component.spec.ts @@ -13,13 +13,4 @@ describe('AppComponent', () => { const app = fixture.componentInstance; expect(app).toBeTruthy(); }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain( - 'Hello, ai-spa-template' - ); - }); }); diff --git a/apps/spa/src/app/app.routes.ts b/apps/spa/src/app/app.routes.ts index 988ed32..158b328 100644 --- a/apps/spa/src/app/app.routes.ts +++ b/apps/spa/src/app/app.routes.ts @@ -12,7 +12,7 @@ export const routes: Routes = [ { path: 'chat', loadChildren: () => - import('./modules/+chat/chat.routes').then((m) => m.routes), + import('./modules/+chat/chat.routes').then(m => m.routes), }, ], }, diff --git a/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.html b/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.html index 787165f..659a0e6 100644 --- a/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.html +++ b/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.html @@ -1,12 +1,9 @@ @if (isAudioEnabled) { - - @if(!isStarted) { - play_circle - } @else { - pause_circle - } - + + @if(!isStarted) { + play_circle + } @else { + pause_circle + } + } diff --git a/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.spec.ts b/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.spec.ts index da6cbde..f76c7b9 100644 --- a/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.spec.ts +++ b/apps/spa/src/app/components/chat/chat-audio/chat-audio.component.spec.ts @@ -1,14 +1,15 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChatAudioComponent } from './chat-audio.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; -describe('ChatComponent', () => { +describe('ChatAudioComponent', () => { let component: ChatAudioComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ChatAudioComponent], + imports: [HttpClientTestingModule, ChatAudioComponent], }).compileComponents(); fixture = TestBed.createComponent(ChatAudioComponent); diff --git a/apps/spa/src/app/components/chat/chat-avatar/chat-avatar.component.ts b/apps/spa/src/app/components/chat/chat-avatar/chat-avatar.component.ts index 1ebf37d..46220ba 100644 --- a/apps/spa/src/app/components/chat/chat-avatar/chat-avatar.component.ts +++ b/apps/spa/src/app/components/chat/chat-avatar/chat-avatar.component.ts @@ -6,8 +6,6 @@ import { ChatStatusComponent } from '../chat-status/chat-status.component'; standalone: true, templateUrl: './chat-avatar.component.html', styleUrl: './chat-avatar.component.scss', - imports: [ - ChatStatusComponent, - ], + imports: [ChatStatusComponent], }) export class ChatAvatarComponent {} diff --git a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.html b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.html index ef643d3..61deb64 100644 --- a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.html +++ b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.html @@ -1,20 +1,11 @@ - @if (isTranscriptionEnabled) { - - } - @if (isAttachmentEnabled) { - + + } @if (isAttachmentEnabled) { + } - - + diff --git a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.scss b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.scss index e798c7a..f7e871b 100644 --- a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.scss +++ b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.scss @@ -1,4 +1,4 @@ -@import "settings"; +@import 'settings'; :host { display: block; diff --git a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.spec.ts b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.spec.ts index a38c5e8..13a87d8 100644 --- a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.spec.ts +++ b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChatFooterComponent } from './chat-footer.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; describe('ChatFooterComponent', () => { let component: ChatFooterComponent; @@ -8,7 +9,7 @@ describe('ChatFooterComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ChatFooterComponent], + imports: [ChatFooterComponent, BrowserAnimationsModule], }).compileComponents(); fixture = TestBed.createComponent(ChatFooterComponent); diff --git a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.ts b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.ts index c6273ea..a116abe 100644 --- a/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.ts +++ b/apps/spa/src/app/components/chat/chat-footer/chat-footer.component.ts @@ -1,6 +1,11 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CardFooterComponent } from '../../cards'; -import { ControlsComponent, FilesComponent, InputComponent, RecorderComponent } from '../../controls'; +import { + ControlsComponent, + FilesComponent, + InputComponent, + RecorderComponent, +} from '../../controls'; import { MatTooltip } from '@angular/material/tooltip'; @Component({ diff --git a/apps/spa/src/app/components/chat/chat-header/chat-header.component.html b/apps/spa/src/app/components/chat/chat-header/chat-header.component.html index b024f7f..cf079fd 100644 --- a/apps/spa/src/app/components/chat/chat-header/chat-header.component.html +++ b/apps/spa/src/app/components/chat/chat-header/chat-header.component.html @@ -1,23 +1,22 @@
@if (isConfigEnabled) { - - } - @if (isRefreshEnabled) { - + + } @if (isRefreshEnabled) { + } -
diff --git a/apps/spa/src/app/components/chat/chat-header/chat-header.component.scss b/apps/spa/src/app/components/chat/chat-header/chat-header.component.scss index d126b60..ff706f9 100644 --- a/apps/spa/src/app/components/chat/chat-header/chat-header.component.scss +++ b/apps/spa/src/app/components/chat/chat-header/chat-header.component.scss @@ -1,4 +1,4 @@ -@import "settings"; +@import 'settings'; :host { position: relative; diff --git a/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.html b/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.html index 8347777..40b3726 100644 --- a/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.html +++ b/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.html @@ -1 +1 @@ - + diff --git a/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.scss b/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.scss index e223f15..2e3a175 100644 --- a/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.scss +++ b/apps/spa/src/app/components/chat/chat-iframe/chat-iframe.component.scss @@ -1,4 +1,4 @@ -@import "settings"; +@import 'settings'; :host { display: block; diff --git a/apps/spa/src/app/components/chat/chat-message/chat-message.component.html b/apps/spa/src/app/components/chat/chat-message/chat-message.component.html index 595de41..6447aa8 100644 --- a/apps/spa/src/app/components/chat/chat-message/chat-message.component.html +++ b/apps/spa/src/app/components/chat/chat-message/chat-message.component.html @@ -1,11 +1,12 @@ -@if (message.role === 'assistant') { - +@if (message) { @if (message.role === 'assistant') { + }
@if (message.role !== chatRole.System) { - + }
+} diff --git a/apps/spa/src/app/components/chat/chat-message/chat-message.component.spec.ts b/apps/spa/src/app/components/chat/chat-message/chat-message.component.spec.ts index 90f68ee..d4bf345 100644 --- a/apps/spa/src/app/components/chat/chat-message/chat-message.component.spec.ts +++ b/apps/spa/src/app/components/chat/chat-message/chat-message.component.spec.ts @@ -1,14 +1,15 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChatMessageComponent } from './chat-message.component'; +import { MarkdownModule } from 'ngx-markdown'; -describe('CardContentComponent', () => { +describe('ChatMessageComponent', () => { let component: ChatMessageComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ChatMessageComponent], + imports: [ChatMessageComponent, MarkdownModule.forRoot()], }).compileComponents(); fixture = TestBed.createComponent(ChatMessageComponent); diff --git a/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.html b/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.html index 037521c..ea37fed 100644 --- a/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.html +++ b/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.html @@ -1,13 +1,10 @@
@for (message of messages; track message) { - - - + + + } @empty { - + }
diff --git a/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.ts b/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.ts index 424def2..678a0fb 100644 --- a/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.ts +++ b/apps/spa/src/app/components/chat/chat-messages/chat-messages.component.ts @@ -1,9 +1,11 @@ import { AfterViewInit, Component, - ElementRef, EventEmitter, + ElementRef, + EventEmitter, Input, - OnChanges, Output, + OnChanges, + Output, QueryList, SimpleChanges, ViewChildren, diff --git a/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.html b/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.html index 8347777..40b3726 100644 --- a/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.html +++ b/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.html @@ -1 +1 @@ - + diff --git a/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.scss b/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.scss index 6432206..78de2b8 100644 --- a/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.scss +++ b/apps/spa/src/app/components/chat/chat-tip/chat-tip.component.scss @@ -1,4 +1,4 @@ -@import "settings"; +@import 'settings'; :host { padding: $size-2 $size-4; diff --git a/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.html b/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.html index b714889..da32b73 100644 --- a/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.html +++ b/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.html @@ -1,5 +1,5 @@ @for (tip of tips; track tip) { - - {{ tip }} - + + {{ tip }} + } diff --git a/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.scss b/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.scss index 3f913a8..9969b72 100644 --- a/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.scss +++ b/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.scss @@ -1,4 +1,4 @@ -@import "settings"; +@import 'settings'; :host { display: flex; diff --git a/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.ts b/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.ts index 71ed861..54689f2 100644 --- a/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.ts +++ b/apps/spa/src/app/components/chat/chat-tips/chat-tips.component.ts @@ -6,9 +6,7 @@ import { ChatTipComponent } from '../chat-tip/chat-tip.component'; standalone: true, templateUrl: './chat-tips.component.html', styleUrl: './chat-tips.component.scss', - imports: [ - ChatTipComponent, - ], + imports: [ChatTipComponent], }) export class ChatTipsComponent { @Input() tips: string[] = []; diff --git a/apps/spa/src/app/components/chat/chat-trigger/chat-trigger.component.scss b/apps/spa/src/app/components/chat/chat-trigger/chat-trigger.component.scss index 498f8be..ec7cd7d 100644 --- a/apps/spa/src/app/components/chat/chat-trigger/chat-trigger.component.scss +++ b/apps/spa/src/app/components/chat/chat-trigger/chat-trigger.component.scss @@ -1,4 +1,4 @@ -@import "settings"; +@import 'settings'; :host { position: fixed; @@ -39,4 +39,3 @@ transform: scale(1); } } - diff --git a/apps/spa/src/app/components/chat/chat-typing/chat-typing.component.html b/apps/spa/src/app/components/chat/chat-typing/chat-typing.component.html index 00fcf04..300c3ee 100644 --- a/apps/spa/src/app/components/chat/chat-typing/chat-typing.component.html +++ b/apps/spa/src/app/components/chat/chat-typing/chat-typing.component.html @@ -1,9 +1,9 @@ @if (isLoading) { -
-
- - - -
+
+
+ + +
+
} diff --git a/apps/spa/src/app/components/controls/files/files.component.html b/apps/spa/src/app/components/controls/files/files.component.html index 24ec6f2..d669310 100644 --- a/apps/spa/src/app/components/controls/files/files.component.html +++ b/apps/spa/src/app/components/controls/files/files.component.html @@ -2,19 +2,16 @@ aiFiles (click)="input.click()" (drop$)="addFiles($event)" - [files]="files()" -> + [files]="files()"> attach_file @if (files().length) { - - - {{ files().length }} - - - close - + + + {{ files().length }} + close + } + #input /> diff --git a/apps/spa/src/app/components/controls/files/files.component.ts b/apps/spa/src/app/components/controls/files/files.component.ts index 5027853..c142cbf 100644 --- a/apps/spa/src/app/components/controls/files/files.component.ts +++ b/apps/spa/src/app/components/controls/files/files.component.ts @@ -9,7 +9,12 @@ import { ControlIconComponent } from '../control-icon/control-icon.component'; @Component({ selector: 'ai-files', standalone: true, - imports: [MatIcon, AiFilesDirective, ControlItemComponent, ControlIconComponent], + imports: [ + MatIcon, + AiFilesDirective, + ControlItemComponent, + ControlIconComponent, + ], templateUrl: './files.component.html', styleUrl: './files.component.scss', }) @@ -19,11 +24,11 @@ export class FilesComponent { constructor(private readonly fileService: FilesService) {} - addFiles(files: FileList){ + addFiles(files: FileList) { this.fileService.add(files); } - onFileChange(event: Event){ + onFileChange(event: Event) { const input = event.target as HTMLInputElement; this.addFiles(input.files as FileList); } diff --git a/apps/spa/src/app/components/controls/files/files.directive.ts b/apps/spa/src/app/components/controls/files/files.directive.ts index 09d929f..80bb359 100644 --- a/apps/spa/src/app/components/controls/files/files.directive.ts +++ b/apps/spa/src/app/components/controls/files/files.directive.ts @@ -1,20 +1,30 @@ -import { Directive, HostListener, HostBinding, Output, EventEmitter, Input } from '@angular/core'; +import { + Directive, + HostListener, + HostBinding, + Output, + EventEmitter, + Input, +} from '@angular/core'; @Directive({ standalone: true, selector: '[aiFiles]', }) - export class AiFilesDirective { - @Output() drop$ : EventEmitter = new EventEmitter(); + @Output() drop$: EventEmitter = new EventEmitter(); @Input() files: File[] = []; event = 'init'; @HostBinding('class') get getClasses(): string { - return `drag-drop--${this.event} ${this.files.length ? 'has-files' : 'no-files'}`; + return `drag-drop--${this.event} ${ + this.files.length ? 'has-files' : 'no-files' + }`; } - @HostListener('dragover', ['$event']) public onDragOver(event: DragEvent): void { + @HostListener('dragover', ['$event']) public onDragOver( + event: DragEvent, + ): void { event.preventDefault(); event.stopPropagation(); this.event = 'dragleave'; @@ -24,7 +34,9 @@ export class AiFilesDirective { this.initEvent(event); } - @HostListener('dragleave', ['$event']) public onDragLeave(event: DragEvent): void { + @HostListener('dragleave', ['$event']) public onDragLeave( + event: DragEvent, + ): void { this.initEvent(event); } diff --git a/apps/spa/src/app/components/controls/files/files.service.ts b/apps/spa/src/app/components/controls/files/files.service.ts index 95546e8..e6a3552 100644 --- a/apps/spa/src/app/components/controls/files/files.service.ts +++ b/apps/spa/src/app/components/controls/files/files.service.ts @@ -5,10 +5,10 @@ import { BehaviorSubject } from 'rxjs'; export class FilesService { files$ = new BehaviorSubject([]); - add(files: FileList){ + add(files: FileList) { const updatedFiles = [ ...this.files$.value, - ...Object.keys(files).map(key => files[key as unknown as number]) + ...Object.keys(files).map(key => files[key as unknown as number]), ]; this.files$.next(updatedFiles); diff --git a/apps/spa/src/app/components/controls/input/input.component.html b/apps/spa/src/app/components/controls/input/input.component.html index 639a871..82fb91d 100644 --- a/apps/spa/src/app/components/controls/input/input.component.html +++ b/apps/spa/src/app/components/controls/input/input.component.html @@ -5,15 +5,13 @@ autocomplete="off" [(ngModel)]="content" [disabled]="isDisabled" - (keydown.enter)="send(content)" - /> + (keydown.enter)="send(content)" /> diff --git a/apps/spa/src/app/components/controls/input/input.component.spec.ts b/apps/spa/src/app/components/controls/input/input.component.spec.ts index dd551ea..2db9c5b 100644 --- a/apps/spa/src/app/components/controls/input/input.component.spec.ts +++ b/apps/spa/src/app/components/controls/input/input.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { InputComponent } from './input.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; describe('CardComponent', () => { let component: InputComponent; @@ -8,7 +9,7 @@ describe('CardComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [InputComponent], + imports: [InputComponent, BrowserAnimationsModule], }).compileComponents(); fixture = TestBed.createComponent(InputComponent); diff --git a/apps/spa/src/app/components/controls/recorder/recorder.component.html b/apps/spa/src/app/components/controls/recorder/recorder.component.html index 6fb57e8..6508906 100644 --- a/apps/spa/src/app/components/controls/recorder/recorder.component.html +++ b/apps/spa/src/app/components/controls/recorder/recorder.component.html @@ -1,7 +1,4 @@ - + mic
diff --git a/apps/spa/src/app/components/controls/recorder/recorder.component.scss b/apps/spa/src/app/components/controls/recorder/recorder.component.scss index 865d1ae..b055477 100644 --- a/apps/spa/src/app/components/controls/recorder/recorder.component.scss +++ b/apps/spa/src/app/components/controls/recorder/recorder.component.scss @@ -12,8 +12,6 @@ } } - - .recorder__circle { display: none; position: absolute; diff --git a/apps/spa/src/app/modules/+chat/chat.routes.ts b/apps/spa/src/app/modules/+chat/chat.routes.ts index 35eb684..f59b518 100644 --- a/apps/spa/src/app/modules/+chat/chat.routes.ts +++ b/apps/spa/src/app/modules/+chat/chat.routes.ts @@ -5,14 +5,12 @@ export const routes: Routes = [ path: '', loadComponent: () => import('./containers/chat-example/chat-example.component').then( - (mod) => mod.ChatExampleComponent + mod => mod.ChatExampleComponent, ), }, { path: 'iframe', loadComponent: () => - import('./containers/chat/chat.component').then( - (mod) => mod.ChatComponent - ), + import('./containers/chat/chat.component').then(mod => mod.ChatComponent), }, ]; diff --git a/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.html b/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.html index d38ce12..ac13a3e 100644 --- a/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.html +++ b/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.html @@ -1,46 +1,55 @@ -

- Integrating Chatbot into Your Website -

+

Integrating Chatbot into Your Website

- Enhance your website's interactivity and user engagement by seamlessly integrating our chatbot. Follow the simple steps below to implement the chatbot into your website: + Enhance your website's interactivity and user engagement by seamlessly + integrating our chatbot. Follow the simple steps below to implement the + chatbot into your website:
-

- Step 1: Locate Your HTML File -

+

Step 1: Locate Your HTML File

- Identify the HTML file where you wish to add the chatbot. This will typically be in the root directory of your website or within a specific subdirectory if you aim to integrate the chatbot on a particular page. + Identify the HTML file where you wish to add the chatbot. This will + typically be in the root directory of your website or within a specific + subdirectory if you aim to integrate the chatbot on a particular page.

-

- Step 2 (a): Copy the Chatbot Integration Code -

+

Step 2 (a): Copy the Chatbot Integration Code

- Below is the chatbot integration code snippet. This piece of code is designed to be lightweight and compatible with most web environments, ensuring a smooth integration process. + Below is the chatbot integration code snippet. This piece of code is + designed to be lightweight and compatible with most web environments, + ensuring a smooth integration process. - We highly recommend inserting the code snippet just before the closing body tag of your HTML file. This placement ensures that the chatbot will load only after all other content on your page has fully loaded, optimizing your page's load time for a better user experience. + We highly recommend inserting the code snippet just before the closing body + tag of your HTML file. This placement ensures that the chatbot will load + only after all other content on your page has fully loaded, optimizing your + page's load time for a better user experience.

-

- Step 2 (b): Customizing Chatbot Initialization -

+

Step 2 (b): Customizing Chatbot Initialization

- For a tailored interaction experience, you may prefer to manually initialize the chatbot rather than opting for automatic activation. This approach gives you greater control over the chatbot's initialization timing and its configuration, ensuring the chatbot seamlessly integrates with the flow of your website. -

- To prevent the chatbot from automatically initializing, locate and remove the following attribute from the chatbot integration code snippet: + For a tailored interaction experience, you may prefer to manually initialize + the chatbot rather than opting for automatic activation. This approach gives + you greater control over the chatbot's initialization timing and its + configuration, ensuring the chatbot seamlessly integrates with the flow of + your website. +

+ To prevent the chatbot from automatically initializing, locate and remove + the following attribute from the chatbot integration code snippet:

- For manual chatbot initialization, incorporate the following JavaScript code snippet into your website's JavaScript file. This script lets you dictate exactly when and how the chatbot becomes active on your site, offering the opportunity to customize its configuration further. + For manual chatbot initialization, incorporate the following JavaScript code + snippet into your website's JavaScript file. This script lets you dictate + exactly when and how the chatbot becomes active on your site, offering the + opportunity to customize its configuration further.

diff --git a/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.spec.ts b/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.spec.ts index f724d18..122d680 100644 --- a/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.spec.ts +++ b/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.spec.ts @@ -1,14 +1,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChatExampleComponent } from './chat-example.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { MarkdownModule } from 'ngx-markdown'; -describe('ChatComponent', () => { +describe('ChatExampleComponent', () => { let component: ChatExampleComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ChatExampleComponent], + imports: [ + ChatExampleComponent, + HttpClientTestingModule, + MarkdownModule.forRoot(), + ], }).compileComponents(); fixture = TestBed.createComponent(ChatExampleComponent); diff --git a/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.ts b/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.ts index 2cc0624..6de6d6d 100644 --- a/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.ts +++ b/apps/spa/src/app/modules/+chat/containers/chat-example/chat-example.component.ts @@ -1,20 +1,16 @@ import { Component } from '@angular/core'; +import { AssistantIframe } from '@boldare/ai-embedded'; +import { AsyncPipe } from '@angular/common'; import { ChatService } from '../../shared/chat.service'; import { environment } from '../../../../../environments/environment'; import { MarkdownComponent, MarkdownPipe } from 'ngx-markdown'; -import { AsyncPipe } from '@angular/common'; -import { AssistantIframe } from '@boldare/ai-embedded'; @Component({ selector: 'ai-chat-example', standalone: true, templateUrl: './chat-example.component.html', styleUrl: './chat-example.component.scss', - imports: [ - MarkdownComponent, - MarkdownPipe, - AsyncPipe, - ], + imports: [MarkdownComponent, MarkdownPipe, AsyncPipe], }) export class ChatExampleComponent { scriptMarkdown = `\`\`\`html diff --git a/apps/spa/src/app/modules/+chat/containers/chat/chat.component.html b/apps/spa/src/app/modules/+chat/containers/chat/chat.component.html index f286051..6dda4b2 100644 --- a/apps/spa/src/app/modules/+chat/containers/chat/chat.component.html +++ b/apps/spa/src/app/modules/+chat/containers/chat/chat.component.html @@ -4,25 +4,22 @@ [isConfigEnabled]="isConfigEnabled && !!threadId()" (refresh$)="chatService.refresh()" (close$)="chatService.toggle()" - (config$)="chatService.clear()" - > + (config$)="chatService.clear()"> @if (isConfigEnabled && !threadId()) { - + } @else { - - + + } diff --git a/apps/spa/src/app/modules/+chat/containers/chat/chat.component.spec.ts b/apps/spa/src/app/modules/+chat/containers/chat/chat.component.spec.ts index 5b89000..4563dfa 100644 --- a/apps/spa/src/app/modules/+chat/containers/chat/chat.component.spec.ts +++ b/apps/spa/src/app/modules/+chat/containers/chat/chat.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChatComponent } from './chat.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; describe('ChatComponent', () => { let component: ChatComponent; @@ -8,7 +10,11 @@ describe('ChatComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ChatComponent], + imports: [ + HttpClientTestingModule, + BrowserAnimationsModule, + ChatComponent, + ], }).compileComponents(); fixture = TestBed.createComponent(ChatComponent); diff --git a/apps/spa/src/app/modules/+chat/containers/chat/chat.component.ts b/apps/spa/src/app/modules/+chat/containers/chat/chat.component.ts index 2545fce..52dccaf 100644 --- a/apps/spa/src/app/modules/+chat/containers/chat/chat.component.ts +++ b/apps/spa/src/app/modules/+chat/containers/chat/chat.component.ts @@ -7,9 +7,7 @@ import { CardComponent } from '../../../../components/cards'; import { ChatHeaderComponent } from '../../../../components/chat/chat-header/chat-header.component'; import { ChatMessagesComponent } from '../../../../components/chat/chat-messages/chat-messages.component'; import { ChatFooterComponent } from '../../../../components/chat/chat-footer/chat-footer.component'; -import { - ConfigurationFormComponent -} from '../../../+configuration/components/configuration-form/configuration-form.component'; +import { ConfigurationFormComponent } from '../../../+configuration/components/configuration-form/configuration-form.component'; import { take } from 'rxjs'; @Component({ @@ -47,10 +45,7 @@ export class ChatComponent implements OnInit { ngOnInit() { if (!this.isConfigEnabled) { - this.threadService - .start() - .pipe(take(1)) - .subscribe(); + this.threadService.start().pipe(take(1)).subscribe(); } } } diff --git a/apps/spa/src/app/modules/+chat/shared/chat-files.service.ts b/apps/spa/src/app/modules/+chat/shared/chat-files.service.ts index a3650b4..0f5708e 100644 --- a/apps/spa/src/app/modules/+chat/shared/chat-files.service.ts +++ b/apps/spa/src/app/modules/+chat/shared/chat-files.service.ts @@ -1,12 +1,10 @@ import { Injectable } from '@angular/core'; import { FilesService } from '../../../components/controls'; import { ChatClientService } from './chat-client.service'; -import OpenAI from 'openai'; import { OpenAiFile } from '@boldare/ai-assistant'; @Injectable({ providedIn: 'root' }) export class ChatFilesService { - constructor( private readonly chatClientService: ChatClientService, private readonly filesService: FilesService, diff --git a/apps/spa/src/app/modules/+chat/shared/chat.service.ts b/apps/spa/src/app/modules/+chat/shared/chat.service.ts index 55b9f43..b685807 100644 --- a/apps/spa/src/app/modules/+chat/shared/chat.service.ts +++ b/apps/spa/src/app/modules/+chat/shared/chat.service.ts @@ -33,7 +33,7 @@ export class ChatService { refresh(): void { this.messages$.next([]); this.threadService.start().subscribe(); - } + } clear(): void { this.threadService.clear(); @@ -50,7 +50,9 @@ export class ChatService { } this.addMessage({ - content: `The user has attached files to the message: ${files.map(file => file.filename).join(', ')}`, + content: `The user has attached files to the message: ${files + .map(file => file.filename) + .join(', ')}`, role: ChatRole.System, }); } @@ -70,14 +72,13 @@ export class ChatService { } watchMessages(): Subscription { - return this.chatGatewayService.getMessages() - .subscribe(data => { - this.addMessage({ - content: data.content, - role: ChatRole.Assistant, - }); - this.isLoading$.next(false); + return this.chatGatewayService.getMessages().subscribe(data => { + this.addMessage({ + content: data.content, + role: ChatRole.Assistant, }); + this.isLoading$.next(false); + }); } sendAudio(file: Blob): void { diff --git a/apps/spa/src/app/modules/+chat/shared/thread.service.ts b/apps/spa/src/app/modules/+chat/shared/thread.service.ts index 42eee02..9dd7e85 100644 --- a/apps/spa/src/app/modules/+chat/shared/thread.service.ts +++ b/apps/spa/src/app/modules/+chat/shared/thread.service.ts @@ -8,7 +8,9 @@ import { ConfigurationFormService } from '../../+configuration/shared/configurat @Injectable({ providedIn: 'root' }) export class ThreadService { key = 'threadId'; - initialThreadId = environment.isThreadMemorized ? localStorage.getItem(this.key) || '' : ''; + initialThreadId = environment.isThreadMemorized + ? localStorage.getItem(this.key) || '' + : ''; threadId$ = new BehaviorSubject(this.initialThreadId); clear$ = new Subject(); diff --git a/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.html b/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.html index 04a36bd..0c0ff18 100644 --- a/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.html +++ b/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.html @@ -1,9 +1,7 @@
- - First name - + First name
@@ -13,8 +11,7 @@ mat-raised-button color="primary" [disabled]="form.invalid" - (click)="startChat()" - > + (click)="startChat()"> Start conversation diff --git a/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.scss b/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.scss index 4f15dd6..7a0bd83 100644 --- a/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.scss +++ b/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.scss @@ -1,4 +1,4 @@ -@import "settings"; +@import 'settings'; .chat-form__content { position: relative; diff --git a/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.spec.ts b/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.spec.ts index 6c4131e..b066250 100644 --- a/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.spec.ts +++ b/apps/spa/src/app/modules/+configuration/components/configuration-form/configuration-form.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ConfigurationFormComponent } from './configuration-form.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; describe('ConfigurationFormComponent', () => { let component: ConfigurationFormComponent; @@ -8,7 +10,11 @@ describe('ConfigurationFormComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ConfigurationFormComponent], + imports: [ + ConfigurationFormComponent, + HttpClientTestingModule, + BrowserAnimationsModule, + ], }).compileComponents(); fixture = TestBed.createComponent(ConfigurationFormComponent); diff --git a/apps/spa/src/index.html b/apps/spa/src/index.html index 589f82f..525e976 100644 --- a/apps/spa/src/index.html +++ b/apps/spa/src/index.html @@ -5,15 +5,15 @@ Boldare - AI Assistant - + + rel="stylesheet" /> + rel="stylesheet" /> diff --git a/apps/spa/src/styles/_extends/_material.scss b/apps/spa/src/styles/_extends/_material.scss index 88bc799..8b3215f 100644 --- a/apps/spa/src/styles/_extends/_material.scss +++ b/apps/spa/src/styles/_extends/_material.scss @@ -16,9 +16,10 @@ line-height: 1.5; - .mat-primary { - --mat-minimal-pseudo-checkbox-selected-checkmark-color: var(--color-primary-500); + --mat-minimal-pseudo-checkbox-selected-checkmark-color: var( + --color-primary-500 + ); } mat-form-field { diff --git a/apps/spa/src/styles/_settings/_breakpoints.scss b/apps/spa/src/styles/_settings/_breakpoints.scss index 066d75a..b2ddeaa 100644 --- a/apps/spa/src/styles/_settings/_breakpoints.scss +++ b/apps/spa/src/styles/_settings/_breakpoints.scss @@ -18,7 +18,7 @@ $breakpoints: ( 'mobile': $mobile, 'tablet': $tablet, 'desktop': $desktop, - 'desktop-big': $desktop-big + 'desktop-big': $desktop-big, ); // Breakpoints mixins diff --git a/apps/spa/src/styles/_settings/_colors.scss b/apps/spa/src/styles/_settings/_colors.scss index 3dca0ed..8c2bc79 100644 --- a/apps/spa/src/styles/_settings/_colors.scss +++ b/apps/spa/src/styles/_settings/_colors.scss @@ -1,5 +1,5 @@ :root { - --color-transparent: rgba(0,0,0, 0); + --color-transparent: rgba(0, 0, 0, 0); --color-white: #ffffff; --color-black: #000000; diff --git a/apps/spa/src/styles/_settings/_shadow.scss b/apps/spa/src/styles/_settings/_shadow.scss index 6b947fd..6bc2d9d 100644 --- a/apps/spa/src/styles/_settings/_shadow.scss +++ b/apps/spa/src/styles/_settings/_shadow.scss @@ -1,5 +1,8 @@ :root { - --shadow-light: rgba(6, 6, 12, 0.05) 0 2px 14px, rgba(6, 6, 12, 0.05) 0 4px 32px; - --shadow-default: rgba(17, 17, 26, 0.1) 0 4px 16px, rgba(17, 17, 26, 0.1) 0 8px 32px; - --shadow-default-hover: rgb(17, 17, 26, .3) 0 4px 26px, rgb(17, 17, 26, 0.1) 0 8px 32px; + --shadow-light: rgba(6, 6, 12, 0.05) 0 2px 14px, + rgba(6, 6, 12, 0.05) 0 4px 32px; + --shadow-default: rgba(17, 17, 26, 0.1) 0 4px 16px, + rgba(17, 17, 26, 0.1) 0 8px 32px; + --shadow-default-hover: rgb(17, 17, 26, 0.3) 0 4px 26px, + rgb(17, 17, 26, 0.1) 0 8px 32px; } diff --git a/apps/spa/src/styles/_settings/_sizes.scss b/apps/spa/src/styles/_settings/_sizes.scss index 0c752cf..87bdd92 100644 --- a/apps/spa/src/styles/_settings/_sizes.scss +++ b/apps/spa/src/styles/_settings/_sizes.scss @@ -24,11 +24,21 @@ $size-15: 15 * $size-unit; $size-16: 16 * $size-unit; $sizes: ( - 'none': ($mobile: $size-0), - 'mini': ($mobile: $size-1), - 'small': ($mobile: $size-4), - 'medium': ($mobile: $size-10), - 'big': ($mobile: $size-14), + 'none': ( + $mobile: $size-0, + ), + 'mini': ( + $mobile: $size-1, + ), + 'small': ( + $mobile: $size-4, + ), + 'medium': ( + $mobile: $size-10, + ), + 'big': ( + $mobile: $size-14, + ), ); // Mixins @@ -36,10 +46,10 @@ $sizes: ( @mixin size-rwd($breakpointName: 'medium') { @each $size-breakpoint, $value in map-get($sizes, $breakpointName) { @if ($mobile == $size-breakpoint) { - @content($value); + @content ($value); } @else { @include min-screen($size-breakpoint) { - @content($value); + @content ($value); } } } @@ -49,10 +59,10 @@ $sizes: ( @each $name, $size-props in $sizes { @each $size-breakpoint, $value in $size-props { @if ($mobile == $size-breakpoint) { - @content($name, $value); + @content ($name, $value); } @else { @include min-screen($size-breakpoint) { - @content($name, $value); + @content ($name, $value); } } } @@ -60,7 +70,8 @@ $sizes: ( } @mixin size-space-vertical($prefix: 'size', $type: 'padding') { - @include size-space-rwd($prefix: 'size', $type: 'padding') using ($name, $value) { + @include size-space-rwd($prefix: 'size', $type: 'padding') using + ($name, $value) { &.#{$prefix}-vertical--#{$name} { #{$type}-top: #{$value}; #{$type}-bottom: #{$value}; @@ -69,7 +80,8 @@ $sizes: ( } @mixin size-space-horizontal($prefix: 'size', $type: 'padding') { - @include size-space-rwd($prefix: 'size', $type: 'padding') using ($name, $value) { + @include size-space-rwd($prefix: 'size', $type: 'padding') using + ($name, $value) { &.#{$prefix}-horizontal--#{$name} { #{$type}-right: #{$value}; #{$type}-left: #{$value}; @@ -78,7 +90,8 @@ $sizes: ( } @mixin size-space-all($prefix: 'size', $type: 'padding') { - @include size-space-rwd($prefix: 'size', $type: 'padding') using ($name, $value) { + @include size-space-rwd($prefix: 'size', $type: 'padding') using + ($name, $value) { &.#{$prefix}--#{$name} { #{$type}: #{$value}; } @@ -86,7 +99,8 @@ $sizes: ( } @mixin size-space-bottom($prefix: 'size', $type: 'padding') { - @include size-space-rwd($prefix: 'size', $type: 'padding') using ($name, $value) { + @include size-space-rwd($prefix: 'size', $type: 'padding') using + ($name, $value) { &.#{$prefix}-bottom--#{$name} { #{$type}-bottom: #{$value}; } @@ -94,7 +108,8 @@ $sizes: ( } @mixin size-space-top($prefix: 'size', $type: 'padding') { - @include size-space-rwd($prefix: 'size', $type: 'padding') using ($name, $value) { + @include size-space-rwd($prefix: 'size', $type: 'padding') using + ($name, $value) { &.#{$prefix}-top--#{$name} { #{$type}-top: #{$value}; } @@ -102,7 +117,8 @@ $sizes: ( } @mixin size-space-right($prefix: 'size', $type: 'padding') { - @include size-space-rwd($prefix: 'size', $type: 'padding') using ($name, $value) { + @include size-space-rwd($prefix: 'size', $type: 'padding') using + ($name, $value) { &.#{$prefix}-right--#{$name} { #{$type}-right: #{$value}; } @@ -110,7 +126,8 @@ $sizes: ( } @mixin size-space-left($prefix: 'size', $type: 'padding') { - @include size-space-rwd($prefix: 'size', $type: 'padding') using ($name, $value) { + @include size-space-rwd($prefix: 'size', $type: 'padding') using + ($name, $value) { &.#{$prefix}-left--#{$name} { #{$type}-left: #{$value}; } diff --git a/apps/spa/src/styles/settings.scss b/apps/spa/src/styles/settings.scss index 9567284..468d714 100644 --- a/apps/spa/src/styles/settings.scss +++ b/apps/spa/src/styles/settings.scss @@ -1,2 +1,2 @@ -@import "_settings/breakpoints"; -@import "_settings/sizes"; +@import '_settings/breakpoints'; +@import '_settings/sizes'; diff --git a/apps/spa/src/styles/styles.scss b/apps/spa/src/styles/styles.scss index b604035..2563651 100644 --- a/apps/spa/src/styles/styles.scss +++ b/apps/spa/src/styles/styles.scss @@ -5,7 +5,7 @@ @import '_settings/shadow'; @import '_settings/borders'; -@import "_extends/material"; +@import '_extends/material'; html, body { diff --git a/libs/ai-assistant/package.json b/libs/ai-assistant/package.json index c3910be..6a13c7e 100644 --- a/libs/ai-assistant/package.json +++ b/libs/ai-assistant/package.json @@ -2,7 +2,16 @@ "name": "@boldare/ai-assistant", "version": "0.0.3", "dependencies": { - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "openai": "^4.26.1", + "@nestjs/common": "^10.0.2", + "@nestjs/platform-express": "^10.0.2", + "dotenv": "^16.3.1", + "envfile": "^7.1.0", + "@nestjs/axios": "^3.0.1", + "@nestjs/websockets": "^10.3.0", + "socket.io": "^4.7.3", + "multer": "^1.4.4-lts.1" }, "type": "commonjs", "main": "./src/index.js", diff --git a/libs/ai-assistant/src/lib/files/files.service.ts b/libs/ai-assistant/src/lib/files/files.service.ts index bad8728..a247df6 100644 --- a/libs/ai-assistant/src/lib/files/files.service.ts +++ b/libs/ai-assistant/src/lib/files/files.service.ts @@ -2,7 +2,8 @@ import { Injectable } from '@nestjs/common'; import { toFile } from 'openai/uploads'; import { FileObject } from 'openai/resources'; import { AiService } from '../ai'; -// @ts-ignore +// @ts-expect-error multer is necessary +// eslint-disable-next-line import { multer } from 'multer'; @Injectable() diff --git a/libs/ai-assistant/src/lib/run/run.service.ts b/libs/ai-assistant/src/lib/run/run.service.ts index ab90807..8981f22 100644 --- a/libs/ai-assistant/src/lib/run/run.service.ts +++ b/libs/ai-assistant/src/lib/run/run.service.ts @@ -19,6 +19,7 @@ export class RunService { } async resolve(run: Run): Promise { + // eslint-disable-next-line no-constant-condition while (true) switch (run.status) { case 'cancelling': diff --git a/libs/ai-embedded/project.json b/libs/ai-embedded/project.json index 8b580bf..a413907 100644 --- a/libs/ai-embedded/project.json +++ b/libs/ai-embedded/project.json @@ -1,7 +1,7 @@ { "name": "ai-embedded", "$schema": "../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", + "projectType": "library", "sourceRoot": "libs/ai-embedded/src", "tags": [], "targets": { diff --git a/libs/ai-embedded/src/lib/assistant-iframe.styles.ts b/libs/ai-embedded/src/lib/assistant-iframe.styles.ts index 3b718f3..246f8cf 100644 --- a/libs/ai-embedded/src/lib/assistant-iframe.styles.ts +++ b/libs/ai-embedded/src/lib/assistant-iframe.styles.ts @@ -13,7 +13,7 @@ export const addIframeClass = (className: string) => `.${className} { border-radius: 16px; border: 0; box-shadow: rgba(17, 17, 26, 0.1) 0 4px 16px, rgba(17, 17, 26, 0.1) 0 8px 32px; - z-index: 50; + z-index: 150; } @media (max-width: 460px) { @@ -57,6 +57,7 @@ export const addTriggerClass = (className: string) => ` background-position: center; transition: 0.2s all ease-in-out; cursor: pointer; + z-index: 100; @media (max-width: 460px) { width: 40px; diff --git a/libs/ai-embedded/src/lib/assistant-iframe.ts b/libs/ai-embedded/src/lib/assistant-iframe.ts index 57dec19..a49b5f6 100644 --- a/libs/ai-embedded/src/lib/assistant-iframe.ts +++ b/libs/ai-embedded/src/lib/assistant-iframe.ts @@ -119,15 +119,19 @@ export class AssistantIframe { const appButtons = document.getElementsByClassName(this.config.toggleClass); appButtons[0].addEventListener('click', () => { - const isVisible = document.body.classList.contains(this.config.bodyOpenClass); + const isVisible = document.body.classList.contains( + this.config.bodyOpenClass, + ); this.changeModalState(isVisible); }); } watchCloseButton(): void { - window.addEventListener('message', (message) => { + window.addEventListener('message', message => { if (message.data.type === 'chatbot.close') { - const isVisible = document.body.classList.contains(this.config.bodyOpenClass); + const isVisible = document.body.classList.contains( + this.config.bodyOpenClass, + ); this.changeModalState(isVisible); } }); diff --git a/libs/ai-embedded/tsconfig.app.json b/libs/ai-embedded/tsconfig.app.json index 5d237f3..461061d 100644 --- a/libs/ai-embedded/tsconfig.app.json +++ b/libs/ai-embedded/tsconfig.app.json @@ -4,12 +4,6 @@ "outDir": "../../dist/out-tsc", "types": ["node"] }, - "exclude": [ - "jest.config.ts", - "src/**/*.spec.ts", - "src/**/*.test.ts" - ], - "include": [ - "src/**/*.ts" - ] + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] } diff --git a/libs/ai-embedded/tsconfig.spec.json b/libs/ai-embedded/tsconfig.spec.json index a38106e..f6a7d97 100644 --- a/libs/ai-embedded/tsconfig.spec.json +++ b/libs/ai-embedded/tsconfig.spec.json @@ -5,9 +5,7 @@ "module": "commonjs", "types": ["jest", "node"] }, - "files": [ - "src/test-setup.ts" - ], + "files": ["src/test-setup.ts"], "include": [ "jest.config.ts", "src/**/*.test.ts", diff --git a/package.json b/package.json index e88fb67..675668d 100644 --- a/package.json +++ b/package.json @@ -3,17 +3,20 @@ "version": "0.0.0", "license": "MIT", "scripts": { + "start": "node dist/apps/api/main.js", "start:dev": "nx run-many --parallel --target=serve --projects=api,spa ", "start:spa": "nx serve spa", "start:api": "nx serve api", + "build": "npm run build:ai-embedded && npm run build:spa && npm run build:api", "build:spa": "nx build --prod --skip-nx-cache spa", "build:api": "nx build --prod api", "build:ai-assistant": "nx build --prod ai-assistant", "build:ai-embedded": "nx build --prod ai-embedded --no-cache && npm run cp:ai-embedded", - "build": "npm run build:ai-embedded && npm run build:spa && npm run build:api", - "start": "node dist/apps/api/main.js", "publish": "npm run build && cd dist/libs/ai-assistant/ && npm publish --access=public && cd ../../..", - "cp:ai-embedded": "cp ./dist/libs/ai-embedded/main.js ./apps/spa/src/assets/js/ai-embedded.js" + "cp:ai-embedded": "cp ./dist/libs/ai-embedded/main.js ./apps/spa/src/assets/js/ai-embedded.js", + "lint": "nx run-many --parallel --target=lint --all", + "test": "nx run-many --parallel --target=test --all", + "format": "nx format:write" }, "private": true, "dependencies": {