ultisuite-client/components/admin/settings/sections/drive-org-section.tsx
R3D347HR4Y 8f81d7aba1
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat(admin-settings): refactor admin settings components for improved usability and consistency
- Replaced legacy components with new `SettingsCard`, `SettingsField`, and `SettingsToggleRow` for a unified design.
- Enhanced `AdminListControls` to support compact mode and improved pagination controls.
- Updated various sections including `AiAssistantSection`, `AuthenticationSection`, and `DriveMountOAuthSection` to utilize new components, streamlining the settings interface.
- Improved accessibility and user experience across admin settings with clearer labels and hints.
- Deprecated old components while maintaining backward compatibility for existing admin sections.
2026-06-15 11:10:17 +02:00

118 lines
3.7 KiB
TypeScript

"use client"
import { useState } from "react"
import {
SettingsCard,
SettingsField,
SettingsGrid,
} from "@/components/settings/settings-kit"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
useAdminDriveOrgFolderMutations,
useAdminDriveOrgFolders,
} from "@/lib/api/hooks/use-admin-drive-queries"
export function DriveOrgFoldersSection({ embedded = false }: { embedded?: boolean }) {
const folders = useAdminDriveOrgFolders()
const { create, remove, sync } = useAdminDriveOrgFolderMutations()
const [orgSlug, setOrgSlug] = useState("")
const [mountPoint, setMountPoint] = useState("")
const [syncSlugs, setSyncSlugs] = useState("")
const content = (
<>
<SettingsGrid columns={1}>
<SettingsField label="Slug organisation" htmlFor="org-slug">
<Input
id="org-slug"
className="h-9"
value={orgSlug}
onChange={(e) => setOrgSlug(e.target.value)}
placeholder="acme"
/>
</SettingsField>
<SettingsField label="Nom du dossier" htmlFor="org-mount">
<Input
id="org-mount"
className="h-9"
value={mountPoint}
onChange={(e) => setMountPoint(e.target.value)}
placeholder="Acme Corp"
/>
</SettingsField>
</SettingsGrid>
<Button
size="sm"
disabled={!orgSlug.trim() || !mountPoint.trim() || create.isPending}
onClick={() =>
void create.mutateAsync({ org_slug: orgSlug.trim(), mount_point: mountPoint.trim() })
}
>
Créer le dossier
</Button>
<SettingsField
label="Provisionnement automatique"
htmlFor="sync-orgs"
hint="Crée un dossier d'organisation pour chaque slug listé, s'il n'existe pas encore. Les slugs correspondent aux organisations Authentik."
>
<Input
id="sync-orgs"
className="h-9"
value={syncSlugs}
onChange={(e) => setSyncSlugs(e.target.value)}
placeholder="acme, beta"
/>
<Button
size="sm"
variant="outline"
className="mt-2"
disabled={!syncSlugs.trim() || sync.isPending}
onClick={() =>
void sync.mutateAsync(
syncSlugs.split(",").map((s) => s.trim()).filter(Boolean)
)
}
>
Provisionner les dossiers
</Button>
</SettingsField>
<ul className="divide-y divide-mail-border rounded-md border border-mail-border text-sm">
{(folders.data ?? []).map((folder) => (
<li key={folder.id} className="flex items-center justify-between gap-3 px-3 py-2">
<div className="min-w-0">
<p className="truncate font-medium">{folder.mount_point}</p>
<p className="truncate text-xs text-muted-foreground">{folder.org_slug}</p>
</div>
<Button
size="sm"
variant="ghost"
className="shrink-0 text-destructive"
disabled={remove.isPending}
onClick={() => void remove.mutateAsync(folder.id)}
>
Supprimer
</Button>
</li>
))}
{folders.data?.length === 0 ? (
<li className="px-3 py-4 text-center text-muted-foreground">Aucun dossier d&apos;organisation</li>
) : null}
</ul>
</>
)
if (embedded) return <div className="space-y-4">{content}</div>
return (
<SettingsCard
title="Dossiers d'organisation"
description="Espaces de stockage internes (group folders Nextcloud) liés aux organisations Authentik."
>
{content}
</SettingsCard>
)
}