Spaces:
Running
Running
Update flare-ui/src/app/dialogs/version-edit-dialog/version-edit-dialog.component.ts
Browse files
flare-ui/src/app/dialogs/version-edit-dialog/version-edit-dialog.component.ts
CHANGED
@@ -169,17 +169,34 @@ export default class VersionEditDialogComponent implements OnInit {
|
|
169 |
}
|
170 |
|
171 |
createIntentFormGroup(intent: any = {}): FormGroup {
|
172 |
-
|
173 |
name: [intent.name || '', [Validators.required, Validators.pattern(/^[a-zA-Z0-9-]+$/)]],
|
174 |
caption: [intent.caption || ''],
|
175 |
locale: [intent.locale || 'tr-TR'],
|
176 |
detection_prompt: [intent.detection_prompt || '', Validators.required],
|
177 |
-
examples: this.fb.array(
|
178 |
-
parameters: this.fb.array([]),
|
179 |
action: [intent.action || '', Validators.required],
|
180 |
fallback_timeout_prompt: [intent.fallback_timeout_prompt || ''],
|
181 |
fallback_error_prompt: [intent.fallback_error_prompt || '']
|
182 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
}
|
184 |
|
185 |
private populateIntentParameters(intentFormGroup: FormGroup, parameters: any[]) {
|
@@ -242,20 +259,49 @@ export default class VersionEditDialogComponent implements OnInit {
|
|
242 |
const { default: IntentEditDialogComponent } = await import('../intent-edit-dialog/intent-edit-dialog.component');
|
243 |
|
244 |
const intent = this.intents.at(intentIndex);
|
|
|
|
|
|
|
245 |
const dialogRef = this.dialog.open(IntentEditDialogComponent, {
|
246 |
width: '90vw',
|
247 |
maxWidth: '1000px',
|
248 |
data: {
|
249 |
-
intent:
|
|
|
|
|
|
|
|
|
250 |
project: this.project,
|
251 |
apis: await this.getAvailableAPIs()
|
252 |
}
|
253 |
});
|
254 |
-
|
255 |
dialogRef.afterClosed().subscribe(result => {
|
256 |
if (result) {
|
257 |
-
//
|
258 |
-
intent.patchValue(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
}
|
260 |
});
|
261 |
}
|
@@ -387,34 +433,64 @@ export default class VersionEditDialogComponent implements OnInit {
|
|
387 |
|
388 |
async saveVersion() {
|
389 |
if (this.versionForm.invalid || !this.selectedVersion) {
|
390 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
391 |
return;
|
392 |
}
|
393 |
-
|
394 |
this.saving = true;
|
395 |
|
396 |
-
// updateData'yı try bloğunun dışında tanımla
|
397 |
-
const formValue = this.versionForm.getRawValue();
|
398 |
-
const intents = formValue.intents.map((intent: any) => ({
|
399 |
-
...intent,
|
400 |
-
examples: intent.examples || []
|
401 |
-
}));
|
402 |
-
|
403 |
-
const updateData = {
|
404 |
-
caption: formValue.caption,
|
405 |
-
general_prompt: formValue.general_prompt,
|
406 |
-
llm: formValue.llm,
|
407 |
-
intents: intents,
|
408 |
-
last_update_date: formValue.last_update_date
|
409 |
-
};
|
410 |
-
|
411 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
412 |
await this.apiService.updateVersion(
|
413 |
this.project.id,
|
414 |
this.selectedVersion.id,
|
415 |
updateData
|
416 |
).toPromise();
|
417 |
-
|
418 |
this.snackBar.open('Version saved successfully', 'Close', { duration: 3000 });
|
419 |
|
420 |
// Update last_update_date for next save
|
@@ -422,55 +498,17 @@ export default class VersionEditDialogComponent implements OnInit {
|
|
422 |
last_update_date: new Date().toISOString()
|
423 |
});
|
424 |
|
|
|
|
|
|
|
425 |
} catch (error: any) {
|
|
|
|
|
426 |
if (error.status === 409 || error.requiresReload) {
|
427 |
-
// Race condition
|
428 |
-
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
|
429 |
-
width: '500px',
|
430 |
-
data: {
|
431 |
-
title: 'Version Modified',
|
432 |
-
message: 'This version was modified by another user. Do you want to reload and lose your changes, or save anyway?',
|
433 |
-
confirmText: 'Reload',
|
434 |
-
cancelText: 'Save Anyway',
|
435 |
-
confirmColor: 'primary'
|
436 |
-
}
|
437 |
-
});
|
438 |
-
|
439 |
-
dialogRef.afterClosed().subscribe(async (shouldReload) => {
|
440 |
-
if (shouldReload) {
|
441 |
-
// Reload version
|
442 |
-
await this.reloadProject();
|
443 |
-
if (this.selectedVersion) {
|
444 |
-
const updated = this.versions.find(v => v.id === this.selectedVersion!.id);
|
445 |
-
if (updated) {
|
446 |
-
this.loadVersion(updated);
|
447 |
-
}
|
448 |
-
}
|
449 |
-
} else {
|
450 |
-
// Force save by removing last_update_date check
|
451 |
-
const forceUpdateData = { ...updateData }; // updateData artık erişilebilir
|
452 |
-
delete forceUpdateData.last_update_date;
|
453 |
-
|
454 |
-
try {
|
455 |
-
await this.apiService.updateVersion(
|
456 |
-
this.project.id,
|
457 |
-
this.selectedVersion!.id,
|
458 |
-
forceUpdateData,
|
459 |
-
true // force parameter
|
460 |
-
).toPromise();
|
461 |
-
|
462 |
-
this.snackBar.open('Version saved (forced)', 'Close', { duration: 3000 });
|
463 |
-
await this.reloadProject();
|
464 |
-
} catch (err: any) {
|
465 |
-
this.snackBar.open(err.error?.detail || 'Failed to save version', 'Close', {
|
466 |
-
duration: 5000,
|
467 |
-
panelClass: 'error-snackbar'
|
468 |
-
});
|
469 |
-
}
|
470 |
-
}
|
471 |
-
});
|
472 |
} else {
|
473 |
-
|
|
|
474 |
duration: 5000,
|
475 |
panelClass: 'error-snackbar'
|
476 |
});
|
|
|
169 |
}
|
170 |
|
171 |
createIntentFormGroup(intent: any = {}): FormGroup {
|
172 |
+
const group = this.fb.group({
|
173 |
name: [intent.name || '', [Validators.required, Validators.pattern(/^[a-zA-Z0-9-]+$/)]],
|
174 |
caption: [intent.caption || ''],
|
175 |
locale: [intent.locale || 'tr-TR'],
|
176 |
detection_prompt: [intent.detection_prompt || '', Validators.required],
|
177 |
+
examples: this.fb.array([]),
|
178 |
+
parameters: this.fb.array([]),
|
179 |
action: [intent.action || '', Validators.required],
|
180 |
fallback_timeout_prompt: [intent.fallback_timeout_prompt || ''],
|
181 |
fallback_error_prompt: [intent.fallback_error_prompt || '']
|
182 |
});
|
183 |
+
|
184 |
+
// Examples ve parameters'ı ayrı olarak ekle
|
185 |
+
if (intent.examples && Array.isArray(intent.examples)) {
|
186 |
+
const examplesArray = group.get('examples') as FormArray;
|
187 |
+
intent.examples.forEach((example: string) => {
|
188 |
+
examplesArray.push(this.fb.control(example));
|
189 |
+
});
|
190 |
+
}
|
191 |
+
|
192 |
+
if (intent.parameters && Array.isArray(intent.parameters)) {
|
193 |
+
const parametersArray = group.get('parameters') as FormArray;
|
194 |
+
intent.parameters.forEach((param: any) => {
|
195 |
+
parametersArray.push(this.createParameterFormGroup(param));
|
196 |
+
});
|
197 |
+
}
|
198 |
+
|
199 |
+
return group;
|
200 |
}
|
201 |
|
202 |
private populateIntentParameters(intentFormGroup: FormGroup, parameters: any[]) {
|
|
|
259 |
const { default: IntentEditDialogComponent } = await import('../intent-edit-dialog/intent-edit-dialog.component');
|
260 |
|
261 |
const intent = this.intents.at(intentIndex);
|
262 |
+
const currentValue = intent.value;
|
263 |
+
|
264 |
+
// Intent verilerini dialog'a gönder
|
265 |
const dialogRef = this.dialog.open(IntentEditDialogComponent, {
|
266 |
width: '90vw',
|
267 |
maxWidth: '1000px',
|
268 |
data: {
|
269 |
+
intent: {
|
270 |
+
...currentValue,
|
271 |
+
examples: currentValue.examples || [],
|
272 |
+
parameters: currentValue.parameters || []
|
273 |
+
},
|
274 |
project: this.project,
|
275 |
apis: await this.getAvailableAPIs()
|
276 |
}
|
277 |
});
|
278 |
+
|
279 |
dialogRef.afterClosed().subscribe(result => {
|
280 |
if (result) {
|
281 |
+
// FormArray'leri yeniden oluştur
|
282 |
+
intent.patchValue({
|
283 |
+
name: result.name,
|
284 |
+
caption: result.caption,
|
285 |
+
locale: result.locale,
|
286 |
+
detection_prompt: result.detection_prompt,
|
287 |
+
action: result.action,
|
288 |
+
fallback_timeout_prompt: result.fallback_timeout_prompt,
|
289 |
+
fallback_error_prompt: result.fallback_error_prompt
|
290 |
+
});
|
291 |
+
|
292 |
+
// Examples'ı güncelle
|
293 |
+
const examplesArray = intent.get('examples') as FormArray;
|
294 |
+
examplesArray.clear();
|
295 |
+
(result.examples || []).forEach((example: string) => {
|
296 |
+
examplesArray.push(this.fb.control(example));
|
297 |
+
});
|
298 |
+
|
299 |
+
// Parameters'ı güncelle
|
300 |
+
const parametersArray = intent.get('parameters') as FormArray;
|
301 |
+
parametersArray.clear();
|
302 |
+
(result.parameters || []).forEach((param: any) => {
|
303 |
+
parametersArray.push(this.createParameterFormGroup(param));
|
304 |
+
});
|
305 |
}
|
306 |
});
|
307 |
}
|
|
|
433 |
|
434 |
async saveVersion() {
|
435 |
if (this.versionForm.invalid || !this.selectedVersion) {
|
436 |
+
// Hangi alanların invalid olduğunu göster
|
437 |
+
const invalidFields: string[] = [];
|
438 |
+
Object.keys(this.versionForm.controls).forEach(key => {
|
439 |
+
const control = this.versionForm.get(key);
|
440 |
+
if (control && control.invalid) {
|
441 |
+
invalidFields.push(key);
|
442 |
+
}
|
443 |
+
});
|
444 |
+
|
445 |
+
// Intents içindeki hataları kontrol et
|
446 |
+
this.intents.controls.forEach((intent, index) => {
|
447 |
+
if (intent.invalid) {
|
448 |
+
invalidFields.push(`Intent ${index + 1}`);
|
449 |
+
}
|
450 |
+
});
|
451 |
+
|
452 |
+
this.snackBar.open(`Please fix validation errors in: ${invalidFields.join(', ')}`, 'Close', {
|
453 |
+
duration: 5000
|
454 |
+
});
|
455 |
return;
|
456 |
}
|
457 |
+
|
458 |
this.saving = true;
|
459 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
try {
|
461 |
+
const formValue = this.versionForm.getRawValue();
|
462 |
+
|
463 |
+
// Intent verilerini düzgün formatta hazırla
|
464 |
+
const intents = formValue.intents.map((intent: any) => ({
|
465 |
+
name: intent.name,
|
466 |
+
caption: intent.caption,
|
467 |
+
locale: intent.locale,
|
468 |
+
detection_prompt: intent.detection_prompt,
|
469 |
+
examples: Array.isArray(intent.examples) ? intent.examples : [],
|
470 |
+
parameters: Array.isArray(intent.parameters) ? intent.parameters : [],
|
471 |
+
action: intent.action,
|
472 |
+
fallback_timeout_prompt: intent.fallback_timeout_prompt,
|
473 |
+
fallback_error_prompt: intent.fallback_error_prompt
|
474 |
+
}));
|
475 |
+
|
476 |
+
const updateData = {
|
477 |
+
caption: formValue.caption,
|
478 |
+
description: formValue.caption,
|
479 |
+
default_api: this.selectedVersion.default_api || '',
|
480 |
+
llm: formValue.llm,
|
481 |
+
intents: intents,
|
482 |
+
parameters: formValue.parameters || [],
|
483 |
+
last_update_date: formValue.last_update_date
|
484 |
+
};
|
485 |
+
|
486 |
+
console.log('Saving version data:', updateData);
|
487 |
+
|
488 |
await this.apiService.updateVersion(
|
489 |
this.project.id,
|
490 |
this.selectedVersion.id,
|
491 |
updateData
|
492 |
).toPromise();
|
493 |
+
|
494 |
this.snackBar.open('Version saved successfully', 'Close', { duration: 3000 });
|
495 |
|
496 |
// Update last_update_date for next save
|
|
|
498 |
last_update_date: new Date().toISOString()
|
499 |
});
|
500 |
|
501 |
+
// Reload versions to get fresh data
|
502 |
+
await this.loadVersions();
|
503 |
+
|
504 |
} catch (error: any) {
|
505 |
+
console.error('Save error:', error);
|
506 |
+
|
507 |
if (error.status === 409 || error.requiresReload) {
|
508 |
+
// Race condition handling kodunuz...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
509 |
} else {
|
510 |
+
const errorMessage = error.error?.detail || error.message || 'Failed to save version';
|
511 |
+
this.snackBar.open(errorMessage, 'Close', {
|
512 |
duration: 5000,
|
513 |
panelClass: 'error-snackbar'
|
514 |
});
|