+
+
Create Application
+
Configure and deploy a new application
-
-
-
- { setSlug(e.target.value); setSlugEdited(true); }} disabled={busy} />
-
-
-
-
-
-
-
-
-
- setFile(e.target.files?.[0] ?? null)} />
-
- {file && {file.name} ({formatBytes(file.size)})}
-
-
-
-
-
- setDeploy(!deploy)} disabled={busy} />
- {deploy ? 'Deploy immediately after upload' : 'Upload only (deploy later)'}
-
-
-
- {step &&
{step}
}
-
-
-
+
+
-
+
+ {step &&
{step}
}
+
+ {/* Identity Section */}
+
Identity & Artifact
+
+
+ {/* Config Tabs */}
+
+
+
+
+
+ {configTab === 'monitoring' && (
+
+
Engine Level
+
+ )}
+
+ {configTab === 'resources' && (
+ <>
+
Container Resources
+
+
Memory Limit
+
+ setMemoryLimit(e.target.value)} style={{ width: 80 }} />
+ MB
+
+
+
Memory Reserve
+
+
+ setMemoryReserve(e.target.value)} placeholder="---" style={{ width: 80 }} />
+ MB
+
+ {!isProd &&
Available in production environments only}
+
+
+
CPU Shares
+
setCpuShares(e.target.value)} style={{ width: 80 }} />
+
+
CPU Limit
+
+ setCpuLimit(e.target.value)} placeholder="e.g. 1.0" style={{ width: 80 }} />
+ cores
+
+
+
Exposed Ports
+
+ {ports.map((p) => (
+
+ {p}
+
+
+ ))}
+ setNewPort(e.target.value)}
+ onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); addPort(); } }} />
+
+
+
+
Environment Variables
+ {envVars.map((v, i) => (
+
+ {
+ const next = [...envVars]; next[i] = { ...v, key: e.target.value }; setEnvVars(next);
+ }} className={styles.envVarKey} placeholder="KEY" />
+ {
+ const next = [...envVars]; next[i] = { ...v, value: e.target.value }; setEnvVars(next);
+ }} className={styles.envVarValue} placeholder="value" />
+
+
+ ))}
+
+ >
+ )}
+
);
}
diff --git a/ui/src/router.tsx b/ui/src/router.tsx
index 7d6daf15..bb008348 100644
--- a/ui/src/router.tsx
+++ b/ui/src/router.tsx
@@ -68,6 +68,7 @@ export const router = createBrowserRouter([
// Apps tab (OPERATOR+ via UI guard, shows all or single app)
{ path: 'apps', element: