Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Added OnboardClaimPage and OnboardMigrationPage components for user onboarding. - Integrated OAuth login flow for Google and Microsoft accounts. - Implemented error handling and user feedback for claim and migration processes. - Created MigrationStepList and MigrationOnboardingAlerts components for progress tracking. - Added MailDomainsSection and MigrationProjectsPanel for admin settings. - Introduced e2e tests for onboarding migration scenarios.
147 lines
5.4 KiB
TypeScript
147 lines
5.4 KiB
TypeScript
"use client"
|
|
|
|
import type { MigrationProject } from "@/lib/api/hooks/use-hosted-mail"
|
|
|
|
export type MigrationOnboardingHints = {
|
|
needs_user_oauth: boolean
|
|
oauth_provider?: string
|
|
waiting_for_admin: boolean
|
|
waiting_reason?: string
|
|
has_migration_credentials?: boolean
|
|
needs_microsoft_admin_consent?: boolean
|
|
}
|
|
|
|
const WAITING_MESSAGES: Record<string, string> = {
|
|
project_not_activated:
|
|
"Votre administrateur doit activer le projet de migration avant que l'import ne démarre. Vos jobs resteront en attente jusqu'à cette activation.",
|
|
}
|
|
|
|
export function usesAppOnlyAuth(project?: Pick<MigrationProject, "auth_mode">): boolean {
|
|
return project?.auth_mode === "google_dwd" || project?.auth_mode === "microsoft_app"
|
|
}
|
|
|
|
export function appOnlyAuthStepLabel(project?: MigrationProject): string {
|
|
if (project?.auth_mode === "microsoft_app") {
|
|
return "Import automatique (app Microsoft)"
|
|
}
|
|
if (project?.auth_mode === "google_dwd") {
|
|
return "Import automatique (compte de service)"
|
|
}
|
|
return "Autoriser l'import Google / Microsoft"
|
|
}
|
|
|
|
export function waitingForAdminMessage(reason?: string): string {
|
|
if (!reason) {
|
|
return "En attente d'une action administrateur avant le démarrage de l'import."
|
|
}
|
|
return WAITING_MESSAGES[reason] ?? "En attente d'une action administrateur."
|
|
}
|
|
|
|
export function MigrationStepList({
|
|
steps,
|
|
}: {
|
|
steps: { label: string; done: boolean; current: boolean }[]
|
|
}) {
|
|
return (
|
|
<ol className="space-y-2 text-sm">
|
|
{steps.map((step) => (
|
|
<li
|
|
key={step.label}
|
|
className={`flex items-center gap-2 rounded-md px-3 py-2 ${
|
|
step.current ? "bg-primary/10 font-medium" : step.done ? "text-muted-foreground" : ""
|
|
}`}
|
|
>
|
|
<span
|
|
className={`inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-xs ${
|
|
step.done
|
|
? "bg-green-600 text-white"
|
|
: step.current
|
|
? "border-2 border-primary text-primary"
|
|
: "border border-muted-foreground/40 text-muted-foreground"
|
|
}`}
|
|
>
|
|
{step.done ? "✓" : "·"}
|
|
</span>
|
|
{step.label}
|
|
</li>
|
|
))}
|
|
</ol>
|
|
)
|
|
}
|
|
|
|
export function MigrationOnboardingAlerts({
|
|
project,
|
|
onboarding,
|
|
}: {
|
|
project?: MigrationProject
|
|
onboarding?: MigrationOnboardingHints
|
|
}) {
|
|
if (!onboarding) return null
|
|
|
|
return (
|
|
<div className="mt-4 space-y-3">
|
|
{onboarding.waiting_for_admin && (
|
|
<p className="rounded-md bg-amber-500/10 px-3 py-2 text-sm text-amber-800">
|
|
{waitingForAdminMessage(onboarding.waiting_reason)}
|
|
</p>
|
|
)}
|
|
{usesAppOnlyAuth(project) && !onboarding.waiting_for_admin && (
|
|
<p className="rounded-md bg-blue-500/10 px-3 py-2 text-sm text-blue-800">
|
|
{project?.auth_mode === "microsoft_app" ? (
|
|
<>
|
|
Import Microsoft 365 configuré par votre administrateur (authentification app-only).
|
|
Aucune autorisation OAuth personnelle requise — l'import démarre automatiquement
|
|
une fois le projet actif et le consentement admin accordé.
|
|
</>
|
|
) : (
|
|
<>
|
|
Import Google configuré par votre administrateur (compte de service). Aucune autorisation
|
|
OAuth personnelle requise — l'import démarre automatiquement une fois le projet
|
|
actif.
|
|
</>
|
|
)}
|
|
</p>
|
|
)}
|
|
{onboarding.needs_microsoft_admin_consent && project?.source_provider === "microsoft" && (
|
|
<p className="rounded-md bg-amber-500/10 px-3 py-2 text-sm text-amber-800">
|
|
L'administrateur de votre organisation Microsoft 365 doit accorder le consentement
|
|
admin à l'application Ultimail
|
|
{project?.auth_mode === "microsoft_app"
|
|
? " (permissions application : Mail, Calendrier, Contacts, OneDrive)."
|
|
: "."}{" "}
|
|
{project?.auth_mode !== "microsoft_app" &&
|
|
"Vous pouvez autoriser votre compte personnel ci-dessous, mais l'import organisationnel peut échouer tant que ce consentement n'est pas fait."}
|
|
</p>
|
|
)}
|
|
{onboarding.needs_user_oauth &&
|
|
!onboarding.has_migration_credentials &&
|
|
!onboarding.waiting_for_admin &&
|
|
!usesAppOnlyAuth(project) && (
|
|
<p className="rounded-md border px-3 py-2 text-sm text-muted-foreground">
|
|
Étape suivante : autorisez l'accès à votre compte{" "}
|
|
{project?.source_provider === "microsoft" ? "Microsoft 365" : "Google Workspace"} pour
|
|
lancer l'import de vos données.
|
|
</p>
|
|
)}
|
|
{onboarding.has_migration_credentials && !onboarding.waiting_for_admin && (
|
|
<p className="rounded-md bg-green-500/10 px-3 py-2 text-sm text-green-700">
|
|
Autorisation enregistrée — l'import progresse en arrière-plan.
|
|
</p>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export function shouldShowOAuthButton(
|
|
project: MigrationProject | undefined,
|
|
onboarding: MigrationOnboardingHints | undefined,
|
|
provider: "google" | "microsoft"
|
|
): boolean {
|
|
if (!project || !onboarding) return false
|
|
if (usesAppOnlyAuth(project)) return false
|
|
if (onboarding.waiting_for_admin) return false
|
|
if (project.source_provider !== provider) return false
|
|
if (onboarding.has_migration_credentials) return false
|
|
return onboarding.needs_user_oauth
|
|
}
|