ui rebuild

This commit is contained in:
2025-11-24 19:52:35 +00:00
parent c9beae93c8
commit 9aa6906ca5
73 changed files with 8514 additions and 4537 deletions

View File

@@ -1,186 +1,141 @@
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { firstValueFrom } from 'rxjs';
import {
IApiResponse,
IService,
IServiceCreate,
IServiceUpdate,
ISystemStatus,
IDomain,
IDomainDetail,
IDnsRecord,
IRegistry,
IRegistryCreate,
ISetting,
ISettings,
} from '../types/api.types';
export interface ApiResponse<T = any> {
success: boolean;
data?: T;
error?: string;
message?: string;
}
export interface Service {
id: number;
name: string;
image: string;
registry?: string;
envVars: Record<string, string>;
port: number;
domain?: string;
containerID?: string;
status: 'stopped' | 'starting' | 'running' | 'stopping' | 'failed';
createdAt: number;
updatedAt: number;
// Onebox Registry fields
useOneboxRegistry?: boolean;
registryRepository?: string;
registryToken?: string;
registryImageTag?: string;
autoUpdateOnPush?: boolean;
imageDigest?: string;
}
export interface Registry {
id: number;
url: string;
username: string;
createdAt: number;
}
export interface SystemStatus {
docker: {
running: boolean;
version: any;
};
reverseProxy: {
http: {
running: boolean;
port: number;
};
https: {
running: boolean;
port: number;
certificates: number;
};
routes: number;
};
dns: {
configured: boolean;
};
ssl: {
configured: boolean;
certbotInstalled: boolean;
};
services: {
total: number;
running: number;
stopped: number;
};
}
@Injectable({
providedIn: 'root',
})
@Injectable({ providedIn: 'root' })
export class ApiService {
private http = inject(HttpClient);
private baseUrl = '/api';
// System
getStatus(): Observable<ApiResponse<SystemStatus>> {
return this.http.get<ApiResponse<SystemStatus>>(`${this.baseUrl}/status`);
// System Status
async getStatus(): Promise<IApiResponse<ISystemStatus>> {
return firstValueFrom(this.http.get<IApiResponse<ISystemStatus>>('/api/status'));
}
// Services
getServices(): Observable<ApiResponse<Service[]>> {
return this.http.get<ApiResponse<Service[]>>(`${this.baseUrl}/services`);
async getServices(): Promise<IApiResponse<IService[]>> {
return firstValueFrom(this.http.get<IApiResponse<IService[]>>('/api/services'));
}
getService(name: string): Observable<ApiResponse<Service>> {
return this.http.get<ApiResponse<Service>>(`${this.baseUrl}/services/${name}`);
async getService(name: string): Promise<IApiResponse<IService>> {
return firstValueFrom(this.http.get<IApiResponse<IService>>(`/api/services/${name}`));
}
createService(data: any): Observable<ApiResponse<Service>> {
return this.http.post<ApiResponse<Service>>(`${this.baseUrl}/services`, data);
async createService(data: IServiceCreate): Promise<IApiResponse<IService>> {
return firstValueFrom(this.http.post<IApiResponse<IService>>('/api/services', data));
}
deleteService(name: string): Observable<ApiResponse> {
return this.http.delete<ApiResponse>(`${this.baseUrl}/services/${name}`);
async updateService(name: string, data: IServiceUpdate): Promise<IApiResponse<IService>> {
return firstValueFrom(this.http.put<IApiResponse<IService>>(`/api/services/${name}`, data));
}
startService(name: string): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/services/${name}/start`, {});
async deleteService(name: string): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.delete<IApiResponse<void>>(`/api/services/${name}`));
}
stopService(name: string): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/services/${name}/stop`, {});
async startService(name: string): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.post<IApiResponse<void>>(`/api/services/${name}/start`, {}));
}
restartService(name: string): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/services/${name}/restart`, {});
async stopService(name: string): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.post<IApiResponse<void>>(`/api/services/${name}/stop`, {}));
}
getServiceLogs(name: string): Observable<ApiResponse<string>> {
return this.http.get<ApiResponse<string>>(`${this.baseUrl}/services/${name}/logs`);
async restartService(name: string): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.post<IApiResponse<void>>(`/api/services/${name}/restart`, {}));
}
updateService(name: string, updates: {
image?: string;
registry?: string;
port?: number;
domain?: string;
envVars?: Record<string, string>;
}): Observable<ApiResponse<Service>> {
return this.http.put<ApiResponse<Service>>(`${this.baseUrl}/services/${name}`, updates);
async getServiceLogs(name: string): Promise<IApiResponse<string>> {
return firstValueFrom(this.http.get<IApiResponse<string>>(`/api/services/${name}/logs`));
}
// Registries
getRegistries(): Observable<ApiResponse<Registry[]>> {
return this.http.get<ApiResponse<Registry[]>>(`${this.baseUrl}/registries`);
async getRegistries(): Promise<IApiResponse<IRegistry[]>> {
return firstValueFrom(this.http.get<IApiResponse<IRegistry[]>>('/api/registries'));
}
createRegistry(data: any): Observable<ApiResponse<Registry>> {
return this.http.post<ApiResponse<Registry>>(`${this.baseUrl}/registries`, data);
async createRegistry(data: IRegistryCreate): Promise<IApiResponse<IRegistry>> {
return firstValueFrom(this.http.post<IApiResponse<IRegistry>>('/api/registries', data));
}
deleteRegistry(url: string): Observable<ApiResponse> {
return this.http.delete<ApiResponse>(`${this.baseUrl}/registries/${encodeURIComponent(url)}`);
async deleteRegistry(id: number): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.delete<IApiResponse<void>>(`/api/registries/${id}`));
}
// DNS
getDnsRecords(): Observable<ApiResponse<any[]>> {
return this.http.get<ApiResponse<any[]>>(`${this.baseUrl}/dns`);
// DNS Records
async getDnsRecords(): Promise<IApiResponse<IDnsRecord[]>> {
return firstValueFrom(this.http.get<IApiResponse<IDnsRecord[]>>('/api/dns'));
}
createDnsRecord(data: any): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/dns`, data);
async createDnsRecord(domain: string, ip?: string): Promise<IApiResponse<IDnsRecord>> {
return firstValueFrom(this.http.post<IApiResponse<IDnsRecord>>('/api/dns', { domain, ip }));
}
deleteDnsRecord(domain: string): Observable<ApiResponse> {
return this.http.delete<ApiResponse>(`${this.baseUrl}/dns/${domain}`);
async deleteDnsRecord(domain: string): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.delete<IApiResponse<void>>(`/api/dns/${domain}`));
}
syncDnsRecords(): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/dns/sync`, {});
}
// SSL
getSslCertificates(): Observable<ApiResponse<any[]>> {
return this.http.get<ApiResponse<any[]>>(`${this.baseUrl}/ssl`);
}
renewSslCertificate(domain: string): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/ssl/${domain}/renew`, {});
async syncDnsRecords(): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.post<IApiResponse<void>>('/api/dns/sync', {}));
}
// Domains
getDomains(): Observable<ApiResponse<any[]>> {
return this.http.get<ApiResponse<any[]>>(`${this.baseUrl}/domains`);
async getDomains(): Promise<IApiResponse<IDomainDetail[]>> {
return firstValueFrom(this.http.get<IApiResponse<IDomainDetail[]>>('/api/domains'));
}
getDomainDetail(domain: string): Observable<ApiResponse<any>> {
return this.http.get<ApiResponse<any>>(`${this.baseUrl}/domains/${domain}`);
async getDomainDetail(domain: string): Promise<IApiResponse<IDomainDetail>> {
return firstValueFrom(this.http.get<IApiResponse<IDomainDetail>>(`/api/domains/${domain}`));
}
syncCloudflareDomains(): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/domains/sync`, {});
async syncCloudflareDomains(): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.post<IApiResponse<void>>('/api/domains/sync', {}));
}
// SSL Certificates
async obtainCertificate(domain: string, includeWildcard?: boolean): Promise<IApiResponse<void>> {
return firstValueFrom(
this.http.post<IApiResponse<void>>('/api/ssl/obtain', { domain, includeWildcard })
);
}
async renewCertificate(domain: string): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.post<IApiResponse<void>>(`/api/ssl/${domain}/renew`, {}));
}
// Settings
getSettings(): Observable<ApiResponse<Record<string, string>>> {
return this.http.get<ApiResponse<Record<string, string>>>(`${this.baseUrl}/settings`);
async getSettings(): Promise<IApiResponse<ISetting[]>> {
return firstValueFrom(this.http.get<IApiResponse<ISetting[]>>('/api/settings'));
}
updateSetting(key: string, value: string): Observable<ApiResponse> {
return this.http.post<ApiResponse>(`${this.baseUrl}/settings`, { key, value });
async updateSettings(settings: Record<string, string> | ISettings): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.put<IApiResponse<void>>('/api/settings', settings));
}
async updateSetting(key: string, value: string): Promise<IApiResponse<void>> {
return firstValueFrom(this.http.put<IApiResponse<void>>('/api/settings', { key, value }));
}
// Auth
async changePassword(currentPassword: string, newPassword: string): Promise<IApiResponse<void>> {
return firstValueFrom(
this.http.post<IApiResponse<void>>('/api/auth/change-password', {
currentPassword,
newPassword,
})
);
}
}