flare / flare-ui /src /app /services /api.service.ts
ciyidogan's picture
Update flare-ui/src/app/services/api.service.ts
de0719d verified
raw
history blame
8.81 kB
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { AuthService } from './auth.service';
// Interfaces
export interface Environment {
work_mode: string;
cloud_token: string;
spark_endpoint: string;
}
export interface API {
name: string;
url: string;
method: string;
headers?: any;
body_template?: any;
timeout_seconds: number;
retry?: {
retry_count: number;
backoff_seconds: number;
strategy: string;
};
auth?: {
enabled: boolean;
token_endpoint?: string;
response_token_path?: string;
token_request_body?: any;
token_refresh_endpoint?: string;
token_refresh_body?: any;
};
response_prompt?: string;
deleted?: boolean;
last_update_date?: string;
last_update_user?: string;
}
export interface Version {
id: number;
version_number: number;
caption: string;
published: boolean;
general_prompt?: string;
llm?: any;
intents?: any[];
created_date?: string;
published_by?: string;
publish_date?: string;
last_update_date?: string;
last_update_user?: string;
}
export interface Project {
id: number;
name: string;
caption: string;
enabled: boolean;
versions: Version[];
last_update_date?: string;
deleted?: boolean;
created_date?: string;
created_by?: string;
last_update_user?: string;
}
@Injectable({
providedIn: 'root'
})
export class ApiService {
private apiUrl = '/api';
constructor(
private http: HttpClient,
private router: Router,
private authService: AuthService
) {}
// ===================== Auth =====================
login(username: string, password: string): Observable<any> {
return this.http.post(`${this.apiUrl}/login`, { username, password }).pipe(
tap((response: any) => {
this.authService.setToken(response.token);
this.authService.setUsername(response.username);
})
);
}
logout(): void {
this.authService.logout();
}
private getAuthHeaders(): HttpHeaders {
const token = this.authService.getToken();
return new HttpHeaders({
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
});
}
// ===================== User =====================
changePassword(currentPassword: string, newPassword: string): Observable<any> {
return this.http.post(
`${this.apiUrl}/change-password`,
{ current_password: currentPassword, new_password: newPassword },
{ headers: this.getAuthHeaders() }
).pipe(
catchError(this.handleError)
);
}
// ===================== Environment =====================
getEnvironment(): Observable<Environment> {
return this.http.get<Environment>(`${this.apiUrl}/environment`, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
updateEnvironment(data: Environment): Observable<any> {
return this.http.put(`${this.apiUrl}/environment`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
// ===================== Projects =====================
getProjects(includeDeleted = false): Observable<Project[]> {
return this.http.get<Project[]>(`${this.apiUrl}/projects`, {
headers: this.getAuthHeaders(),
params: { include_deleted: includeDeleted.toString() }
}).pipe(
catchError(this.handleError)
);
}
createProject(data: any): Observable<any> {
return this.http.post(`${this.apiUrl}/projects`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
updateProject(id: number, data: any): Observable<any> {
return this.http.put(`${this.apiUrl}/projects/${id}`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
deleteProject(id: number): Observable<any> {
return this.http.delete(`${this.apiUrl}/projects/${id}`, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
toggleProject(id: number): Observable<any> {
return this.http.patch(`${this.apiUrl}/projects/${id}/toggle`, {}, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
exportProject(id: number): Observable<any> {
return this.http.get(`${this.apiUrl}/projects/${id}/export`, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
importProject(data: any): Observable<any> {
return this.http.post(`${this.apiUrl}/projects/import`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
// ===================== Versions =====================
createVersion(projectId: number, data: any): Observable<any> {
return this.http.post(`${this.apiUrl}/projects/${projectId}/versions`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
updateVersion(projectId: number, versionId: number, data: any, force: boolean = false): Observable<any> {
return this.http.put(
`${this.apiUrl}/projects/${projectId}/versions/${versionId}${force ? '?force=true' : ''}`,
data,
{ headers: this.getAuthHeaders() }
).pipe(
catchError(this.handleError)
);
}
deleteVersion(projectId: number, versionId: number): Observable<any> {
return this.http.delete(`${this.apiUrl}/projects/${projectId}/versions/${versionId}`, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
publishVersion(projectId: number, versionId: number): Observable<any> {
return this.http.post(`${this.apiUrl}/projects/${projectId}/versions/${versionId}/publish`, {}, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
// ===================== APIs =====================
getAPIs(includeDeleted = false): Observable<API[]> {
return this.http.get<API[]>(`${this.apiUrl}/apis`, {
headers: this.getAuthHeaders(),
params: { include_deleted: includeDeleted.toString() }
}).pipe(
catchError(this.handleError)
);
}
createAPI(data: any): Observable<any> {
return this.http.post(`${this.apiUrl}/apis`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
updateAPI(name: string, data: any): Observable<any> {
return this.http.put(`${this.apiUrl}/apis/${name}`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
deleteAPI(name: string): Observable<any> {
return this.http.delete(`${this.apiUrl}/apis/${name}`, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
testAPI(data: any): Observable<any> {
return this.http.post(`${this.apiUrl}/apis/test`, data, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
// ===================== Tests =====================
runTests(testType: string): Observable<any> {
return this.http.post(`${this.apiUrl}/test/run-all`, { test_type: testType }, {
headers: this.getAuthHeaders()
}).pipe(
catchError(this.handleError)
);
}
// ===================== Activity Log =====================
getActivityLog(limit = 50): Observable<any[]> {
return this.http.get<any[]>(`${this.apiUrl}/activity-log`, {
headers: this.getAuthHeaders(),
params: { limit: limit.toString() }
}).pipe(
catchError(this.handleError)
);
}
// ===================== Validation =====================
validateRegex(pattern: string, testValue: string): Observable<any> {
return this.http.post(`${this.apiUrl}/validate/regex`,
{ pattern, test_value: testValue },
{ headers: this.getAuthHeaders() }
).pipe(
catchError(this.handleError)
);
}
// ===================== Error Handler =====================
// ===================== Error Handler =====================
private handleError(error: any) {
console.error('API Error:', error);
if (error.status === 401) {
// Token expired or invalid
this.authService.logout();
} else if (error.status === 409) {
// Race condition error - add specific handling
const message = error.error?.detail || 'Resource was modified by another user';
// Create a more user-friendly error object
return throwError(() => ({
...error,
userMessage: message,
requiresReload: true
}));
}
return throwError(() => error.error || error);
}
}