diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7a58099..bc18305 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Deploy Angelos-UI +name: Deploy Chatbot on: push: @@ -13,13 +13,15 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + # Create the updated environment.prod.ts file - name: Create Environment File run: | echo "export const environment = { production: true, - angelosUrl: '/api/v1/question/chat', - angelosToken: '/api/token', - angelosAppApiKey: '${{secrets.ANGELOS_APP_API_KEY}}' + angelosUrl: '/api/chat', + angelosAppApiKey: '${{secrets.ANGELOS_APP_API_KEY}}', + organisation: 2, + filterByOrg: false };" > src/environments/environment.prod.ts - name: Verify Environment File Creation @@ -58,7 +60,7 @@ jobs: runs-on: ubuntu-latest steps: - - name: checkout + - name: Checkout code uses: actions/checkout@v4 - name: Copy Docker Compose File From Repo to VM Host @@ -90,4 +92,4 @@ jobs: docker network create angelos-network fi docker network ls - docker compose -f /home/${{ vars.VM_USERNAME }}/${{ github.repository }}/docker-compose.yml up --pull=always -d --force-recreate --remove-orphans + docker compose -f /home/${{ vars.VM_USERNAME }}/${{ github.repository }}/docker-compose.yml up --pull=always -d --force-recreate --remove-orphans \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 1de5dc2..bb5c710 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,21 @@ +# Stage 1: Build the Angular app FROM node:20-alpine AS build WORKDIR /app +# Copy package files and install dependencies COPY package.json package-lock.json ./ RUN npm install +# Copy the application code and build the app COPY . ./ -RUN npm install -RUN npm run build -- --configuration=production +RUN npm run build -- --configuration=production --base-href=/chatbot/ +# Stage 2: Serve the app with NGINX FROM nginx:stable-alpine COPY nginx.conf /etc/nginx/conf.d/default.conf -COPY --from=build /app/dist/angelos-ui/browser /usr/share/nginx/html +COPY --from=build /app/dist/chatbot/browser /usr/share/nginx/html EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] +# Start NGINX +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/angular.json b/angular.json index 9fbfd88..55b7ba7 100644 --- a/angular.json +++ b/angular.json @@ -57,7 +57,8 @@ "with": "src/environments/environment.prod.ts" } ], - "outputHashing": "all" + "outputHashing": "all", + "baseHref": "/chat/" }, "development": { "optimization": false, diff --git a/docker-compose.yml b/docker-compose.yml index 762cfc6..ecfdc30 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,12 @@ services: - angelos-ui: + chatbot: image: "ghcr.io/ls1intum/angelos-ui:latest" - container_name: angelos-ui - ports: - - "443:443" + container_name: chatbot expose: - - "443" - volumes: - - type: bind - source: /var/lib/rbg-cert/2024-10-31T11:10:43+01:00 - target: /etc/ssl/certs + - "80" networks: - - angelos-network + - angelos-network networks: angelos-network: - external: true + external: true \ No newline at end of file diff --git a/nginx.conf b/nginx.conf index 8281bfe..889eff7 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,51 +1,23 @@ server { listen 80; - listen [::]:80; - server_name chatbot.ase.cit.tum.de www.chatbot.ase.cit.tum.de; - - return 301 https://$host$request_uri; -} - -server { - listen 443 ssl; - listen [::]:443 ssl; - http2 on; - server_name chatbot.ase.cit.tum.de www.chatbot.ase.cit.tum.de; - - # SSL Certificate files - ssl_certificate /etc/ssl/certs/host:f:asevm83.cit.tum.de.cert.pem; - ssl_certificate_key /etc/ssl/certs/host:f:asevm83.cit.tum.de.privkey.pem; - - # SSL Settings (recommended for security) - # ssl_dhparam /etc/nginx/dhparam.pem; - ssl_prefer_server_ciphers on; - ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; - ssl_ecdh_curve secp384r1; - ssl_session_timeout 10m; - ssl_session_cache shared:SSL:10m; - ssl_session_tickets off; - ssl_stapling on; - ssl_stapling_verify on; -# ssl_early_data on; - location / { - root /usr/share/nginx/html; - index index.html; - try_files $uri $uri/ /index.html; - } - - location /api/ { - proxy_pass http://angelos-app:8000; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Internal-Access "true"; - } - - error_page 500 502 503 504 /50x.html; - - location = /50x.html { - root /usr/share/nginx/html; - } - + server_name localhost; + + # Serve Angular app from /usr/share/nginx/html + root /usr/share/nginx/html; + index index.csr.html; + + # Handle Angular routing + location /chatbot/ { + try_files $uri /index.csr.html; + } + + # Redirect 404 errors to Angular's index.csr.html + error_page 404 /index.csr.html; + + # Optional: Cache static files + location ~* \.(?:ico|css|js|woff2?|eot|ttf|otf|svg|png|jpg|jpeg|gif|webp|avif|mp4|webm|ogg|mp3|wav|flac|aac)$ { + expires 6M; + access_log off; + add_header Cache-Control "public"; + } } \ No newline at end of file diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 2c162a0..166c1f9 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -5,8 +5,8 @@ import { AuthGuard } from './utils/auth.guard'; export const routes: Routes = [ { path: 'login', component: LoginComponent }, - { path: 'chat/en', component: ChatComponent, canActivate: [AuthGuard], data: { language: 'en' } }, - { path: 'chat/de', component: ChatComponent, canActivate: [AuthGuard], data: { language: 'de' } }, + { path: 'en', component: ChatComponent, canActivate: [AuthGuard], data: { language: 'en' } }, + { path: 'de', component: ChatComponent, canActivate: [AuthGuard], data: { language: 'de' } }, { path: '', redirectTo: 'login', pathMatch: 'full' }, { path: '**', redirectTo: 'login', pathMatch: 'full' } ]; \ No newline at end of file diff --git a/src/app/chat/chat.component.html b/src/app/chat/chat.component.html index 03c98f5..db18f42 100644 --- a/src/app/chat/chat.component.html +++ b/src/app/chat/chat.component.html @@ -1,8 +1,9 @@
+
- +
diff --git a/src/app/chat/chat.component.scss b/src/app/chat/chat.component.scss index 20846ac..bf6f15e 100644 --- a/src/app/chat/chat.component.scss +++ b/src/app/chat/chat.component.scss @@ -178,4 +178,5 @@ $logo-size: 40px; transform: translateY(-2px); opacity: 0.7; } -} \ No newline at end of file +} + diff --git a/src/app/chat/chat.component.ts b/src/app/chat/chat.component.ts index 7b6fa21..566cffc 100644 --- a/src/app/chat/chat.component.ts +++ b/src/app/chat/chat.component.ts @@ -3,8 +3,10 @@ import { Component, ElementRef, ViewChild, OnInit, ViewChildren, QueryList, Afte import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ChatbotService } from '../services/chatbot.service'; import { NgSelectModule } from '@ng-select/ng-select'; -import { studyPrograms } from '../utils/study_programs'; import { ActivatedRoute } from '@angular/router'; +import { ErrorSnackbarComponent } from '../utils/error-snackbar/error-snackbar.component'; +import { StudyProgramService } from '../services/study-program.service'; +import { StudyProgram } from '../data/study-program'; export interface ChatMessage { message: string; @@ -41,7 +43,13 @@ export const MESSAGES = { @Component({ selector: 'app-chat', standalone: true, - imports: [CommonModule, FormsModule, NgSelectModule, ReactiveFormsModule], + imports: [ + CommonModule, + FormsModule, + NgSelectModule, + ReactiveFormsModule, + ErrorSnackbarComponent + ], providers: [ChatbotService], templateUrl: './chat.component.html', styleUrls: ['./chat.component.scss'] @@ -50,6 +58,7 @@ export class ChatComponent implements OnInit, AfterViewChecked { @ViewChild('chatBody', { static: false }) chatBody: ElementRef | undefined; @ViewChild('messageInput') messageInput!: ElementRef; @ViewChildren('messageElements') messageElements!: QueryList; + @ViewChild('errorSnackbar') errorSnackbar!: ErrorSnackbarComponent; messages: ChatMessage[] = []; userMessage: string = ''; @@ -58,18 +67,29 @@ export class ChatComponent implements OnInit, AfterViewChecked { errorMessage: string = ''; dropdownLabel: string = ''; - // FormControl for the study program dropdown - studyProgramControl = new FormControl(null); - studyPrograms = studyPrograms; + studyPrograms: StudyProgram[] = []; + selectedStudyProgram: StudyProgram | null = null; language: 'en' | 'de' = 'en'; // Default language is English private needScrollToBottom: boolean = false; disableSending: boolean = false; - constructor(private chatbotService: ChatbotService, private route: ActivatedRoute) { } + constructor(private chatbotService: ChatbotService, private studyProgramService: StudyProgramService, private route: ActivatedRoute) { } ngOnInit() { // Get language from route data (or query params if applicable) + this.studyProgramService.getStudyPrograms().subscribe({ + next: (studyPrograms) => { + this.studyPrograms = studyPrograms.sort((a, b) => { + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + return 0; + }); + }, + error: (error) => { + this.errorSnackbar.showError('Studiengänge konnten nicht geladen werden. Bitte versuchen Sie es zu einem späteren Zeitpunkt erneut.', 5000); + } + }); this.route.data.subscribe(data => { this.language = data['language'] || 'en'; this.setLanguageContent(); @@ -113,8 +133,11 @@ export class ChatComponent implements OnInit, AfterViewChecked { this.userMessage = ''; this.resetTextAreaHeight(); this.needScrollToBottom = true; - - const selectedProgram = this.studyProgramControl.value? this.studyProgramControl.value as string : ''; + + // Study program name in request format + const selectedProgramName = this.selectedStudyProgram?.name + .toLowerCase() + .replace(/\s+/g, '-') || ''; // Add a loading message to indicate the bot is typing const loadingMessage: ChatMessage = { message: '', type: 'loading' }; @@ -126,7 +149,7 @@ export class ChatComponent implements OnInit, AfterViewChecked { const messagesToSend = nonLoadingMessages.slice(-5); // Call the bot service with the filtered messages - this.chatbotService.getBotResponse(messagesToSend, selectedProgram).subscribe({ + this.chatbotService.getBotResponse(messagesToSend, selectedProgramName).subscribe({ next: (response: any) => { // Remove the loading message this.messages.pop(); @@ -136,8 +159,7 @@ export class ChatComponent implements OnInit, AfterViewChecked { this.needScrollToBottom = true; this.disableSending = false; }, - error: (error) => { - console.error('Error fetching response:', error); + error: (error: any) => { // Remove the loading message this.messages.pop(); // Add an error message @@ -147,6 +169,9 @@ export class ChatComponent implements OnInit, AfterViewChecked { }); this.needScrollToBottom = true; this.disableSending = false; + if (error.message && error.message === 'TokenMissing') { + this.errorSnackbar.showError('Ihre Session ist abgelaufen. Bitte melden Sie sich erneut an.', 5000); + } } }); } @@ -211,7 +236,6 @@ export class ChatComponent implements OnInit, AfterViewChecked { protected scrollToBottom(): void { setTimeout(() => { if (this.messageElements && this.chatBody && this.messageElements.length > 0) { - console.log("Scrolling down") const lastMessageElement = this.messageElements.last; lastMessageElement.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'end' }); @@ -221,4 +245,8 @@ export class ChatComponent implements OnInit, AfterViewChecked { } }, 0); } + + onProgramChange(program: StudyProgram | null): void { + this.selectedStudyProgram = program; + } } diff --git a/src/app/data/study-program.ts b/src/app/data/study-program.ts new file mode 100644 index 0000000..ca839e8 --- /dev/null +++ b/src/app/data/study-program.ts @@ -0,0 +1,4 @@ +export interface StudyProgram { + id: number; + name: string; + } \ No newline at end of file diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 461aa67..6170886 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -32,7 +32,7 @@ export class LoginComponent { if (this.loginForm.valid) { const { username, password } = this.loginForm.value; this.authService.login(username, password).subscribe({ - next: () => this.router.navigate(['/chat/en']), // Redirect to chat after login + next: () => this.router.navigate(['/en']), // Redirect to chat after login error: (err) => (this.errorMessage = 'Invalid username or password') }); } diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index ef40d41..8cdceb7 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -2,11 +2,9 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, tap } from 'rxjs'; import { environment } from '../../environments/environment'; -import * as CryptoJS from 'crypto-js'; export interface AuthResponse { - access_token: string; - token_type: string; + accessToken: string; } @Injectable({ providedIn: 'root' @@ -14,14 +12,16 @@ export interface AuthResponse { export class AuthService { private isAuthenticated = new BehaviorSubject(this.getToken() !== null); + private url = environment.angelosUrl; + constructor(private http: HttpClient) { } login(username: string, password: string): Observable { const headers = new HttpHeaders().set('x-api-key', environment.angelosAppApiKey); - const body = { username: username, password: password }; - return this.http.post(environment.angelosToken, body, { headers }).pipe( + const body = { email: username, password: password }; + return this.http.post(this.url + "/login", body, { headers }).pipe( tap((response: AuthResponse) => { - sessionStorage.setItem('access_token', response.access_token); + sessionStorage.setItem('access_token', response.accessToken); this.isAuthenticated.next(true); }) ); diff --git a/src/app/services/chatbot.service.ts b/src/app/services/chatbot.service.ts index 6cc9e57..43b8564 100644 --- a/src/app/services/chatbot.service.ts +++ b/src/app/services/chatbot.service.ts @@ -1,7 +1,7 @@ -import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { ChatMessage } from '../chat/chat.component'; -import { catchError, Observable, switchMap, throwError } from 'rxjs'; +import { Observable, throwError } from 'rxjs'; import { environment } from '../../environments/environment'; import { AuthService } from './auth.service'; @@ -9,13 +9,22 @@ import { AuthService } from './auth.service'; providedIn: 'root' }) export class ChatbotService { + private url = environment.angelosUrl; + private orgId: number = environment.organisation; + private filterByOrg: boolean = environment.filterByOrg; constructor(private http: HttpClient, private authService: AuthService) { } sendBotRequest(token: string | null, chatHistory: ChatMessage[], study_program: string): Observable { - const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`); - return this.http.post(environment.angelosUrl, - { messages: chatHistory, study_program: study_program }, + const headers = new HttpHeaders().set('ChatAuth', `Bearer ${token}`); + + return this.http.post( + `${this.url}/send?filterByOrg=${this.filterByOrg}`, + { + messages: chatHistory, + study_program: study_program, + orgId: this.orgId + }, { headers } ); } @@ -25,7 +34,7 @@ export class ChatbotService { if (token) { return this.sendBotRequest(token, chatHistory, study_program); } else { - throw new Error('No token found. Access should have been restricted by AuthGuard.'); + return throwError(() => new Error('TokenMissing')); } } } diff --git a/src/app/services/study-program.service.spec.ts b/src/app/services/study-program.service.spec.ts new file mode 100644 index 0000000..8e1ea30 --- /dev/null +++ b/src/app/services/study-program.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { StudyProgramService } from './study-program.service'; + +describe('StudyProgramService', () => { + let service: StudyProgramService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(StudyProgramService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/study-program.service.ts b/src/app/services/study-program.service.ts new file mode 100644 index 0000000..09ee7d8 --- /dev/null +++ b/src/app/services/study-program.service.ts @@ -0,0 +1,31 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { StudyProgram } from '../data/study-program'; +import { environment } from '../../environments/environment'; + +@Injectable({ + providedIn: 'root' +}) +export class StudyProgramService { + private url = environment.angelosUrl; + private orgId: number = environment.organisation; + private filterByOrg: boolean = environment.filterByOrg; + + constructor(private http: HttpClient) { } + + getStudyPrograms(): Observable { + const token = sessionStorage.getItem('access_token'); + + if (!token) { + throw new Error('User is not authenticated.'); + } + + const headers = new HttpHeaders().set('ChatAuth', `Bearer ${token}`); + + const params = { filterByOrg: this.filterByOrg.toString() }; + const url = `${this.url}/study-programs/${this.orgId}`; + + return this.http.get(url, { headers, params }); + } +} diff --git a/src/app/utils/error-snackbar/error-snackbar.component.html b/src/app/utils/error-snackbar/error-snackbar.component.html new file mode 100644 index 0000000..9f8d7d5 --- /dev/null +++ b/src/app/utils/error-snackbar/error-snackbar.component.html @@ -0,0 +1,24 @@ +
+
+ {{ message }} + +
+
\ No newline at end of file diff --git a/src/app/utils/error-snackbar/error-snackbar.component.scss b/src/app/utils/error-snackbar/error-snackbar.component.scss new file mode 100644 index 0000000..1b52112 --- /dev/null +++ b/src/app/utils/error-snackbar/error-snackbar.component.scss @@ -0,0 +1,41 @@ +.snackbar-container { + position: fixed; + top: 16px; + right: 16px; + z-index: 1000; + } + + .snackbar { + background-color: #d32f2f; /* Error red */ + color: white; + padding: 12px 24px; + border-radius: 4px; + box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); + cursor: default; /* Disabling pointer cursor so user knows to click only the X */ + transition: opacity 0.3s ease, transform 0.3s ease; + font-size: 0.875rem; /* Slightly smaller text */ + display: flex; + align-items: center; + justify-content: space-between; + } + + .snackbar:hover { + transform: translateY(-2px); + } + + .dismiss-button { + background: none; + border: none; + color: white; + cursor: pointer; + margin-left: 16px; /* Space between text and icon */ + padding: 0; + display: flex; + align-items: center; + } + + /* Ensure the icon is visible and properly sized */ + .dismiss-button svg { + width: 20px; + height: 20px; + } \ No newline at end of file diff --git a/src/app/utils/error-snackbar/error-snackbar.component.spec.ts b/src/app/utils/error-snackbar/error-snackbar.component.spec.ts new file mode 100644 index 0000000..3598638 --- /dev/null +++ b/src/app/utils/error-snackbar/error-snackbar.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ErrorSnackbarComponent } from './error-snackbar.component'; + +describe('ErrorSnackbarComponent', () => { + let component: ErrorSnackbarComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ErrorSnackbarComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ErrorSnackbarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/utils/error-snackbar/error-snackbar.component.ts b/src/app/utils/error-snackbar/error-snackbar.component.ts new file mode 100644 index 0000000..9344658 --- /dev/null +++ b/src/app/utils/error-snackbar/error-snackbar.component.ts @@ -0,0 +1,27 @@ +import { NgIf } from '@angular/common'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-error-snackbar', + standalone: true, + imports: [NgIf], + templateUrl: './error-snackbar.component.html', + styleUrl: './error-snackbar.component.scss' +}) +export class ErrorSnackbarComponent { + message: string = ''; + isVisible: boolean = false; + + showError(message: string, duration: number = 5000): void { + this.message = message; + this.isVisible = true; + + setTimeout(() => { + this.isVisible = false; + }, duration); + } + + dismiss(): void { + this.isVisible = false; + } +} diff --git a/src/app/utils/study_programs.ts b/src/app/utils/study_programs.ts deleted file mode 100644 index 9886451..0000000 --- a/src/app/utils/study_programs.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const studyPrograms: Array<{ value: string, label: string }> = [ - { value: 'bachelor-bioinformatik', label: 'Bachelor Bioinformatik' }, - { value: 'bachelor-elektrotechnik-informationstechnik', label: 'Bachelor Elektrotechnik Informationstechnik' }, - { value: 'bachelor-informatik', label: 'Bachelor Informatik' }, - { value: 'bachelor-informatik-games-engineering', label: 'Bachelor Informatik Games Engineering' }, - { value: 'bachelor-information-engineering', label: 'Bachelor Information Engineering' }, - { value: 'bachelor-mathematik', label: 'Bachelor Mathematik' }, - { value: 'bachelor-wirtschaftsinformatik', label: 'Bachelor Wirtschaftsinformatik' }, - { value: 'master-bioinformatik', label: 'Master Bioinformatik' }, - { value: 'master-biomedical-computing', label: 'Master Biomedical Computing' }, - { value: 'master-communications-electronics-engineering', label: 'Master Communications Electronics Engineering' }, - { value: 'master-computational-science-engineering', label: 'Master Computational Science Engineering' }, - { value: 'master-data-engineering-analytics', label: 'Master Data Engineering Analytics' }, - { value: 'master-elektrotechnik-informationstechnik', label: 'Master Elektrotechnik Informationstechnik' }, - { value: 'master-informatik', label: 'Master Informatik' }, - { value: 'master-informatik-games-engineering', label: 'Master Informatik Games Engineering' }, - { value: 'master-information-engineering', label: 'Master Information Engineering' }, - { value: 'master-information-systems', label: 'Master Information Systems' }, - { value: 'master-mathematical-finance-actuarial-science', label: 'Master Mathematical Finance Actuarial Science' }, - { value: 'master-mathematics-data-science', label: 'Master Mathematics Data Science' }, - { value: 'master-mathematics-operations-research', label: 'Master Mathematics Operations Research' }, - { value: 'master-mathematics-science-engineering', label: 'Master Mathematics Science Engineering' }, - { value: 'master-mathematik', label: 'Master Mathematik' }, - { value: 'master-neuroengineering', label: 'Neuroengineering' }, - { value: 'master-robotics-cognition-intelligence', label: 'Master Robotics Cognition Intelligence' }, - { value: 'master-topmath', label: 'TopMath' } -]; \ No newline at end of file diff --git a/src/environments/environment.development.ts b/src/environments/environment.development.ts index dfadc01..8976fc6 100644 --- a/src/environments/environment.development.ts +++ b/src/environments/environment.development.ts @@ -1,6 +1,7 @@ export const environment = { production: false, - angelosUrl: 'http://localhost:8000/api/v1/question/chat', - angelosToken: 'http://localhost:8000/api/token', + angelosUrl: 'http://localhost:9007/api/chat', angelosAppApiKey: 'SOME_SECRET_KEY', + organisation : 2, + filterByOrg: true, }; \ No newline at end of file diff --git a/src/environments/environment.ts b/src/environments/environment.ts index e84e5f3..56ad618 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,6 +1,7 @@ export const environment = { production: true, - angelosUrl: '/api/v1/question/chat', - angelosToken: '/api/token', + angelosUrl: 'http://localhost:9007/api/chat', angelosAppApiKey: 'SOME_SECRET_KEY', + organisation : 2, + filterByOrg: true, };