diff --git a/packages/twenty-front/src/App.tsx b/packages/twenty-front/src/App.tsx
index 9abf50e83..cf74464c5 100644
--- a/packages/twenty-front/src/App.tsx
+++ b/packages/twenty-front/src/App.tsx
@@ -20,6 +20,7 @@ import { RecordIndexPage } from '~/pages/object-record/RecordIndexPage';
import { RecordShowPage } from '~/pages/object-record/RecordShowPage';
import { Opportunities } from '~/pages/opportunities/Opportunities';
import { SettingsAccounts } from '~/pages/settings/accounts/SettingsAccounts';
+import { SettingsAccountsCalendars } from '~/pages/settings/accounts/SettingsAccountsCalendars';
import { SettingsAccountsEmails } from '~/pages/settings/accounts/SettingsAccountsEmails';
import { SettingsAccountsEmailsInboxSettings } from '~/pages/settings/accounts/SettingsAccountsEmailsInboxSettings';
import { SettingsNewAccount } from '~/pages/settings/accounts/SettingsNewAccount';
@@ -95,6 +96,10 @@ export const App = () => {
path={SettingsPath.NewAccount}
element={}
/>
+ }
+ />
}
diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
index 0bd6a76e2..2f09bd5d6 100644
--- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
+++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
@@ -2,9 +2,12 @@ import { useNavigate } from 'react-router-dom';
import styled from '@emotion/styled';
import { SettingsNavigationCard } from '@/settings/components/SettingsNavigationCard';
+import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
+import { SettingsPath } from '@/types/SettingsPath';
import { IconCalendarEvent, IconMailCog } from '@/ui/display/icon';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { Section } from '@/ui/layout/section/components/Section';
+import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
const StyledCardsContainer = styled.div`
display: flex;
@@ -12,12 +15,9 @@ const StyledCardsContainer = styled.div`
margin-top: ${({ theme }) => theme.spacing(6)};
`;
-const StyledSettingsNavigationCard = styled(SettingsNavigationCard)`
- color: ${({ theme }) => theme.font.color.extraLight};
-`;
-
export const SettingsAccountsSettingsSection = () => {
const navigate = useNavigate();
+ const isCalendarEnabled = useIsFeatureEnabled('IS_CALENDAR_ENABLED');
return (
@@ -29,18 +29,22 @@ export const SettingsAccountsSettingsSection = () => {
navigate('/settings/accounts/emails')}
+ onClick={() =>
+ navigate(getSettingsPagePath(SettingsPath.AccountsEmails))
+ }
>
Set email visibility, manage your blocklist and more.
-
+ navigate(getSettingsPagePath(SettingsPath.AccountsCalendars))
+ }
>
Configure and customize your calendar preferences.
-
+
);
diff --git a/packages/twenty-front/src/modules/settings/components/SettingsNavigationCard.tsx b/packages/twenty-front/src/modules/settings/components/SettingsNavigationCard.tsx
index 3167f4257..9c79a5a58 100644
--- a/packages/twenty-front/src/modules/settings/components/SettingsNavigationCard.tsx
+++ b/packages/twenty-front/src/modules/settings/components/SettingsNavigationCard.tsx
@@ -11,7 +11,7 @@ import { CardContent } from '@/ui/layout/card/components/CardContent';
type SettingsNavigationCardProps = {
children: ReactNode;
disabled?: boolean;
- hasSoonPill?: boolean;
+ soon?: boolean;
Icon: IconComponent;
onClick?: () => void;
title: string;
@@ -22,7 +22,8 @@ const StyledCard = styled(Card)<{
disabled?: boolean;
onClick?: () => void;
}>`
- color: ${({ theme }) => theme.font.color.tertiary};
+ color: ${({ disabled, theme }) =>
+ disabled ? theme.font.color.extraLight : theme.font.color.tertiary};
cursor: ${({ disabled, onClick }) =>
disabled ? 'not-allowed' : onClick ? 'pointer' : 'default'};
`;
@@ -40,8 +41,9 @@ const StyledHeader = styled.div`
gap: ${({ theme }) => theme.spacing(3)};
`;
-const StyledTitle = styled.div`
- color: ${({ theme }) => theme.font.color.secondary};
+const StyledTitle = styled.div<{ disabled?: boolean }>`
+ color: ${({ disabled, theme }) =>
+ disabled ? 'inherit' : theme.font.color.secondary};
display: flex;
flex: 1 0 auto;
font-weight: ${({ theme }) => theme.font.weight.medium};
@@ -59,8 +61,8 @@ const StyledDescription = styled.div`
export const SettingsNavigationCard = ({
children,
- disabled,
- hasSoonPill,
+ soon,
+ disabled = soon,
Icon,
onClick,
title,
@@ -69,13 +71,17 @@ export const SettingsNavigationCard = ({
const theme = useTheme();
return (
-
+
-
+
{title}
- {hasSoonPill && }
+ {soon && }
diff --git a/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItem.tsx b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItem.tsx
new file mode 100644
index 000000000..60733c0b6
--- /dev/null
+++ b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItem.tsx
@@ -0,0 +1,42 @@
+import { useMatch, useResolvedPath } from 'react-router-dom';
+
+import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
+import { SettingsPath } from '@/types/SettingsPath';
+import {
+ NavigationDrawerItem,
+ NavigationDrawerItemProps,
+} from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
+
+type SettingsNavigationDrawerItemProps = Pick<
+ NavigationDrawerItemProps,
+ 'Icon' | 'label' | 'level' | 'soon'
+> & {
+ matchSubPages?: boolean;
+ path: SettingsPath;
+};
+
+export const SettingsNavigationDrawerItem = ({
+ Icon,
+ label,
+ level,
+ matchSubPages = false,
+ path,
+ soon,
+}: SettingsNavigationDrawerItemProps) => {
+ const href = getSettingsPagePath(path);
+ const isActive = !!useMatch({
+ path: useResolvedPath(href).pathname,
+ end: !matchSubPages,
+ });
+
+ return (
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx
index 9c7c7a451..1fb4cdbda 100644
--- a/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx
+++ b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx
@@ -1,8 +1,10 @@
import { useCallback } from 'react';
-import { useMatch, useNavigate, useResolvedPath } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { useAuth } from '@/auth/hooks/useAuth';
+import { SettingsNavigationDrawerItem } from '@/settings/components/SettingsNavigationDrawerItem';
import { AppPath } from '@/types/AppPath';
+import { SettingsPath } from '@/types/SettingsPath';
import {
IconApps,
IconAt,
@@ -31,67 +33,45 @@ export const SettingsNavigationDrawerItems = () => {
navigate(AppPath.SignIn);
}, [signOut, navigate]);
+ const isCalendarEnabled = useIsFeatureEnabled('IS_CALENDAR_ENABLED');
const isMessagingEnabled = useIsFeatureEnabled('IS_MESSAGING_ENABLED');
- const isIntegrationsItemActive = !!useMatch({
- path: useResolvedPath('/settings/integrations').pathname,
- end: true,
- });
-
- const isAccountsItemActive = !!useMatch({
- path: useResolvedPath('/settings/accounts').pathname,
- end: true,
- });
- const isAccountsEmailsItemActive = !!useMatch({
- path: useResolvedPath('/settings/accounts/emails').pathname,
- end: true,
- });
return (
<>
-
-
+
{isMessagingEnabled && (
-
-
-
)}
@@ -99,55 +79,31 @@ export const SettingsNavigationDrawerItems = () => {
-
-
-
-
-
diff --git a/packages/twenty-front/src/modules/settings/utils/getSettingsPagePath.ts b/packages/twenty-front/src/modules/settings/utils/getSettingsPagePath.ts
new file mode 100644
index 000000000..11c12d61f
--- /dev/null
+++ b/packages/twenty-front/src/modules/settings/utils/getSettingsPagePath.ts
@@ -0,0 +1,4 @@
+import { SettingsPath } from '@/types/SettingsPath';
+
+export const getSettingsPagePath = (path: Path) =>
+ `/settings/${path}` as const;
diff --git a/packages/twenty-front/src/modules/types/SettingsPath.ts b/packages/twenty-front/src/modules/types/SettingsPath.ts
index 24b7446d5..de4a2c620 100644
--- a/packages/twenty-front/src/modules/types/SettingsPath.ts
+++ b/packages/twenty-front/src/modules/types/SettingsPath.ts
@@ -3,6 +3,7 @@ export enum SettingsPath {
Appearance = 'profile/appearance',
Accounts = 'accounts',
NewAccount = 'accounts/new',
+ AccountsCalendars = 'accounts/calendars',
AccountsEmails = 'accounts/emails',
AccountsEmailsInboxSettings = 'accounts/emails/:accountUuid',
Objects = 'objects',
@@ -14,7 +15,7 @@ export enum SettingsPath {
NewObject = 'objects/new',
WorkspaceMembersPage = 'workspace-members',
Workspace = 'workspace',
- Developers = '',
+ Developers = 'developers',
DevelopersNewApiKey = 'api-keys/new',
DevelopersApiKeyDetail = 'api-keys/:apiKeyId',
Integrations = 'integrations',
diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx
index 6c542f292..69e1be741 100644
--- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx
+++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx
@@ -8,7 +8,7 @@ import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigation
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
-type NavigationDrawerItemProps = {
+export type NavigationDrawerItemProps = {
className?: string;
label: string;
level?: 1 | 2;
diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx
index c7d04d18f..9d1739efb 100644
--- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx
+++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx
@@ -1,6 +1,8 @@
import { Meta, StoryObj } from '@storybook/react';
import { Favorites } from '@/favorites/components/Favorites';
+import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
+import { SettingsPath } from '@/types/SettingsPath';
import {
IconAt,
IconBell,
@@ -91,32 +93,32 @@ export const Submenu: Story = {
@@ -125,12 +127,12 @@ export const Submenu: Story = {
diff --git a/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts b/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts
index b0b10fef2..1a85d16de 100644
--- a/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts
+++ b/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts
@@ -1,5 +1,6 @@
export type FeatureFlagKey =
- | 'IS_MESSAGING_ENABLED'
| 'IS_BLOCKLIST_ENABLED'
- | 'IS_QUICK_ACTIONS_ENABLED'
- | 'IS_NEW_RECORD_BOARD_ENABLED';
+ | 'IS_CALENDAR_ENABLED'
+ | 'IS_MESSAGING_ENABLED'
+ | 'IS_NEW_RECORD_BOARD_ENABLED'
+ | 'IS_QUICK_ACTIONS_ENABLED';
diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx
new file mode 100644
index 000000000..d9f90f1ad
--- /dev/null
+++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx
@@ -0,0 +1,22 @@
+import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
+import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
+import { SettingsPath } from '@/types/SettingsPath';
+import { IconSettings } from '@/ui/display/icon';
+import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
+import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
+
+export const SettingsAccountsCalendars = () => (
+
+
+
+
+
+);
diff --git a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx
new file mode 100644
index 000000000..6b636ea4f
--- /dev/null
+++ b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx
@@ -0,0 +1,30 @@
+import { Meta, StoryObj } from '@storybook/react';
+
+import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
+import { SettingsPath } from '@/types/SettingsPath';
+import {
+ PageDecorator,
+ PageDecoratorArgs,
+} from '~/testing/decorators/PageDecorator';
+import { graphqlMocks } from '~/testing/graphqlMocks';
+
+import { SettingsAccountsCalendars } from '../SettingsAccountsCalendars';
+
+const meta: Meta = {
+ title: 'Pages/Settings/Accounts/SettingsAccountsCalendars',
+ component: SettingsAccountsCalendars,
+ decorators: [PageDecorator],
+ args: {
+ routePath: getSettingsPagePath(SettingsPath.AccountsCalendars),
+ },
+ parameters: {
+ layout: 'fullscreen',
+ msw: graphqlMocks,
+ },
+};
+
+export default meta;
+
+export type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/packages/twenty-server/src/core/feature-flag/feature-flag.entity.ts b/packages/twenty-server/src/core/feature-flag/feature-flag.entity.ts
index f106028ba..ea3528000 100644
--- a/packages/twenty-server/src/core/feature-flag/feature-flag.entity.ts
+++ b/packages/twenty-server/src/core/feature-flag/feature-flag.entity.ts
@@ -14,10 +14,11 @@ import { IDField } from '@ptc-org/nestjs-query-graphql';
import { Workspace } from 'src/core/workspace/workspace.entity';
export enum FeatureFlagKeys {
- IsMessagingEnabled = 'IS_MESSAGING_ENABLED',
IsBlocklistEnabled = 'IS_BLOCKLIST_ENABLED',
- IsWorkspaceCleanable = 'IS_WORKSPACE_CLEANABLE',
+ IsCalendarEnabled = 'IS_CALENDAR_ENABLED',
+ IsMessagingEnabled = 'IS_MESSAGING_ENABLED',
IsNewRecordBoardEnabled = 'IS_NEW_RECORD_BOARD_ENABLED',
+ IsWorkspaceCleanable = 'IS_WORKSPACE_CLEANABLE',
}
@Entity({ name: 'featureFlag', schema: 'core' })
diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts
index 5d0a77fea..63e07708f 100644
--- a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts
+++ b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts
@@ -15,6 +15,11 @@ export const seedFeatureFlags = async (
.into(`${schemaName}.${tableName}`, ['key', 'workspaceId', 'value'])
.orIgnore()
.values([
+ {
+ key: FeatureFlagKeys.IsCalendarEnabled,
+ workspaceId: workspaceId,
+ value: true,
+ },
{
key: FeatureFlagKeys.IsMessagingEnabled,
workspaceId: workspaceId,