mirror of
				https://github.com/lingble/twenty.git
				synced 2025-11-03 22:27:57 +00:00 
			
		
		
		
	New Settings Layout (#6867)
#### \ Description - **Added "Exit Settings" Back Button**: Introduced a new back button labeled "Exit Settings" for easy navigation back to the app content. - **Implemented Settings Navbar Breadcrumb**: A breadcrumb navigation bar for each settings page has been added to improve navigation within the settings. This ensures users can easily trace their location within the settings. - **Persistent CTA Zone**: The Call-to-Action (CTA) zone at the top of the page now remains visible even when the user scrolls down, preventing unresponsive behavior and improving accessibility. - **Page Title**: The page title has been added to each settings page and separated from the breadcrumb, following the app's layout standards. - we could not reproduce the Billing and CMR Migrations settings on the app, but we updated the files according, please let's us know if is there any way to log in with access to these pages, or if is everything ok. - Some breadcrumbs are not following the Figma, are following the current app sections isntead, because we would need to change the sidebar structure, and we should not do it on this PR ### Demo <https://www.loom.com/share/21b20a2cd2f3471e94d61563c9901b19?sid=9dc49456-6cae-48e1-9149-8d706f00ab65> ### Refs: #6144 Fixes #6144 --------- Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							fe4ca2133d
						
					
				
				
					commit
					c42ea57b97
				
			@@ -42,7 +42,7 @@ export const AppNavigationDrawer = ({
 | 
				
			|||||||
  const drawerProps: NavigationDrawerProps = isSettingsDrawer
 | 
					  const drawerProps: NavigationDrawerProps = isSettingsDrawer
 | 
				
			||||||
    ? {
 | 
					    ? {
 | 
				
			||||||
        isSubMenu: true,
 | 
					        isSubMenu: true,
 | 
				
			||||||
        title: 'Settings',
 | 
					        title: 'Exit Settings',
 | 
				
			||||||
        children: <SettingsNavigationDrawerItems />,
 | 
					        children: <SettingsNavigationDrawerItems />,
 | 
				
			||||||
        footer: <GithubVersionLink />,
 | 
					        footer: <GithubVersionLink />,
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,7 +96,7 @@ export const SettingsNavigationDrawerItems = () => {
 | 
				
			|||||||
          Icon={IconUserCircle}
 | 
					          Icon={IconUserCircle}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <SettingsNavigationDrawerItem
 | 
					        <SettingsNavigationDrawerItem
 | 
				
			||||||
          label="Appearance"
 | 
					          label="Experience"
 | 
				
			||||||
          path={SettingsPath.Appearance}
 | 
					          path={SettingsPath.Appearance}
 | 
				
			||||||
          Icon={IconColorSwatch}
 | 
					          Icon={IconColorSwatch}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ const StyledSettingsPageContainer = styled.div<{ width?: number }>`
 | 
				
			|||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  gap: ${({ theme }) => theme.spacing(8)};
 | 
					  gap: ${({ theme }) => theme.spacing(8)};
 | 
				
			||||||
  overflow: auto;
 | 
					  overflow: auto;
 | 
				
			||||||
  padding: ${({ theme }) => theme.spacing(8)};
 | 
					  padding: ${({ theme }) => theme.spacing(6, 8, 8)};
 | 
				
			||||||
  width: ${({ width }) => {
 | 
					  width: ${({ width }) => {
 | 
				
			||||||
    if (isDefined(width)) {
 | 
					    if (isDefined(width)) {
 | 
				
			||||||
      return width + 'px';
 | 
					      return width + 'px';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ export const SettingsReadDocumentationButton = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Button
 | 
					    <Button
 | 
				
			||||||
      title="Read documentation"
 | 
					      title="Read documentation"
 | 
				
			||||||
      variant="primary"
 | 
					      variant="secondary"
 | 
				
			||||||
      accent="default"
 | 
					      accent="default"
 | 
				
			||||||
      size="small"
 | 
					      size="small"
 | 
				
			||||||
      Icon={IconBook2}
 | 
					      Icon={IconBook2}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,7 +89,7 @@ type PageHeaderProps = {
 | 
				
			|||||||
  hasNextRecord?: boolean;
 | 
					  hasNextRecord?: boolean;
 | 
				
			||||||
  navigateToPreviousRecord?: () => void;
 | 
					  navigateToPreviousRecord?: () => void;
 | 
				
			||||||
  navigateToNextRecord?: () => void;
 | 
					  navigateToNextRecord?: () => void;
 | 
				
			||||||
  Icon: IconComponent;
 | 
					  Icon?: IconComponent;
 | 
				
			||||||
  children?: ReactNode;
 | 
					  children?: ReactNode;
 | 
				
			||||||
  width?: number;
 | 
					  width?: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ const StyledPanel = styled.div`
 | 
				
			|||||||
  overflow-x: auto;
 | 
					  overflow-x: auto;
 | 
				
			||||||
  overflow-y: hidden;
 | 
					  overflow-y: hidden;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  padding-bottom: ${({ theme }) => theme.spacing(10)};
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PagePanelProps = {
 | 
					type PagePanelProps = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,48 +2,52 @@ import styled from '@emotion/styled';
 | 
				
			|||||||
import { JSX, ReactNode } from 'react';
 | 
					import { JSX, ReactNode } from 'react';
 | 
				
			||||||
import { IconComponent } from 'twenty-ui';
 | 
					import { IconComponent } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper';
 | 
					import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper';
 | 
				
			||||||
import { OBJECT_SETTINGS_WIDTH } from '@/settings/data-model/constants/ObjectSettings';
 | 
					import {
 | 
				
			||||||
 | 
					  Breadcrumb,
 | 
				
			||||||
 | 
					  BreadcrumbProps,
 | 
				
			||||||
 | 
					} from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
				
			||||||
import { PageBody } from './PageBody';
 | 
					import { PageBody } from './PageBody';
 | 
				
			||||||
import { PageHeader } from './PageHeader';
 | 
					import { PageHeader } from './PageHeader';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SubMenuTopBarContainerProps = {
 | 
					type SubMenuTopBarContainerProps = {
 | 
				
			||||||
  children: JSX.Element | JSX.Element[];
 | 
					  children: JSX.Element | JSX.Element[];
 | 
				
			||||||
  title: string | ReactNode;
 | 
					  title?: string;
 | 
				
			||||||
  actionButton?: ReactNode;
 | 
					  actionButton?: ReactNode;
 | 
				
			||||||
  Icon: IconComponent;
 | 
					  Icon: IconComponent;
 | 
				
			||||||
  className?: string;
 | 
					  className?: string;
 | 
				
			||||||
 | 
					  links: BreadcrumbProps['links'];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledContainer = styled.div<{ isMobile: boolean }>`
 | 
					const StyledContainer = styled.div`
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  padding-top: ${({ theme, isMobile }) => (!isMobile ? theme.spacing(3) : 0)};
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const StyledTitle = styled.h3`
 | 
				
			||||||
 | 
					  color: ${({ theme }) => theme.font.color.primary};
 | 
				
			||||||
 | 
					  font-size: ${({ theme }) => theme.font.size.lg};
 | 
				
			||||||
 | 
					  font-weight: ${({ theme }) => theme.font.weight.semiBold};
 | 
				
			||||||
 | 
					  line-height: 1.2;
 | 
				
			||||||
 | 
					  margin: ${({ theme }) => theme.spacing(8, 8, 2)};
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SubMenuTopBarContainer = ({
 | 
					export const SubMenuTopBarContainer = ({
 | 
				
			||||||
  children,
 | 
					  children,
 | 
				
			||||||
  title,
 | 
					  title,
 | 
				
			||||||
  actionButton,
 | 
					  actionButton,
 | 
				
			||||||
  Icon,
 | 
					 | 
				
			||||||
  className,
 | 
					  className,
 | 
				
			||||||
 | 
					  links,
 | 
				
			||||||
}: SubMenuTopBarContainerProps) => {
 | 
					}: SubMenuTopBarContainerProps) => {
 | 
				
			||||||
  const isMobile = useIsMobile();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <StyledContainer isMobile={isMobile} className={className}>
 | 
					    <StyledContainer className={className}>
 | 
				
			||||||
      <PageHeader
 | 
					      <PageHeader title={<Breadcrumb links={links} />}>
 | 
				
			||||||
        title={title}
 | 
					 | 
				
			||||||
        Icon={Icon}
 | 
					 | 
				
			||||||
        width={OBJECT_SETTINGS_WIDTH + 4 * 8}
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        {actionButton}
 | 
					        {actionButton}
 | 
				
			||||||
      </PageHeader>
 | 
					      </PageHeader>
 | 
				
			||||||
      <PageBody>
 | 
					      <PageBody>
 | 
				
			||||||
        <InformationBannerWrapper />
 | 
					        <InformationBannerWrapper />
 | 
				
			||||||
 | 
					        {title && <StyledTitle>{title}</StyledTitle>}
 | 
				
			||||||
        {children}
 | 
					        {children}
 | 
				
			||||||
      </PageBody>
 | 
					      </PageBody>
 | 
				
			||||||
    </StyledContainer>
 | 
					    </StyledContainer>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,27 +1,22 @@
 | 
				
			|||||||
import styled from '@emotion/styled';
 | 
					import styled from '@emotion/styled';
 | 
				
			||||||
import { CSSProperties, Fragment, ReactNode } from 'react';
 | 
					import { Fragment, ReactNode } from 'react';
 | 
				
			||||||
import { Link } from 'react-router-dom';
 | 
					import { Link } from 'react-router-dom';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BreadcrumbProps = {
 | 
					export type BreadcrumbProps = {
 | 
				
			||||||
  className?: string;
 | 
					  className?: string;
 | 
				
			||||||
  links: {
 | 
					  links: { children: string | ReactNode; href?: string }[];
 | 
				
			||||||
    href?: string;
 | 
					 | 
				
			||||||
    styles?: CSSProperties;
 | 
					 | 
				
			||||||
    children?: string | ReactNode;
 | 
					 | 
				
			||||||
  }[];
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledWrapper = styled.nav`
 | 
					const StyledWrapper = styled.nav`
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  color: ${({ theme }) => theme.font.color.secondary};
 | 
					  color: ${({ theme }) => theme.font.color.tertiary};
 | 
				
			||||||
  display: flex;
 | 
					  display: grid;
 | 
				
			||||||
  font-size: ${({ theme }) => theme.font.size.md};
 | 
					  font-size: ${({ theme }) => theme.font.size.md};
 | 
				
			||||||
  // font-weight: ${({ theme }) => theme.font.weight.semiBold};
 | 
					  grid-auto-flow: column;
 | 
				
			||||||
  gap: ${({ theme }) => theme.spacing(2)};
 | 
					  grid-column-gap: ${({ theme }) => theme.spacing(1)};
 | 
				
			||||||
  line-height: ${({ theme }) => theme.text.lineHeight.lg};
 | 
					 | 
				
			||||||
  white-space: nowrap;
 | 
					 | 
				
			||||||
  max-width: 100%;
 | 
					  max-width: 100%;
 | 
				
			||||||
  min-width: 0;
 | 
					  min-width: 0;
 | 
				
			||||||
 | 
					  height: ${({ theme }) => theme.spacing(8)};
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledLink = styled(Link)`
 | 
					const StyledLink = styled(Link)`
 | 
				
			||||||
@@ -39,7 +34,10 @@ const StyledText = styled.span`
 | 
				
			|||||||
  white-space: nowrap;
 | 
					  white-space: nowrap;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: not sure that passing styles to the link is a good idea
 | 
					const StyledDivider = styled.span`
 | 
				
			||||||
 | 
					  width: ${({ theme }) => theme.spacing(2)};
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Breadcrumb = ({ className, links }: BreadcrumbProps) => {
 | 
					export const Breadcrumb = ({ className, links }: BreadcrumbProps) => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <StyledWrapper className={className}>
 | 
					    <StyledWrapper className={className}>
 | 
				
			||||||
@@ -49,15 +47,13 @@ export const Breadcrumb = ({ className, links }: BreadcrumbProps) => {
 | 
				
			|||||||
        return (
 | 
					        return (
 | 
				
			||||||
          <Fragment key={index}>
 | 
					          <Fragment key={index}>
 | 
				
			||||||
            {link.href ? (
 | 
					            {link.href ? (
 | 
				
			||||||
              <StyledLink style={link.styles} title={text} to={link.href}>
 | 
					              <StyledLink title={text} to={link.href}>
 | 
				
			||||||
                {link.children}
 | 
					                {link.children}
 | 
				
			||||||
              </StyledLink>
 | 
					              </StyledLink>
 | 
				
			||||||
            ) : (
 | 
					            ) : (
 | 
				
			||||||
              <StyledText style={link.styles} title={text}>
 | 
					              <StyledText title={text}>{link.children}</StyledText>
 | 
				
			||||||
                {link.children}
 | 
					 | 
				
			||||||
              </StyledText>
 | 
					 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
            {index < links.length - 1 && '/'}
 | 
					            {index < links.length - 1 && <StyledDivider>/</StyledDivider>}
 | 
				
			||||||
          </Fragment>
 | 
					          </Fragment>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      })}
 | 
					      })}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import { ReactNode, useState } from 'react';
 | 
					 | 
				
			||||||
import { css, useTheme } from '@emotion/react';
 | 
					import { css, useTheme } from '@emotion/react';
 | 
				
			||||||
import styled from '@emotion/styled';
 | 
					import styled from '@emotion/styled';
 | 
				
			||||||
import { motion } from 'framer-motion';
 | 
					import { motion } from 'framer-motion';
 | 
				
			||||||
 | 
					import { ReactNode, useState } from 'react';
 | 
				
			||||||
import { useRecoilValue } from 'recoil';
 | 
					import { useRecoilValue } from 'recoil';
 | 
				
			||||||
import { MOBILE_VIEWPORT } from 'twenty-ui';
 | 
					import { MOBILE_VIEWPORT } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,7 +32,7 @@ const StyledContainer = styled.div<{ isSubMenu?: boolean }>`
 | 
				
			|||||||
  box-sizing: border-box;
 | 
					  box-sizing: border-box;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  gap: ${({ theme }) => theme.spacing(3.5)};
 | 
					  gap: ${({ theme }) => theme.spacing(3)};
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
  min-width: ${DESKTOP_NAV_DRAWER_WIDTHS.menu}px;
 | 
					  min-width: ${DESKTOP_NAV_DRAWER_WIDTHS.menu}px;
 | 
				
			||||||
  padding: ${({ theme }) => theme.spacing(3, 2, 4)};
 | 
					  padding: ${({ theme }) => theme.spacing(3, 2, 4)};
 | 
				
			||||||
@@ -41,7 +41,6 @@ const StyledContainer = styled.div<{ isSubMenu?: boolean }>`
 | 
				
			|||||||
    isSubMenu
 | 
					    isSubMenu
 | 
				
			||||||
      ? css`
 | 
					      ? css`
 | 
				
			||||||
          padding-right: ${theme.spacing(8)};
 | 
					          padding-right: ${theme.spacing(8)};
 | 
				
			||||||
          padding-top: 41px;
 | 
					 | 
				
			||||||
        `
 | 
					        `
 | 
				
			||||||
      : ''}
 | 
					      : ''}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import { useTheme } from '@emotion/react';
 | 
					import { useTheme } from '@emotion/react';
 | 
				
			||||||
import styled from '@emotion/styled';
 | 
					import styled from '@emotion/styled';
 | 
				
			||||||
import { useRecoilValue } from 'recoil';
 | 
					import { useRecoilValue } from 'recoil';
 | 
				
			||||||
import { IconChevronLeft } from 'twenty-ui';
 | 
					import { IconX } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
 | 
					import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
 | 
				
			||||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
 | 
					import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
 | 
				
			||||||
@@ -18,17 +18,22 @@ const StyledIconAndButtonContainer = styled.button`
 | 
				
			|||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: row;
 | 
					  flex-direction: row;
 | 
				
			||||||
  font-size: ${({ theme }) => theme.font.size.lg};
 | 
					  font-weight: ${({ theme }) => theme.font.weight.medium};
 | 
				
			||||||
  font-weight: ${({ theme }) => theme.font.weight.semiBold};
 | 
					 | 
				
			||||||
  gap: ${({ theme }) => theme.spacing(2)};
 | 
					  gap: ${({ theme }) => theme.spacing(2)};
 | 
				
			||||||
  line-height: ${({ theme }) => theme.text.lineHeight.md};
 | 
					  padding: ${({ theme }) => theme.spacing(1.5, 1)};
 | 
				
			||||||
  padding: ${({ theme }) => theme.spacing(1)};
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  font-family: ${({ theme }) => theme.font.family};
 | 
				
			||||||
 | 
					  &:hover {
 | 
				
			||||||
 | 
					    background: ${({ theme }) => theme.background.transparent.light};
 | 
				
			||||||
 | 
					    border-radius: ${({ theme }) => theme.border.radius.sm};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledContainer = styled.div`
 | 
					const StyledContainer = styled.div`
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: row;
 | 
					  flex-direction: row;
 | 
				
			||||||
 | 
					  height: ${({ theme }) => theme.spacing(8)};
 | 
				
			||||||
  justify-content: space-between;
 | 
					  justify-content: space-between;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,9 +47,10 @@ export const NavigationDrawerBackButton = ({
 | 
				
			|||||||
    <StyledContainer>
 | 
					    <StyledContainer>
 | 
				
			||||||
      <UndecoratedLink to={navigationMemorizedUrl} replace>
 | 
					      <UndecoratedLink to={navigationMemorizedUrl} replace>
 | 
				
			||||||
        <StyledIconAndButtonContainer>
 | 
					        <StyledIconAndButtonContainer>
 | 
				
			||||||
          <IconChevronLeft
 | 
					          <IconX
 | 
				
			||||||
            size={theme.icon.size.md}
 | 
					            size={theme.icon.size.md}
 | 
				
			||||||
            stroke={theme.icon.stroke.lg}
 | 
					            stroke={theme.icon.stroke.lg}
 | 
				
			||||||
 | 
					            color={theme.font.color.tertiary}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
          <span>{title}</span>
 | 
					          <span>{title}</span>
 | 
				
			||||||
        </StyledIconAndButtonContainer>
 | 
					        </StyledIconAndButtonContainer>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,18 +3,16 @@ import React, { useEffect, useState } from 'react';
 | 
				
			|||||||
import rehypeStringify from 'rehype-stringify';
 | 
					import rehypeStringify from 'rehype-stringify';
 | 
				
			||||||
import remarkParse from 'remark-parse';
 | 
					import remarkParse from 'remark-parse';
 | 
				
			||||||
import remarkRehype from 'remark-rehype';
 | 
					import remarkRehype from 'remark-rehype';
 | 
				
			||||||
import { H1Title, IconRocket } from 'twenty-ui';
 | 
					import { IconRocket } from 'twenty-ui';
 | 
				
			||||||
import { unified } from 'unified';
 | 
					import { unified } from 'unified';
 | 
				
			||||||
import { visit } from 'unist-util-visit';
 | 
					import { visit } from 'unist-util-visit';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
 | 
					import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledH1Title = styled(H1Title)`
 | 
					 | 
				
			||||||
  margin-bottom: 0;
 | 
					 | 
				
			||||||
`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ReleaseNote = {
 | 
					type ReleaseNote = {
 | 
				
			||||||
  slug: string;
 | 
					  slug: string;
 | 
				
			||||||
  date: string;
 | 
					  date: string;
 | 
				
			||||||
@@ -108,9 +106,20 @@ export const Releases = () => {
 | 
				
			|||||||
  }, []);
 | 
					  }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer Icon={IconRocket} title="Releases">
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					      Icon={IconRocket}
 | 
				
			||||||
 | 
					      title="Releases"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Others',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Releases),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Releases',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <StyledH1Title title="Releases" />
 | 
					 | 
				
			||||||
        <ScrollWrapper contextProviderName="releases">
 | 
					        <ScrollWrapper contextProviderName="releases">
 | 
				
			||||||
          <StyledReleaseContainer>
 | 
					          <StyledReleaseContainer>
 | 
				
			||||||
            {releases.map((release) => (
 | 
					            {releases.map((release) => (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,9 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
 | 
				
			|||||||
import { SettingsBillingCoverImage } from '@/billing/components/SettingsBillingCoverImage';
 | 
					import { SettingsBillingCoverImage } from '@/billing/components/SettingsBillingCoverImage';
 | 
				
			||||||
import { useOnboardingStatus } from '@/onboarding/hooks/useOnboardingStatus';
 | 
					import { useOnboardingStatus } from '@/onboarding/hooks/useOnboardingStatus';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
import { AppPath } from '@/types/AppPath';
 | 
					import { AppPath } from '@/types/AppPath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { Info } from '@/ui/display/info/components/Info';
 | 
					import { Info } from '@/ui/display/info/components/Info';
 | 
				
			||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
 | 
					import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
 | 
				
			||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
					import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
				
			||||||
@@ -140,7 +142,17 @@ export const SettingsBilling = () => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer Icon={IconCurrencyDollar} title="Billing">
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					      Icon={IconCurrencyDollar}
 | 
				
			||||||
 | 
					      title="Billing"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Billing' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <StyledH1Title title="Billing" />
 | 
					        <StyledH1Title title="Billing" />
 | 
				
			||||||
        <SettingsBillingCoverImage />
 | 
					        <SettingsBillingCoverImage />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,11 +6,23 @@ import { DeleteAccount } from '@/settings/profile/components/DeleteAccount';
 | 
				
			|||||||
import { EmailField } from '@/settings/profile/components/EmailField';
 | 
					import { EmailField } from '@/settings/profile/components/EmailField';
 | 
				
			||||||
import { NameFields } from '@/settings/profile/components/NameFields';
 | 
					import { NameFields } from '@/settings/profile/components/NameFields';
 | 
				
			||||||
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
 | 
					import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsProfile = () => (
 | 
					export const SettingsProfile = () => (
 | 
				
			||||||
  <SubMenuTopBarContainer Icon={IconUserCircle} title="Profile">
 | 
					  <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					    Icon={IconUserCircle}
 | 
				
			||||||
 | 
					    title="Profile"
 | 
				
			||||||
 | 
					    links={[
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        children: 'User',
 | 
				
			||||||
 | 
					        href: getSettingsPagePath(SettingsPath.ProfilePage),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      { children: 'Profile' },
 | 
				
			||||||
 | 
					    ]}
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
    <SettingsPageContainer>
 | 
					    <SettingsPageContainer>
 | 
				
			||||||
      <Section>
 | 
					      <Section>
 | 
				
			||||||
        <H2Title title="Picture" />
 | 
					        <H2Title title="Picture" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,14 +2,26 @@ import { H2Title, IconSettings } from 'twenty-ui';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { DeleteWorkspace } from '@/settings/profile/components/DeleteWorkspace';
 | 
					import { DeleteWorkspace } from '@/settings/profile/components/DeleteWorkspace';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
import { NameField } from '@/settings/workspace/components/NameField';
 | 
					import { NameField } from '@/settings/workspace/components/NameField';
 | 
				
			||||||
import { ToggleImpersonate } from '@/settings/workspace/components/ToggleImpersonate';
 | 
					import { ToggleImpersonate } from '@/settings/workspace/components/ToggleImpersonate';
 | 
				
			||||||
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
 | 
					import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsWorkspace = () => (
 | 
					export const SettingsWorkspace = () => (
 | 
				
			||||||
  <SubMenuTopBarContainer Icon={IconSettings} title="General">
 | 
					  <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					    Icon={IconSettings}
 | 
				
			||||||
 | 
					    title="General"
 | 
				
			||||||
 | 
					    links={[
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        children: 'Workspace',
 | 
				
			||||||
 | 
					        href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      { children: 'General' },
 | 
				
			||||||
 | 
					    ]}
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
    <SettingsPageContainer>
 | 
					    <SettingsPageContainer>
 | 
				
			||||||
      <Section>
 | 
					      <Section>
 | 
				
			||||||
        <H2Title title="Picture" />
 | 
					        <H2Title title="Picture" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,8 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
 | 
				
			|||||||
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
 | 
					import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
 | 
				
			||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
 | 
					import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { IconButton } from '@/ui/input/button/components/IconButton';
 | 
					import { IconButton } from '@/ui/input/button/components/IconButton';
 | 
				
			||||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
 | 
					import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
@@ -46,7 +48,17 @@ export const SettingsWorkspaceMembers = () => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer Icon={IconUsers} title="Members">
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					      Icon={IconUsers}
 | 
				
			||||||
 | 
					      title="Members"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Members' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <Section>
 | 
					        <Section>
 | 
				
			||||||
          <H2Title
 | 
					          <H2Title
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ export const Default: Story = {
 | 
				
			|||||||
  play: async ({ canvasElement }) => {
 | 
					  play: async ({ canvasElement }) => {
 | 
				
			||||||
    const canvas = within(canvasElement);
 | 
					    const canvas = within(canvasElement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await canvas.findByText('Theme', undefined, {
 | 
					    await canvas.findByText('Appearance', undefined, {
 | 
				
			||||||
      timeout: 3000,
 | 
					      timeout: 3000,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,8 @@ import { SettingsAccountsBlocklistSection } from '@/settings/accounts/components
 | 
				
			|||||||
import { SettingsAccountsConnectedAccountsListCard } from '@/settings/accounts/components/SettingsAccountsConnectedAccountsListCard';
 | 
					import { SettingsAccountsConnectedAccountsListCard } from '@/settings/accounts/components/SettingsAccountsConnectedAccountsListCard';
 | 
				
			||||||
import { SettingsAccountsSettingsSection } from '@/settings/accounts/components/SettingsAccountsSettingsSection';
 | 
					import { SettingsAccountsSettingsSection } from '@/settings/accounts/components/SettingsAccountsSettingsSection';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,7 +35,17 @@ export const SettingsAccounts = () => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer Icon={IconAt} title="Account">
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					      Icon={IconAt}
 | 
				
			||||||
 | 
					      title="Account"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'User',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.ProfilePage),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Account' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        {loading ? (
 | 
					        {loading ? (
 | 
				
			||||||
          <SettingsAccountLoader />
 | 
					          <SettingsAccountLoader />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,24 +4,24 @@ import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			|||||||
import { SettingsPath } from '@/types/SettingsPath';
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { IconCalendarEvent } from 'twenty-ui';
 | 
					import { IconCalendarEvent } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsAccountsCalendars = () => {
 | 
					export const SettingsAccountsCalendars = () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconCalendarEvent}
 | 
					      Icon={IconCalendarEvent}
 | 
				
			||||||
      title={
 | 
					      title="Calendars"
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'User',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.ProfilePage),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          children: 'Accounts',
 | 
					          children: 'Accounts',
 | 
				
			||||||
          href: getSettingsPagePath(SettingsPath.Accounts),
 | 
					          href: getSettingsPagePath(SettingsPath.Accounts),
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        { children: 'Calendars' },
 | 
					        { children: 'Calendars' },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <Section>
 | 
					        <Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +1,26 @@
 | 
				
			|||||||
import { SettingsAccountsMessageChannelsContainer } from '@/settings/accounts/components/SettingsAccountsMessageChannelsContainer';
 | 
					import { SettingsAccountsMessageChannelsContainer } from '@/settings/accounts/components/SettingsAccountsMessageChannelsContainer';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { IconMail } from 'twenty-ui';
 | 
					import { IconMail } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsAccountsEmails = () => (
 | 
					export const SettingsAccountsEmails = () => (
 | 
				
			||||||
  <SubMenuTopBarContainer
 | 
					  <SubMenuTopBarContainer
 | 
				
			||||||
    Icon={IconMail}
 | 
					    Icon={IconMail}
 | 
				
			||||||
    title={
 | 
					    title="Emails"
 | 
				
			||||||
      <Breadcrumb
 | 
					 | 
				
			||||||
    links={[
 | 
					    links={[
 | 
				
			||||||
          { children: 'Accounts', href: '/settings/accounts' },
 | 
					      {
 | 
				
			||||||
 | 
					        children: 'User',
 | 
				
			||||||
 | 
					        href: getSettingsPagePath(SettingsPath.ProfilePage),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        children: 'Accounts',
 | 
				
			||||||
 | 
					        href: getSettingsPagePath(SettingsPath.Accounts),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      { children: 'Emails' },
 | 
					      { children: 'Emails' },
 | 
				
			||||||
    ]}
 | 
					    ]}
 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <SettingsPageContainer>
 | 
					    <SettingsPageContainer>
 | 
				
			||||||
      <Section>
 | 
					      <Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +1,26 @@
 | 
				
			|||||||
import { SettingsNewAccountSection } from '@/settings/accounts/components/SettingsNewAccountSection';
 | 
					import { SettingsNewAccountSection } from '@/settings/accounts/components/SettingsNewAccountSection';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { IconAt } from 'twenty-ui';
 | 
					import { IconAt } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsNewAccount = () => {
 | 
					export const SettingsNewAccount = () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconAt}
 | 
					      Icon={IconAt}
 | 
				
			||||||
      title={
 | 
					      title="New Account"
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
            { children: 'Accounts', href: '/settings/accounts' },
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'User',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.ProfilePage),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Accounts',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Accounts),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        { children: `New` },
 | 
					        { children: `New` },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <SettingsNewAccountSection />
 | 
					        <SettingsNewAccountSection />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,9 +6,10 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
 | 
				
			|||||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
 | 
					import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { SettingsReadDocumentationButton } from '@/settings/developers/components/SettingsReadDocumentationButton';
 | 
					import { SettingsReadDocumentationButton } from '@/settings/developers/components/SettingsReadDocumentationButton';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { useRecoilValue } from 'recoil';
 | 
					import { useRecoilValue } from 'recoil';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const REVERT_PUBLIC_KEY = 'pk_live_a87fee8c-28c7-494f-99a3-996ff89f9918';
 | 
					const REVERT_PUBLIC_KEY = 'pk_live_a87fee8c-28c7-494f-99a3-996ff89f9918';
 | 
				
			||||||
@@ -18,7 +19,14 @@ export const SettingsCRMMigration = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconSettings}
 | 
					      Icon={IconSettings}
 | 
				
			||||||
      title={<Breadcrumb links={[{ children: 'Migrate' }]} />}
 | 
					      title="Migrate"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Migrate' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
      actionButton={<SettingsReadDocumentationButton />}
 | 
					      actionButton={<SettingsReadDocumentationButton />}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@ import { z } from 'zod';
 | 
				
			|||||||
import { useCreateOneObjectMetadataItem } from '@/object-metadata/hooks/useCreateOneObjectMetadataItem';
 | 
					import { useCreateOneObjectMetadataItem } from '@/object-metadata/hooks/useCreateOneObjectMetadataItem';
 | 
				
			||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
 | 
					import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
 | 
				
			||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
					import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
				
			||||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
 | 
					 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  SettingsDataModelObjectAboutForm,
 | 
					  SettingsDataModelObjectAboutForm,
 | 
				
			||||||
@@ -20,7 +19,6 @@ import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/Snac
 | 
				
			|||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
					import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const newObjectFormSchema = settingsDataModelObjectAboutFormSchema;
 | 
					const newObjectFormSchema = settingsDataModelObjectAboutFormSchema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,17 +70,18 @@ export const SettingsNewObject = () => {
 | 
				
			|||||||
    <FormProvider {...formConfig}>
 | 
					    <FormProvider {...formConfig}>
 | 
				
			||||||
      <SubMenuTopBarContainer
 | 
					      <SubMenuTopBarContainer
 | 
				
			||||||
        Icon={IconHierarchy2}
 | 
					        Icon={IconHierarchy2}
 | 
				
			||||||
        title={
 | 
					        title="New Object"
 | 
				
			||||||
          <Breadcrumb
 | 
					 | 
				
			||||||
        links={[
 | 
					        links={[
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            children: 'Workspace',
 | 
				
			||||||
 | 
					            href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            children: 'Objects',
 | 
					            children: 'Objects',
 | 
				
			||||||
            href: settingsObjectsPagePath,
 | 
					            href: settingsObjectsPagePath,
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          { children: 'New' },
 | 
					          { children: 'New' },
 | 
				
			||||||
        ]}
 | 
					        ]}
 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        actionButton={
 | 
					        actionButton={
 | 
				
			||||||
          <SaveAndCancelButtons
 | 
					          <SaveAndCancelButtons
 | 
				
			||||||
            isSaveDisabled={!canSave}
 | 
					            isSaveDisabled={!canSave}
 | 
				
			||||||
@@ -93,7 +92,6 @@ export const SettingsNewObject = () => {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <SettingsPageContainer>
 | 
					        <SettingsPageContainer>
 | 
				
			||||||
          <SettingsHeaderContainer></SettingsHeaderContainer>
 | 
					 | 
				
			||||||
          <Section>
 | 
					          <Section>
 | 
				
			||||||
            <H2Title
 | 
					            <H2Title
 | 
				
			||||||
              title="About"
 | 
					              title="About"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@ import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			|||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
 | 
					import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
 | 
				
			||||||
import styled from '@emotion/styled';
 | 
					import styled from '@emotion/styled';
 | 
				
			||||||
import { isNonEmptyArray } from '@sniptt/guards';
 | 
					import { isNonEmptyArray } from '@sniptt/guards';
 | 
				
			||||||
@@ -49,14 +48,15 @@ export const SettingsObjectDetailPageContent = ({
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconHierarchy2}
 | 
					      Icon={IconHierarchy2}
 | 
				
			||||||
      title={
 | 
					      title={objectMetadataItem.labelPlural}
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        { children: 'Objects', href: '/settings/objects' },
 | 
					        { children: 'Objects', href: '/settings/objects' },
 | 
				
			||||||
        { children: objectMetadataItem.labelPlural },
 | 
					        { children: objectMetadataItem.labelPlural },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <Section>
 | 
					        <Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,6 @@ import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdat
 | 
				
			|||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
 | 
					import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
 | 
				
			||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
 | 
					import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
 | 
				
			||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
					import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
				
			||||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
 | 
					 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  SettingsDataModelObjectAboutForm,
 | 
					  SettingsDataModelObjectAboutForm,
 | 
				
			||||||
@@ -30,7 +29,6 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
				
			|||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const objectEditFormSchema = z
 | 
					const objectEditFormSchema = z
 | 
				
			||||||
  .object({})
 | 
					  .object({})
 | 
				
			||||||
@@ -110,9 +108,12 @@ export const SettingsObjectEdit = () => {
 | 
				
			|||||||
      <FormProvider {...formConfig}>
 | 
					      <FormProvider {...formConfig}>
 | 
				
			||||||
        <SubMenuTopBarContainer
 | 
					        <SubMenuTopBarContainer
 | 
				
			||||||
          Icon={IconHierarchy2}
 | 
					          Icon={IconHierarchy2}
 | 
				
			||||||
          title={
 | 
					          title="Edit"
 | 
				
			||||||
            <Breadcrumb
 | 
					 | 
				
			||||||
          links={[
 | 
					          links={[
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              children: 'Workspace',
 | 
				
			||||||
 | 
					              href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              children: 'Objects',
 | 
					              children: 'Objects',
 | 
				
			||||||
              href: settingsObjectsPagePath,
 | 
					              href: settingsObjectsPagePath,
 | 
				
			||||||
@@ -121,14 +122,10 @@ export const SettingsObjectEdit = () => {
 | 
				
			|||||||
              children: activeObjectMetadataItem.labelPlural,
 | 
					              children: activeObjectMetadataItem.labelPlural,
 | 
				
			||||||
              href: `${settingsObjectsPagePath}/${objectSlug}`,
 | 
					              href: `${settingsObjectsPagePath}/${objectSlug}`,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
                { children: 'Edit' },
 | 
					            { children: 'Edit Object' },
 | 
				
			||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
            />
 | 
					          actionButton={
 | 
				
			||||||
          }
 | 
					            activeObjectMetadataItem.isCustom && (
 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <SettingsPageContainer>
 | 
					 | 
				
			||||||
            <SettingsHeaderContainer>
 | 
					 | 
				
			||||||
              {activeObjectMetadataItem.isCustom && (
 | 
					 | 
				
			||||||
              <SaveAndCancelButtons
 | 
					              <SaveAndCancelButtons
 | 
				
			||||||
                isSaveDisabled={!canSave}
 | 
					                isSaveDisabled={!canSave}
 | 
				
			||||||
                isCancelDisabled={isSubmitting}
 | 
					                isCancelDisabled={isSubmitting}
 | 
				
			||||||
@@ -137,8 +134,10 @@ export const SettingsObjectEdit = () => {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                onSave={formConfig.handleSubmit(handleSave)}
 | 
					                onSave={formConfig.handleSubmit(handleSave)}
 | 
				
			||||||
              />
 | 
					              />
 | 
				
			||||||
              )}
 | 
					            )
 | 
				
			||||||
            </SettingsHeaderContainer>
 | 
					          }
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <SettingsPageContainer>
 | 
				
			||||||
            <Section>
 | 
					            <Section>
 | 
				
			||||||
              <H2Title
 | 
					              <H2Title
 | 
				
			||||||
                title="About"
 | 
					                title="About"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,13 +26,14 @@ import { SettingsDataModelFieldIconLabelForm } from '@/settings/data-model/field
 | 
				
			|||||||
import { SettingsDataModelFieldSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard';
 | 
					import { SettingsDataModelFieldSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard';
 | 
				
			||||||
import { settingsFieldFormSchema } from '@/settings/data-model/fields/forms/validation-schemas/settingsFieldFormSchema';
 | 
					import { settingsFieldFormSchema } from '@/settings/data-model/fields/forms/validation-schemas/settingsFieldFormSchema';
 | 
				
			||||||
import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
 | 
					import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
import { AppPath } from '@/types/AppPath';
 | 
					import { AppPath } from '@/types/AppPath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
 | 
					import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
 | 
				
			||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
					import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
				
			||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
 | 
					import { FieldMetadataType } from '~/generated-metadata/graphql';
 | 
				
			||||||
import { isDefined } from '~/utils/isDefined';
 | 
					import { isDefined } from '~/utils/isDefined';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -173,23 +174,24 @@ export const SettingsObjectFieldEdit = () => {
 | 
				
			|||||||
      <FormProvider {...formConfig}>
 | 
					      <FormProvider {...formConfig}>
 | 
				
			||||||
        <SubMenuTopBarContainer
 | 
					        <SubMenuTopBarContainer
 | 
				
			||||||
          Icon={IconHierarchy2}
 | 
					          Icon={IconHierarchy2}
 | 
				
			||||||
          title={
 | 
					          title={activeMetadataField?.label}
 | 
				
			||||||
            <Breadcrumb
 | 
					 | 
				
			||||||
          links={[
 | 
					          links={[
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              children: 'Workspace',
 | 
				
			||||||
 | 
					              href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              children: 'Objects',
 | 
					              children: 'Objects',
 | 
				
			||||||
              href: '/settings/objects',
 | 
					              href: '/settings/objects',
 | 
				
			||||||
                  styles: { minWidth: 'max-content' },
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              children: activeObjectMetadataItem.labelPlural,
 | 
					              children: activeObjectMetadataItem.labelPlural,
 | 
				
			||||||
              href: `/settings/objects/${objectSlug}`,
 | 
					              href: `/settings/objects/${objectSlug}`,
 | 
				
			||||||
                  styles: { maxWidth: '60%' },
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
                { children: activeMetadataField.label },
 | 
					            {
 | 
				
			||||||
 | 
					              children: activeMetadataField.label,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          actionButton={
 | 
					          actionButton={
 | 
				
			||||||
            shouldDisplaySaveAndCancel && (
 | 
					            shouldDisplaySaveAndCancel && (
 | 
				
			||||||
              <SaveAndCancelButtons
 | 
					              <SaveAndCancelButtons
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,11 +9,12 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
 | 
					import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
 | 
				
			||||||
import { settingsObjectFieldsFamilyState } from '@/settings/data-model/object-details/states/settingsObjectFieldsFamilyState';
 | 
					import { settingsObjectFieldsFamilyState } from '@/settings/data-model/object-details/states/settingsObjectFieldsFamilyState';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
import { AppPath } from '@/types/AppPath';
 | 
					import { AppPath } from '@/types/AppPath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { useRecoilState } from 'recoil';
 | 
					import { useRecoilState } from 'recoil';
 | 
				
			||||||
import { SettingsObjectFieldTable } from '~/pages/settings/data-model/SettingsObjectFieldTable';
 | 
					import { SettingsObjectFieldTable } from '~/pages/settings/data-model/SettingsObjectFieldTable';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -86,9 +87,11 @@ export const SettingsObjectNewFieldStep1 = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconHierarchy2}
 | 
					      Icon={IconHierarchy2}
 | 
				
			||||||
      title={
 | 
					 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        { children: 'Objects', href: '/settings/objects' },
 | 
					        { children: 'Objects', href: '/settings/objects' },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          children: activeObjectMetadataItem.labelPlural,
 | 
					          children: activeObjectMetadataItem.labelPlural,
 | 
				
			||||||
@@ -96,8 +99,6 @@ export const SettingsObjectNewFieldStep1 = () => {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        { children: 'New Field' },
 | 
					        { children: 'New Field' },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      actionButton={
 | 
					      actionButton={
 | 
				
			||||||
        !activeObjectMetadataItem.isRemote && (
 | 
					        !activeObjectMetadataItem.isRemote && (
 | 
				
			||||||
          <SaveAndCancelButtons
 | 
					          <SaveAndCancelButtons
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,6 @@ import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/Snac
 | 
				
			|||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
					import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { View } from '@/views/types/View';
 | 
					import { View } from '@/views/types/View';
 | 
				
			||||||
import { ViewType } from '@/views/types/ViewType';
 | 
					import { ViewType } from '@/views/types/ViewType';
 | 
				
			||||||
import { useApolloClient } from '@apollo/client';
 | 
					import { useApolloClient } from '@apollo/client';
 | 
				
			||||||
@@ -41,6 +40,7 @@ type SettingsDataModelNewFieldFormValues = z.infer<
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const StyledH1Title = styled(H1Title)`
 | 
					const StyledH1Title = styled(H1Title)`
 | 
				
			||||||
  margin-bottom: 0;
 | 
					  margin-bottom: 0;
 | 
				
			||||||
 | 
					  padding-top: ${({ theme }) => theme.spacing(3)};
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
export const SettingsObjectNewFieldStep2 = () => {
 | 
					export const SettingsObjectNewFieldStep2 = () => {
 | 
				
			||||||
  const navigate = useNavigate();
 | 
					  const navigate = useNavigate();
 | 
				
			||||||
@@ -177,18 +177,14 @@ export const SettingsObjectNewFieldStep2 = () => {
 | 
				
			|||||||
      >
 | 
					      >
 | 
				
			||||||
        <SubMenuTopBarContainer
 | 
					        <SubMenuTopBarContainer
 | 
				
			||||||
          Icon={IconHierarchy2}
 | 
					          Icon={IconHierarchy2}
 | 
				
			||||||
          title={
 | 
					 | 
				
			||||||
            <Breadcrumb
 | 
					 | 
				
			||||||
          links={[
 | 
					          links={[
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              children: 'Objects',
 | 
					              children: 'Objects',
 | 
				
			||||||
              href: '/settings/objects',
 | 
					              href: '/settings/objects',
 | 
				
			||||||
                  styles: { minWidth: 'max-content' },
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              children: activeObjectMetadataItem.labelPlural,
 | 
					              children: activeObjectMetadataItem.labelPlural,
 | 
				
			||||||
              href: `/settings/objects/${objectSlug}`,
 | 
					              href: `/settings/objects/${objectSlug}`,
 | 
				
			||||||
                  styles: { maxWidth: '50%' },
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              children: (
 | 
					              children: (
 | 
				
			||||||
@@ -199,8 +195,6 @@ export const SettingsObjectNewFieldStep2 = () => {
 | 
				
			|||||||
              ),
 | 
					              ),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          actionButton={
 | 
					          actionButton={
 | 
				
			||||||
            !activeObjectMetadataItem.isRemote && (
 | 
					            !activeObjectMetadataItem.isRemote && (
 | 
				
			||||||
              <SaveAndCancelButtons
 | 
					              <SaveAndCancelButtons
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,24 +1,25 @@
 | 
				
			|||||||
import { ReactFlowProvider } from 'reactflow';
 | 
					import { ReactFlowProvider } from 'reactflow';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SettingsDataModelOverview } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverview';
 | 
					import { SettingsDataModelOverview } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverview';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { IconHierarchy2 } from 'twenty-ui';
 | 
					import { IconHierarchy2 } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsObjectOverview = () => {
 | 
					export const SettingsObjectOverview = () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconHierarchy2}
 | 
					      Icon={IconHierarchy2}
 | 
				
			||||||
      title={
 | 
					 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
            { children: 'Data model', href: '/settings/objects' },
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Objects', href: '/settings/objects' },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          children: 'Overview',
 | 
					          children: 'Overview',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <ReactFlowProvider>
 | 
					      <ReactFlowProvider>
 | 
				
			||||||
        <SettingsDataModelOverview />
 | 
					        <SettingsDataModelOverview />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -145,6 +145,15 @@ export const SettingsObjects = () => {
 | 
				
			|||||||
          />
 | 
					          />
 | 
				
			||||||
        </UndecoratedLink>
 | 
					        </UndecoratedLink>
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Objects',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <>
 | 
					        <>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,6 @@ export type Story = StoryObj<typeof SettingsObjectNewFieldStep1>;
 | 
				
			|||||||
export const Default: Story = {
 | 
					export const Default: Story = {
 | 
				
			||||||
  play: async ({ canvasElement }) => {
 | 
					  play: async ({ canvasElement }) => {
 | 
				
			||||||
    const canvas = within(canvasElement);
 | 
					    const canvas = within(canvasElement);
 | 
				
			||||||
    await canvas.findByText('Settings');
 | 
					 | 
				
			||||||
    await canvas.findByText('Objects');
 | 
					    await canvas.findByText('Objects');
 | 
				
			||||||
    await canvas.findByText('Companies');
 | 
					    await canvas.findByText('Companies');
 | 
				
			||||||
    await canvas.findByText('Check deactivated fields');
 | 
					    await canvas.findByText('Check deactivated fields');
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,8 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain
 | 
				
			|||||||
import { SettingsApiKeysTable } from '@/settings/developers/components/SettingsApiKeysTable';
 | 
					import { SettingsApiKeysTable } from '@/settings/developers/components/SettingsApiKeysTable';
 | 
				
			||||||
import { SettingsReadDocumentationButton } from '@/settings/developers/components/SettingsReadDocumentationButton';
 | 
					import { SettingsReadDocumentationButton } from '@/settings/developers/components/SettingsReadDocumentationButton';
 | 
				
			||||||
import { SettingsWebhooksTable } from '@/settings/developers/components/SettingsWebhooksTable';
 | 
					import { SettingsWebhooksTable } from '@/settings/developers/components/SettingsWebhooksTable';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
@@ -21,6 +23,13 @@ export const SettingsDevelopers = () => {
 | 
				
			|||||||
      Icon={IconCode}
 | 
					      Icon={IconCode}
 | 
				
			||||||
      title="Developers"
 | 
					      title="Developers"
 | 
				
			||||||
      actionButton={<SettingsReadDocumentationButton />}
 | 
					      actionButton={<SettingsReadDocumentationButton />}
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Developers' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <Section>
 | 
					        <Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,8 +25,7 @@ export type Story = StoryObj<typeof SettingsDevelopersApiKeysNew>;
 | 
				
			|||||||
export const Default: Story = {
 | 
					export const Default: Story = {
 | 
				
			||||||
  play: async ({ canvasElement }) => {
 | 
					  play: async ({ canvasElement }) => {
 | 
				
			||||||
    const canvas = within(canvasElement);
 | 
					    const canvas = within(canvasElement);
 | 
				
			||||||
    await canvas.findByText('Settings');
 | 
					    await canvas.findByText('New Key');
 | 
				
			||||||
    await canvas.findByText('New API Key');
 | 
					 | 
				
			||||||
    await canvas.findByText('Name');
 | 
					    await canvas.findByText('Name');
 | 
				
			||||||
    await canvas.findByText('Expiration Date');
 | 
					    await canvas.findByText('Expiration Date');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,12 +17,13 @@ import { apiKeyTokenState } from '@/settings/developers/states/generatedApiKeyTo
 | 
				
			|||||||
import { ApiKey } from '@/settings/developers/types/api-key/ApiKey';
 | 
					import { ApiKey } from '@/settings/developers/types/api-key/ApiKey';
 | 
				
			||||||
import { computeNewExpirationDate } from '@/settings/developers/utils/compute-new-expiration-date';
 | 
					import { computeNewExpirationDate } from '@/settings/developers/utils/compute-new-expiration-date';
 | 
				
			||||||
import { formatExpiration } from '@/settings/developers/utils/format-expiration';
 | 
					import { formatExpiration } from '@/settings/developers/utils/format-expiration';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { TextInput } from '@/ui/input/components/TextInput';
 | 
					import { TextInput } from '@/ui/input/components/TextInput';
 | 
				
			||||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
 | 
					import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
 | 
					import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledInfo = styled.span`
 | 
					const StyledInfo = styled.span`
 | 
				
			||||||
@@ -65,6 +66,7 @@ export const SettingsDevelopersApiKeyDetail = () => {
 | 
				
			|||||||
      setApiKeyName(record.name);
 | 
					      setApiKeyName(record.name);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					  const developerPath = getSettingsPagePath(SettingsPath.Developers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const deleteIntegration = async (redirect = true) => {
 | 
					  const deleteIntegration = async (redirect = true) => {
 | 
				
			||||||
    await updateApiKey?.({
 | 
					    await updateApiKey?.({
 | 
				
			||||||
@@ -72,7 +74,7 @@ export const SettingsDevelopersApiKeyDetail = () => {
 | 
				
			|||||||
      updateOneRecordInput: { revokedAt: DateTime.now().toString() },
 | 
					      updateOneRecordInput: { revokedAt: DateTime.now().toString() },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    if (redirect) {
 | 
					    if (redirect) {
 | 
				
			||||||
      navigate('/settings/developers');
 | 
					      navigate(developerPath);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -122,14 +124,15 @@ export const SettingsDevelopersApiKeyDetail = () => {
 | 
				
			|||||||
      {apiKeyData?.name && (
 | 
					      {apiKeyData?.name && (
 | 
				
			||||||
        <SubMenuTopBarContainer
 | 
					        <SubMenuTopBarContainer
 | 
				
			||||||
          Icon={IconCode}
 | 
					          Icon={IconCode}
 | 
				
			||||||
          title={
 | 
					          title={apiKeyData?.name}
 | 
				
			||||||
            <Breadcrumb
 | 
					 | 
				
			||||||
          links={[
 | 
					          links={[
 | 
				
			||||||
                { children: 'Developers', href: '/settings/developers' },
 | 
					            {
 | 
				
			||||||
 | 
					              children: 'Workspace',
 | 
				
			||||||
 | 
					              href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            { children: 'Developers', href: developerPath },
 | 
				
			||||||
            { children: `${apiKeyName} API Key` },
 | 
					            { children: `${apiKeyName} API Key` },
 | 
				
			||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <SettingsPageContainer>
 | 
					          <SettingsPageContainer>
 | 
				
			||||||
            <Section>
 | 
					            <Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,11 +10,12 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain
 | 
				
			|||||||
import { EXPIRATION_DATES } from '@/settings/developers/constants/ExpirationDates';
 | 
					import { EXPIRATION_DATES } from '@/settings/developers/constants/ExpirationDates';
 | 
				
			||||||
import { apiKeyTokenState } from '@/settings/developers/states/generatedApiKeyTokenState';
 | 
					import { apiKeyTokenState } from '@/settings/developers/states/generatedApiKeyTokenState';
 | 
				
			||||||
import { ApiKey } from '@/settings/developers/types/api-key/ApiKey';
 | 
					import { ApiKey } from '@/settings/developers/types/api-key/ApiKey';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { Select } from '@/ui/input/components/Select';
 | 
					import { Select } from '@/ui/input/components/Select';
 | 
				
			||||||
import { TextInput } from '@/ui/input/components/TextInput';
 | 
					import { TextInput } from '@/ui/input/components/TextInput';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { useSetRecoilState } from 'recoil';
 | 
					import { useSetRecoilState } from 'recoil';
 | 
				
			||||||
import { Key } from 'ts-key-enum';
 | 
					import { Key } from 'ts-key-enum';
 | 
				
			||||||
import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
 | 
					import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
 | 
				
			||||||
@@ -65,14 +66,18 @@ export const SettingsDevelopersApiKeysNew = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconCode}
 | 
					      Icon={IconCode}
 | 
				
			||||||
      title={
 | 
					      title="New key"
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
            { children: 'Developers', href: '/settings/developers' },
 | 
					        {
 | 
				
			||||||
            { children: 'New API Key' },
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Developers',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Developers),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'New Key' },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      actionButton={
 | 
					      actionButton={
 | 
				
			||||||
        <SaveAndCancelButtons
 | 
					        <SaveAndCancelButtons
 | 
				
			||||||
          isSaveDisabled={!canSave}
 | 
					          isSaveDisabled={!canSave}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,8 @@ import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
 | 
				
			|||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
					import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { Webhook } from '@/settings/developers/types/webhook/Webhook';
 | 
					import { Webhook } from '@/settings/developers/types/webhook/Webhook';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { Select } from '@/ui/input/components/Select';
 | 
					import { Select } from '@/ui/input/components/Select';
 | 
				
			||||||
import { TextArea } from '@/ui/input/components/TextArea';
 | 
					import { TextArea } from '@/ui/input/components/TextArea';
 | 
				
			||||||
@@ -18,7 +20,6 @@ import { TextInput } from '@/ui/input/components/TextInput';
 | 
				
			|||||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
 | 
					import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledFilterRow = styled.div`
 | 
					const StyledFilterRow = styled.div`
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
@@ -55,9 +56,11 @@ export const SettingsDevelopersWebhooksDetail = () => {
 | 
				
			|||||||
    objectNameSingular: CoreObjectNameSingular.Webhook,
 | 
					    objectNameSingular: CoreObjectNameSingular.Webhook,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const developerPath = getSettingsPagePath(SettingsPath.Developers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const deleteWebhook = () => {
 | 
					  const deleteWebhook = () => {
 | 
				
			||||||
    deleteOneWebhook(webhookId);
 | 
					    deleteOneWebhook(webhookId);
 | 
				
			||||||
    navigate('/settings/developers');
 | 
					    navigate(developerPath);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const fieldTypeOptions = [
 | 
					  const fieldTypeOptions = [
 | 
				
			||||||
@@ -81,7 +84,7 @@ export const SettingsDevelopersWebhooksDetail = () => {
 | 
				
			|||||||
        description: description,
 | 
					        description: description,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    navigate('/settings/developers');
 | 
					    navigate(developerPath);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -89,19 +92,23 @@ export const SettingsDevelopersWebhooksDetail = () => {
 | 
				
			|||||||
      {webhookData?.targetUrl && (
 | 
					      {webhookData?.targetUrl && (
 | 
				
			||||||
        <SubMenuTopBarContainer
 | 
					        <SubMenuTopBarContainer
 | 
				
			||||||
          Icon={IconCode}
 | 
					          Icon={IconCode}
 | 
				
			||||||
          title={
 | 
					          title={webhookData.targetUrl}
 | 
				
			||||||
            <Breadcrumb
 | 
					 | 
				
			||||||
          links={[
 | 
					          links={[
 | 
				
			||||||
                { children: 'Developers', href: '/settings/developers' },
 | 
					            {
 | 
				
			||||||
 | 
					              children: 'Workspace',
 | 
				
			||||||
 | 
					              href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              children: 'Developers',
 | 
				
			||||||
 | 
					              href: developerPath,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            { children: 'Webhook' },
 | 
					            { children: 'Webhook' },
 | 
				
			||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          actionButton={
 | 
					          actionButton={
 | 
				
			||||||
            <SaveAndCancelButtons
 | 
					            <SaveAndCancelButtons
 | 
				
			||||||
              isSaveDisabled={!isDirty}
 | 
					              isSaveDisabled={!isDirty}
 | 
				
			||||||
              onCancel={() => {
 | 
					              onCancel={() => {
 | 
				
			||||||
                navigate('/settings/developers');
 | 
					                navigate(developerPath);
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
              onSave={handleSave}
 | 
					              onSave={handleSave}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,10 +7,11 @@ import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
 | 
				
			|||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
					import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { Webhook } from '@/settings/developers/types/webhook/Webhook';
 | 
					import { Webhook } from '@/settings/developers/types/webhook/Webhook';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { TextInput } from '@/ui/input/components/TextInput';
 | 
					import { TextInput } from '@/ui/input/components/TextInput';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { isValidUrl } from '~/utils/url/isValidUrl';
 | 
					import { isValidUrl } from '~/utils/url/isValidUrl';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsDevelopersWebhooksNew = () => {
 | 
					export const SettingsDevelopersWebhooksNew = () => {
 | 
				
			||||||
@@ -49,19 +50,23 @@ export const SettingsDevelopersWebhooksNew = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconCode}
 | 
					      Icon={IconCode}
 | 
				
			||||||
      title={
 | 
					      title="New Webhook"
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
            { children: 'Developers', href: '/settings/developers' },
 | 
					        {
 | 
				
			||||||
            { children: 'New webhook' },
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Developers',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Developers),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'New Webhook' },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      actionButton={
 | 
					      actionButton={
 | 
				
			||||||
        <SaveAndCancelButtons
 | 
					        <SaveAndCancelButtons
 | 
				
			||||||
          isSaveDisabled={!canSave}
 | 
					          isSaveDisabled={!canSave}
 | 
				
			||||||
          onCancel={() => {
 | 
					          onCancel={() => {
 | 
				
			||||||
            navigate('/settings/developers');
 | 
					            navigate(getSettingsPagePath(SettingsPath.Developers));
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
          onSave={handleSave}
 | 
					          onSave={handleSave}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,6 @@ import { AppPath } from '@/types/AppPath';
 | 
				
			|||||||
import { SettingsPath } from '@/types/SettingsPath';
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsIntegrationDatabase = () => {
 | 
					export const SettingsIntegrationDatabase = () => {
 | 
				
			||||||
  const { databaseKey = '' } = useParams();
 | 
					  const { databaseKey = '' } = useParams();
 | 
				
			||||||
@@ -44,17 +43,18 @@ export const SettingsIntegrationDatabase = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconSettings}
 | 
					      Icon={IconSettings}
 | 
				
			||||||
      title={
 | 
					      title={integration.text}
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          children: 'Integrations',
 | 
					          children: 'Integrations',
 | 
				
			||||||
          href: getSettingsPagePath(SettingsPath.Integrations),
 | 
					          href: getSettingsPagePath(SettingsPath.Integrations),
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        { children: integration.text },
 | 
					        { children: integration.text },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <SettingsIntegrationPreview
 | 
					        <SettingsIntegrationPreview
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,21 +2,26 @@ import { IconSettings } from 'twenty-ui';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { SettingsIntegrationEditDatabaseConnectionContainer } from '@/settings/integrations/database-connection/components/SettingsIntegrationEditDatabaseConnectionContainer';
 | 
					import { SettingsIntegrationEditDatabaseConnectionContainer } from '@/settings/integrations/database-connection/components/SettingsIntegrationEditDatabaseConnectionContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsIntegrationEditDatabaseConnection = () => {
 | 
					export const SettingsIntegrationEditDatabaseConnection = () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconSettings}
 | 
					      Icon={IconSettings}
 | 
				
			||||||
      title={
 | 
					      title="Edit connection"
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
            // TODO
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Integrations',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Integrations),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        { children: 'Edit connection' },
 | 
					        { children: 'Edit connection' },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <SettingsIntegrationEditDatabaseConnectionContainer />
 | 
					        <SettingsIntegrationEditDatabaseConnectionContainer />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@ import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/Snac
 | 
				
			|||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
					import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { CreateRemoteServerInput } from '~/generated-metadata/graphql';
 | 
					import { CreateRemoteServerInput } from '~/generated-metadata/graphql';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const createRemoteServerInputPostgresSchema =
 | 
					const createRemoteServerInputPostgresSchema =
 | 
				
			||||||
@@ -133,9 +132,12 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconSettings}
 | 
					      Icon={IconSettings}
 | 
				
			||||||
      title={
 | 
					      title="New"
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          children: 'Integrations',
 | 
					          children: 'Integrations',
 | 
				
			||||||
          href: settingsIntegrationsPagePath,
 | 
					          href: settingsIntegrationsPagePath,
 | 
				
			||||||
@@ -146,8 +148,6 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        { children: 'New' },
 | 
					        { children: 'New' },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      actionButton={
 | 
					      actionButton={
 | 
				
			||||||
        <SaveAndCancelButtons
 | 
					        <SaveAndCancelButtons
 | 
				
			||||||
          isSaveDisabled={!canSave}
 | 
					          isSaveDisabled={!canSave}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,27 @@ import { IconSettings } from 'twenty-ui';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { SettingsIntegrationDatabaseConnectionShowContainer } from '@/settings/integrations/database-connection/components/SettingsIntegrationDatabaseConnectionShowContainer';
 | 
					import { SettingsIntegrationDatabaseConnectionShowContainer } from '@/settings/integrations/database-connection/components/SettingsIntegrationDatabaseConnectionShowContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SettingsIntegrationShowDatabaseConnection = () => {
 | 
					export const SettingsIntegrationShowDatabaseConnection = () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer Icon={IconSettings} title="Settings">
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					      Icon={IconSettings}
 | 
				
			||||||
 | 
					      title="Database Connection"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Integrations',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Integrations),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Database Connection' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <SettingsIntegrationDatabaseConnectionShowContainer />
 | 
					        <SettingsIntegrationDatabaseConnectionShowContainer />
 | 
				
			||||||
      </SettingsPageContainer>
 | 
					      </SettingsPageContainer>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { SettingsIntegrationGroup } from '@/settings/integrations/components/SettingsIntegrationGroup';
 | 
					import { SettingsIntegrationGroup } from '@/settings/integrations/components/SettingsIntegrationGroup';
 | 
				
			||||||
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
 | 
					import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { IconApps } from 'twenty-ui';
 | 
					import { IconApps } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -8,7 +10,17 @@ export const SettingsIntegrations = () => {
 | 
				
			|||||||
  const integrationCategories = useSettingsIntegrationCategories();
 | 
					  const integrationCategories = useSettingsIntegrationCategories();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer Icon={IconApps} title="Integrations">
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					      Icon={IconApps}
 | 
				
			||||||
 | 
					      title="Integrations"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Integrations' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        {integrationCategories.map((group) => (
 | 
					        {integrationCategories.map((group) => (
 | 
				
			||||||
          <SettingsIntegrationGroup key={group.key} integrationGroup={group} />
 | 
					          <SettingsIntegrationGroup key={group.key} integrationGroup={group} />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
import { H2Title, IconColorSwatch } from 'twenty-ui';
 | 
					import { H2Title, IconColorSwatch } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { ColorSchemePicker } from '@/ui/input/color-scheme/components/ColorSchemePicker';
 | 
					import { ColorSchemePicker } from '@/ui/input/color-scheme/components/ColorSchemePicker';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
@@ -11,10 +13,20 @@ export const SettingsAppearance = () => {
 | 
				
			|||||||
  const { colorScheme, setColorScheme } = useColorScheme();
 | 
					  const { colorScheme, setColorScheme } = useColorScheme();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer Icon={IconColorSwatch} title="Appearance">
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
 | 
					      Icon={IconColorSwatch}
 | 
				
			||||||
 | 
					      title="Experience"
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'User',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.ProfilePage),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { children: 'Experience' },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <Section>
 | 
					        <Section>
 | 
				
			||||||
          <H2Title title="Theme" />
 | 
					          <H2Title title="Appearance" />
 | 
				
			||||||
          <ColorSchemePicker value={colorScheme} onChange={setColorScheme} />
 | 
					          <ColorSchemePicker value={colorScheme} onChange={setColorScheme} />
 | 
				
			||||||
        </Section>
 | 
					        </Section>
 | 
				
			||||||
        <Section>
 | 
					        <Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,25 +4,26 @@ import { SettingsServerlessFunctionSettingsTab } from '@/settings/serverless-fun
 | 
				
			|||||||
import { SettingsServerlessFunctionTestTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab';
 | 
					import { SettingsServerlessFunctionTestTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab';
 | 
				
			||||||
import { SettingsServerlessFunctionTestTabEffect } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTabEffect';
 | 
					import { SettingsServerlessFunctionTestTabEffect } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTabEffect';
 | 
				
			||||||
import { useExecuteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useExecuteOneServerlessFunction';
 | 
					import { useExecuteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useExecuteOneServerlessFunction';
 | 
				
			||||||
 | 
					import { useGetOneServerlessFunctionSourceCode } from '@/settings/serverless-functions/hooks/useGetOneServerlessFunctionSourceCode';
 | 
				
			||||||
 | 
					import { usePublishOneServerlessFunction } from '@/settings/serverless-functions/hooks/usePublishOneServerlessFunction';
 | 
				
			||||||
import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
 | 
					import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
 | 
				
			||||||
import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
 | 
					import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
 | 
				
			||||||
import { usePublishOneServerlessFunction } from '@/settings/serverless-functions/hooks/usePublishOneServerlessFunction';
 | 
					 | 
				
			||||||
import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
 | 
					import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
 | 
				
			||||||
import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
 | 
					import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
 | 
				
			||||||
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
 | 
					import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
 | 
					import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
 | 
				
			||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
					import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { TabList } from '@/ui/layout/tab/components/TabList';
 | 
					import { TabList } from '@/ui/layout/tab/components/TabList';
 | 
				
			||||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
 | 
					import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					import { useState } from 'react';
 | 
				
			||||||
import { useParams } from 'react-router-dom';
 | 
					import { useParams } from 'react-router-dom';
 | 
				
			||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
 | 
					import { useRecoilValue, useSetRecoilState } from 'recoil';
 | 
				
			||||||
import { IconCode, IconFunction, IconSettings, IconTestPipe } from 'twenty-ui';
 | 
					import { IconCode, IconFunction, IconSettings, IconTestPipe } from 'twenty-ui';
 | 
				
			||||||
import { isDefined } from '~/utils/isDefined';
 | 
					 | 
				
			||||||
import { useGetOneServerlessFunctionSourceCode } from '@/settings/serverless-functions/hooks/useGetOneServerlessFunctionSourceCode';
 | 
					 | 
				
			||||||
import { useState } from 'react';
 | 
					 | 
				
			||||||
import { usePreventOverlapCallback } from '~/hooks/usePreventOverlapCallback';
 | 
					import { usePreventOverlapCallback } from '~/hooks/usePreventOverlapCallback';
 | 
				
			||||||
 | 
					import { isDefined } from '~/utils/isDefined';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TAB_LIST_COMPONENT_ID = 'serverless-function-detail';
 | 
					const TAB_LIST_COMPONENT_ID = 'serverless-function-detail';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -204,14 +205,18 @@ export const SettingsServerlessFunctionDetail = () => {
 | 
				
			|||||||
    !loading && (
 | 
					    !loading && (
 | 
				
			||||||
      <SubMenuTopBarContainer
 | 
					      <SubMenuTopBarContainer
 | 
				
			||||||
        Icon={IconFunction}
 | 
					        Icon={IconFunction}
 | 
				
			||||||
        title={
 | 
					        title={formValues.name}
 | 
				
			||||||
          <Breadcrumb
 | 
					 | 
				
			||||||
        links={[
 | 
					        links={[
 | 
				
			||||||
              { children: 'Functions', href: '/settings/functions' },
 | 
					          {
 | 
				
			||||||
 | 
					            children: 'Workspace',
 | 
				
			||||||
 | 
					            href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            children: 'Functions',
 | 
				
			||||||
 | 
					            href: getSettingsPagePath(SettingsPath.ServerlessFunctions),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          { children: `${formValues.name}` },
 | 
					          { children: `${formValues.name}` },
 | 
				
			||||||
        ]}
 | 
					        ]}
 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <SettingsPageContainer>
 | 
					        <SettingsPageContainer>
 | 
				
			||||||
          <Section>
 | 
					          <Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
 | 
					 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { SettingsServerlessFunctionsTable } from '@/settings/serverless-functions/components/SettingsServerlessFunctionsTable';
 | 
					import { SettingsServerlessFunctionsTable } from '@/settings/serverless-functions/components/SettingsServerlessFunctionsTable';
 | 
				
			||||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
					import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
 | 
				
			||||||
@@ -6,7 +5,6 @@ import { SettingsPath } from '@/types/SettingsPath';
 | 
				
			|||||||
import { Button } from '@/ui/input/button/components/Button';
 | 
					import { Button } from '@/ui/input/button/components/Button';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Section } from '@/ui/layout/section/components/Section';
 | 
					import { Section } from '@/ui/layout/section/components/Section';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
 | 
					import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
 | 
				
			||||||
import { IconFunction, IconPlus } from 'twenty-ui';
 | 
					import { IconFunction, IconPlus } from 'twenty-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,11 +25,17 @@ export const SettingsServerlessFunctions = () => {
 | 
				
			|||||||
          />
 | 
					          />
 | 
				
			||||||
        </UndecoratedLink>
 | 
					        </UndecoratedLink>
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      links={[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Functions',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SettingsPageContainer>
 | 
					      <SettingsPageContainer>
 | 
				
			||||||
        <SettingsHeaderContainer>
 | 
					 | 
				
			||||||
          <Breadcrumb links={[{ children: 'Functions' }]} />
 | 
					 | 
				
			||||||
        </SettingsHeaderContainer>
 | 
					 | 
				
			||||||
        <Section>
 | 
					        <Section>
 | 
				
			||||||
          <SettingsServerlessFunctionsTable />
 | 
					          <SettingsServerlessFunctionsTable />
 | 
				
			||||||
        </Section>
 | 
					        </Section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
					import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
 | 
				
			||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
					import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
 | 
				
			||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
					import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
 | 
				
			||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
 | 
					 | 
				
			||||||
import { useNavigate } from 'react-router-dom';
 | 
					import { useNavigate } from 'react-router-dom';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SettingsServerlessFunctionNewForm } from '@/settings/serverless-functions/components/SettingsServerlessFunctionNewForm';
 | 
					import { SettingsServerlessFunctionNewForm } from '@/settings/serverless-functions/components/SettingsServerlessFunctionNewForm';
 | 
				
			||||||
@@ -81,14 +80,18 @@ export const SettingsServerlessFunctionsNew = () => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SubMenuTopBarContainer
 | 
					    <SubMenuTopBarContainer
 | 
				
			||||||
      Icon={IconFunction}
 | 
					      Icon={IconFunction}
 | 
				
			||||||
      title={
 | 
					      title="New Function"
 | 
				
			||||||
        <Breadcrumb
 | 
					 | 
				
			||||||
      links={[
 | 
					      links={[
 | 
				
			||||||
            { children: 'Functions', href: '/settings/functions' },
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Workspace',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.Workspace),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          children: 'Functions',
 | 
				
			||||||
 | 
					          href: getSettingsPagePath(SettingsPath.ServerlessFunctions),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        { children: 'New' },
 | 
					        { children: 'New' },
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      actionButton={
 | 
					      actionButton={
 | 
				
			||||||
        <SaveAndCancelButtons
 | 
					        <SaveAndCancelButtons
 | 
				
			||||||
          isSaveDisabled={!canSave}
 | 
					          isSaveDisabled={!canSave}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user