Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web,dashboard): migrate dashboard v2 #7741

Open
wants to merge 3 commits into
base: next
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .source
92 changes: 0 additions & 92 deletions apps/dashboard/src/components/opt-in-modal.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const OrganizationDropdown = () => {
<ClerkOrganizationSwitcher
hidePersonal
skipInvitationScreen
afterCreateOrganizationUrl={ROUTES.USECASE_SELECT + '?v2_opt_in=true'}
afterCreateOrganizationUrl={ROUTES.USECASE_SELECT}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the opt-in logic is now handled with the Clerk webhook event: https://github.com/novuhq/packages-enterprise/pull/270

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be that there will be some delivery delay on their webhook? It happened before, and during that time our service might redirect the user to the wrong place. How can we ensure that by the time the user reaches the USECASE SELECT he already opted in?

appearance={OrganizationSwitcherAppearance}
/>
);
Expand Down
2 changes: 0 additions & 2 deletions apps/dashboard/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ export const MIXPANEL_KEY = import.meta.env.VITE_MIXPANEL_KEY;

export const LEGACY_DASHBOARD_URL = import.meta.env.VITE_LEGACY_DASHBOARD_URL;

export const NEW_DASHBOARD_FEEDBACK_FORM_URL = import.meta.env.VITE_NEW_DASHBOARD_FEEDBACK_FORM_URL;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the google feedback form


export const PLAIN_SUPPORT_CHAT_APP_ID = import.meta.env.VITE_PLAIN_SUPPORT_CHAT_APP_ID;

export const ONBOARDING_DEMO_WORKFLOW_ID = 'onboarding-demo-workflow';
28 changes: 10 additions & 18 deletions apps/dashboard/src/context/opt-in-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import { PropsWithChildren, useLayoutEffect } from 'react';
import { PropsWithChildren, useEffect } from 'react';
import { NewDashboardOptInStatusEnum } from '@novu/shared';
import { useNewDashboardOptIn } from '@/hooks/use-new-dashboard-opt-in';
import { useSearchParams } from 'react-router-dom';

export const OptInProvider = (props: PropsWithChildren) => {
const { children } = props;
const { status, isLoaded, redirectToLegacyDashboard, optIn } = useNewDashboardOptIn();
const [searchParams] = useSearchParams();
const hasV2OptIn = searchParams.has('v2_opt_in');

useLayoutEffect(() => {
if (isLoaded && status !== NewDashboardOptInStatusEnum.OPTED_IN) {
if (hasV2OptIn) {
(async () => {
await optIn();
})();
} else {
redirectToLegacyDashboard();
}
}
const { status, isLoaded, redirectToLegacyDashboard } = useNewDashboardOptIn();

useEffect(() => {
// set light theme on the new domain for both legacy and new dashboard
localStorage.setItem('mantine-theme', 'light');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status, redirectToLegacyDashboard, isLoaded, hasV2OptIn]);
}, [status, redirectToLegacyDashboard, isLoaded]);

if (isLoaded && status !== NewDashboardOptInStatusEnum.OPTED_IN) {
redirectToLegacyDashboard();

return null;
}

Comment on lines +14 to +18
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when the user is opted-out redirect him to the old dashboard with preserving the URL route and query params

return <>{children}</>;
};
10 changes: 3 additions & 7 deletions apps/dashboard/src/hooks/use-new-dashboard-opt-in.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LEGACY_DASHBOARD_URL, NEW_DASHBOARD_FEEDBACK_FORM_URL } from '@/config';
import { LEGACY_DASHBOARD_URL } from '@/config';
import { useTelemetry } from '@/hooks/use-telemetry';
import { TelemetryEvent } from '@/utils/telemetry';
import { useUser } from '@clerk/clerk-react';
Expand Down Expand Up @@ -43,18 +43,14 @@ export function useNewDashboardOptIn() {
};

const redirectToLegacyDashboard = () => {
window.location.href = LEGACY_DASHBOARD_URL || window.location.origin + '/legacy/workflows';
window.location.href = `${LEGACY_DASHBOARD_URL}${window.location.pathname}${window.location.search}`;
};

const optOut = async () => {
track(TelemetryEvent.NEW_DASHBOARD_OPT_OUT);
await updateUserOptInStatus(NewDashboardOptInStatusEnum.OPTED_OUT);

if (NEW_DASHBOARD_FEEDBACK_FORM_URL) {
window.open(NEW_DASHBOARD_FEEDBACK_FORM_URL, '_blank');
}

redirectToLegacyDashboard();
window.location.href = LEGACY_DASHBOARD_URL;
};

const optIn = async () => {
Expand Down
2 changes: 0 additions & 2 deletions apps/dashboard/src/pages/workflows.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { DashboardLayout } from '@/components/dashboard-layout';
import { OptInModal } from '@/components/opt-in-modal';
import { PageMeta } from '@/components/page-meta';
import { Button } from '@/components/primitives/button';
import { ButtonGroupItem, ButtonGroupRoot } from '@/components/primitives/button-group';
Expand Down Expand Up @@ -120,7 +119,6 @@ export const WorkflowsPage = () => {
<>
<PageMeta title="Workflows" />
<DashboardLayout headerStartItems={<h1 className="text-foreground-950 flex items-center gap-1">Workflows</h1>}>
<OptInModal />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed opt-in modal

<div className="h-full w-full">
<div className="flex justify-between px-2.5 py-2.5">
<Form {...form}>
Expand Down
19 changes: 0 additions & 19 deletions apps/web/src/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ import { ActivitiesPage } from './pages/activities/ActivitiesPage';
import InvitationPage from './pages/auth/InvitationPage';
import LoginPage from './pages/auth/LoginPage';
import { PasswordResetPage } from './pages/auth/PasswordResetPage';
import QuestionnairePage from './pages/auth/QuestionnairePage';
import SignUpPage from './pages/auth/SignUpPage';
import { BrandingPage } from './pages/brand/BrandingPage';
import { PromoteChangesPage } from './pages/changes/PromoteChangesPage';
import { GetStartedPage } from './pages/get-started/GetStartedPage';
import HomePage from './pages/HomePage';
import {
ApiKeysPage,
Expand All @@ -28,12 +26,6 @@ import { IntegrationsListPage } from './pages/integrations/IntegrationsListPage'
import { UpdateProviderPage } from './pages/integrations/UpdateProviderPage';
import { MembersInvitePage } from './pages/invites/MembersInvitePage';
import { LinkVercelProjectPage } from './pages/partner-integrations/LinkVercelProjectPage';
import { DigestPreview } from './pages/quick-start/steps/DigestPreview';
import { FrameworkSetup } from './pages/quick-start/steps/FrameworkSetup';
import { GetStarted } from './pages/quick-start/steps/GetStarted';
import { InAppSuccess } from './pages/quick-start/steps/InAppSuccess';
import { NotificationCenter } from './pages/quick-start/steps/NotificationCenter';
import { Setup } from './pages/quick-start/steps/Setup';
import SubscribersList from './pages/subscribers/SubscribersListPage';
import { ChannelPreview } from './pages/templates/components/ChannelPreview';
import { ChannelStepEditor } from './pages/templates/components/ChannelStepEditor';
Expand Down Expand Up @@ -77,7 +69,6 @@ const AuthRoutes = () => {
<Route path={ROUTES.AUTH_RESET_REQUEST} element={<PasswordResetPage />} />
<Route path={ROUTES.AUTH_RESET_TOKEN} element={<PasswordResetPage />} />
<Route path={ROUTES.AUTH_INVITATION_TOKEN} element={<InvitationPage />} />
<Route path={ROUTES.AUTH_APPLICATION} element={<QuestionnairePage />} />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the questionnaire page and all related code. All old/new users will sign-in/up through the new Dashboard and it's flow.

</Route>
);

Expand Down Expand Up @@ -123,16 +114,6 @@ export const AppRoutes = () => {
<Route path="create" element={<CreateTenantPage />} />
<Route path=":identifier" element={<UpdateTenantPage />} />
</Route>
{isV2Enabled ? (
<Route path={ROUTES.GET_STARTED} element={<GetStartedPage />} />
) : (
<Route path={ROUTES.GET_STARTED} element={<GetStarted />} />
)}
<Route path={ROUTES.GET_STARTED_PREVIEW} element={<DigestPreview />} />
<Route path={ROUTES.QUICK_START_NOTIFICATION_CENTER} element={<NotificationCenter />} />
<Route path={ROUTES.QUICK_START_SETUP} element={<FrameworkSetup />} />
<Route path={ROUTES.QUICK_START_SETUP_FRAMEWORK} element={<Setup />} />
<Route path={ROUTES.QUICK_START_SETUP_SUCCESS} element={<InAppSuccess />} />
Comment on lines -126 to -135
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed get started page and all related code

<Route path={ROUTES.ACTIVITIES} element={<ActivitiesPage />} />
{!IS_EE_AUTH_ENABLED ? (
<Route path={ROUTES.SETTINGS} element={<SettingsPage />}>
Expand Down
30 changes: 1 addition & 29 deletions apps/web/src/ApplicationReadyGuard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import { Navigate, useLocation } from 'react-router-dom';
import { type PropsWithChildren, useLayoutEffect } from 'react';
import { useAuth, useEnvironment, useMonitoring, useRouteScopes } from './hooks';
import { ROUTES } from './constants/routes';
import { IS_EE_AUTH_ENABLED, IS_UNDER_DASHBOARD } from './config/index';
import { navigateToAuthApplication } from './utils';

export function ApplicationReadyGuard({ children }: PropsWithChildren<{}>) {
useMonitoring();
const location = useLocation();
const { inPublicRoute, inStudioRoute } = useRouteScopes();
const { isUserLoaded, isOrganizationLoaded, currentUser, currentOrganization } = useAuth();
const { isUserLoaded, isOrganizationLoaded, currentUser } = useAuth();
const { isLoaded: isEnvironmentLoaded } = useEnvironment();

const isLoaded = isUserLoaded && isOrganizationLoaded && isEnvironmentLoaded;
Expand All @@ -32,26 +30,6 @@ export function ApplicationReadyGuard({ children }: PropsWithChildren<{}>) {
}
}, [inPublicRoute, inStudioRoute, isLoaded]);

function isOnboardingComplete() {
if (IS_EE_AUTH_ENABLED) {
if (!currentOrganization) {
return true;
}

const createdBefore =
currentOrganization?.createdAt && new Date(currentOrganization.createdAt) < new Date('2024-07-31');

// Prompt organizations to complete onboarding if created on or after 2024-07-31
if (!createdBefore) {
return currentOrganization?.productUseCases !== undefined || currentOrganization?.language !== undefined;
}

return true;
}

return currentOrganization;
}

if (inPublicRoute || inStudioRoute) {
return <>{children}</>;
}
Expand All @@ -64,11 +42,5 @@ export function ApplicationReadyGuard({ children }: PropsWithChildren<{}>) {
return <Navigate to={ROUTES.AUTH_LOGIN} replace />;
}

if (IS_UNDER_DASHBOARD !== 'true' && !isOnboardingComplete() && location.pathname !== ROUTES.AUTH_APPLICATION) {
navigateToAuthApplication();

return null;
}

return <>{children}</>;
}
44 changes: 0 additions & 44 deletions apps/web/src/api/hooks/useUserOnboardingStatus.ts

This file was deleted.

Loading
Loading