🐳 Added Docker vars in the UI

This commit is contained in:
2025-07-14 12:06:04 -04:00
parent 0def39cd73
commit 80f0ced0b0
3 changed files with 125 additions and 95 deletions

View File

@@ -0,0 +1,38 @@
import React from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import axios from "axios";
export const DockerVars = (): React.ReactElement => {
const [environmentVariables, setEnvironmentVariables] = React.useState<
Record<string, string>
>({});
const { data } = useQuery({
queryKey: ["docker-vars"],
queryFn: async () => {
await axios({
method: "GET",
url: "http://localhost:3000/api/settings/getEnvironmentVariables",
}).then((response) => {
setEnvironmentVariables(response.data);
});
},
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
console.log("Docker Vars: ", environmentVariables);
return (
<div className="flex flex-col gap-4">
<h2 className="text-xl font-semibold">Docker Environment Variables</h2>
<p className="text-gray-600 dark:text-gray-400">
<pre>
{Object.entries(environmentVariables).length > 0
? JSON.stringify(environmentVariables, null, 2)
: "No environment variables found."}
</pre>
</p>
{/* Add your form or content for Docker environment variables here */}
</div>
);
};
export default DockerVars;

View File

@@ -4,6 +4,7 @@ import { AirDCPPHubsForm } from "./AirDCPPSettings/AirDCPPHubsForm";
import { QbittorrentConnectionForm } from "./QbittorrentSettings/QbittorrentConnectionForm";
import { SystemSettingsForm } from "./SystemSettings/SystemSettingsForm";
import ProwlarrSettingsForm from "./ProwlarrSettings/ProwlarrSettingsForm";
import DockerVars from "./DockerVars/DockerVars";
import { ServiceStatuses } from "../ServiceStatuses/ServiceStatuses";
import settingsObject from "../../constants/settings/settingsMenu.json";
import { isUndefined, map } from "lodash";
@@ -12,139 +13,130 @@ interface ISettingsProps {}
export const Settings = (props: ISettingsProps): ReactElement => {
const [active, setActive] = useState("gen-db");
console.log(active);
const [expanded, setExpanded] = useState<Record<string, boolean>>({});
const toggleExpanded = (id: string) => {
setExpanded((prev) => ({
...prev,
[id]: !prev[id],
}));
};
const settingsContent = [
{
id: "adc-hubs",
content: (
<div key="adc-hubs">
<AirDCPPHubsForm />
</div>
),
},
{
id: "adc-connection",
content: (
<div key="adc-connection">
<AirDCPPSettingsForm />
</div>
),
},
{
id: "qbt-connection",
content: (
<div key="qbt-connection">
<QbittorrentConnectionForm />
</div>
),
},
{
id: "prwlr-connection",
content: (
<>
<ProwlarrSettingsForm />
</>
),
},
{
id: "core-service",
content: <>a</>,
},
{
id: "flushdb",
content: (
<div key="flushdb">
<SystemSettingsForm />
</div>
),
},
{ id: "adc-hubs", content: <AirDCPPHubsForm /> },
{ id: "adc-connection", content: <AirDCPPSettingsForm /> },
{id: "gen-docker-vars", content: <DockerVars />},
{ id: "qbt-connection", content: <QbittorrentConnectionForm /> },
{ id: "prwlr-connection", content: <ProwlarrSettingsForm /> },
{ id: "core-service", content: <>a</> },
{ id: "flushdb", content: <SystemSettingsForm /> },
];
return (
<div>
<section>
{/* Header */}
<header className="bg-slate-200 dark:bg-slate-500">
<div className="mx-auto max-w-screen-xl px-2 py-2 sm:px-6 sm:py-8 lg:px-8 lg:py-4">
<div className="mx-auto max-w-screen-xl px-4 py-6 sm:px-6 lg:px-8">
<div className="sm:flex sm:items-center sm:justify-between">
<div className="text-center sm:text-left">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white sm:text-3xl">
<h1 className="text-2xl sm:text-3xl font-bold text-gray-900 dark:text-white">
Settings
</h1>
<p className="mt-1.5 text-sm text-gray-500 dark:text-white">
<p className="mt-1 text-sm text-gray-500 dark:text-white">
Import comics into the ThreeTwo library.
</p>
</div>
</div>
</div>
</header>
<div className="flex flex-row">
<div className="inset-y-0 w-80 dark:bg-gray-800 bg-slate-300 text-white overflow-y-auto">
<aside className="px-4 py-4 sm:px-6 sm:py-8 lg:px-8">
{map(settingsObject, (settingObject, idx) => {
return (
{/* Main Layout */}
<div className="flex gap-8 px-12 py-6">
{/* Sidebar */}
<div className="relative z-30">
<aside
className="sticky top-6 w-72 max-h-[90vh]
rounded-2xl shadow-xl backdrop-blur-md
bg-white/70 dark:bg-slate-800/60
border border-slate-200 dark:border-slate-700
overflow-hidden"
>
<div className="px-4 py-6 overflow-y-auto">
{map(settingsObject, (settingObject, idx) => (
<div
className="w-64 py-2 text-slate-700 dark:text-slate-400"
key={idx}
className="mb-6 text-slate-700 dark:text-slate-300"
>
<h3 className="text-l pb-2">
<h3 className="text-xs font-semibold text-slate-500 dark:text-slate-400 tracking-wide mb-3">
{settingObject.category.toUpperCase()}
</h3>
{/* First level children */}
{!isUndefined(settingObject.children) ? (
<ul key={settingObject.id}>
{!isUndefined(settingObject.children) && (
<ul>
{map(settingObject.children, (item, idx) => {
const isOpen = expanded[item.id];
return (
<li key={idx} className="mb-2">
<a
className={
item.id.toString() === active
? "is-active flex items-center"
: "flex items-center"
}
onClick={() => setActive(item.id.toString())}
<li key={idx} className="mb-1">
<div
onClick={() => toggleExpanded(item.id)}
className={`cursor-pointer flex justify-between items-center px-1 py-1 rounded-md transition-colors hover:bg-white/50 dark:hover:bg-slate-700 ${
item.id === active
? "font-semibold text-blue-600 dark:text-blue-400"
: ""
}`}
>
{item.displayName}
</a>
{/* Second level children */}
{!isUndefined(item.children) ? (
<ul className="pl-4 mt-2">
{map(item.children, (item, idx) => (
<li key={item.id} className="mb-2">
<span
onClick={() => setActive(item.id.toString())}
className="flex-1"
>
{item.displayName}
</span>
{!isUndefined(item.children) && (
<span className="text-xs opacity-60">
{isOpen ? "" : "+"}
</span>
)}
</div>
{!isUndefined(item.children) && isOpen && (
<ul className="pl-4 mt-1">
{map(item.children, (subItem) => (
<li key={subItem.id} className="mb-1">
<a
className={
item.id.toString() === active
? "is-active flex items-center"
: "flex items-center"
}
onClick={() =>
setActive(item.id.toString())
setActive(subItem.id.toString())
}
className={`cursor-pointer flex items-center px-1 py-1 rounded-md transition-colors hover:bg-white/50 dark:hover:bg-slate-700 ${
subItem.id.toString() === active
? "font-semibold text-blue-600 dark:text-blue-400"
: ""
}`}
>
{item.displayName}
{subItem.displayName}
</a>
</li>
))}
</ul>
) : null}
)}
</li>
);
})}
</ul>
) : null}
)}
</div>
);
})}
))}
</div>
</aside>
</div>
{/* content for settings */}
<div className="flex mx-12">
<div className="">
{map(settingsContent, ({ id, content }) =>
active === id ? content : null,
)}
</div>
</div>
{/* Content */}
<main className="flex-1 px-2 py-2">
{settingsContent.map(({ id, content }) =>
active === id ? <div key={id}>{content}</div> : null,
)}
</main>
</div>
</section>
</div>

View File

@@ -9,8 +9,8 @@
"displayName": "Dashboard"
},
{
"id": "gen-gls",
"displayName": "Global Search"
"id": "gen-docker-vars",
"displayName": "Docker ENV vars"
}
]
},