import { agentNativePath } from "@agent-native/core/client/api-path"; import { DbAdminPage } from "@agent-native/core/client/db-admin"; import { useActionMutation, useActionQuery, } from "@agent-native/core/client/hooks"; import { useFormatters, useT } from "@agent-native/core/client/i18n"; import { ObservabilityDashboard } from "@agent-native/core/client/observability"; import { useOrgRole } from "@agent-native/core/client/org"; import { IconActivity, IconAlertTriangle, IconChartBar, IconChevronDown, IconDatabase, IconEye, IconLoader2, IconMouse, IconPlus, IconToggleRight, IconTrash, } from "@tabler/icons-react"; import { useEffect, useMemo, useState, type FormEvent } from "react"; import { Link, useSearchParams } from "react-router"; import { FeatureFlagsFleetPanel } from "@/components/agents/FeatureFlagsFleetPanel"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { cn } from "@/lib/utils"; type AgentAdminView = "monitoring" | "dashboards" | "database" | "flags"; interface DbAdminConnection { id: string; name: string; appId: string | null; appUrl: string | null; databaseUrlLast4: string | null; hasDatabaseAuthToken: boolean; databaseAuthTokenLast4: string | null; } interface SaveDbAdminConnectionInput { name: string; appId?: string; appUrl?: string; databaseUrl: string; databaseAuthToken?: string; } interface DashboardUsageStats { id: string; name: string; kind: "explorer" | "sql"; ownerEmail: string | null; visibility: "private" | "org" | "public"; createdAt: string; updatedAt: string; updatedBy: string | null; archivedAt: string | null; hiddenAt: string | null; hiddenBy: string | null; viewCount: number; engagementCount: number; eventEngagementCount: number; editCount: number; savedViewCount: number; uniqueUserCount: number; lastViewedAt: string | null; lastSavedViewAt: string | null; panelCount: number | null; url: string; } const AGENT_ADMIN_VIEWS: AgentAdminView[] = [ "monitoring", "dashboards", "database", "flags", ]; function parseView(value: string | null): AgentAdminView { return AGENT_ADMIN_VIEWS.includes(value as AgentAdminView) ? (value as AgentAdminView) : "monitoring"; } function toCount(value: unknown): number { return typeof value === "number" && Number.isFinite(value) ? value : 0; } function DashboardUsageAdminPanel() { const t = useT(); const { formatDate } = useFormatters(); const numberFormat = useMemo(() => new Intl.NumberFormat(), []); const [sortBy, setSortBy] = useState<"views" | "edits">("views"); const { data: dashboards = [], isLoading, error, } = useActionQuery( "list-dashboard-usage-stats", undefined, { retry: false }, ); function formatCount(value: unknown) { return numberFormat.format(toCount(value)); } function formatMaybeDate(value: string | null) { if (!value) return t("agents.notTracked"); try { return formatDate(value, { year: "numeric", month: "short", day: "numeric", }); } catch { return value; } } const activeDashboards = dashboards.filter( (dashboard) => !dashboard.archivedAt, ); const totalViews = dashboards.reduce( (sum, dashboard) => sum + toCount(dashboard.viewCount), 0, ); const staleDashboards = dashboards.filter( (dashboard) => dashboard.viewCount === 0 && !dashboard.archivedAt, ); const mostViewedDashboard = dashboards.reduce( (mostViewed, dashboard) => !mostViewed || dashboard.viewCount > mostViewed.viewCount ? dashboard : mostViewed, null, ); const sortedDashboards = useMemo( () => [...dashboards].sort((a, b) => { const primary = sortBy === "views" ? b.viewCount - a.viewCount : b.editCount - a.editCount; if (primary !== 0) return primary; return b.updatedAt.localeCompare(a.updatedAt); }), [dashboards, sortBy], ); return (

{t("agents.dashboardUsageTitle")}

{t("agents.dashboardUsageDescription")}

{error ? (
{error.message}
) : isLoading ? (
) : dashboards.length === 0 ? (

{t("agents.dashboardUsageEmpty")}

{t("agents.dashboardUsageEmptyDescription")}

) : ( <>
sum + toCount(dashboard.engagementCount), 0, ), )} detail={t("agents.dashboardUsageEngagementsHint")} />
{t("agents.dashboardUsageDashboard")} {t("agents.dashboardUsageOwner")} {t("agents.dashboardUsageViews")} {t("agents.dashboardUsageEdits")} {t("agents.dashboardUsageEngagements")} {t("agents.dashboardUsageUsers")} {t("agents.dashboardUsageModified")} {t("agents.dashboardUsageCreated")} {t("agents.dashboardUsageState")} {sortedDashboards.map((dashboard) => (
{dashboard.name}
{dashboard.kind.toUpperCase()} {typeof dashboard.panelCount === "number" ? ( {t("agents.dashboardUsagePanels", { count: formatCount(dashboard.panelCount), })} ) : null}
{dashboard.ownerEmail ?? t("agents.notTracked")}
{formatCount(dashboard.viewCount)}
{formatMaybeDate(dashboard.lastViewedAt)}
{formatCount(dashboard.editCount)}
{formatCount(dashboard.engagementCount)}
{t("agents.dashboardUsageSavedViews", { count: formatCount(dashboard.savedViewCount), })}
{formatCount(dashboard.uniqueUserCount)}
{formatMaybeDate(dashboard.updatedAt)}
{dashboard.updatedBy ?? t("agents.notTracked")}
{formatMaybeDate(dashboard.createdAt)}
{t(`agents.visibility${dashboard.visibility}`)} {dashboard.hiddenAt ? ( {t("agents.dashboardUsageHidden")} ) : null} {dashboard.archivedAt ? ( {t("agents.dashboardUsageArchived")} ) : null}
))}
)}
); } function UsageStatCard({ icon: Icon, label, value, detail, }: { icon: typeof IconChartBar; label: string; value: string; detail: string; }) { return (
{label}
{value}
{detail}
); } export default function AgentsPage() { const t = useT(); const { canManageOrg, isLoading: orgRoleLoading } = useOrgRole(); const [searchParams, setSearchParams] = useSearchParams(); const view = parseView(searchParams.get("view")); const selectedConnectionId = searchParams.get("db"); const isAdminView = view !== "monitoring"; function setView(next: AgentAdminView) { const params = new URLSearchParams(searchParams); if (next === "monitoring") { params.delete("view"); params.delete("db"); } else { params.set("view", next); } setSearchParams(params, { replace: true }); } function setSelectedConnectionId(id: string | null) { const params = new URLSearchParams(searchParams); params.set("view", "database"); if (id) params.set("db", id); else params.delete("db"); setSearchParams(params, { replace: true }); } if (orgRoleLoading) { return (
); } if (!canManageOrg && isAdminView) { return (

{t("agents.adminOnlyTitle")}

{t("agents.adminOnlyDescription")}

); } return (

{t("agents.title")}

{t("agents.description")}

{canManageOrg ? ( {t("agents.advanced")} setView("database")}> {t("agents.database")} ) : null}
{canManageOrg ? ( ) : null} {canManageOrg ? ( ) : null} {canManageOrg && view === "database" && ( )}
{view === "database" ? ( ) : view === "dashboards" ? ( ) : view === "flags" ? ( ) : (
{t("agents.monitoringDescription")}
)}
); } function AnalyticsDbAdminPanel({ selectedConnectionId, onSelectConnection, }: { selectedConnectionId: string | null; onSelectConnection: (id: string | null) => void; }) { const t = useT(); const [connectOpen, setConnectOpen] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); const [form, setForm] = useState({ name: "", appId: "", appUrl: "", databaseUrl: "", databaseAuthToken: "", }); const [formError, setFormError] = useState(null); const { data: connections = [], isLoading, error, } = useActionQuery( "list-db-admin-connections", undefined, { retry: false }, ); const saveConnection = useActionMutation< DbAdminConnection, SaveDbAdminConnectionInput >("save-db-admin-connection"); const deleteConnection = useActionMutation< { deleted: boolean }, { id: string } >("delete-db-admin-connection"); const selectedConnection = useMemo(() => { return ( connections.find( (connection) => connection.id === selectedConnectionId, ) ?? connections[0] ?? null ); }, [connections, selectedConnectionId]); useEffect(() => { if (!selectedConnection) { if (selectedConnectionId) onSelectConnection(null); return; } if (selectedConnection.id !== selectedConnectionId) { onSelectConnection(selectedConnection.id); } }, [onSelectConnection, selectedConnection, selectedConnectionId]); const apiBasePath = selectedConnection ? agentNativePath( `/_agent-native/analytics-db-admin/${encodeURIComponent( selectedConnection.id, )}`, ) : null; async function handleSaveConnection(event: FormEvent) { event.preventDefault(); setFormError(null); try { const saved = await saveConnection.mutateAsync(form); setConnectOpen(false); setForm({ name: "", appId: "", appUrl: "", databaseUrl: "", databaseAuthToken: "", }); onSelectConnection(saved.id); } catch (err) { setFormError(err instanceof Error ? err.message : String(err)); } } async function handleDeleteConnection() { if (!selectedConnection) return; await deleteConnection.mutateAsync({ id: selectedConnection.id }); setDeleteOpen(false); const next = connections.find( (connection) => connection.id !== selectedConnection.id, ); onSelectConnection(next?.id ?? null); } return (

{t("agents.dbConnectionsTitle")}

{t("agents.dbConnectionsDescription")}

{connections.length > 0 ? ( ) : null} {selectedConnection ? ( ) : null}
{error ? (
{error.message}
) : isLoading ? (
) : selectedConnection && apiBasePath ? (
) : (

{t("agents.noConnections")}

{t("agents.noConnectionsDescription")}

)} {t("agents.connectDatabase")} {t("agents.connectDatabaseDescription")}
setForm((current) => ({ ...current, name: event.target.value, })) } required />
setForm((current) => ({ ...current, appId: event.target.value, })) } />
setForm((current) => ({ ...current, appUrl: event.target.value, })) } />
setForm((current) => ({ ...current, databaseUrl: event.target.value, })) } type="password" autoComplete="off" required />
setForm((current) => ({ ...current, databaseAuthToken: event.target.value, })) } type="password" autoComplete="off" />
{formError ? (

{formError}

) : null}
{t("agents.deleteConnectionTitle")} {t("agents.deleteConnectionDescription", { name: selectedConnection?.name ?? t("agents.connectedDatabase"), })} {t("sidebar.cancel")} {t("agents.deleteConnection")}
); }