112 lines
4.5 KiB
TypeScript
112 lines
4.5 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import { ChevronDown, ChevronRight, Container, Lock } from "lucide-react"
|
|
import { useOrgSettingsStore } from "@/lib/admin-settings/org-settings-store"
|
|
import { envGroupLabel, groupEnvVars } from "@/lib/admin/deploy-runtime"
|
|
import { Badge } from "@/components/ui/badge"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
export function AdminRuntimePanel() {
|
|
const meta = useOrgSettingsStore((s) => s.meta)
|
|
const synced = useOrgSettingsStore((s) => s.apiSynced)
|
|
const [envOpen, setEnvOpen] = useState(false)
|
|
|
|
if (!synced || !meta) return null
|
|
|
|
const eff = meta.effective
|
|
const envGroups = groupEnvVars(meta.envVars ?? [])
|
|
const setCount = (meta.envVars ?? []).filter((v) => v.set).length
|
|
|
|
return (
|
|
<div className="mb-4 space-y-3 rounded-lg border border-border bg-muted/30 p-4 text-xs">
|
|
<div className="flex items-start gap-2">
|
|
<Container className="mt-0.5 size-4 shrink-0 text-muted-foreground" aria-hidden />
|
|
<div className="min-w-0 flex-1 space-y-1">
|
|
<p className="font-medium text-foreground">Configuration runtime (Docker Compose)</p>
|
|
<p className="text-muted-foreground">
|
|
Les services ci-dessous sont pilotés par les variables d'environnement du
|
|
déploiement. Les interrupteurs correspondants dans l'administration sont en
|
|
lecture seule.
|
|
</p>
|
|
<p className="text-muted-foreground">
|
|
Recherche <span className="font-medium text-foreground">{eff.search.suite_engine}</span>
|
|
{" · "}
|
|
Nextcloud {eff.nextcloud.enabled ? "actif" : "inactif"}
|
|
{" · "}
|
|
OnlyOffice {eff.onlyoffice.enabled ? "actif" : "inactif"}
|
|
{eff.immich ? (
|
|
<>
|
|
{" · "}
|
|
Immich {eff.immich.enabled ? "actif" : "inactif"}
|
|
</>
|
|
) : null}
|
|
{eff.jitsi ? (
|
|
<>
|
|
{" · "}
|
|
Jitsi {eff.jitsi.enabled ? "actif" : "inactif"}
|
|
</>
|
|
) : null}
|
|
</p>
|
|
</div>
|
|
<Badge variant="outline" className="shrink-0 gap-1">
|
|
<Lock className="size-3" aria-hidden />
|
|
Compose
|
|
</Badge>
|
|
</div>
|
|
|
|
<button
|
|
type="button"
|
|
className="flex w-full items-center gap-1.5 text-left font-medium text-foreground hover:underline"
|
|
onClick={() => setEnvOpen((v) => !v)}
|
|
>
|
|
{envOpen ? (
|
|
<ChevronDown className="size-4" aria-hidden />
|
|
) : (
|
|
<ChevronRight className="size-4" aria-hidden />
|
|
)}
|
|
Variables d'environnement ({setCount} définies)
|
|
</button>
|
|
|
|
{envOpen ? (
|
|
<div className="space-y-4 border-t border-border/60 pt-3">
|
|
{Object.entries(envGroups).map(([group, vars]) => (
|
|
<div key={group}>
|
|
<p className="mb-2 font-medium text-foreground">{envGroupLabel(group)}</p>
|
|
<div className="overflow-x-auto rounded-md border bg-background/80">
|
|
<table className="w-full text-left">
|
|
<thead>
|
|
<tr className="border-b text-muted-foreground">
|
|
<th className="px-2 py-1.5 font-medium">Variable</th>
|
|
<th className="px-2 py-1.5 font-medium">Définie</th>
|
|
<th className="px-2 py-1.5 font-medium">Valeur</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{vars.map((v) => (
|
|
<tr key={v.name} className="border-b border-border/40 last:border-0">
|
|
<td className="px-2 py-1.5 font-mono text-[11px]">{v.name}</td>
|
|
<td className="px-2 py-1.5">
|
|
<Badge
|
|
variant={v.set ? "default" : "secondary"}
|
|
className={cn("text-[10px]", !v.set && "opacity-70")}
|
|
>
|
|
{v.set ? "oui" : "non"}
|
|
</Badge>
|
|
</td>
|
|
<td className="max-w-[200px] truncate px-2 py-1.5 font-mono text-[11px] text-muted-foreground">
|
|
{v.secret ? (v.set ? "••••••••" : "—") : (v.value ?? "—")}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
)
|
|
}
|