mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 23:25:24 +00:00
feat: full screen onboarding with a plugin picker and per step versions
This commit is contained in:
1 parent
1e74ce4827
commit
b9dd3488a5
59 files changed
+5413
-643
No files matched your search
@@ -0,0 +1,75 @@
|
||||
import { getUiPreferences } from "@/api/ui-preferences-api";
|
||||
import {
|
||||
getOnboardingPlugins,
|
||||
type OnboardingPluginList,
|
||||
} from "@/api/plugins-api";
|
||||
import { loadPermissionChecker } from "@/hooks/use-permissions";
|
||||
import { isElectron } from "@/lib/electron";
|
||||
import { isEmbeddedAuthFrame } from "@/lib/embedded-frame";
|
||||
import type { UiPreferences } from "@/types/ui-preferences";
|
||||
import {
|
||||
computeFlow,
|
||||
needsFullFlow,
|
||||
ONBOARDING_ADMIN_PERMISSION,
|
||||
} from "./onboarding-flow";
|
||||
import type { OnboardingCtx, OnboardingMode } from "./onboarding-registry";
|
||||
import { canEnrollSecondFactor, currentStepDefs } from "./use-onboarding-steps";
|
||||
|
||||
export interface StartupOnboarding {
|
||||
preferences: UiPreferences | null;
|
||||
/** Null when there is nothing to show. */
|
||||
mode: Exclude<OnboardingMode, "rerun"> | null;
|
||||
plugins: OnboardingPluginList | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides, after sign in and once plugins have loaded, whether the app opens
|
||||
* on onboarding: the full run for a new user, or just the steps someone has
|
||||
* not seen yet. Never inside the mobile app or a desktop's link window,
|
||||
* which only borrow this page to sign in.
|
||||
*/
|
||||
export async function resolveStartupOnboarding(): Promise<StartupOnboarding> {
|
||||
const none: StartupOnboarding = {
|
||||
preferences: null,
|
||||
mode: null,
|
||||
plugins: null,
|
||||
};
|
||||
if (isEmbeddedAuthFrame()) return none;
|
||||
if (new URLSearchParams(window.location.search).has("view")) return none;
|
||||
|
||||
let preferences: UiPreferences;
|
||||
try {
|
||||
preferences = await getUiPreferences();
|
||||
} catch {
|
||||
return none;
|
||||
}
|
||||
|
||||
const has = await loadPermissionChecker();
|
||||
const isAdmin = has(ONBOARDING_ADMIN_PERMISSION);
|
||||
const plugins = isAdmin
|
||||
? await getOnboardingPlugins().catch(() => null)
|
||||
: null;
|
||||
|
||||
const result: StartupOnboarding = { preferences, mode: null, plugins };
|
||||
const { onboarding } = preferences;
|
||||
|
||||
if (needsFullFlow(onboarding)) return { ...result, mode: "full" };
|
||||
|
||||
const ctx: OnboardingCtx = {
|
||||
mode: "partial",
|
||||
isAdmin,
|
||||
isDesktop: isElectron(),
|
||||
has,
|
||||
pluginSetupPending: !!plugins?.pending,
|
||||
pluginsManagedElsewhere: !!plugins?.managedByLinkedServer,
|
||||
canEnrollSecondFactor: canEnrollSecondFactor(),
|
||||
};
|
||||
const steps = currentStepDefs(has);
|
||||
// Someone carried over from the old onboarding has their plugin steps
|
||||
// marked seen by the shell first, so only core steps count for them here.
|
||||
const candidates = onboarding.baselinePending
|
||||
? steps.filter((step) => !step.pluginId)
|
||||
: steps;
|
||||
const pending = computeFlow(candidates, onboarding.seen, ctx);
|
||||
return { ...result, mode: pending.length > 0 ? "partial" : null };
|
||||
}
|
||||
Reference in new issue
Block a user