AUDIT / src /components /workspace /WorkspaceMoreMenu.tsx
Arypulka98's picture
feat(audit): deploy full backend cluster node (part 2)
cc11e77 verified
Raw
History Blame Contribute Delete
5.37 kB
import { memo } from "react";
import type * as React from "react";
import { useUIStore } from "@/store/uiStore";
import AnimatedBrain from "@/components/chat/AnimatedBrain";
import {
IconConnectors, IconSettings as IconSettingsSvg,
} from "@/components/TabIcons";
import {
FolderOpen, Activity, Bug, GitBranch, Rocket, Database, Lock, } from "lucide-react";
// S761: estratto da MainWorkspace.tsx (AUDIT P0 — decomposizione MoreTab)
// Tutte le azioni leggono UIStore direttamente — zero prop drilling.
// Unico prop esterno: onNewProject (local useState in MainWorkspace — non in store).
interface WorkspaceMoreMenuProps {
/** Callback per aprire NewProjectPanel (local useState in MainWorkspace) */
onNewProject: () => void;
}
const WorkspaceMoreMenu = memo(function WorkspaceMoreMenu(_props: WorkspaceMoreMenuProps) {
const tab = useUIStore(s => s.activeTab);
const setShowMemory = useUIStore(s => s.setShowMemory);
const setShowConnectors = useUIStore(s => s.setShowConnectors);
const setShowFileExplorer = useUIStore(s => s.setShowFileExplorer);
const setShowSettings = useUIStore(s => s.setShowSettings);
const toggleTelemetry = useUIStore(s => s.toggleTelemetry);
const toggleWorkspacePicker = useUIStore(s => s.toggleWorkspacePicker);
const toggleGitSync = useUIStore(s => s.toggleGitSync);
const toggleDeployPanel = useUIStore(s => s.toggleDeployPanel);
const toggleProblems = useUIStore(s => s.toggleProblems);
const toggleDbBrowser = useUIStore(s => s.toggleDbBrowser);
const toggleSecretsPanel = useUIStore(s => s.toggleSecretsPanel);
const setShowNewProject = useUIStore(s => s.setShowNewProject);
const items: { icon: React.ReactNode; label: string; desc: string; onClick: () => void }[] = [
{ icon: <AnimatedBrain size={18} />, label: "Memoria Agente", desc: "Ricordi, sessioni, pattern appresi", onClick: () => setShowMemory(true) },
{ icon: <IconConnectors />, label: "Connettori API", desc: "Servizi REST collegati all'agente", onClick: () => setShowConnectors(true) },
{ icon: <FolderOpen size={18} />, label: "File System VFS", desc: "Esplora, carica ed esporta file nel VFS", onClick: () => setShowFileExplorer(true) },
{ icon: <IconSettingsSvg />, label: "Impostazioni", desc: "Token provider, modello AI, routing", onClick: () => setShowSettings(true) },
{ icon: <Activity size={18} />, label: "Statistiche", desc: "TTFT provider, tool usage, success rate", onClick: toggleTelemetry },
{ icon: <FolderOpen size={18} />, label: "Workspace", desc: "Gestisci workspace multipli", onClick: toggleWorkspacePicker },
{ icon: <span style={{ fontSize: "1.1rem" }}>🏗</span>, label: "Nuovo progetto", desc: "Scaffold react/nextjs/fastapi/flask/…", onClick: () => setShowNewProject(true) },
{ icon: <GitBranch size={18} />, label: "Git Sync", desc: "Pull, diff e push VFS ↔ GitHub", onClick: toggleGitSync },
{ icon: <Rocket size={18} />, label: "Deploy", desc: "Publish su Cloudflare Pages — 1 click", onClick: toggleDeployPanel },
{ icon: <Bug size={18} />, label: "Problemi", desc: "Diagnostics, run profiles e stato CI/CD", onClick: toggleProblems },
{ icon: <Database size={18} />, label: "Database", desc: "Esplora tabelle IndexedDB, export, stats", onClick: toggleDbBrowser },
{ icon: <Lock size={18} />, label: "Segreti", desc: "Vault segreti cifrati — Railway", onClick: toggleSecretsPanel },
];
return (
<div className={tab === "more" ? "tab-pane-active" : undefined}
style={{ display: tab === "more" ? "flex" : "none", flex: 1, overflow: "auto", flexDirection: "column", padding: "1.2rem 1rem" }}>
<p style={{ fontSize: "0.7rem", color: "#3a3a6a", fontFamily: "monospace", letterSpacing: "0.08em", marginBottom: "1rem" }}>
STRUMENTI / TOOLS
</p>
{items.map(item => (
<button key={item.label} onClick={item.onClick} style={{
all: "unset", display: "flex", alignItems: "center", gap: 14, cursor: "pointer",
padding: "0.9rem 1rem", borderRadius: 12, marginBottom: 8,
background: "rgba(99,102,241,0.04)", border: "1px solid rgba(99,102,241,0.10)",
transition: "background 0.15s, border-color 0.15s",
}}
onMouseEnter={e => { e.currentTarget.style.background = "rgba(99,102,241,0.09)"; e.currentTarget.style.borderColor = "rgba(99,102,241,0.22)"; }}
onMouseLeave={e => { e.currentTarget.style.background = "rgba(99,102,241,0.04)"; e.currentTarget.style.borderColor = "rgba(99,102,241,0.10)"; }}
>
<span style={{ color: "var(--primary)", flexShrink: 0 }}>{item.icon}</span>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ fontSize: "0.88rem", fontWeight: 600, color: "#d0d0f0" }}>{item.label}</div>
<div style={{ fontSize: "0.72rem", color: "#4a4a78", marginTop: 2 }}>{item.desc}</div>
</div>
</button>
))}
</div>
);
});
export default WorkspaceMoreMenu;