fix(style): change tab style in 'server config' modal
This commit is contained in:
1 parent
ec73a52aa9
commit
96c58c73ed
1 file changed
+90
-42
@@ -1,19 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { type ReactNode, useCallback, useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import {
|
||||
AlertTriangle,
|
||||
Eye,
|
||||
EyeOff,
|
||||
Globe,
|
||||
HardDrive,
|
||||
Loader2,
|
||||
Power,
|
||||
RefreshCw,
|
||||
Settings2,
|
||||
Users,
|
||||
Wrench,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
@@ -87,6 +81,14 @@ export default function ServerConfigModal({
|
||||
const deleteConfirmed = resetConfirmation.trim() === "DELETE";
|
||||
const hasSelectedDockerPruneOption =
|
||||
Object.values(dockerPruneOptions).some(Boolean);
|
||||
const tabs: Array<{ id: ServerConfigTab; label: string }> = [
|
||||
{ id: "overview", label: "Overview" },
|
||||
{ id: "users", label: "Users" },
|
||||
{ id: "services", label: "Services" },
|
||||
{ id: "web-server", label: "Web Server" },
|
||||
{ id: "mounts", label: "Disk Mounts" },
|
||||
{ id: "actions", label: "Actions" },
|
||||
];
|
||||
|
||||
const publishNotice = useCallback((nextNotice: ServerConfigNotice) => {
|
||||
setNotice(nextNotice);
|
||||
@@ -602,26 +604,26 @@ export default function ServerConfigModal({
|
||||
}
|
||||
};
|
||||
|
||||
const tabButton = (id: ServerConfigTab, label: string, icon: ReactNode) => (
|
||||
const tabButton = (id: ServerConfigTab, label: string) => (
|
||||
<button
|
||||
type="button"
|
||||
key={id}
|
||||
onClick={() => setActiveTab(id)}
|
||||
className="btn btn-ghost"
|
||||
style={{
|
||||
padding: "9px 14px",
|
||||
borderRadius: 10,
|
||||
border: `1px solid ${activeTab === id ? "rgba(59,130,246,0.35)" : "var(--border)"}`,
|
||||
background:
|
||||
activeTab === id ? "rgba(59,130,246,0.12)" : "var(--bg-input)",
|
||||
color: activeTab === id ? "#3b82f6" : "var(--text-secondary)",
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: 8,
|
||||
cursor: "pointer",
|
||||
height: 28,
|
||||
minHeight: 28,
|
||||
padding: "5px 12px",
|
||||
borderRadius: 4,
|
||||
boxSizing: "border-box",
|
||||
borderColor: activeTab === id ? "rgba(59,130,246,0.5)" : "transparent",
|
||||
background: activeTab === id ? "rgba(59,130,246,0.16)" : "transparent",
|
||||
color:
|
||||
activeTab === id ? "var(--accent-blue)" : "var(--text-secondary)",
|
||||
flex: "0 0 auto",
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
@@ -643,10 +645,12 @@ export default function ServerConfigModal({
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
maxWidth: 920,
|
||||
maxHeight: "90vh",
|
||||
padding: 24,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 18,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{pendingConfirm && typeof document !== "undefined"
|
||||
@@ -675,7 +679,9 @@ export default function ServerConfigModal({
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<strong style={{ color: "var(--text-primary)", fontSize: 16 }}>
|
||||
<strong
|
||||
style={{ color: "var(--text-primary)", fontSize: 16 }}
|
||||
>
|
||||
{pendingConfirm.title}
|
||||
</strong>
|
||||
<p
|
||||
@@ -715,7 +721,8 @@ export default function ServerConfigModal({
|
||||
{
|
||||
key: "containers",
|
||||
label: "Stopped containers",
|
||||
description: "Equivalent to docker container prune.",
|
||||
description:
|
||||
"Equivalent to docker container prune.",
|
||||
},
|
||||
{
|
||||
key: "networks",
|
||||
@@ -808,7 +815,9 @@ export default function ServerConfigModal({
|
||||
padding: "12px 14px",
|
||||
fontSize: 12,
|
||||
color:
|
||||
pendingConfirm.tone === "danger" ? "#ef4444" : "#b45309",
|
||||
pendingConfirm.tone === "danger"
|
||||
? "#ef4444"
|
||||
: "#b45309",
|
||||
background:
|
||||
pendingConfirm.tone === "danger"
|
||||
? "rgba(239,68,68,0.08)"
|
||||
@@ -823,7 +832,11 @@ export default function ServerConfigModal({
|
||||
interruption or cleanup change on the host.
|
||||
</div>
|
||||
<div
|
||||
style={{ display: "flex", gap: 10, justifyContent: "flex-end" }}
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: 10,
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<button
|
||||
className="btn"
|
||||
@@ -864,7 +877,9 @@ export default function ServerConfigModal({
|
||||
}
|
||||
|
||||
if (currentConfirm.kind === "service") {
|
||||
void handleServiceRestart(currentConfirm.serviceName);
|
||||
void handleServiceRestart(
|
||||
currentConfirm.serviceName,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -885,7 +900,9 @@ export default function ServerConfigModal({
|
||||
? "rgba(239,68,68,0.12)"
|
||||
: "rgba(245,158,11,0.12)",
|
||||
color:
|
||||
pendingConfirm.tone === "danger" ? "#ef4444" : "#f59e0b",
|
||||
pendingConfirm.tone === "danger"
|
||||
? "#ef4444"
|
||||
: "#f59e0b",
|
||||
border:
|
||||
pendingConfirm.tone === "danger"
|
||||
? "1px solid rgba(239,68,68,0.22)"
|
||||
@@ -944,15 +961,23 @@ export default function ServerConfigModal({
|
||||
/>
|
||||
</div>
|
||||
<p
|
||||
style={{ color: "var(--text-muted)", fontSize: 13, marginTop: 6 }}
|
||||
style={{
|
||||
color: "var(--text-muted)",
|
||||
fontSize: 13,
|
||||
marginTop: 6,
|
||||
}}
|
||||
>
|
||||
{server.name} • {server.ip}:{server.sshPort}
|
||||
</p>
|
||||
<p
|
||||
style={{ color: "var(--text-muted)", fontSize: 12, marginTop: 6 }}
|
||||
style={{
|
||||
color: "var(--text-muted)",
|
||||
fontSize: 12,
|
||||
marginTop: 6,
|
||||
}}
|
||||
>
|
||||
Snapshot refresh runs only when this modal opens or when you click
|
||||
Refresh.
|
||||
Snapshot refresh runs only when this modal opens or when you
|
||||
click Refresh.
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ display: "flex", gap: 8, paddingRight: 36 }}>
|
||||
@@ -966,15 +991,33 @@ export default function ServerConfigModal({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
|
||||
{tabButton("overview", "Overview", <Settings2 size={14} />)}
|
||||
{tabButton("users", "Users", <Users size={14} />)}
|
||||
{tabButton("services", "Services", <Wrench size={14} />)}
|
||||
{tabButton("web-server", "Web Server", <Globe size={14} />)}
|
||||
{tabButton("mounts", "Disk Mounts", <HardDrive size={14} />)}
|
||||
{tabButton("actions", "Actions", <Power size={14} />)}
|
||||
</div>
|
||||
<nav
|
||||
className="ui-tab-scroll no-scrollbar"
|
||||
style={{
|
||||
width: "100%",
|
||||
borderRadius: 6,
|
||||
background: "var(--bg-card)",
|
||||
minWidth: 0,
|
||||
minHeight: 38,
|
||||
alignItems: "center",
|
||||
overflowY: "hidden",
|
||||
flex: "0 0 auto",
|
||||
}}
|
||||
aria-label="Server config sections"
|
||||
>
|
||||
{tabs.map((tab) => tabButton(tab.id, tab.label))}
|
||||
</nav>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
flex: "1 1 auto",
|
||||
gap: 18,
|
||||
minHeight: 0,
|
||||
overflowY: "auto",
|
||||
paddingRight: 2,
|
||||
}}
|
||||
>
|
||||
{notice && notice.tab === activeTab ? (
|
||||
<div
|
||||
style={{
|
||||
@@ -1048,7 +1091,11 @@ export default function ServerConfigModal({
|
||||
onClick={() => setNoticeExpanded((current) => !current)}
|
||||
style={{ width: "fit-content" }}
|
||||
>
|
||||
{noticeExpanded ? <EyeOff size={12} /> : <Eye size={12} />}
|
||||
{noticeExpanded ? (
|
||||
<EyeOff size={12} />
|
||||
) : (
|
||||
<Eye size={12} />
|
||||
)}
|
||||
{noticeExpanded ? "Hide detail" : "More detail"}
|
||||
</button>
|
||||
{noticeExpanded ? (
|
||||
@@ -1127,9 +1174,9 @@ export default function ServerConfigModal({
|
||||
lineHeight: 1.6,
|
||||
}}
|
||||
>
|
||||
The server did not return a full config snapshot, so this modal
|
||||
is showing fallback information. Recovery actions remain
|
||||
available, especially in the Actions tab.
|
||||
The server did not return a full config snapshot, so this
|
||||
modal is showing fallback information. Recovery actions
|
||||
remain available, especially in the Actions tab.
|
||||
</p>
|
||||
</div>
|
||||
<IssueDetailsSummary
|
||||
@@ -1157,5 +1204,6 @@ export default function ServerConfigModal({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user