5899 display a banner to alert users which need to reconnect their account (#6301)

Closes #5899

<img width="1280" alt="Index - banner"
src="https://github.com/twentyhq/twenty/assets/71827178/313cf20d-eb34-496a-8c7c-7589fbd55954">

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
bosiraphael
2024-07-27 18:34:52 +02:00
committed by GitHub
parent d0db3b765f
commit 6728e40256
48 changed files with 910 additions and 147 deletions

View File

@ -20,6 +20,8 @@ export type Scalars = {
DateTime: { input: any; output: any; }
/** The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */
JSON: { input: any; output: any; }
/** The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */
JSONObject: { input: any; output: any; }
/** A UUID scalar type */
UUID: { input: any; output: any; }
/** The `Upload` scalar type represents a file upload. */
@ -381,6 +383,13 @@ export type LinkMetadata = {
url: Scalars['String']['output'];
};
export type LinksMetadata = {
__typename?: 'LinksMetadata';
primaryLinkLabel: Scalars['String']['output'];
primaryLinkUrl: Scalars['String']['output'];
secondaryLinks?: Maybe<Array<LinkMetadata>>;
};
export type LoginToken = {
__typename?: 'LoginToken';
loginToken: AuthToken;
@ -1025,7 +1034,7 @@ export type Telemetry = {
export type TimelineCalendarEvent = {
__typename?: 'TimelineCalendarEvent';
conferenceLink: LinkMetadata;
conferenceLink: LinksMetadata;
conferenceSolution: Scalars['String']['output'];
description: Scalars['String']['output'];
endsAt: Scalars['DateTime']['output'];
@ -1186,12 +1195,9 @@ export type User = {
lastName: Scalars['String']['output'];
onboardingStatus?: Maybe<OnboardingStatus>;
passwordHash?: Maybe<Scalars['String']['output']>;
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
passwordResetToken?: Maybe<Scalars['String']['output']>;
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
passwordResetTokenExpiresAt?: Maybe<Scalars['DateTime']['output']>;
supportUserHash?: Maybe<Scalars['String']['output']>;
updatedAt: Scalars['DateTime']['output'];
userVars: Scalars['JSONObject']['output'];
workspaceMember?: Maybe<WorkspaceMember>;
workspaces: Array<UserWorkspace>;
};
@ -1412,6 +1418,7 @@ export type ServerlessFunction = {
createdAt: Scalars['DateTime']['output'];
id: Scalars['UUID']['output'];
name: Scalars['String']['output'];
sourceCodeHash: Scalars['String']['output'];
syncStatus: ServerlessFunctionSyncStatus;
updatedAt: Scalars['DateTime']['output'];
};

View File

@ -16,6 +16,7 @@ export type Scalars = {
ConnectionCursor: any;
DateTime: string;
JSON: any;
JSONObject: any;
UUID: any;
Upload: any;
};
@ -280,6 +281,13 @@ export type LinkMetadata = {
url: Scalars['String'];
};
export type LinksMetadata = {
__typename?: 'LinksMetadata';
primaryLinkLabel: Scalars['String'];
primaryLinkUrl: Scalars['String'];
secondaryLinks?: Maybe<Array<LinkMetadata>>;
};
export type LoginToken = {
__typename?: 'LoginToken';
loginToken: AuthToken;
@ -752,7 +760,7 @@ export type Telemetry = {
export type TimelineCalendarEvent = {
__typename?: 'TimelineCalendarEvent';
conferenceLink: LinkMetadata;
conferenceLink: LinksMetadata;
conferenceSolution: Scalars['String'];
description: Scalars['String'];
endsAt: Scalars['DateTime'];
@ -884,12 +892,9 @@ export type User = {
lastName: Scalars['String'];
onboardingStatus?: Maybe<OnboardingStatus>;
passwordHash?: Maybe<Scalars['String']>;
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
passwordResetToken?: Maybe<Scalars['String']>;
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
passwordResetTokenExpiresAt?: Maybe<Scalars['DateTime']>;
supportUserHash?: Maybe<Scalars['String']>;
updatedAt: Scalars['DateTime'];
userVars: Scalars['JSONObject'];
workspaceMember?: Maybe<WorkspaceMember>;
workspaces: Array<UserWorkspace>;
};
@ -1090,6 +1095,7 @@ export type ServerlessFunction = {
createdAt: Scalars['DateTime'];
id: Scalars['UUID'];
name: Scalars['String'];
sourceCodeHash: Scalars['String'];
syncStatus: ServerlessFunctionSyncStatus;
updatedAt: Scalars['DateTime'];
};
@ -1228,7 +1234,7 @@ export type ImpersonateMutationVariables = Exact<{
}>;
export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type RenewTokenMutationVariables = Exact<{
appToken: Scalars['String'];
@ -1260,7 +1266,7 @@ export type VerifyMutationVariables = Exact<{
}>;
export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type CheckUserExistsQueryVariables = Exact<{
email: Scalars['String'];
@ -1321,7 +1327,7 @@ export type GetAisqlQueryQueryVariables = Exact<{
export type GetAisqlQueryQuery = { __typename?: 'Query', getAISQLQuery: { __typename?: 'AISQLQueryResult', sqlQuery: string, sqlQueryResult?: string | null, queryFailedErrorMessage?: string | null } };
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> };
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> };
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
@ -1338,7 +1344,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> } };
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> } };
export type AddUserToWorkspaceMutationVariables = Exact<{
inviteHash: Scalars['String'];
@ -1523,6 +1529,7 @@ export const UserQueryFragmentFragmentDoc = gql`
domainName
}
}
userVars
}
`;
export const GetTimelineCalendarEventsFromCompanyIdDocument = gql`

View File

@ -4,8 +4,8 @@ import { CalendarChannelVisibility } from '~/generated/graphql';
// TODO: use backend CalendarEvent type when ready
export type CalendarEvent = {
conferenceLink?: {
label: string;
url: string;
primaryLinkLabel: string;
primaryLinkUrl: string;
};
description?: string;
endsAt?: string;

View File

@ -4,7 +4,12 @@ import { User } from '~/generated/graphql';
export type CurrentUser = Pick<
User,
'id' | 'email' | 'supportUserHash' | 'canImpersonate' | 'onboardingStatus'
| 'id'
| 'email'
| 'supportUserHash'
| 'canImpersonate'
| 'onboardingStatus'
| 'userVars'
>;
export const currentUserState = createState<CurrentUser | null>({

View File

@ -0,0 +1,26 @@
import { currentUserState } from '@/auth/states/currentUserState';
import { InformationBannerAccountToReconnect } from '@/information-banner/InformationBannerReconnectAccount';
import { useRecoilValue } from 'recoil';
export enum InformationBannerKeys {
ACCOUNTS_TO_RECONNECT = 'ACCOUNTS_TO_RECONNECT',
}
export const InformationBanner = () => {
const currentUser = useRecoilValue(currentUserState);
const userVars = currentUser?.userVars;
const firstAccountIdToReconnect =
userVars?.[InformationBannerKeys.ACCOUNTS_TO_RECONNECT]?.[0];
return (
<>
{firstAccountIdToReconnect && (
<InformationBannerAccountToReconnect
accountIdToReconnect={firstAccountIdToReconnect}
/>
)}
</>
);
};

View File

@ -0,0 +1,38 @@
import { ConnectedAccount } from '@/accounts/types/ConnectedAccount';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useTriggerGoogleApisOAuth } from '@/settings/accounts/hooks/useTriggerGoogleApisOAuth';
import { Button } from '@/ui/input/button/components/Button';
import { Banner, IconRefresh } from 'twenty-ui';
export const InformationBannerAccountToReconnect = ({
accountIdToReconnect,
}: {
accountIdToReconnect: string;
}) => {
const accountToReconnect = useFindOneRecord<ConnectedAccount>({
objectNameSingular: CoreObjectNameSingular.ConnectedAccount,
objectRecordId: accountIdToReconnect,
});
const { triggerGoogleApisOAuth } = useTriggerGoogleApisOAuth();
if (!accountToReconnect?.record) {
return null;
}
return (
<Banner>
Sync lost with mailbox {accountToReconnect?.record?.handle}. Please
reconnect for updates:
<Button
variant="secondary"
title="Reconnect"
Icon={IconRefresh}
size="small"
inverted
onClick={() => triggerGoogleApisOAuth()}
/>
</Banner>
);
};

View File

@ -1,6 +1,7 @@
import styled from '@emotion/styled';
import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil';
import { InformationBanner } from '@/information-banner/InformationBanner';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
@ -125,6 +126,7 @@ export const RecordIndexContainer = ({
return (
<StyledContainer>
<InformationBanner />
<RecordFieldValueSelectorContextProvider>
<SpreadsheetImportProvider>
<StyledContainerWithPadding>

View File

@ -51,8 +51,8 @@ export const SettingsAccountsCalendarChannelsGeneral = () => {
startsAt: exampleStartDate.toISOString(),
conferenceSolution: '',
conferenceLink: {
label: '',
url: '',
primaryLinkLabel: '',
primaryLinkUrl: '',
},
description: '',
isCanceled: false,

View File

@ -1,22 +0,0 @@
import styled from '@emotion/styled';
const StyledBanner = styled.div`
align-items: center;
backdrop-filter: blur(5px);
background: ${({ theme }) => theme.color.blue};
display: flex;
gap: ${({ theme }) => theme.spacing(3)};
height: 40px;
justify-content: center;
padding: ${({ theme }) => theme.spacing(2) + ' ' + theme.spacing(3)};
width: 100%;
color: ${({ theme }) => theme.font.color.inverted};
font-family: Inter;
font-size: ${({ theme }) => theme.font.size.md};
font-style: normal;
font-weight: ${({ theme }) => theme.font.weight.medium};
line-height: 150%;
box-sizing: border-box;
`;
export { StyledBanner as Banner };

View File

@ -1,34 +0,0 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator, IconRefresh } from 'twenty-ui';
import { Button } from '@/ui/input/button/components/Button';
import { Banner } from '../Banner';
const meta: Meta<typeof Banner> = {
title: 'UI/Layout/Banner/Banner',
component: Banner,
decorators: [ComponentDecorator],
render: (args) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<Banner {...args}>
Sync lost with mailbox hello@twenty.com. Please reconnect for updates:
<Button
variant="secondary"
title="Reconnect"
Icon={IconRefresh}
size="small"
inverted
/>
</Banner>
),
argTypes: {
as: { control: false },
theme: { control: false },
},
};
export default meta;
type Story = StoryObj<typeof Banner>;
export const Default: Story = {};

View File

@ -1,9 +1,10 @@
import { JSX } from 'react';
import styled from '@emotion/styled';
import { JSX } from 'react';
import { IconComponent } from 'twenty-ui';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { InformationBanner } from '@/information-banner/InformationBanner';
import { PageBody } from './PageBody';
import { PageHeader } from './PageHeader';
@ -32,7 +33,10 @@ export const SubMenuTopBarContainer = ({
return (
<StyledContainer isMobile={isMobile} className={className}>
{isMobile && <PageHeader title={title} Icon={Icon} />}
<PageBody>{children}</PageBody>
<PageBody>
<InformationBanner />
{children}
</PageBody>
</StyledContainer>
);
};

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { currentUserState } from '@/auth/states/currentUserState';

View File

@ -49,5 +49,6 @@ export const USER_QUERY_FRAGMENT = gql`
domainName
}
}
userVars
}
`;

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import styled from '@emotion/styled';
import React, { useEffect, useState } from 'react';
import rehypeStringify from 'rehype-stringify';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import styled from '@emotion/styled';
import { useState } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import {
H1Title,

View File

@ -1,5 +1,5 @@
import { useState } from 'react';
import styled from '@emotion/styled';
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import { H1Title, H2Title, IconSettings, IconTrash } from 'twenty-ui';
@ -13,10 +13,10 @@ import { IconButton } from '@/ui/input/button/components/IconButton';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Section } from '@/ui/layout/section/components/Section';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { WorkspaceInviteLink } from '@/workspace/components/WorkspaceInviteLink';
import { WorkspaceInviteTeam } from '@/workspace/components/WorkspaceInviteTeam';
import { WorkspaceMemberCard } from '@/workspace/components/WorkspaceMemberCard';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
const StyledH1Title = styled(H1Title)`
margin-bottom: 0;

View File

@ -1,8 +1,8 @@
import React from 'react';
// @ts-expect-error external library has a typing issue
import { RevertConnect } from '@revertdotdev/revert-react';
import { IconSettings } from 'twenty-ui';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsReadDocumentationButton } from '@/settings/developers/components/SettingsReadDocumentationButton';
@ -10,7 +10,6 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
import { Section } from '@/ui/layout/section/components/Section';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { useRecoilValue } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
const REVERT_PUBLIC_KEY = 'pk_live_a87fee8c-28c7-494f-99a3-996ff89f9918';

View File

@ -1,6 +1,6 @@
import { DateTime } from 'luxon';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { DateTime } from 'luxon';
import { H2Title, IconSettings } from 'twenty-ui';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';

View File

@ -6,12 +6,10 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
export const SettingsIntegrationEditDatabaseConnection = () => {
return (
<>
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
<SettingsIntegrationEditDatabaseConnectionContainer />
</SettingsPageContainer>
</SubMenuTopBarContainer>
</>
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
<SettingsIntegrationEditDatabaseConnectionContainer />
</SettingsPageContainer>
</SubMenuTopBarContainer>
);
};

View File

@ -1,7 +1,7 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom';
import { zodResolver } from '@hookform/resolvers/zod';
import { H2Title, IconSettings } from 'twenty-ui';
import { z } from 'zod';

View File

@ -11,8 +11,8 @@ export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
startsAt: '2024-05-16T12:00:00.000Z',
endsAt: '2024-05-16T13:00:00.000Z',
conferenceLink: {
url: 'https://meet.google.com/xxx-xxx-xxx',
label: 'Rejoindre la visio',
primaryLinkUrl: 'https://meet.google.com/xxx-xxx-xxx',
primaryLinkLabel: 'Rejoindre la visio',
},
conferenceSolution: 'GOOGLE_MEET',
isCanceled: false,
@ -51,8 +51,8 @@ export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
endsAt: '2024-05-08T12:25:00.000Z',
isFullDay: false,
conferenceLink: {
url: 'https://meet.google.com/xxx-xxx-xxx',
label: 'Rejoindre la visio',
primaryLinkUrl: 'https://meet.google.com/xxx-xxx-xxx',
primaryLinkLabel: 'Rejoindre la visio',
},
conferenceSolution: 'GOOGLE_MEET',
isCanceled: false,
@ -80,8 +80,8 @@ export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
endsAt: '2024-05-06T12:25:00.000Z',
isFullDay: false,
conferenceLink: {
url: 'https://meet.google.com/xxx-xxx-xxx',
label: 'Rejoindre la visio',
primaryLinkUrl: 'https://meet.google.com/xxx-xxx-xxx',
primaryLinkLabel: 'Rejoindre la visio',
},
conferenceSolution: 'GOOGLE_MEET',
isCanceled: false,

View File

@ -17,6 +17,7 @@ type MockedUser = Pick<
| '__typename'
| 'supportUserHash'
| 'onboardingStatus'
| 'userVars'
> & {
workspaceMember: WorkspaceMember | null;
locale: string;
@ -99,6 +100,7 @@ export const mockedUserData: MockedUser = {
locale: 'en',
workspaces: [{ workspace: mockDefaultWorkspace }],
onboardingStatus: OnboardingStatus.Completed,
userVars: {},
};
export const mockedOnboardingUserData = (