diff --git a/apps/web/.env.example b/apps/web/.env.example
index fe475a7aca..34d97bc736 100644
--- a/apps/web/.env.example
+++ b/apps/web/.env.example
@@ -136,3 +136,8 @@ LOOPS_API_SECRET=
# Sanity config for blog. (Not needed. Only for blog):
# NEXT_PUBLIC_SANITY_PROJECT_ID=
# NEXT_PUBLIC_SANITY_DATASET="production"
+
+# Feature flags
+# NEXT_PUBLIC_DIGEST_ENABLED=true
+# NEXT_PUBLIC_MEETING_BRIEFS_ENABLED=true
+# NEXT_PUBLIC_INTEGRATIONS_ENABLED=true
\ No newline at end of file
diff --git a/apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx b/apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
index 9cc15d3825..09d1bdcc29 100644
--- a/apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
+++ b/apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
@@ -52,6 +52,7 @@ import { getRuleConfig } from "@/utils/rule/consts";
import { RuleSectionCard } from "@/app/(app)/[emailAccountId]/assistant/RuleSectionCard";
import { ConditionSteps } from "@/app/(app)/[emailAccountId]/assistant/ConditionSteps";
import { ActionSteps } from "@/app/(app)/[emailAccountId]/assistant/ActionSteps";
+import { env } from "@/env";
export function Rule({
ruleId,
@@ -493,22 +494,24 @@ export function RuleForm({
-
diff --git a/apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx b/apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
index 759a3d4efa..dd5e0e1789 100644
--- a/apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
+++ b/apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
@@ -7,6 +7,7 @@ import { LearnedPatternsSetting } from "@/app/(app)/[emailAccountId]/assistant/s
import { PersonalSignatureSetting } from "@/app/(app)/[emailAccountId]/assistant/settings/PersonalSignatureSetting";
import { MultiRuleSetting } from "@/app/(app)/[emailAccountId]/assistant/settings/MultiRuleSetting";
import { WritingStyleSetting } from "@/app/(app)/[emailAccountId]/assistant/settings/WritingStyleSetting";
+import { env } from "@/env";
export function SettingsTab() {
return (
@@ -16,7 +17,7 @@ export function SettingsTab() {
-
+ {env.NEXT_PUBLIC_DIGEST_ENABLED &&
}
diff --git a/apps/web/components/SideNav.tsx b/apps/web/components/SideNav.tsx
index a3ae2749bf..ff7fee8e1b 100644
--- a/apps/web/components/SideNav.tsx
+++ b/apps/web/components/SideNav.tsx
@@ -15,7 +15,6 @@ import {
ChevronDownIcon,
ChevronRightIcon,
FileIcon,
- HomeIcon,
FileTextIcon,
InboxIcon,
type LucideIcon,
@@ -29,6 +28,7 @@ import {
SparklesIcon,
TagIcon,
Users2Icon,
+ ZapIcon,
} from "lucide-react";
import { Logo } from "@/components/Logo";
import { useComposeModal } from "@/providers/ComposeModalProvider";
@@ -53,6 +53,7 @@ import { useSplitLabels } from "@/hooks/useLabels";
import { LoadingContent } from "@/components/LoadingContent";
import {
useCleanerEnabled,
+ useIntegrationsEnabled,
useMeetingBriefsEnabled,
} from "@/hooks/useFeatureFlags";
import { ClientOnly } from "@/components/ClientOnly";
@@ -72,22 +73,19 @@ type NavItem = {
target?: "_blank";
count?: number;
hideInMail?: boolean;
+ beta?: boolean;
};
export const useNavigation = () => {
const showCleaner = useCleanerEnabled();
const showMeetingBriefs = useMeetingBriefsEnabled();
+ const showIntegrations = useIntegrationsEnabled();
const { emailAccountId, emailAccount, provider } = useAccount();
const currentEmailAccountId = emailAccount?.id || emailAccountId;
const navItems: NavItem[] = useMemo(
() => [
- // {
- // name: "Dashboard",
- // href: prefixPath(currentEmailAccountId, "/setup"),
- // icon: HomeIcon,
- // },
{
name: "Assistant",
href: prefixPath(currentEmailAccountId, "/automation"),
@@ -117,17 +115,28 @@ export const useNavigation = () => {
href: prefixPath(currentEmailAccountId, "/calendars"),
icon: CalendarIcon,
},
+ ...(showIntegrations
+ ? [
+ {
+ name: "Integrations",
+ href: prefixPath(currentEmailAccountId, "/integrations"),
+ icon: ZapIcon,
+ beta: true,
+ },
+ ]
+ : []),
...(showMeetingBriefs
? [
{
name: "Meeting Briefs",
href: prefixPath(currentEmailAccountId, "/briefs"),
icon: FileTextIcon,
+ beta: true,
},
]
: []),
],
- [currentEmailAccountId, provider, showMeetingBriefs],
+ [currentEmailAccountId, provider, showMeetingBriefs, showIntegrations],
);
const navItemsFiltered = useMemo(
diff --git a/apps/web/components/SideNavMenu.tsx b/apps/web/components/SideNavMenu.tsx
index 77004e6be8..91fe360d59 100644
--- a/apps/web/components/SideNavMenu.tsx
+++ b/apps/web/components/SideNavMenu.tsx
@@ -7,6 +7,7 @@ import {
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar";
+import { Badge } from "@/components/ui/badge";
type NavItem = {
name: string;
@@ -16,6 +17,7 @@ type NavItem = {
count?: number;
hideInMail?: boolean;
active?: boolean;
+ beta?: boolean;
};
export function SideNavMenu({
@@ -39,6 +41,11 @@ export function SideNavMenu({
{item.name}
+ {item.beta && (
+
+ Beta
+
+ )}
diff --git a/apps/web/env.ts b/apps/web/env.ts
index 1e9017da1d..4655e252a6 100644
--- a/apps/web/env.ts
+++ b/apps/web/env.ts
@@ -187,6 +187,9 @@ export const env = createEnv({
.default(false),
NEXT_PUBLIC_USE_AEONIK_FONT: z.coerce.boolean().optional().default(false),
NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS: z.coerce.boolean().optional(),
+ NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
+ NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional(),
+ NEXT_PUBLIC_INTEGRATIONS_ENABLED: z.coerce.boolean().optional(),
},
// For Next.js >= 13.4.4, you only need to destructure client variables:
experimental__runtimeEnv: {
@@ -243,5 +246,10 @@ export const env = createEnv({
NEXT_PUBLIC_USE_AEONIK_FONT: process.env.NEXT_PUBLIC_USE_AEONIK_FONT,
NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS:
process.env.NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS,
+ NEXT_PUBLIC_DIGEST_ENABLED: process.env.NEXT_PUBLIC_DIGEST_ENABLED,
+ NEXT_PUBLIC_MEETING_BRIEFS_ENABLED:
+ process.env.NEXT_PUBLIC_MEETING_BRIEFS_ENABLED,
+ NEXT_PUBLIC_INTEGRATIONS_ENABLED:
+ process.env.NEXT_PUBLIC_INTEGRATIONS_ENABLED,
},
});
diff --git a/apps/web/hooks/useFeatureFlags.ts b/apps/web/hooks/useFeatureFlags.ts
index 4abc2c9415..0434bbf34f 100644
--- a/apps/web/hooks/useFeatureFlags.ts
+++ b/apps/web/hooks/useFeatureFlags.ts
@@ -2,13 +2,18 @@ import {
useFeatureFlagEnabled,
useFeatureFlagVariantKey,
} from "posthog-js/react";
+import { env } from "@/env";
export function useCleanerEnabled() {
return useFeatureFlagEnabled("inbox-cleaner");
}
export function useMeetingBriefsEnabled() {
- return useFeatureFlagEnabled("meeting-briefs");
+ return env.NEXT_PUBLIC_MEETING_BRIEFS_ENABLED;
+}
+
+export function useIntegrationsEnabled() {
+ return env.NEXT_PUBLIC_INTEGRATIONS_ENABLED;
}
const HERO_FLAG_NAME = "hero-copy-7";
diff --git a/apps/web/utils/action-item.ts b/apps/web/utils/action-item.ts
index dd0bc06e0c..09205194d4 100644
--- a/apps/web/utils/action-item.ts
+++ b/apps/web/utils/action-item.ts
@@ -109,15 +109,15 @@ export const actionInputs: Record<
},
[ActionType.FORWARD]: {
fields: [
+ {
+ name: "to",
+ label: "To",
+ },
{
name: "content",
label: "Extra Content",
textArea: true,
},
- {
- name: "to",
- label: "To",
- },
{
name: "cc",
label: "CC",
diff --git a/docs/hosting/environment-variables.md b/docs/hosting/environment-variables.md
index 40c33aed19..d090f1f12c 100644
--- a/docs/hosting/environment-variables.md
+++ b/docs/hosting/environment-variables.md
@@ -85,6 +85,9 @@ cp apps/web/.env.example apps/web/.env
| `NEXT_PUBLIC_CONTACTS_ENABLED` | No | Enable contacts feature | `false` |
| `NEXT_PUBLIC_EMAIL_SEND_ENABLED` | No | Enable email sending | `true` |
| `NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS` | No | Bypass premium checks (recommended for self-hosting) | `true` |
+| `NEXT_PUBLIC_DIGEST_ENABLED` | No | Enable email digest feature, which sends periodic summaries of emails. Requires QStash to be configured. | `false` |
+| `NEXT_PUBLIC_MEETING_BRIEFS_ENABLED` | No | Enable meeting briefs, which automatically sends pre-meeting briefings to users. Requires the meeting briefs cron job to be running. | `false` |
+| `NEXT_PUBLIC_INTEGRATIONS_ENABLED` | No | Enable the integrations feature, allowing users to connect external services. | `false` |
| **Debugging** ||||
| `LOG_ZOD_ERRORS` | No | Log Zod validation errors | — |
| `ENABLE_DEBUG_LOGS` | No | Enable debug logging | `false` |
diff --git a/turbo.json b/turbo.json
index 989333442e..9ecaf4d4a3 100644
--- a/turbo.json
+++ b/turbo.json
@@ -128,7 +128,11 @@
"NEXT_PUBLIC_AXIOM_DATASET",
"NEXT_PUBLIC_AXIOM_TOKEN",
"NEXT_PUBLIC_DUB_REFER_DOMAIN",
- "NEXT_PUBLIC_USE_AEONIK_FONT"
+ "NEXT_PUBLIC_USE_AEONIK_FONT",
+ "NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS",
+ "NEXT_PUBLIC_DIGEST_ENABLED",
+ "NEXT_PUBLIC_MEETING_BRIEFS_ENABLED",
+ "NEXT_PUBLIC_INTEGRATIONS_ENABLED"
],
"outputs": [".next/**", "!.next/cache/**"]
},
diff --git a/version.txt b/version.txt
index e74893adad..aaccdefabd 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-v2.23.0
+v2.23.1