Files
twenty/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx
T
martmull b16ab1b7c9 1518 extensibility front add an application section in settings (#15056)
Protected by IS_APPLICATION_ENABLED featureFlag

Add `Application` section in settings

<img width="301" height="137" alt="image"
src="https://github.com/user-attachments/assets/ee53bdd2-36f6-45c6-8646-17b1e08abf00"
/>


A `settings/applications` route listing all installed applications

<img width="661" height="428" alt="image"
src="https://github.com/user-attachments/assets/69d534c4-4e9e-452a-a3d9-ded0223bb457"
/>

Introduce a new Tag for application managed items

<img width="885" height="759" alt="image"
src="https://github.com/user-attachments/assets/19767be5-61e5-4bd2-a51d-54ed9bfb1923"
/>



A `settings/applications/<application_id>` details setting page listing
all objects, serverlessFunctions and agents created by the application:

<img width="917" height="778" alt="image"
src="https://github.com/user-attachments/assets/7fc056a6-1d73-4242-b2eb-6f8955d8597d"
/>

A `settings/applications/<application_id>/<serverless_function_id>`

<img width="905" height="652" alt="image"
src="https://github.com/user-attachments/assets/56ca0021-26bf-42cb-9abf-34879f16050a"
/>

Add trigger tab in serverless function details (readonly for now)

<img width="899" height="724" alt="image"
src="https://github.com/user-attachments/assets/5eeefa35-f2a4-4fd8-a640-7b5c5891f226"
/>

Set object, serverless and agent setting detail pages readonly for
managed items
<img width="1075" height="859" alt="image"
src="https://github.com/user-attachments/assets/57c73d69-4980-47a2-b752-8dc5ab494530"
/>
<img width="648" height="582" alt="image"
src="https://github.com/user-attachments/assets/5ad5f3f7-3bc3-4e40-870a-4981c6492524"
/>
<img width="982" height="692" alt="image"
src="https://github.com/user-attachments/assets/7ad756c4-5d33-4a0a-9eb8-416c040362b9"
/>
<img width="1077" height="647" alt="image"
src="https://github.com/user-attachments/assets/e086b9f5-4062-4d10-82a9-4023de3cad3f"
/>
2025-10-15 17:13:29 +02:00

210 lines
5.7 KiB
TypeScript

import { SettingsPath } from 'twenty-shared/types';
import { useAuth } from '@/auth/hooks/useAuth';
import { currentUserState } from '@/auth/states/currentUserState';
import { billingState } from '@/client-config/states/billingState';
import { usePermissionFlagMap } from '@/settings/roles/hooks/usePermissionFlagMap';
import { type NavigationDrawerItemIndentationLevel } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { t } from '@lingui/core/macro';
import { useRecoilValue } from 'recoil';
import {
IconApi,
IconApps,
IconAt,
IconCalendarEvent,
IconColorSwatch,
type IconComponent,
IconCurrencyDollar,
IconDoorEnter,
IconHierarchy2,
IconKey,
IconLock,
IconMail,
IconRocket,
IconServer,
IconSettings,
IconSparkles,
IconPuzzle2,
IconUserCircle,
IconUsers,
IconWorld,
} from 'twenty-ui/display';
import { FeatureFlagKey, PermissionFlagType } from '~/generated/graphql';
export type SettingsNavigationSection = {
label: string;
items: SettingsNavigationItem[];
isAdvanced?: boolean;
};
export type SettingsNavigationItem = {
label: string;
path?: SettingsPath;
onClick?: () => void;
Icon: IconComponent;
indentationLevel?: NavigationDrawerItemIndentationLevel;
matchSubPages?: boolean;
isHidden?: boolean;
subItems?: SettingsNavigationItem[];
isAdvanced?: boolean;
soon?: boolean;
isNew?: boolean;
};
const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
const billing = useRecoilValue(billingState);
const { signOut } = useAuth();
const isBillingEnabled = billing?.isBillingEnabled ?? false;
const currentUser = useRecoilValue(currentUserState);
const isAdminEnabled =
(currentUser?.canImpersonate || currentUser?.canAccessFullAdminPanel) ??
false;
const isAIEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const isApplicationEnabled = useIsFeatureEnabled(
FeatureFlagKey.IS_APPLICATION_ENABLED,
);
const permissionMap = usePermissionFlagMap();
return [
{
label: t`User`,
items: [
{
label: t`Profile`,
path: SettingsPath.ProfilePage,
Icon: IconUserCircle,
},
{
label: t`Experience`,
path: SettingsPath.Experience,
Icon: IconColorSwatch,
},
{
label: t`Accounts`,
path: SettingsPath.Accounts,
Icon: IconAt,
subItems: [
{
label: t`Emails`,
path: SettingsPath.AccountsEmails,
Icon: IconMail,
indentationLevel: 2,
},
{
label: t`Calendars`,
path: SettingsPath.AccountsCalendars,
Icon: IconCalendarEvent,
indentationLevel: 2,
},
],
},
],
},
{
label: t`Workspace`,
items: [
{
label: t`General`,
path: SettingsPath.Workspace,
Icon: IconSettings,
isHidden: !permissionMap[PermissionFlagType.WORKSPACE],
},
{
label: t`Data model`,
path: SettingsPath.Objects,
Icon: IconHierarchy2,
isHidden: !permissionMap[PermissionFlagType.DATA_MODEL],
},
{
label: t`Members`,
path: SettingsPath.WorkspaceMembersPage,
Icon: IconUsers,
isHidden: !permissionMap[PermissionFlagType.WORKSPACE_MEMBERS],
},
{
label: t`Roles`,
path: SettingsPath.Roles,
Icon: IconLock,
isHidden: !permissionMap[PermissionFlagType.ROLES],
},
{
label: t`Domains`,
path: SettingsPath.Domains,
Icon: IconWorld,
isHidden: !permissionMap[PermissionFlagType.WORKSPACE],
},
{
label: t`Billing`,
path: SettingsPath.Billing,
Icon: IconCurrencyDollar,
isHidden:
!isBillingEnabled || !permissionMap[PermissionFlagType.WORKSPACE],
},
{
label: t`APIs & Webhooks`,
path: SettingsPath.ApiWebhooks,
Icon: IconApi,
isHidden: !permissionMap[PermissionFlagType.API_KEYS_AND_WEBHOOKS],
},
{
label: t`Integrations`,
path: SettingsPath.Integrations,
Icon: IconApps,
isHidden: !permissionMap[PermissionFlagType.API_KEYS_AND_WEBHOOKS],
},
{
label: t`Applications`,
path: SettingsPath.Applications,
Icon: IconPuzzle2,
isHidden:
!isApplicationEnabled ||
!permissionMap[PermissionFlagType.WORKSPACE],
isNew: true,
},
{
label: t`AI`,
path: SettingsPath.AI,
Icon: IconSparkles,
isHidden:
!isAIEnabled || !permissionMap[PermissionFlagType.WORKSPACE],
isNew: true,
},
{
label: t`Security`,
path: SettingsPath.Security,
Icon: IconKey,
isAdvanced: true,
isHidden: !permissionMap[PermissionFlagType.SECURITY],
},
],
},
{
label: t`Other`,
items: [
{
label: t`Admin Panel`,
path: SettingsPath.AdminPanel,
Icon: IconServer,
isHidden: !isAdminEnabled,
},
{
label: t`Releases`,
path: SettingsPath.Releases,
Icon: IconRocket,
isHidden: !permissionMap[PermissionFlagType.WORKSPACE],
},
{
label: t`Logout`,
onClick: signOut,
Icon: IconDoorEnter,
matchSubPages: false,
},
],
},
];
};
export { useSettingsNavigationItems };