Skip to content

Commit cf4a2c8

Browse files
Feat: Add config path to website (#4005)
* Feat: Add config path to website * Handel Responsive/Mobile
1 parent 945a32d commit cf4a2c8

File tree

8 files changed

+89
-2
lines changed

8 files changed

+89
-2
lines changed

frontend/public/json/podman-homeassistant.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"documentation": "https://www.home-assistant.io/docs/",
1313
"website": "https://www.home-assistant.io/",
1414
"logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/home-assistant.svg",
15-
"config_path": "",
15+
"config_path": "/var/lib/containers/storage/volumes/hass_config/_data",
1616
"description": "A standalone Podman container-based installation of Home Assistant Core means that the Home Assistant Core software is installed inside a container managed by Podman, separate from the host operating system. This provides a flexible and scalable solution for running the software, as the container can be easily moved between host systems or isolated from other processes for security. Podman is a popular open-source tool for managing containers that is similar to Docker, but designed for use on Linux systems without a daemon.\r\n\r\n\ud83d\udec8 If the LXC is created Privileged, the script will automatically set up USB passthrough.",
1717
"install_methods": [
1818
{

frontend/public/json/watchyourlan.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"documentation": null,
1313
"website": "https://github.com/aceberg/WatchYourLAN",
1414
"logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/webp/watchyourlan.webp",
15-
"config_path": "",
15+
"config_path": "/data/config.yaml",
1616
"description": "WatchYourLAN is a lightweight network IP scanner with web GUI.",
1717
"install_methods": [
1818
{

frontend/src/app/json-editor/_schemas/schemas.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const ScriptSchema = z.object({
3333
documentation: z.string().nullable(),
3434
website: z.string().url().nullable(),
3535
logo: z.string().url().nullable(),
36+
config_path: z.string(),
3637
description: z.string().min(1, "Description is required"),
3738
install_methods: z.array(InstallMethodSchema).min(1, "At least one install method is required"),
3839
default_credentials: z.object({

frontend/src/app/json-editor/page.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const initialScript: Script = {
3232
privileged: false,
3333
interface_port: null,
3434
documentation: null,
35+
config_path: "",
3536
website: null,
3637
logo: null,
3738
description: "",
@@ -174,6 +175,14 @@ export default function JSONGenerator() {
174175
onChange={(e) => updateScript("logo", e.target.value || null)}
175176
/>
176177
</div>
178+
<div>
179+
<Label>Config Path</Label>
180+
<Input
181+
placeholder="Path to config file"
182+
value={script.config_path || ""}
183+
onChange={(e) => updateScript("config_path", e.target.value || null)}
184+
/>
185+
</div>
177186
<div>
178187
<Label>
179188
Description <span className="text-red-500">*</span>

frontend/src/app/scripts/_components/ScriptItem.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import Description from "./ScriptItems/Description";
2020
import InstallCommand from "./ScriptItems/InstallCommand";
2121
import InterFaces from "./ScriptItems/InterFaces";
2222
import Tooltips from "./ScriptItems/Tooltips";
23+
import ConfigFile from "./ScriptItems/ConfigFile";
2324

2425
interface ScriptItemProps {
2526
item: Script;
@@ -151,6 +152,16 @@ export function ScriptItem({ item, setSelectedScript }: ScriptItemProps) {
151152
<div className="">
152153
<InstallCommand item={item} />
153154
</div>
155+
<Separator />
156+
<div className="flex gap-3 px-4 py-2 bg-accent/25">
157+
<h2 className="text-lg font-semibold">
158+
Location of config file
159+
</h2>
160+
</div>
161+
<Separator />
162+
<div className="">
163+
<ConfigFile item={item} />
164+
</div>
154165
</div>
155166

156167
<DefaultPassword item={item} />
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import ConfigCopyButton from "@/components/ui/config-copy-button";
2+
import { Script } from "@/lib/types";
3+
4+
export default function ConfigFile({ item }: { item: Script }) {
5+
return (
6+
<div className="px-4 pb-4">
7+
<ConfigCopyButton>{item.config_path ? item.config_path : "No config path set"}</ConfigCopyButton>
8+
</div>
9+
);
10+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"use client";
2+
import { cn } from "@/lib/utils";
3+
import { CheckIcon, ClipboardIcon } from "lucide-react";
4+
import { useEffect, useState } from "react";
5+
import { toast } from "sonner";
6+
import { Card } from "./card";
7+
8+
export default function CodeCopyButton({
9+
children,
10+
}: {
11+
children: React.ReactNode;
12+
}) {
13+
const [hasCopied, setHasCopied] = useState(false);
14+
const isMobile = window.innerWidth <= 640;
15+
16+
useEffect(() => {
17+
if (hasCopied) {
18+
setTimeout(() => {
19+
setHasCopied(false);
20+
}, 2000);
21+
}
22+
}, [hasCopied]);
23+
24+
const handleCopy = (type: string, value: any) => {
25+
navigator.clipboard.writeText(value);
26+
27+
setHasCopied(true);
28+
29+
30+
// toast.success(`copied ${type} to clipboard`, {
31+
// icon: <ClipboardCheck className="h-4 w-4" />,
32+
// });
33+
};
34+
35+
return (
36+
<div className="mt-4 flex">
37+
<Card className="flex items-center overflow-x-auto bg-primary-foreground pl-4">
38+
<div className="overflow-x-auto whitespace-pre-wrap text-nowrap break-all pr-4 text-sm">
39+
{!isMobile && children ? children : "Copy Config File Path"}
40+
</div>
41+
<div
42+
className={cn(" right-0 cursor-pointer bg-muted px-3 py-4")}
43+
onClick={() => handleCopy("install command", children)}
44+
>
45+
{hasCopied ? (
46+
<CheckIcon className="h-4 w-4" />
47+
) : (
48+
<ClipboardIcon className="h-4 w-4" />
49+
)}
50+
<span className="sr-only">Copy</span>
51+
</div>
52+
</Card>
53+
</div>
54+
);
55+
}

frontend/src/lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type Script = {
1212
documentation: string | null;
1313
website: string | null;
1414
logo: string | null;
15+
config_path: string;
1516
description: string;
1617
install_methods: {
1718
type: "default" | "alpine";

0 commit comments

Comments
 (0)