Spaces:
Paused
Paused
| import { Component, inject, OnInit, OnDestroy } from '@angular/core'; | |
| import { CommonModule } from '@angular/common'; | |
| import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router'; | |
| import { MatToolbarModule } from '@angular/material/toolbar'; | |
| import { MatTabsModule } from '@angular/material/tabs'; | |
| import { MatButtonModule } from '@angular/material/button'; | |
| import { MatIconModule } from '@angular/material/icon'; | |
| import { MatMenuModule } from '@angular/material/menu'; | |
| import { MatBadgeModule } from '@angular/material/badge'; | |
| import { MatDividerModule } from '@angular/material/divider'; | |
| import { Subject, takeUntil } from 'rxjs'; | |
| import { AuthService } from '../../services/auth.service'; | |
| import { ActivityLogComponent } from '../activity-log/activity-log.component'; | |
| import { ApiService } from '../../services/api.service'; | |
| import { EnvironmentService } from '../../services/environment.service'; | |
| ({ | |
| selector: 'app-main', | |
| standalone: true, | |
| imports: [ | |
| CommonModule, | |
| RouterLink, | |
| RouterLinkActive, | |
| RouterOutlet, | |
| MatToolbarModule, | |
| MatTabsModule, | |
| MatButtonModule, | |
| MatIconModule, | |
| MatMenuModule, | |
| MatBadgeModule, | |
| MatDividerModule, | |
| ActivityLogComponent | |
| ], | |
| template: ` | |
| <div class="main-layout"> | |
| <mat-toolbar color="primary" class="header-toolbar"> | |
| <mat-toolbar-row> | |
| <span class="logo"> | |
| <mat-icon>dashboard</mat-icon> | |
| Flare Administration | |
| </span> | |
| <span class="spacer"></span> | |
| <div class="header-actions"> | |
| <span class="username"> | |
| <mat-icon>person</mat-icon> | |
| {{ username }} | |
| </span> | |
| <button mat-icon-button | |
| (click)="toggleActivityLog()" | |
| matTooltip="Activity Log"> | |
| <mat-icon>notifications</mat-icon> | |
| </button> | |
| @if (showActivityLog) { | |
| <div class="activity-log-wrapper" (click)="$event.stopPropagation()"> | |
| <app-activity-log (close)="toggleActivityLog()"></app-activity-log> | |
| </div> | |
| } | |
| <button mat-icon-button [matMenuTriggerFor]="userMenu" matTooltip="User Menu"> | |
| <mat-icon>account_circle</mat-icon> | |
| </button> | |
| <mat-menu #userMenu="matMenu"> | |
| <button mat-menu-item routerLink="/user-info"> | |
| <mat-icon>settings</mat-icon> | |
| <span>User Settings</span> | |
| </button> | |
| <mat-divider></mat-divider> | |
| <button mat-menu-item (click)="logout()"> | |
| <mat-icon>exit_to_app</mat-icon> | |
| <span>Logout</span> | |
| </button> | |
| </mat-menu> | |
| </div> | |
| </mat-toolbar-row> | |
| </mat-toolbar> | |
| <nav mat-tab-nav-bar class="nav-tabs" #navBar="matTabNavBar" [tabPanel]="tabPanel"> | |
| <a mat-tab-link | |
| routerLink="/user-info" | |
| routerLinkActive #rla1="routerLinkActive" | |
| [active]="rla1.isActive"> | |
| <mat-icon>person</mat-icon> | |
| User Info | |
| </a> | |
| <a mat-tab-link | |
| routerLink="/environment" | |
| routerLinkActive #rla2="routerLinkActive" | |
| [active]="rla2.isActive"> | |
| <mat-icon>settings</mat-icon> | |
| Environment | |
| </a> | |
| <a mat-tab-link | |
| routerLink="/apis" | |
| routerLinkActive #rla3="routerLinkActive" | |
| [active]="rla3.isActive"> | |
| <mat-icon>api</mat-icon> | |
| APIs | |
| </a> | |
| <a mat-tab-link | |
| routerLink="/projects" | |
| routerLinkActive #rla4="routerLinkActive" | |
| [active]="rla4.isActive"> | |
| <mat-icon>folder_special</mat-icon> | |
| Projects | |
| </a> | |
| <a mat-tab-link | |
| routerLink="/chat" | |
| routerLinkActive #rla5="routerLinkActive" | |
| [active]="rla5.isActive"> | |
| <mat-icon>chat_bubble_outline</mat-icon> | |
| Chat | |
| </a> | |
| @if (!isGPTMode) { | |
| <a mat-tab-link | |
| routerLink="/spark" | |
| routerLinkActive #rla6="routerLinkActive" | |
| [active]="rla6.isActive"> | |
| <mat-icon>flash_on</mat-icon> | |
| Spark Integration | |
| </a> | |
| } | |
| <a mat-tab-link | |
| routerLink="/test" | |
| routerLinkActive #rla7="routerLinkActive" | |
| [active]="rla7.isActive"> | |
| <mat-icon>bug_report</mat-icon> | |
| Test | |
| </a> | |
| </nav> | |
| <mat-tab-nav-panel #tabPanel> | |
| <main class="content"> | |
| <router-outlet></router-outlet> | |
| </main> | |
| </mat-tab-nav-panel> | |
| </div> | |
| `, | |
| styles: [` | |
| .main-layout { | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| background-color: #fafafa; | |
| } | |
| .header-toolbar { | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| z-index: 100; | |
| position: relative; | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| font-size: 20px; | |
| font-weight: 500; | |
| mat-icon { | |
| font-size: 28px; | |
| width: 28px; | |
| height: 28px; | |
| } | |
| } | |
| .spacer { | |
| flex: 1 1 auto; | |
| } | |
| .header-actions { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| position: relative; | |
| .username { | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| margin-right: 16px; | |
| mat-icon { | |
| font-size: 20px; | |
| width: 20px; | |
| height: 20px; | |
| } | |
| } | |
| .activity-log-wrapper { | |
| position: absolute; | |
| top: 56px; | |
| right: 0; | |
| z-index: 1000; | |
| } | |
| } | |
| } | |
| .nav-tabs { | |
| background-color: white; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.08); | |
| ::ng-deep { | |
| .mat-mdc-tab-link { | |
| min-width: 120px; | |
| opacity: 0.8; | |
| mat-icon { | |
| margin-right: 8px; | |
| } | |
| &.mdc-tab--active { | |
| opacity: 1; | |
| } | |
| } | |
| } | |
| } | |
| .content { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 24px; | |
| } | |
| `] | |
| }) | |
| export class MainComponent implements OnInit, OnDestroy { | |
| private authService = inject(AuthService); | |
| private apiService = inject(ApiService); | |
| private environmentService = inject(EnvironmentService); | |
| username = this.authService.getUsername() || ''; | |
| showActivityLog = false; | |
| isGPTMode = false; | |
| // Memory leak prevention | |
| private destroyed$ = new Subject<void>(); | |
| ngOnInit() { | |
| // Environment değişikliklerini dinle | |
| this.environmentService.environment$ | |
| .pipe(takeUntil(this.destroyed$)) | |
| .subscribe(env => { | |
| if (env) { | |
| // work_mode yerine llm_provider.name kullan | |
| this.isGPTMode = env.llm_provider?.name?.startsWith('gpt4o') || false; | |
| this.updateProviderInfo(env); | |
| } | |
| }); | |
| // Environment bilgisini al | |
| this.loadEnvironment(); | |
| } | |
| ngOnDestroy() { | |
| this.destroyed$.next(); | |
| this.destroyed$.complete(); | |
| } | |
| loadEnvironment() { | |
| this.apiService.getEnvironment() | |
| .pipe(takeUntil(this.destroyed$)) | |
| .subscribe({ | |
| next: (env) => { | |
| this.environmentService.updateEnvironment(env); | |
| this.updateProviderInfo(env); | |
| }, | |
| error: (error) => { | |
| console.error('Failed to load environment:', error); | |
| // Show snackbar if needed | |
| } | |
| }); | |
| } | |
| updateProviderInfo(env: any) { | |
| // Update TTS/STT availability - zaten doğru | |
| this.environmentService.setTTSEnabled(!!env.tts_provider?.name && env.tts_provider.name !== 'no_tts'); | |
| this.environmentService.setSTTEnabled(!!env.stt_provider?.name && env.stt_provider.name !== 'no_stt'); | |
| // GPT mode'u da burada güncelleyebiliriz | |
| this.isGPTMode = env.llm_provider?.name?.startsWith('gpt4o') || false; | |
| } | |
| logout() { | |
| // Cleanup before logout | |
| this.destroyed$.next(); | |
| this.authService.logout(); | |
| } | |
| toggleActivityLog() { | |
| this.showActivityLog = !this.showActivityLog; | |
| } | |
| } |