mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 14:45:24 +00:00
feat: redesign user host defaults system
This commit is contained in:
1 parent
3028ab1176
commit
a4a4d4f27b
144 files changed
+24609
-2555
No files matched your search
@@ -102,25 +102,6 @@ export function registerRoutes(router: Router, deps: RouteDeps): void {
|
||||
poller.registerViewer(hostId, sessionId, userId),
|
||||
};
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /plugin-api/host-metrics/defaults:
|
||||
* get:
|
||||
* summary: Get defaults for new hosts
|
||||
* description: Whether a new host starts with metrics on, an admin setting any user creating a host needs.
|
||||
* tags:
|
||||
* - Host Metrics
|
||||
* responses:
|
||||
* 200:
|
||||
* description: The defaults.
|
||||
*/
|
||||
router.get("/defaults", async (_req, res) => {
|
||||
res.json({
|
||||
enabledForNewHosts:
|
||||
(await ctx.settings.get<boolean>("enabledForNewHosts")) !== false,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /plugin-api/host-metrics/metrics/{id}:
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import {
|
||||
Button,
|
||||
HostDefaultBadge,
|
||||
Input,
|
||||
SectionCard,
|
||||
SettingRow,
|
||||
FakeSwitch,
|
||||
useIsDefaultsEditor,
|
||||
} from "@termix/plugin-sdk/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
usePluginApi,
|
||||
useTranslation,
|
||||
type HostEditorSectionProps,
|
||||
} from "@termix/plugin-sdk/frontend";
|
||||
@@ -24,11 +25,7 @@ type PluginSettingsBag = Record<string, Record<string, unknown>>;
|
||||
* host settings, carried on form.pluginSettings and saved by the editor after
|
||||
* the host itself.
|
||||
*/
|
||||
export function HostStatsTab({
|
||||
form,
|
||||
updateForm,
|
||||
host,
|
||||
}: HostEditorSectionProps) {
|
||||
export function HostStatsTab({ form, updateForm }: HostEditorSectionProps) {
|
||||
const { t } = useTranslation();
|
||||
const [newMount, setNewMount] = useState("");
|
||||
const [newMonitoredPath, setNewMonitoredPath] = useState("");
|
||||
@@ -38,7 +35,7 @@ export function HostStatsTab({
|
||||
];
|
||||
const settings = readHostMetricsSettings(bag);
|
||||
const { excludedMounts, monitoredMounts } = settings;
|
||||
const api = usePluginApi();
|
||||
const defaultsEditor = useIsDefaultsEditor();
|
||||
|
||||
const patch = (values: Record<string, unknown>) =>
|
||||
updateForm((current) => {
|
||||
@@ -52,23 +49,6 @@ export function HostStatsTab({
|
||||
};
|
||||
});
|
||||
|
||||
// A new host starts with the admin's default for metrics.
|
||||
useEffect(() => {
|
||||
if (host || bag?.metricsEnabled !== undefined) return;
|
||||
let cancelled = false;
|
||||
api
|
||||
.get<{ enabledForNewHosts: boolean }>("/defaults")
|
||||
.then(({ data }) => {
|
||||
if (!cancelled && data.enabledForNewHosts === false) {
|
||||
patch({ metricsEnabled: false });
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [host]);
|
||||
|
||||
const addExcludedMount = () => {
|
||||
const value = newMount.trim();
|
||||
if (!value || excludedMounts.includes(value)) {
|
||||
@@ -102,6 +82,7 @@ export function HostStatsTab({
|
||||
<SettingRow
|
||||
label={t("hosts.enableMetricsLabel")}
|
||||
description={t("hosts.enableMetricsDesc")}
|
||||
defaultKey="metricsEnabled"
|
||||
>
|
||||
<FakeSwitch
|
||||
checked={settings.metricsEnabled}
|
||||
@@ -112,6 +93,7 @@ export function HostStatsTab({
|
||||
<SettingRow
|
||||
label={t("hosts.useGlobalMetrics")}
|
||||
description={t("hosts.useGlobalMetricsDesc")}
|
||||
defaultKey="metricsInterval"
|
||||
>
|
||||
<FakeSwitch
|
||||
checked={settings.metricsInterval === null}
|
||||
@@ -141,8 +123,9 @@ export function HostStatsTab({
|
||||
icon={<HardDrive className="size-3.5" />}
|
||||
>
|
||||
<div className="flex flex-col gap-3 py-3">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||
{t("hosts.monitoredMountsDesc")}
|
||||
<HostDefaultBadge settingKey="monitoredMounts" />
|
||||
</p>
|
||||
<div className="grid grid-cols-[1fr_0.7fr_auto] gap-2">
|
||||
<Input
|
||||
@@ -212,8 +195,9 @@ export function HostStatsTab({
|
||||
icon={<HardDrive className="size-3.5" />}
|
||||
>
|
||||
<div className="flex flex-col gap-3 py-3">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||
{t("hosts.excludedMountsDesc")}
|
||||
<HostDefaultBadge settingKey="excludedMounts" />
|
||||
</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<Input
|
||||
@@ -265,16 +249,18 @@ export function HostStatsTab({
|
||||
))}
|
||||
</div>
|
||||
</SectionCard>
|
||||
<SectionCard
|
||||
title={t("hosts.visibleWidgets")}
|
||||
icon={<LayoutDashboard className="size-3.5" />}
|
||||
>
|
||||
<div className="flex flex-col gap-2 py-3">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("hosts.widgetsMovedToHostMetrics")}
|
||||
</p>
|
||||
</div>
|
||||
</SectionCard>
|
||||
{!defaultsEditor && (
|
||||
<SectionCard
|
||||
title={t("hosts.visibleWidgets")}
|
||||
icon={<LayoutDashboard className="size-3.5" />}
|
||||
>
|
||||
<div className="flex flex-col gap-2 py-3">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("hosts.widgetsMovedToHostMetrics")}
|
||||
</p>
|
||||
</div>
|
||||
</SectionCard>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -96,6 +96,7 @@ export async function activate(app: TermixApp): Promise<void> {
|
||||
titleKey: "hosts.tabHostMetrics",
|
||||
icon: Activity,
|
||||
order: 70,
|
||||
defaults: true,
|
||||
component: MetricsHostSection,
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user