flare / flare-ui /src /app /dialogs /project-edit-dialog /project-edit-dialog.component.ts
ciyidogan's picture
Update flare-ui/src/app/dialogs/project-edit-dialog/project-edit-dialog.component.ts
8226901 verified
raw
history blame
8.9 kB
// 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;
}
@Component({
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>,
@Inject(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();
}
}