diff --git a/ui/src/pages/AppsTab/AppDeploymentPage/hooks/useDeploymentPageState.ts b/ui/src/pages/AppsTab/AppDeploymentPage/hooks/useDeploymentPageState.ts new file mode 100644 index 00000000..485812b1 --- /dev/null +++ b/ui/src/pages/AppsTab/AppDeploymentPage/hooks/useDeploymentPageState.ts @@ -0,0 +1,124 @@ +// ui/src/pages/AppsTab/AppDeploymentPage/hooks/useDeploymentPageState.ts +import { useState, useEffect, useMemo } from 'react'; +import type { ApplicationConfig } from '../../../../api/queries/commands'; +import type { App } from '../../../../api/queries/admin/apps'; + +export interface MonitoringFormState { + engineLevel: string; + payloadCaptureMode: string; + applicationLogLevel: string; + agentLogLevel: string; + metricsEnabled: boolean; + samplingRate: string; + compressSuccess: boolean; +} + +export interface ResourcesFormState { + memoryLimit: string; + memoryReserve: string; + cpuRequest: string; + cpuLimit: string; + ports: number[]; + appPort: string; + replicas: string; + deployStrategy: string; + stripPrefix: boolean; + sslOffloading: boolean; + runtimeType: string; + customArgs: string; + extraNetworks: string[]; +} + +export interface VariablesFormState { + envVars: { key: string; value: string }[]; +} + +export interface SensitiveKeysFormState { + sensitiveKeys: string[]; +} + +export interface DeploymentPageFormState { + monitoring: MonitoringFormState; + resources: ResourcesFormState; + variables: VariablesFormState; + sensitiveKeys: SensitiveKeysFormState; +} + +const defaultForm: DeploymentPageFormState = { + monitoring: { + engineLevel: 'REGULAR', + payloadCaptureMode: 'BOTH', + applicationLogLevel: 'INFO', + agentLogLevel: 'INFO', + metricsEnabled: true, + samplingRate: '1.0', + compressSuccess: false, + }, + resources: { + memoryLimit: '512', memoryReserve: '', cpuRequest: '500', cpuLimit: '', + ports: [], appPort: '8080', replicas: '1', deployStrategy: 'blue-green', + stripPrefix: true, sslOffloading: true, runtimeType: 'auto', customArgs: '', + extraNetworks: [], + }, + variables: { envVars: [] }, + sensitiveKeys: { sensitiveKeys: [] }, +}; + +export function useDeploymentPageState( + app: App | null, + agentConfig: ApplicationConfig | null, + envDefaults: Record, +): { + form: DeploymentPageFormState; + setForm: React.Dispatch>; + reset: () => void; + serverState: DeploymentPageFormState; +} { + const serverState = useMemo(() => { + const merged = { ...envDefaults, ...(app?.containerConfig ?? {}) } as Record; + return { + monitoring: { + engineLevel: (agentConfig?.engineLevel as string) ?? defaultForm.monitoring.engineLevel, + payloadCaptureMode: (agentConfig?.payloadCaptureMode as string) ?? defaultForm.monitoring.payloadCaptureMode, + applicationLogLevel: (agentConfig?.applicationLogLevel as string) ?? defaultForm.monitoring.applicationLogLevel, + agentLogLevel: (agentConfig?.agentLogLevel as string) ?? defaultForm.monitoring.agentLogLevel, + metricsEnabled: agentConfig?.metricsEnabled ?? defaultForm.monitoring.metricsEnabled, + samplingRate: agentConfig?.samplingRate !== undefined ? String(agentConfig.samplingRate) : defaultForm.monitoring.samplingRate, + compressSuccess: agentConfig?.compressSuccess ?? defaultForm.monitoring.compressSuccess, + }, + resources: { + memoryLimit: String(merged.memoryLimitMb ?? defaultForm.resources.memoryLimit), + memoryReserve: merged.memoryReserveMb != null ? String(merged.memoryReserveMb) : defaultForm.resources.memoryReserve, + cpuRequest: String(merged.cpuRequest ?? defaultForm.resources.cpuRequest), + cpuLimit: merged.cpuLimit != null ? String(merged.cpuLimit) : defaultForm.resources.cpuLimit, + ports: Array.isArray(merged.exposedPorts) ? (merged.exposedPorts as number[]) : defaultForm.resources.ports, + appPort: String(merged.appPort ?? defaultForm.resources.appPort), + replicas: String(merged.replicas ?? defaultForm.resources.replicas), + deployStrategy: String(merged.deploymentStrategy ?? defaultForm.resources.deployStrategy), + stripPrefix: merged.stripPathPrefix !== false, + sslOffloading: merged.sslOffloading !== false, + runtimeType: String(merged.runtimeType ?? defaultForm.resources.runtimeType), + customArgs: String(merged.customArgs ?? defaultForm.resources.customArgs), + extraNetworks: Array.isArray(merged.extraNetworks) ? (merged.extraNetworks as string[]) : defaultForm.resources.extraNetworks, + }, + variables: { + envVars: merged.customEnvVars + ? Object.entries(merged.customEnvVars as Record).map(([key, value]) => ({ key, value })) + : [], + }, + sensitiveKeys: { + sensitiveKeys: Array.isArray(agentConfig?.sensitiveKeys) + ? (agentConfig!.sensitiveKeys as string[]) + : [], + }, + }; + }, [app, agentConfig, envDefaults]); + + const [form, setForm] = useState(serverState); + + useEffect(() => { + setForm(serverState); + }, [serverState]); + + return { form, setForm, reset: () => setForm(serverState), serverState }; +}