feat(ui): add teams, tools, feature flags, temp files, logo to settings dialog

- Add Teams section with CRUD (create, rename, delete) and member count display
- Add Tools section with per-tool enable/disable toggles grouped by category
- Add logo upload/delete, experimental tools toggle, file management settings to System Settings
- Replace free-text team input with dropdown populated from teams API in People section
- Filter disabled/experimental tools in tool panel, pipeline builder, and fullscreen grid
- Display custom logo in mobile header and sidebar when configured
This commit is contained in:
Siddharth Kumar Sah
2026-03-26 01:10:51 +08:00
parent ffb676d648
commit 4b2621d9f2
5 changed files with 699 additions and 29 deletions
@@ -13,12 +13,13 @@ import {
Upload,
X,
} from "lucide-react";
import { useCallback, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { apiGet } from "@/lib/api";
import { cn } from "@/lib/utils";
import { PipelineStepSettings } from "./pipeline-step-settings";
/** Tools that can be used as pipeline steps (excludes pipeline/batch/multi-file tools). */
const PIPELINE_TOOLS = TOOLS.filter(
const PIPELINE_TOOLS_BASE = TOOLS.filter(
(t) => !["pipeline", "batch", "compare", "find-duplicates", "collage", "compose"].includes(t.id),
);
@@ -58,6 +59,27 @@ export function PipelineBuilder({
const [saveDescription, setSaveDescription] = useState("");
const [showSaveForm, setShowSaveForm] = useState(false);
const [file, setFile] = useState<File | null>(null);
const [disabledTools, setDisabledTools] = useState<string[]>([]);
const [experimentalEnabled, setExperimentalEnabled] = useState(false);
useEffect(() => {
apiGet<{ settings: Record<string, string> }>("/v1/settings")
.then((data) => {
setDisabledTools(
data.settings.disabledTools ? JSON.parse(data.settings.disabledTools) : [],
);
setExperimentalEnabled(data.settings.enableExperimentalTools === "true");
})
.catch(() => {});
}, []);
const PIPELINE_TOOLS = useMemo(() => {
return PIPELINE_TOOLS_BASE.filter((t) => {
if (disabledTools.includes(t.id)) return false;
if (t.experimental && !experimentalEnabled) return false;
return true;
});
}, [disabledTools, experimentalEnabled]);
const addStep = useCallback(
(toolId: string) => {