mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 06:35:24 +00:00
feat: consent check, developer mode file installs, install counts and issue links for plugins
This commit is contained in:
1 parent
26a474bb3d
commit
08db1fcdde
28 files changed
+2248
-72
No files matched your search
@@ -0,0 +1,77 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import { SettingRow } from "@/components/section-card";
|
||||
import { useConfirm } from "@/components/surface/surface-scope";
|
||||
import { getDeveloperMode, setDeveloperMode } from "@/api/plugins-api";
|
||||
import { AdminToggle } from "./AdminSettingsShared";
|
||||
|
||||
/** Lets admins install plugins from a file. Asks before turning it on. */
|
||||
export function AdminPluginDeveloperMode() {
|
||||
const { t } = useTranslation();
|
||||
const confirm = useConfirm();
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
const [signedOnly, setSignedOnly] = useState(false);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
getDeveloperMode()
|
||||
.then((state) => {
|
||||
if (cancelled) return;
|
||||
setEnabled(state.enabled);
|
||||
setSignedOnly(state.signedOnly);
|
||||
setLoaded(true);
|
||||
})
|
||||
.catch(() => {});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const toggle = async () => {
|
||||
const next = !enabled;
|
||||
if (next) {
|
||||
const ok = await confirm({
|
||||
title: t("plugins.manager.developer.enableTitle"),
|
||||
description: t("plugins.manager.developer.enableBody"),
|
||||
confirmLabel: t("plugins.manager.developer.enable"),
|
||||
});
|
||||
if (!ok) return;
|
||||
}
|
||||
setSaving(true);
|
||||
try {
|
||||
await setDeveloperMode(next);
|
||||
setEnabled(next);
|
||||
} catch (error) {
|
||||
toast.error(
|
||||
t("plugins.manager.errors.developerMode", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
}),
|
||||
);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingRow
|
||||
label={t("plugins.manager.developer.title")}
|
||||
description={t("plugins.manager.developer.hint")}
|
||||
>
|
||||
<AdminToggle
|
||||
on={enabled}
|
||||
onToggle={() => void toggle()}
|
||||
disabled={!loaded || saving}
|
||||
/>
|
||||
</SettingRow>
|
||||
{enabled && signedOnly && (
|
||||
<p className="text-[10px] text-destructive">
|
||||
{t("plugins.manager.developer.signedOnly")}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { SettingRow } from "@/components/section-card";
|
||||
import { Database, Lock, RefreshCw, Server, Settings } from "lucide-react";
|
||||
import { AccordionSection, AdminToggle } from "./AdminSettingsShared";
|
||||
import { AdminHostTags } from "./AdminHostTags";
|
||||
import { AdminPluginDeveloperMode } from "./AdminPluginDeveloperMode";
|
||||
import type { TlsStatus } from "@/api/tls-api";
|
||||
|
||||
type GeneralSettingsSectionProps = {
|
||||
@@ -142,6 +143,7 @@ export function AdminGeneralSettingsSection({
|
||||
onToggle={handleTogglePasswordReset}
|
||||
/>
|
||||
</SettingRow>
|
||||
<AdminPluginDeveloperMode />
|
||||
<div className="flex flex-col gap-2 pt-3 mt-2">
|
||||
<span className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground">
|
||||
{t("admin.sessionTimeout")}
|
||||
|
||||
Reference in new issue
Block a user