Spaces:
Paused
Paused
| // project-edit-dialog.component.ts (TÜMÜ) - Template inline olarak | |
| import { Component, Inject, OnInit } from '@angular/core'; | |
| import { CommonModule } from '@angular/common'; | |
| import { FormBuilder, FormGroup, Validators, ReactiveFormsModule, FormArray } from '@angular/forms'; | |
| import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; | |
| import { MatFormFieldModule } from '@angular/material/form-field'; | |
| import { MatInputModule } from '@angular/material/input'; | |
| import { MatSelectModule } from '@angular/material/select'; | |
| import { MatCheckboxModule } from '@angular/material/checkbox'; | |
| import { MatButtonModule } from '@angular/material/button'; | |
| import { MatIconModule } from '@angular/material/icon'; | |
| import { MatChipsModule } from '@angular/material/chips'; | |
| import { MatDividerModule } from '@angular/material/divider'; | |
| import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; | |
| import { ApiService } from '../../services/api.service'; | |
| export interface ProjectDialogData { | |
| mode: 'create' | 'edit'; | |
| project?: any; | |
| } | |
| ({ | |
| selector: 'app-project-edit-dialog', | |
| standalone: true, | |
| imports: [ | |
| CommonModule, | |
| ReactiveFormsModule, | |
| MatDialogModule, | |
| MatFormFieldModule, | |
| MatInputModule, | |
| MatSelectModule, | |
| MatCheckboxModule, | |
| MatButtonModule, | |
| MatIconModule, | |
| MatChipsModule, | |
| MatDividerModule, | |
| MatSnackBarModule | |
| ], | |
| template: ` | |
| <h2 mat-dialog-title>{{ data.mode === 'create' ? 'Create New Project' : 'Edit Project' }}</h2> | |
| <mat-dialog-content> | |
| <form [formGroup]="form"> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Name*</mat-label> | |
| <input matInput formControlName="name" | |
| [readonly]="data.mode === 'edit'" | |
| placeholder="e.g., airline_agent"> | |
| <mat-hint>Use only letters, numbers, and underscores</mat-hint> | |
| <mat-error *ngIf="form.get('name')?.hasError('required')">Name is required</mat-error> | |
| <mat-error *ngIf="form.get('name')?.hasError('pattern')">Invalid characters in name</mat-error> | |
| </mat-form-field> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Caption*</mat-label> | |
| <input matInput formControlName="caption" | |
| placeholder="e.g., Airline Customer Service Agent"> | |
| <mat-error *ngIf="form.get('caption')?.hasError('required')">Caption is required</mat-error> | |
| </mat-form-field> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Icon</mat-label> | |
| <mat-select formControlName="icon"> | |
| @for (icon of projectIcons; track icon) { | |
| <mat-option [value]="icon"> | |
| <mat-icon>{{ icon }}</mat-icon> | |
| {{ icon }} | |
| </mat-option> | |
| } | |
| </mat-select> | |
| </mat-form-field> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Description</mat-label> | |
| <textarea matInput formControlName="description" rows="3"></textarea> | |
| </mat-form-field> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Default Language</mat-label> | |
| <mat-select formControlName="defaultLanguage"> | |
| @for (lang of languages; track lang.code) { | |
| <mat-option [value]="lang.code">{{ lang.name }}</mat-option> | |
| } | |
| </mat-select> | |
| </mat-form-field> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Supported Languages</mat-label> | |
| <mat-select formControlName="supportedLanguages" multiple> | |
| @for (lang of languages; track lang.code) { | |
| <mat-option [value]="lang.code">{{ lang.name }}</mat-option> | |
| } | |
| </mat-select> | |
| </mat-form-field> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Timezone</mat-label> | |
| <mat-select formControlName="timezone"> | |
| @for (tz of timezones; track tz) { | |
| <mat-option [value]="tz">{{ tz }}</mat-option> | |
| } | |
| </mat-select> | |
| </mat-form-field> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Region</mat-label> | |
| <input matInput formControlName="region" placeholder="e.g., tr-TR"> | |
| </mat-form-field> | |
| </form> | |
| </mat-dialog-content> | |
| <mat-dialog-actions align="end"> | |
| <button mat-button (click)="close()">Cancel</button> | |
| <button mat-raised-button color="primary" | |
| (click)="save()" | |
| [disabled]="form.invalid || saving"> | |
| {{ saving ? 'Saving...' : (data.mode === 'create' ? 'Create' : 'Save') }} | |
| </button> | |
| </mat-dialog-actions> | |
| `, | |
| styleUrls: ['./project-edit-dialog.component.scss'] | |
| }) | |
| export default class ProjectEditDialogComponent implements OnInit { | |
| form!: FormGroup; | |
| saving = false; | |
| projectIcons = ['folder', 'work', 'shopping_cart', 'school', 'local_hospital', 'restaurant', 'home', 'business']; | |
| languages = [ | |
| { code: 'tr', name: 'Turkish' }, | |
| { code: 'en', name: 'English' }, | |
| { code: 'de', name: 'German' }, | |
| { code: 'fr', name: 'French' }, | |
| { code: 'es', name: 'Spanish' } | |
| ]; | |
| timezones = [ | |
| 'Europe/Istanbul', | |
| 'Europe/London', | |
| 'Europe/Berlin', | |
| 'America/New_York', | |
| 'America/Los_Angeles', | |
| 'Asia/Tokyo' | |
| ]; | |
| constructor( | |
| private fb: FormBuilder, | |
| private apiService: ApiService, | |
| private snackBar: MatSnackBar, | |
| public dialogRef: MatDialogRef<ProjectEditDialogComponent>, | |
| (MAT_DIALOG_DATA) public data: ProjectDialogData | |
| ) {} | |
| ngOnInit() { | |
| this.initializeForm(); | |
| if (this.data.mode === 'edit' && this.data.project) { | |
| this.form.patchValue({ | |
| name: this.data.project.name, | |
| caption: this.data.project.caption || '', | |
| icon: this.data.project.icon || 'folder', | |
| description: this.data.project.description || '', | |
| defaultLanguage: this.data.project.default_language || 'tr', | |
| supportedLanguages: this.data.project.supported_languages || ['tr'], | |
| timezone: this.data.project.timezone || 'Europe/Istanbul', | |
| region: this.data.project.region || 'tr-TR' | |
| }); | |
| // Rebuild test users form array | |
| const testUsersArray = this.form.get('testUsers') as FormArray; | |
| testUsersArray.clear(); | |
| (this.data.project.test_users || []).forEach((phoneNumber: string) => { | |
| testUsersArray.push(this.fb.control(phoneNumber, Validators.required)); | |
| }); | |
| } | |
| } | |
| initializeForm() { | |
| this.form = this.fb.group({ | |
| name: ['', [Validators.required, Validators.pattern(/^[a-z0-9_]+$/)]], | |
| caption: ['', Validators.required], | |
| icon: ['folder'], | |
| description: [''], | |
| defaultLanguage: ['tr'], | |
| supportedLanguages: [['tr']], | |
| timezone: ['Europe/Istanbul'], | |
| region: ['tr-TR'] | |
| // testUsers kaldırıldı | |
| }); | |
| } | |
| async save() { | |
| if (this.form.invalid) { | |
| this.form.markAllAsTouched(); | |
| return; | |
| } | |
| this.saving = true; | |
| try { | |
| const formValue = this.form.value; | |
| // Base project data | |
| const baseProjectData = { | |
| name: formValue.name, | |
| caption: formValue.caption, | |
| icon: formValue.icon, | |
| description: formValue.description, | |
| default_language: formValue.defaultLanguage, | |
| supported_languages: formValue.supportedLanguages, | |
| timezone: formValue.timezone, | |
| region: formValue.region | |
| }; | |
| let result; | |
| if (this.data.mode === 'create') { | |
| result = await this.apiService.createProject(baseProjectData).toPromise(); | |
| this.showMessage('Project created successfully!', false); | |
| } else { | |
| // Edit mode için ek alanlarla birlikte gönder | |
| const updateProjectData = { | |
| ...baseProjectData, | |
| id: this.data.project.id, | |
| last_update_date: this.data.project.last_update_date | |
| }; | |
| result = await this.apiService.updateProject(this.data.project.id, updateProjectData).toPromise(); | |
| this.showMessage('Project updated successfully!', false); | |
| } | |
| this.dialogRef.close(result); | |
| } catch (error: any) { | |
| if (error.status === 409) { | |
| this.showMessage('This record was modified by another user. Please reload and try again.', true); | |
| } else { | |
| this.showMessage(error.error?.detail || 'Operation failed', true); | |
| } | |
| } finally { | |
| this.saving = false; | |
| } | |
| } | |
| private showMessage(message: string, isError: boolean) { | |
| this.snackBar.open(message, 'Close', { | |
| duration: isError ? 5000 : 3000, | |
| panelClass: isError ? 'error-snackbar' : 'success-snackbar' | |
| }); | |
| } | |
| close() { | |
| this.dialogRef.close(); | |
| } | |
| } |