Major update to Apps page. Add instance switcher.

This commit is contained in:
2025-10-22 22:28:02 +00:00
parent 1d2f0b7891
commit 35296b3bd2
11 changed files with 1882 additions and 45 deletions

View File

@@ -6,6 +6,10 @@ import type {
AppAddResponse,
AppStatus,
OperationResponse,
EnhancedApp,
RuntimeStatus,
LogEntry,
KubernetesEvent,
} from './types';
export const appsApi = {
@@ -39,6 +43,33 @@ export const appsApi = {
return apiClient.get(`/api/v1/instances/${instanceName}/apps/${appName}/status`);
},
// Enhanced app details endpoints
async getEnhanced(instanceName: string, appName: string): Promise<EnhancedApp> {
return apiClient.get(`/api/v1/instances/${instanceName}/apps/${appName}/enhanced`);
},
async getRuntime(instanceName: string, appName: string): Promise<RuntimeStatus> {
return apiClient.get(`/api/v1/instances/${instanceName}/apps/${appName}/runtime`);
},
async getLogs(
instanceName: string,
appName: string,
params?: { tail?: number; sinceSeconds?: number; pod?: string }
): Promise<LogEntry> {
const queryParams = new URLSearchParams();
if (params?.tail) queryParams.append('tail', params.tail.toString());
if (params?.sinceSeconds) queryParams.append('sinceSeconds', params.sinceSeconds.toString());
if (params?.pod) queryParams.append('pod', params.pod);
const query = queryParams.toString();
return apiClient.get(`/api/v1/instances/${instanceName}/apps/${appName}/logs${query ? `?${query}` : ''}`);
},
async getEvents(instanceName: string, appName: string, limit = 20): Promise<{ events: KubernetesEvent[] }> {
return apiClient.get(`/api/v1/instances/${instanceName}/apps/${appName}/events?limit=${limit}`);
},
// Backup operations
async backup(instanceName: string, appName: string): Promise<OperationResponse> {
return apiClient.post(`/api/v1/instances/${instanceName}/apps/${appName}/backup`);
@@ -51,4 +82,16 @@ export const appsApi = {
async restore(instanceName: string, appName: string, backupId: string): Promise<OperationResponse> {
return apiClient.post(`/api/v1/instances/${instanceName}/apps/${appName}/restore`, { backup_id: backupId });
},
// README content
async getReadme(instanceName: string, appName: string): Promise<string> {
const response = await fetch(`${import.meta.env.VITE_API_BASE_URL || 'http://localhost:5055'}/api/v1/instances/${instanceName}/apps/${appName}/readme`);
if (!response.ok) {
if (response.status === 404) {
return ''; // Return empty string if README not found
}
throw new Error(`Failed to fetch README: ${response.statusText}`);
}
return response.text();
},
};

View File

@@ -10,6 +10,8 @@ export interface App {
dependencies?: string[];
config?: Record<string, string>;
status?: AppStatus;
readme?: string;
documentation?: string;
}
export interface AppRequirement {
@@ -38,6 +40,92 @@ export interface AppResources {
storage?: string;
}
// Enhanced types for app details with runtime status
export interface ContainerInfo {
name: string;
image: string;
ready: boolean;
restartCount: number;
state: string; // "running", "waiting", "terminated"
}
export interface PodInfo {
name: string;
status: string;
ready: string; // "1/1"
restarts: number;
age: string;
node: string;
ip: string;
containers?: ContainerInfo[];
}
export interface ReplicaInfo {
desired: number;
current: number;
ready: number;
available: number;
}
export interface ResourceMetric {
used: string;
requested: string;
limit: string;
percentage: number;
}
export interface ResourceUsage {
cpu: ResourceMetric;
memory: ResourceMetric;
storage?: ResourceMetric;
}
export interface KubernetesEvent {
type: string;
reason: string;
message: string;
timestamp: string;
count: number;
}
export interface RuntimeStatus {
pods: PodInfo[];
replicas?: ReplicaInfo;
resources?: ResourceUsage;
recentEvents?: KubernetesEvent[];
}
export interface AppManifest {
name: string;
description: string;
version: string;
category?: string;
icon?: string;
dependencies?: string[];
defaultConfig?: Record<string, unknown>;
requiredSecrets?: string[];
}
export interface EnhancedApp {
name: string;
status: string;
version?: string;
namespace: string;
url?: string;
description?: string;
icon?: string;
manifest?: AppManifest;
config?: Record<string, string>;
runtime?: RuntimeStatus;
readme?: string;
documentation?: string;
}
export interface LogEntry {
pod: string;
logs: string[];
}
export interface AppListResponse {
apps: App[];
}