// project-edit-dialog.component.ts
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 { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ApiService } from '../../services/api.service';
import { LocaleManagerService, Locale } from '../../services/locale-manager.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,
MatProgressSpinnerModule
],
template: `
{{ data.mode === 'create' ? 'Create New Project' : 'Edit Project' }}
`,
styleUrls: ['./project-edit-dialog.component.scss']
})
export default class ProjectEditDialogComponent implements OnInit {
form!: FormGroup;
saving = false;
loadingLocales = true;
availableLocales: Locale[] = [];
projectIcons = ['folder', 'work', 'shopping_cart', 'school', 'local_hospital', 'restaurant', 'home', 'business'];
timezones = [
'Europe/Istanbul',
'Europe/London',
'Europe/Berlin',
'America/New_York',
'America/Los_Angeles',
'Asia/Tokyo'
];
constructor(
private fb: FormBuilder,
private apiService: ApiService,
private localeManager: LocaleManagerService,
private snackBar: MatSnackBar,
public dialogRef: MatDialogRef,
@Inject(MAT_DIALOG_DATA) public data: ProjectDialogData
) {}
ngOnInit() {
this.initializeForm();
this.loadAvailableLocales();
}
initializeForm() {
const defaultValues = this.data.mode === 'edit' && this.data.project ? {
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 || 'Türkçe',
supportedLanguages: this.data.project.supported_languages || ['tr-TR'],
timezone: this.data.project.timezone || 'Europe/Istanbul',
region: this.data.project.region || 'tr-TR'
} : {
name: '',
caption: '',
icon: 'folder',
description: '',
defaultLanguage: 'Türkçe',
supportedLanguages: ['tr-TR'],
timezone: 'Europe/Istanbul',
region: 'tr-TR'
};
this.form = this.fb.group({
name: [defaultValues.name, [Validators.required, Validators.pattern(/^[a-z0-9_]+$/)]],
caption: [defaultValues.caption, Validators.required],
icon: [defaultValues.icon],
description: [defaultValues.description],
defaultLanguage: [defaultValues.defaultLanguage],
supportedLanguages: [defaultValues.supportedLanguages],
timezone: [defaultValues.timezone],
region: [defaultValues.region]
});
// Disable name field in edit mode
if (this.data.mode === 'edit') {
this.form.get('name')?.disable();
}
}
loadAvailableLocales() {
this.loadingLocales = true;
this.localeManager.getAvailableLocales().subscribe({
next: (locales) => {
this.availableLocales = locales;
this.loadingLocales = false;
this.validateSelectedLanguages();
},
error: (err) => {
this.showMessage('Failed to load available languages', 'error');
this.loadingLocales = false;
// Use fallback locales
this.availableLocales = [
{ code: 'tr-TR', name: 'Türkçe', english_name: 'Turkish' },
{ code: 'en-US', name: 'English', english_name: 'English (US)' }
];
}
});
}
validateSelectedLanguages() {
const availableCodes = this.availableLocales.map(l => l.code);
const currentSupported = this.form.get('supportedLanguages')?.value || [];
const currentDefault = this.form.get('defaultLanguage')?.value;
// Filter out any unsupported languages
const validSupported = currentSupported.filter((lang: string) =>
availableCodes.includes(lang)
);
// Update form if any languages were removed
if (validSupported.length !== currentSupported.length) {
this.form.patchValue({ supportedLanguages: validSupported });
}
// Ensure default language is valid
if (!availableCodes.includes(currentDefault)) {
const newDefault = availableCodes[0] || 'tr-TR';
this.form.patchValue({
defaultLanguage: newDefault,
supportedLanguages: [...validSupported, newDefault]
});
}
}
onDefaultLanguageChange() {
// Default language değiştiğinde bir şey yapmaya gerek yok
// Çünkü default_language (Türkçe) ve supported_languages (tr-TR) farklı tipte
}
onSupportedLanguagesChange() {
// Supported languages değiştiğinde de bir şey yapmaya gerek yok
// En az bir dil seçili olduğu sürece sorun yok
const supportedLangs = this.form.get('supportedLanguages')?.value || [];
if (supportedLangs.length === 0) {
// En az bir dil seçilmeli
this.form.patchValue({
supportedLanguages: ['tr-TR']
});
}
}
getLocaleName(code: string): string {
const locale = this.availableLocales.find(l => l.code === code);
return locale ? locale.name : code;
}
async save() {
if (this.form.invalid) {
this.form.markAllAsTouched();
return;
}
this.saving = true;
try {
const formValue = this.form.getRawValue(); // getRawValue to include disabled fields
// Project data format matching backend expectations
const projectData = {
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(projectData).toPromise();
this.showMessage('Project created successfully!');
} else {
// Add last_update_date for edit mode
const updateData = {
...projectData,
last_update_date: this.data.project.last_update_date || ''
};
result = await this.apiService.updateProject(this.data.project.id, updateData).toPromise();
this.showMessage('Project updated successfully!');
}
this.dialogRef.close(result);
} catch (error: any) {
this.showMessage(error.error?.detail || 'Operation failed', 'error');
} finally {
this.saving = false;
}
}
close() {
this.dialogRef.close();
}
private showMessage(message: string, type: 'success' | 'error' = 'success') {
this.snackBar.open(message, 'Close', {
duration: 5000,
panelClass: type === 'error' ? 'error-snackbar' : 'success-snackbar',
horizontalPosition: 'right',
verticalPosition: 'top'
});
}
}