Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions apps/web/core/components/onboarding/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { TOnboardingStep } from "@plane/types";
import { EOnboardingSteps } from "@plane/types";
import { cn } from "@plane/utils";
// hooks
import { useInstance } from "@/hooks/store/use-instance";
import { useUser } from "@/hooks/store/user";
// local imports
import { SwitchAccountDropdown } from "./switch-account-dropdown";
Expand All @@ -26,6 +27,8 @@ export const OnboardingHeader = observer(function OnboardingHeader(props: Onboar
const { currentStep, updateCurrentStep, hasInvitations } = props;
// store hooks
const { data: user } = useUser();
const { config: instanceConfig } = useInstance();
const isSelfManaged = instanceConfig?.is_self_managed;

// handle step back
const handleStepBack = () => {
Expand All @@ -37,30 +40,26 @@ export const OnboardingHeader = observer(function OnboardingHeader(props: Onboar
updateCurrentStep(EOnboardingSteps.ROLE_SETUP);
break;
case EOnboardingSteps.WORKSPACE_CREATE_OR_JOIN:
updateCurrentStep(EOnboardingSteps.USE_CASE_SETUP);
updateCurrentStep(isSelfManaged ? EOnboardingSteps.PROFILE_SETUP : EOnboardingSteps.USE_CASE_SETUP);
break;
}
};

// can go back
const canGoBack = ![EOnboardingSteps.PROFILE_SETUP, EOnboardingSteps.INVITE_MEMBERS].includes(currentStep);

// Get current step number for progress tracking
const getCurrentStepNumber = (): number => {
const stepOrder: TOnboardingStep[] = [
EOnboardingSteps.PROFILE_SETUP,
EOnboardingSteps.ROLE_SETUP,
EOnboardingSteps.USE_CASE_SETUP,
...(hasInvitations
? [EOnboardingSteps.WORKSPACE_CREATE_OR_JOIN]
: [EOnboardingSteps.WORKSPACE_CREATE_OR_JOIN, EOnboardingSteps.INVITE_MEMBERS]),
];
return stepOrder.indexOf(currentStep) + 1;
};
// step order for progress tracking — include INVITE_MEMBERS if user is currently on it
const showInviteStep = !hasInvitations || currentStep === EOnboardingSteps.INVITE_MEMBERS;
const stepOrder: TOnboardingStep[] = [
EOnboardingSteps.PROFILE_SETUP,
...(isSelfManaged ? [] : [EOnboardingSteps.ROLE_SETUP, EOnboardingSteps.USE_CASE_SETUP]),
EOnboardingSteps.WORKSPACE_CREATE_OR_JOIN,
...(showInviteStep ? [EOnboardingSteps.INVITE_MEMBERS] : []),
];

// derived values
const currentStepNumber = getCurrentStepNumber();
const totalSteps = hasInvitations ? 4 : 5; // 4 if invites available, 5 if not
const currentStepNumber = stepOrder.indexOf(currentStep) + 1;
const totalSteps = stepOrder.length;
const userName = user?.display_name
? user?.display_name
: user?.first_name
Expand Down
14 changes: 12 additions & 2 deletions apps/web/core/components/onboarding/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { IWorkspaceMemberInvitation, TOnboardingStep, TOnboardingSteps, TUserProfile } from "@plane/types";
import { EOnboardingSteps } from "@plane/types";
// hooks
import { useInstance } from "@/hooks/store/use-instance";
import { useWorkspace } from "@/hooks/store/use-workspace";
import { useUser, useUserProfile } from "@/hooks/store/user";
// local components
Expand All @@ -27,8 +28,10 @@ export const OnboardingRoot = observer(function OnboardingRoot({ invitations = [
const { data: user } = useUser();
const { data: userProfile, updateUserProfile, finishUserOnboarding } = useUserProfile();
const { workspaces } = useWorkspace();
const { config: instanceConfig } = useInstance();

const workspacesList = Object.values(workspaces ?? {});
const isSelfManaged = instanceConfig?.is_self_managed;

// Calculate total steps based on whether invitations are available
const hasInvitations = invitations.length > 0;
Expand Down Expand Up @@ -68,7 +71,14 @@ export const OnboardingRoot = observer(function OnboardingRoot({ invitations = [
(step: EOnboardingSteps, skipInvites?: boolean) => {
switch (step) {
case EOnboardingSteps.PROFILE_SETUP:
setCurrentStep(EOnboardingSteps.ROLE_SETUP);
if (isSelfManaged) {
// Skip role & use case steps for self-hosted
stepChange({ profile_complete: true });
if (workspacesList.length > 0) finishOnboarding();
else setCurrentStep(EOnboardingSteps.WORKSPACE_CREATE_OR_JOIN);
} else {
setCurrentStep(EOnboardingSteps.ROLE_SETUP);
}
break;
case EOnboardingSteps.ROLE_SETUP:
setCurrentStep(EOnboardingSteps.USE_CASE_SETUP);
Expand All @@ -91,7 +101,7 @@ export const OnboardingRoot = observer(function OnboardingRoot({ invitations = [
break;
}
},
[stepChange, finishOnboarding, workspacesList]
[stepChange, finishOnboarding, workspacesList, isSelfManaged]
);

const updateCurrentStep = (step: EOnboardingSteps) => setCurrentStep(step);
Expand Down
Loading