Add button to download ctl config (#743)

* Move saveJson to util file

* Add button to download ctl config

* Add icon and tooltip to describe what the button does

---------

Co-authored-by: Danielv123 <danielv@danielv.no>
This commit is contained in:
Cooldude2606andDanielv123 authored and GitHub committed 2025-04-08 20:34:50 +01:00
1 parent 42cd099eea
commit 0e6d33aa82
3 files changed
+43 -17

No files matched your search

+17 -1
View File
@@ -1,6 +1,6 @@
import React, { Fragment, useContext, useEffect, useState } from "react";
import { Route, Routes, useNavigate } from "react-router-dom";
import { Dropdown, Layout, Menu, MenuProps } from "antd";
import { Button, Dropdown, Layout, Menu, MenuProps, Tooltip } from "antd";
import UserOutlined from "@ant-design/icons/UserOutlined";
import webUiPackage from "../../package.json";
@@ -10,6 +10,9 @@ import ErrorPage from "./ErrorPage";
import ControlContext from "./ControlContext";
import { pages } from "../pages";
import { DraggingContext } from "../model/is_dragging";
import { saveJson } from "../util/save_file";
import { ControlConfig } from "@clusterio/lib";
import { DownloadOutlined } from "@ant-design/icons";
type MenuItem = Required<MenuProps>["items"][number];
@@ -38,6 +41,7 @@ export default function SiteLayout() {
let [currentSidebarPath, setCurrentSidebarPath] = useState<string | null>(null);
let account = useAccount();
let plugins = useContext(ControlContext).plugins;
const control = useContext(ControlContext);
const [dragging, setDragging] = useState(0);
function SetSidebar(props: { path: string | null }) {
@@ -51,12 +55,24 @@ export default function SiteLayout() {
onClick: ({ key }: { key: string }) => {
if (key === "user") {
navigate(`/users/${account.name}/view`);
} else if (key === "ctlConfig") {
const config = new ControlConfig("control", {
"control.controller_token": control.connector.token,
"control.controller_url": (new URL(webRoot, document.location.href)).href,
});
saveJson("config-control.json", config.toJSON());
} else if (key === "logOut") {
account.logOut();
}
},
items: [
{ label: account.name, key: "user" },
{
label: <Tooltip title="Download credentials and configuration file for cli interface">
Ctl Config <Button size="small" icon={<DownloadOutlined />} />
</Tooltip>,
key: "ctlConfig",
},
{ type: "divider" },
{ label: "Log out", danger: true, key: "logOut" },
],
+1 -16
View File
@@ -10,6 +10,7 @@ import { useAccount } from "../model/account";
import ControlContext from "./ControlContext";
import { notifyErrorHandler } from "../util/notify";
import { formatDuration } from "../util/time_format";
import { saveJson } from "../util/save_file";
import PageHeader from "./PageHeader";
import PageLayout from "./PageLayout";
import PluginExtra from "./PluginExtra";
@@ -58,22 +59,6 @@ function CreateUserButton() {
</>;
}
// This is the most common and best supported method
// For full support we should consider using npm:file-saver
function saveFile(name: string, blob: Blob) {
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = name;
a.addEventListener("click", (e) => {
setTimeout(() => URL.revokeObjectURL(a.href), 30 * 1000);
});
a.click();
};
function saveJson(name: string, json: object) {
return saveFile(name, new Blob([JSON.stringify(json, null, 2)], { type: "application/json" }));
}
type UserBulkActionProps = {
setApplyAction(func: () => Promise<void>): void,
form: FormInstance,
+25
View File
@@ -0,0 +1,25 @@
/**
* Downloads a file to the users PC, should only be used following direct user input.
* @param name Name of the file to save
* @param blob Content to save
*/
export function saveFile(name: string, blob: Blob) {
// This is the most common and best supported method, for full support we should consider using npm:file-saver
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = name;
a.addEventListener("click", (e) => {
setTimeout(() => URL.revokeObjectURL(a.href), 30 * 1000);
});
a.click();
};
/**
* Downloads a json file to the users PC
* @param name Name of the file to save, should include .json
* @param json The object to save as a formated json string
*/
export function saveJson(name: string, json: object) {
saveFile(name, new Blob([JSON.stringify(json, null, 2)], { type: "application/json" }));
}