feat: add server process control panel to Tauri app
This commit is contained in:
1 parent
818d9f99e6
commit
99672b33d0
7 files changed
+437
-2
No files matched your search
@@ -0,0 +1,127 @@
|
||||
import { useState } from "react";
|
||||
import type { ProcessStatus, ServerConfig } from "../hooks/useServerProcess";
|
||||
import "./ServerPanel.css";
|
||||
|
||||
interface Props {
|
||||
status: ProcessStatus;
|
||||
message: string;
|
||||
onStart: (cfg: ServerConfig) => void;
|
||||
onStop: () => void;
|
||||
}
|
||||
|
||||
const STATUS_LABEL: Record<ProcessStatus, string> = {
|
||||
stopped: "Stopped",
|
||||
starting: "Starting…",
|
||||
running: "Running",
|
||||
stopping: "Stopping…",
|
||||
error: "Error",
|
||||
};
|
||||
|
||||
const STATUS_COLOR: Record<ProcessStatus, string> = {
|
||||
stopped: "#6b7280",
|
||||
starting: "#f59e0b",
|
||||
running: "#22c55e",
|
||||
stopping: "#f59e0b",
|
||||
error: "#ef4444",
|
||||
};
|
||||
|
||||
export default function ServerPanel({ status, message, onStart, onStop }: Props) {
|
||||
const [modelPath, setModelPath] = useState(
|
||||
() => localStorage.getItem("forgelm_model_path") || ""
|
||||
);
|
||||
const [addr, setAddr] = useState(
|
||||
() => localStorage.getItem("forgelm_server_addr") || "127.0.0.1:8080"
|
||||
);
|
||||
const [gpuLayers, setGpuLayers] = useState(
|
||||
() => parseInt(localStorage.getItem("forgelm_gpu_layers") || "0", 10)
|
||||
);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
|
||||
const isActive = status === "running" || status === "starting" || status === "stopping";
|
||||
|
||||
const handleStart = () => {
|
||||
localStorage.setItem("forgelm_model_path", modelPath);
|
||||
localStorage.setItem("forgelm_server_addr", addr);
|
||||
localStorage.setItem("forgelm_gpu_layers", String(gpuLayers));
|
||||
onStart({ modelPath, addr, gpuLayers });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="server-panel">
|
||||
<div className="server-panel-header" onClick={() => setExpanded(!expanded)}>
|
||||
<div className="server-panel-title">
|
||||
<span
|
||||
className="server-status-dot"
|
||||
style={{ background: STATUS_COLOR[status] }}
|
||||
/>
|
||||
<span className="server-panel-label">Local Server</span>
|
||||
<span className="server-status-text" style={{ color: STATUS_COLOR[status] }}>
|
||||
{STATUS_LABEL[status]}
|
||||
</span>
|
||||
</div>
|
||||
<span className="server-panel-chevron">{expanded ? "▲" : "▼"}</span>
|
||||
</div>
|
||||
|
||||
{expanded && (
|
||||
<div className="server-panel-body">
|
||||
<label className="sp-label">Model path (.gguf)</label>
|
||||
<input
|
||||
className="sp-input"
|
||||
type="text"
|
||||
value={modelPath}
|
||||
onChange={(e) => setModelPath(e.target.value)}
|
||||
placeholder="models/your-model.gguf"
|
||||
disabled={isActive}
|
||||
/>
|
||||
|
||||
<label className="sp-label">Address</label>
|
||||
<input
|
||||
className="sp-input"
|
||||
type="text"
|
||||
value={addr}
|
||||
onChange={(e) => setAddr(e.target.value)}
|
||||
placeholder="127.0.0.1:8080"
|
||||
disabled={isActive}
|
||||
/>
|
||||
|
||||
<label className="sp-label">GPU Layers (0 = CPU only)</label>
|
||||
<input
|
||||
className="sp-input sp-input-num"
|
||||
type="number"
|
||||
min={0}
|
||||
max={999}
|
||||
value={gpuLayers}
|
||||
onChange={(e) => setGpuLayers(parseInt(e.target.value, 10) || 0)}
|
||||
disabled={isActive}
|
||||
/>
|
||||
|
||||
<div className="sp-actions">
|
||||
{status === "stopped" || status === "error" ? (
|
||||
<button
|
||||
className="sp-btn sp-btn-start"
|
||||
onClick={handleStart}
|
||||
disabled={!modelPath.trim()}
|
||||
>
|
||||
▶ Start Server
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
className="sp-btn sp-btn-stop"
|
||||
onClick={onStop}
|
||||
disabled={status === "starting" || status === "stopping"}
|
||||
>
|
||||
■ Stop Server
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{message && (
|
||||
<div className={`sp-message ${status === "error" ? "sp-message-error" : ""}`}>
|
||||
{message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user