mirror of
https://github.com/lingble/twenty.git
synced 2025-11-02 05:37:56 +00:00
5622 add a syncemail onboarding step (#5689)
- add sync email onboarding step - refactor calendar and email visibility enums - add a new table `keyValuePair` in `core` schema - add a new resolved boolean field `skipSyncEmail` in current user https://github.com/twentyhq/twenty/assets/29927851/de791475-5bfe-47f9-8e90-76c349fba56f
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
VITE_SERVER_BASE_URL=https://api.twenty.com
|
VITE_SERVER_BASE_URL=https://api.twenty.com
|
||||||
VITE_FRONT_BASE_URL=https://app.twenty.com
|
VITE_FRONT_BASE_URL=https://app.twenty.com
|
||||||
VITE_MODE=production
|
VITE_MODE=production
|
||||||
|
|
||||||
|
# Used to generate packages/twenty-chrome-extension/src/generated/graphql.tsx
|
||||||
|
AUTH_TOKEN=<YOUR-TOKEN-HERE>
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
import { CodegenConfig } from '@graphql-codegen/cli';
|
import { CodegenConfig } from '@graphql-codegen/cli';
|
||||||
|
|
||||||
const config: CodegenConfig = {
|
const config: CodegenConfig = {
|
||||||
schema: [{
|
schema: [
|
||||||
[`${import.meta.env.VITE_SERVER_BASE_URL}/graphql`]: {
|
{
|
||||||
// some of the mutations and queries require authorization (people or companies)
|
[`${import.meta.env.VITE_SERVER_BASE_URL}/graphql`]: {
|
||||||
// so to regenrate the schema with types we need to pass a auth token
|
// some of the mutations and queries require authorization (people or companies)
|
||||||
headers: {
|
// so to regenerate the schema with types we need to pass an auth token
|
||||||
Authorization: 'YOUR-TOKEN-HERE',
|
headers: {
|
||||||
|
Authorization: `Bearer ${import.meta.env.AUTH_TOKEN}`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}],
|
],
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
documents: ['./src/**/*.ts', '!src/generated/**/*.*' ],
|
documents: ['./src/**/*.ts', '!src/generated/**/*.*'],
|
||||||
generates: {
|
generates: {
|
||||||
'./src/generated/graphql.tsx': {
|
'./src/generated/graphql.tsx': {
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@ interface ImportMetaEnv {
|
|||||||
readonly VITE_SERVER_BASE_URL: string;
|
readonly VITE_SERVER_BASE_URL: string;
|
||||||
readonly VITE_FRONT_BASE_URL: string;
|
readonly VITE_FRONT_BASE_URL: string;
|
||||||
readonly VITE_MODE: string;
|
readonly VITE_MODE: string;
|
||||||
|
readonly AUTH_TOKEN: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
|
|||||||
@@ -38,17 +38,18 @@ import { CommandMenuEffect } from '~/effect-components/CommandMenuEffect';
|
|||||||
import { GotoHotkeysEffect } from '~/effect-components/GotoHotkeysEffect';
|
import { GotoHotkeysEffect } from '~/effect-components/GotoHotkeysEffect';
|
||||||
import { PageChangeEffect } from '~/effect-components/PageChangeEffect';
|
import { PageChangeEffect } from '~/effect-components/PageChangeEffect';
|
||||||
import { Authorize } from '~/pages/auth/Authorize';
|
import { Authorize } from '~/pages/auth/Authorize';
|
||||||
import { ChooseYourPlan } from '~/pages/auth/ChooseYourPlan';
|
|
||||||
import { CreateProfile } from '~/pages/auth/CreateProfile';
|
|
||||||
import { CreateWorkspace } from '~/pages/auth/CreateWorkspace';
|
|
||||||
import { Invite } from '~/pages/auth/Invite';
|
import { Invite } from '~/pages/auth/Invite';
|
||||||
import { PasswordReset } from '~/pages/auth/PasswordReset';
|
import { PasswordReset } from '~/pages/auth/PasswordReset';
|
||||||
import { PaymentSuccess } from '~/pages/auth/PaymentSuccess';
|
|
||||||
import { SignInUp } from '~/pages/auth/SignInUp';
|
import { SignInUp } from '~/pages/auth/SignInUp';
|
||||||
import { ImpersonateEffect } from '~/pages/impersonate/ImpersonateEffect';
|
import { ImpersonateEffect } from '~/pages/impersonate/ImpersonateEffect';
|
||||||
import { NotFound } from '~/pages/not-found/NotFound';
|
import { NotFound } from '~/pages/not-found/NotFound';
|
||||||
import { RecordIndexPage } from '~/pages/object-record/RecordIndexPage';
|
import { RecordIndexPage } from '~/pages/object-record/RecordIndexPage';
|
||||||
import { RecordShowPage } from '~/pages/object-record/RecordShowPage';
|
import { RecordShowPage } from '~/pages/object-record/RecordShowPage';
|
||||||
|
import { ChooseYourPlan } from '~/pages/onboarding/ChooseYourPlan';
|
||||||
|
import { CreateProfile } from '~/pages/onboarding/CreateProfile';
|
||||||
|
import { CreateWorkspace } from '~/pages/onboarding/CreateWorkspace';
|
||||||
|
import { PaymentSuccess } from '~/pages/onboarding/PaymentSuccess';
|
||||||
|
import { SyncEmails } from '~/pages/onboarding/SyncEmails';
|
||||||
import { SettingsAccounts } from '~/pages/settings/accounts/SettingsAccounts';
|
import { SettingsAccounts } from '~/pages/settings/accounts/SettingsAccounts';
|
||||||
import { SettingsAccountsCalendars } from '~/pages/settings/accounts/SettingsAccountsCalendars';
|
import { SettingsAccountsCalendars } from '~/pages/settings/accounts/SettingsAccountsCalendars';
|
||||||
import { SettingsAccountsCalendarsSettings } from '~/pages/settings/accounts/SettingsAccountsCalendarsSettings';
|
import { SettingsAccountsCalendarsSettings } from '~/pages/settings/accounts/SettingsAccountsCalendarsSettings';
|
||||||
@@ -141,6 +142,7 @@ const createRouter = (isBillingEnabled?: boolean) =>
|
|||||||
<Route path={AppPath.ResetPassword} element={<PasswordReset />} />
|
<Route path={AppPath.ResetPassword} element={<PasswordReset />} />
|
||||||
<Route path={AppPath.CreateWorkspace} element={<CreateWorkspace />} />
|
<Route path={AppPath.CreateWorkspace} element={<CreateWorkspace />} />
|
||||||
<Route path={AppPath.CreateProfile} element={<CreateProfile />} />
|
<Route path={AppPath.CreateProfile} element={<CreateProfile />} />
|
||||||
|
<Route path={AppPath.SyncEmails} element={<SyncEmails />} />
|
||||||
<Route path={AppPath.PlanRequired} element={<ChooseYourPlan />} />
|
<Route path={AppPath.PlanRequired} element={<ChooseYourPlan />} />
|
||||||
<Route
|
<Route
|
||||||
path={AppPath.PlanRequiredSuccess}
|
path={AppPath.PlanRequiredSuccess}
|
||||||
|
|||||||
@@ -123,6 +123,12 @@ export type BooleanFieldComparison = {
|
|||||||
isNot?: InputMaybe<Scalars['Boolean']['input']>;
|
isNot?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Visibility of the calendar channel */
|
||||||
|
export enum CalendarChannelVisibility {
|
||||||
|
Metadata = 'METADATA',
|
||||||
|
ShareEverything = 'SHARE_EVERYTHING'
|
||||||
|
}
|
||||||
|
|
||||||
export type Captcha = {
|
export type Captcha = {
|
||||||
__typename?: 'Captcha';
|
__typename?: 'Captcha';
|
||||||
provider?: Maybe<CaptchaDriverType>;
|
provider?: Maybe<CaptchaDriverType>;
|
||||||
@@ -367,6 +373,13 @@ export type LoginToken = {
|
|||||||
loginToken: AuthToken;
|
loginToken: AuthToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Visibility of the message channel */
|
||||||
|
export enum MessageChannelVisibility {
|
||||||
|
Metadata = 'METADATA',
|
||||||
|
ShareEverything = 'SHARE_EVERYTHING',
|
||||||
|
Subject = 'SUBJECT'
|
||||||
|
}
|
||||||
|
|
||||||
export type Mutation = {
|
export type Mutation = {
|
||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
activateWorkspace: Workspace;
|
activateWorkspace: Workspace;
|
||||||
@@ -394,6 +407,7 @@ export type Mutation = {
|
|||||||
renewToken: AuthTokens;
|
renewToken: AuthTokens;
|
||||||
sendInviteLink: SendInviteLink;
|
sendInviteLink: SendInviteLink;
|
||||||
signUp: LoginToken;
|
signUp: LoginToken;
|
||||||
|
skipSyncEmailOnboardingStep: SkipSyncEmailOnboardingStep;
|
||||||
syncRemoteTable: RemoteTable;
|
syncRemoteTable: RemoteTable;
|
||||||
syncRemoteTableSchemaChanges: RemoteTable;
|
syncRemoteTableSchemaChanges: RemoteTable;
|
||||||
track: Analytics;
|
track: Analytics;
|
||||||
@@ -874,6 +888,12 @@ export type SessionEntity = {
|
|||||||
url?: Maybe<Scalars['String']['output']>;
|
url?: Maybe<Scalars['String']['output']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SkipSyncEmailOnboardingStep = {
|
||||||
|
__typename?: 'SkipSyncEmailOnboardingStep';
|
||||||
|
/** Boolean that confirms query was dispatched */
|
||||||
|
success: Scalars['Boolean']['output'];
|
||||||
|
};
|
||||||
|
|
||||||
/** Sort Directions */
|
/** Sort Directions */
|
||||||
export enum SortDirection {
|
export enum SortDirection {
|
||||||
Asc = 'ASC',
|
Asc = 'ASC',
|
||||||
@@ -911,7 +931,7 @@ export type TimelineCalendarEvent = {
|
|||||||
participants: Array<TimelineCalendarEventParticipant>;
|
participants: Array<TimelineCalendarEventParticipant>;
|
||||||
startsAt: Scalars['DateTime']['output'];
|
startsAt: Scalars['DateTime']['output'];
|
||||||
title: Scalars['String']['output'];
|
title: Scalars['String']['output'];
|
||||||
visibility: TimelineCalendarEventVisibility;
|
visibility: CalendarChannelVisibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TimelineCalendarEventParticipant = {
|
export type TimelineCalendarEventParticipant = {
|
||||||
@@ -925,12 +945,6 @@ export type TimelineCalendarEventParticipant = {
|
|||||||
workspaceMemberId?: Maybe<Scalars['UUID']['output']>;
|
workspaceMemberId?: Maybe<Scalars['UUID']['output']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Visibility of the calendar event */
|
|
||||||
export enum TimelineCalendarEventVisibility {
|
|
||||||
Metadata = 'METADATA',
|
|
||||||
ShareEverything = 'SHARE_EVERYTHING'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TimelineCalendarEventsWithTotal = {
|
export type TimelineCalendarEventsWithTotal = {
|
||||||
__typename?: 'TimelineCalendarEventsWithTotal';
|
__typename?: 'TimelineCalendarEventsWithTotal';
|
||||||
timelineCalendarEvents: Array<TimelineCalendarEvent>;
|
timelineCalendarEvents: Array<TimelineCalendarEvent>;
|
||||||
@@ -948,7 +962,7 @@ export type TimelineThread = {
|
|||||||
participantCount: Scalars['Float']['output'];
|
participantCount: Scalars['Float']['output'];
|
||||||
read: Scalars['Boolean']['output'];
|
read: Scalars['Boolean']['output'];
|
||||||
subject: Scalars['String']['output'];
|
subject: Scalars['String']['output'];
|
||||||
visibility: Scalars['String']['output'];
|
visibility: MessageChannelVisibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TimelineThreadParticipant = {
|
export type TimelineThreadParticipant = {
|
||||||
@@ -1070,6 +1084,7 @@ export type User = {
|
|||||||
passwordResetToken?: Maybe<Scalars['String']['output']>;
|
passwordResetToken?: Maybe<Scalars['String']['output']>;
|
||||||
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
|
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
|
||||||
passwordResetTokenExpiresAt?: Maybe<Scalars['DateTime']['output']>;
|
passwordResetTokenExpiresAt?: Maybe<Scalars['DateTime']['output']>;
|
||||||
|
state: UserState;
|
||||||
supportUserHash?: Maybe<Scalars['String']['output']>;
|
supportUserHash?: Maybe<Scalars['String']['output']>;
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
updatedAt: Scalars['DateTime']['output'];
|
||||||
workspaceMember?: Maybe<WorkspaceMember>;
|
workspaceMember?: Maybe<WorkspaceMember>;
|
||||||
@@ -1104,6 +1119,11 @@ export type UserMappingOptionsUser = {
|
|||||||
user?: Maybe<Scalars['String']['output']>;
|
user?: Maybe<Scalars['String']['output']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type UserState = {
|
||||||
|
__typename?: 'UserState';
|
||||||
|
skipSyncEmailOnboardingStep?: Maybe<Scalars['Boolean']['output']>;
|
||||||
|
};
|
||||||
|
|
||||||
export type UserWorkspace = {
|
export type UserWorkspace = {
|
||||||
__typename?: 'UserWorkspace';
|
__typename?: 'UserWorkspace';
|
||||||
createdAt: Scalars['DateTime']['output'];
|
createdAt: Scalars['DateTime']['output'];
|
||||||
|
|||||||
@@ -117,6 +117,12 @@ export type BooleanFieldComparison = {
|
|||||||
isNot?: InputMaybe<Scalars['Boolean']>;
|
isNot?: InputMaybe<Scalars['Boolean']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Visibility of the calendar channel */
|
||||||
|
export enum CalendarChannelVisibility {
|
||||||
|
Metadata = 'METADATA',
|
||||||
|
ShareEverything = 'SHARE_EVERYTHING'
|
||||||
|
}
|
||||||
|
|
||||||
export type Captcha = {
|
export type Captcha = {
|
||||||
__typename?: 'Captcha';
|
__typename?: 'Captcha';
|
||||||
provider?: Maybe<CaptchaDriverType>;
|
provider?: Maybe<CaptchaDriverType>;
|
||||||
@@ -266,6 +272,13 @@ export type LoginToken = {
|
|||||||
loginToken: AuthToken;
|
loginToken: AuthToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Visibility of the message channel */
|
||||||
|
export enum MessageChannelVisibility {
|
||||||
|
Metadata = 'METADATA',
|
||||||
|
ShareEverything = 'SHARE_EVERYTHING',
|
||||||
|
Subject = 'SUBJECT'
|
||||||
|
}
|
||||||
|
|
||||||
export type Mutation = {
|
export type Mutation = {
|
||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
activateWorkspace: Workspace;
|
activateWorkspace: Workspace;
|
||||||
@@ -287,6 +300,7 @@ export type Mutation = {
|
|||||||
renewToken: AuthTokens;
|
renewToken: AuthTokens;
|
||||||
sendInviteLink: SendInviteLink;
|
sendInviteLink: SendInviteLink;
|
||||||
signUp: LoginToken;
|
signUp: LoginToken;
|
||||||
|
skipSyncEmailOnboardingStep: SkipSyncEmailOnboardingStep;
|
||||||
track: Analytics;
|
track: Analytics;
|
||||||
updateBillingSubscription: UpdateBillingEntity;
|
updateBillingSubscription: UpdateBillingEntity;
|
||||||
updateOneObject: Object;
|
updateOneObject: Object;
|
||||||
@@ -629,6 +643,12 @@ export type SessionEntity = {
|
|||||||
url?: Maybe<Scalars['String']>;
|
url?: Maybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SkipSyncEmailOnboardingStep = {
|
||||||
|
__typename?: 'SkipSyncEmailOnboardingStep';
|
||||||
|
/** Boolean that confirms query was dispatched */
|
||||||
|
success: Scalars['Boolean'];
|
||||||
|
};
|
||||||
|
|
||||||
/** Sort Directions */
|
/** Sort Directions */
|
||||||
export enum SortDirection {
|
export enum SortDirection {
|
||||||
Asc = 'ASC',
|
Asc = 'ASC',
|
||||||
@@ -666,7 +686,7 @@ export type TimelineCalendarEvent = {
|
|||||||
participants: Array<TimelineCalendarEventParticipant>;
|
participants: Array<TimelineCalendarEventParticipant>;
|
||||||
startsAt: Scalars['DateTime'];
|
startsAt: Scalars['DateTime'];
|
||||||
title: Scalars['String'];
|
title: Scalars['String'];
|
||||||
visibility: TimelineCalendarEventVisibility;
|
visibility: CalendarChannelVisibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TimelineCalendarEventParticipant = {
|
export type TimelineCalendarEventParticipant = {
|
||||||
@@ -680,12 +700,6 @@ export type TimelineCalendarEventParticipant = {
|
|||||||
workspaceMemberId?: Maybe<Scalars['UUID']>;
|
workspaceMemberId?: Maybe<Scalars['UUID']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Visibility of the calendar event */
|
|
||||||
export enum TimelineCalendarEventVisibility {
|
|
||||||
Metadata = 'METADATA',
|
|
||||||
ShareEverything = 'SHARE_EVERYTHING'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TimelineCalendarEventsWithTotal = {
|
export type TimelineCalendarEventsWithTotal = {
|
||||||
__typename?: 'TimelineCalendarEventsWithTotal';
|
__typename?: 'TimelineCalendarEventsWithTotal';
|
||||||
timelineCalendarEvents: Array<TimelineCalendarEvent>;
|
timelineCalendarEvents: Array<TimelineCalendarEvent>;
|
||||||
@@ -703,7 +717,7 @@ export type TimelineThread = {
|
|||||||
participantCount: Scalars['Float'];
|
participantCount: Scalars['Float'];
|
||||||
read: Scalars['Boolean'];
|
read: Scalars['Boolean'];
|
||||||
subject: Scalars['String'];
|
subject: Scalars['String'];
|
||||||
visibility: Scalars['String'];
|
visibility: MessageChannelVisibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TimelineThreadParticipant = {
|
export type TimelineThreadParticipant = {
|
||||||
@@ -796,6 +810,7 @@ export type User = {
|
|||||||
passwordResetToken?: Maybe<Scalars['String']>;
|
passwordResetToken?: Maybe<Scalars['String']>;
|
||||||
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
|
/** @deprecated field migrated into the AppTokens Table ref: https://github.com/twentyhq/twenty/issues/5021 */
|
||||||
passwordResetTokenExpiresAt?: Maybe<Scalars['DateTime']>;
|
passwordResetTokenExpiresAt?: Maybe<Scalars['DateTime']>;
|
||||||
|
state: UserState;
|
||||||
supportUserHash?: Maybe<Scalars['String']>;
|
supportUserHash?: Maybe<Scalars['String']>;
|
||||||
updatedAt: Scalars['DateTime'];
|
updatedAt: Scalars['DateTime'];
|
||||||
workspaceMember?: Maybe<WorkspaceMember>;
|
workspaceMember?: Maybe<WorkspaceMember>;
|
||||||
@@ -820,6 +835,11 @@ export type UserMappingOptionsUser = {
|
|||||||
user?: Maybe<Scalars['String']>;
|
user?: Maybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type UserState = {
|
||||||
|
__typename?: 'UserState';
|
||||||
|
skipSyncEmailOnboardingStep?: Maybe<Scalars['Boolean']>;
|
||||||
|
};
|
||||||
|
|
||||||
export type UserWorkspace = {
|
export type UserWorkspace = {
|
||||||
__typename?: 'UserWorkspace';
|
__typename?: 'UserWorkspace';
|
||||||
createdAt: Scalars['DateTime'];
|
createdAt: Scalars['DateTime'];
|
||||||
@@ -993,11 +1013,11 @@ export type RelationEdge = {
|
|||||||
node: Relation;
|
node: Relation;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TimelineCalendarEventFragmentFragment = { __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: TimelineCalendarEventVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> };
|
export type TimelineCalendarEventFragmentFragment = { __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: CalendarChannelVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> };
|
||||||
|
|
||||||
export type TimelineCalendarEventParticipantFragmentFragment = { __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
export type TimelineCalendarEventParticipantFragmentFragment = { __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
||||||
|
|
||||||
export type TimelineCalendarEventsWithTotalFragmentFragment = { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: TimelineCalendarEventVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> };
|
export type TimelineCalendarEventsWithTotalFragmentFragment = { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: CalendarChannelVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> };
|
||||||
|
|
||||||
export type GetTimelineCalendarEventsFromCompanyIdQueryVariables = Exact<{
|
export type GetTimelineCalendarEventsFromCompanyIdQueryVariables = Exact<{
|
||||||
companyId: Scalars['UUID'];
|
companyId: Scalars['UUID'];
|
||||||
@@ -1006,7 +1026,7 @@ export type GetTimelineCalendarEventsFromCompanyIdQueryVariables = Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type GetTimelineCalendarEventsFromCompanyIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromCompanyId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: TimelineCalendarEventVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
export type GetTimelineCalendarEventsFromCompanyIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromCompanyId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: CalendarChannelVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||||
|
|
||||||
export type GetTimelineCalendarEventsFromPersonIdQueryVariables = Exact<{
|
export type GetTimelineCalendarEventsFromPersonIdQueryVariables = Exact<{
|
||||||
personId: Scalars['UUID'];
|
personId: Scalars['UUID'];
|
||||||
@@ -1015,13 +1035,13 @@ export type GetTimelineCalendarEventsFromPersonIdQueryVariables = Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type GetTimelineCalendarEventsFromPersonIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromPersonId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: TimelineCalendarEventVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
export type GetTimelineCalendarEventsFromPersonIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromPersonId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: CalendarChannelVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||||
|
|
||||||
export type ParticipantFragmentFragment = { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
export type ParticipantFragmentFragment = { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
||||||
|
|
||||||
export type TimelineThreadFragmentFragment = { __typename?: 'TimelineThread', id: any, read: boolean, visibility: string, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> };
|
export type TimelineThreadFragmentFragment = { __typename?: 'TimelineThread', id: any, read: boolean, visibility: MessageChannelVisibility, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> };
|
||||||
|
|
||||||
export type TimelineThreadsWithTotalFragmentFragment = { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: string, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> };
|
export type TimelineThreadsWithTotalFragmentFragment = { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: MessageChannelVisibility, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> };
|
||||||
|
|
||||||
export type GetTimelineThreadsFromCompanyIdQueryVariables = Exact<{
|
export type GetTimelineThreadsFromCompanyIdQueryVariables = Exact<{
|
||||||
companyId: Scalars['UUID'];
|
companyId: Scalars['UUID'];
|
||||||
@@ -1030,7 +1050,7 @@ export type GetTimelineThreadsFromCompanyIdQueryVariables = Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type GetTimelineThreadsFromCompanyIdQuery = { __typename?: 'Query', getTimelineThreadsFromCompanyId: { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: string, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
export type GetTimelineThreadsFromCompanyIdQuery = { __typename?: 'Query', getTimelineThreadsFromCompanyId: { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: MessageChannelVisibility, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||||
|
|
||||||
export type GetTimelineThreadsFromPersonIdQueryVariables = Exact<{
|
export type GetTimelineThreadsFromPersonIdQueryVariables = Exact<{
|
||||||
personId: Scalars['UUID'];
|
personId: Scalars['UUID'];
|
||||||
@@ -1039,7 +1059,7 @@ export type GetTimelineThreadsFromPersonIdQueryVariables = Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type GetTimelineThreadsFromPersonIdQuery = { __typename?: 'Query', getTimelineThreadsFromPersonId: { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: string, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
export type GetTimelineThreadsFromPersonIdQuery = { __typename?: 'Query', getTimelineThreadsFromPersonId: { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: MessageChannelVisibility, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||||
|
|
||||||
export type TimelineThreadFragment = { __typename?: 'TimelineThread', id: any, subject: string, lastMessageReceivedAt: string };
|
export type TimelineThreadFragment = { __typename?: 'TimelineThread', id: any, subject: string, lastMessageReceivedAt: string };
|
||||||
|
|
||||||
@@ -1121,7 +1141,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, 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | 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, state: { __typename?: 'UserState', skipSyncEmailOnboardingStep?: boolean | 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | 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<{
|
export type RenewTokenMutationVariables = Exact<{
|
||||||
appToken: Scalars['String'];
|
appToken: Scalars['String'];
|
||||||
@@ -1153,7 +1173,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, 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | 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, state: { __typename?: 'UserState', skipSyncEmailOnboardingStep?: boolean | 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | 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<{
|
export type CheckUserExistsQueryVariables = Exact<{
|
||||||
email: Scalars['String'];
|
email: Scalars['String'];
|
||||||
@@ -1202,7 +1222,12 @@ export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>;
|
|||||||
|
|
||||||
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, signUpDisabled: boolean, debugMode: boolean, chromeExtensionId?: string | null, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean }, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, billingFreeTrialDurationInDays?: number | null }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null, environment?: string | null, release?: string | null }, captcha: { __typename?: 'Captcha', provider?: CaptchaDriverType | null, siteKey?: string | null } } };
|
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, signUpDisabled: boolean, debugMode: boolean, chromeExtensionId?: string | null, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean }, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, billingFreeTrialDurationInDays?: number | null }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null, environment?: string | null, release?: string | null }, captcha: { __typename?: 'Captcha', provider?: CaptchaDriverType | null, siteKey?: string | null } } };
|
||||||
|
|
||||||
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> };
|
export type SkipSyncEmailOnboardingStepMutationVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type SkipSyncEmailOnboardingStepMutation = { __typename?: 'Mutation', skipSyncEmailOnboardingStep: { __typename?: 'SkipSyncEmailOnboardingStep', success: boolean } };
|
||||||
|
|
||||||
|
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, state: { __typename?: 'UserState', skipSyncEmailOnboardingStep?: boolean | 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | 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; }>;
|
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
@@ -1219,7 +1244,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf
|
|||||||
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
|
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, 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: 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, state: { __typename?: 'UserState', skipSyncEmailOnboardingStep?: boolean | 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, subscriptionStatus: string, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: string, interval?: string | 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<{
|
export type AddUserToWorkspaceMutationVariables = Exact<{
|
||||||
inviteHash: Scalars['String'];
|
inviteHash: Scalars['String'];
|
||||||
@@ -1370,6 +1395,9 @@ export const UserQueryFragmentFragmentDoc = gql`
|
|||||||
email
|
email
|
||||||
canImpersonate
|
canImpersonate
|
||||||
supportUserHash
|
supportUserHash
|
||||||
|
state {
|
||||||
|
skipSyncEmailOnboardingStep
|
||||||
|
}
|
||||||
workspaceMember {
|
workspaceMember {
|
||||||
id
|
id
|
||||||
name {
|
name {
|
||||||
@@ -2359,6 +2387,38 @@ export function useGetClientConfigLazyQuery(baseOptions?: Apollo.LazyQueryHookOp
|
|||||||
export type GetClientConfigQueryHookResult = ReturnType<typeof useGetClientConfigQuery>;
|
export type GetClientConfigQueryHookResult = ReturnType<typeof useGetClientConfigQuery>;
|
||||||
export type GetClientConfigLazyQueryHookResult = ReturnType<typeof useGetClientConfigLazyQuery>;
|
export type GetClientConfigLazyQueryHookResult = ReturnType<typeof useGetClientConfigLazyQuery>;
|
||||||
export type GetClientConfigQueryResult = Apollo.QueryResult<GetClientConfigQuery, GetClientConfigQueryVariables>;
|
export type GetClientConfigQueryResult = Apollo.QueryResult<GetClientConfigQuery, GetClientConfigQueryVariables>;
|
||||||
|
export const SkipSyncEmailOnboardingStepDocument = gql`
|
||||||
|
mutation SkipSyncEmailOnboardingStep {
|
||||||
|
skipSyncEmailOnboardingStep {
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export type SkipSyncEmailOnboardingStepMutationFn = Apollo.MutationFunction<SkipSyncEmailOnboardingStepMutation, SkipSyncEmailOnboardingStepMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useSkipSyncEmailOnboardingStepMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useSkipSyncEmailOnboardingStepMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useSkipSyncEmailOnboardingStepMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [skipSyncEmailOnboardingStepMutation, { data, loading, error }] = useSkipSyncEmailOnboardingStepMutation({
|
||||||
|
* variables: {
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useSkipSyncEmailOnboardingStepMutation(baseOptions?: Apollo.MutationHookOptions<SkipSyncEmailOnboardingStepMutation, SkipSyncEmailOnboardingStepMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useMutation<SkipSyncEmailOnboardingStepMutation, SkipSyncEmailOnboardingStepMutationVariables>(SkipSyncEmailOnboardingStepDocument, options);
|
||||||
|
}
|
||||||
|
export type SkipSyncEmailOnboardingStepMutationHookResult = ReturnType<typeof useSkipSyncEmailOnboardingStepMutation>;
|
||||||
|
export type SkipSyncEmailOnboardingStepMutationResult = Apollo.MutationResult<SkipSyncEmailOnboardingStepMutation>;
|
||||||
|
export type SkipSyncEmailOnboardingStepMutationOptions = Apollo.BaseMutationOptions<SkipSyncEmailOnboardingStepMutation, SkipSyncEmailOnboardingStepMutationVariables>;
|
||||||
export const DeleteUserAccountDocument = gql`
|
export const DeleteUserAccountDocument = gql`
|
||||||
mutation DeleteUserAccount {
|
mutation DeleteUserAccount {
|
||||||
deleteUser {
|
deleteUser {
|
||||||
@@ -2425,55 +2485,10 @@ export type UploadProfilePictureMutationOptions = Apollo.BaseMutationOptions<Upl
|
|||||||
export const GetCurrentUserDocument = gql`
|
export const GetCurrentUserDocument = gql`
|
||||||
query GetCurrentUser {
|
query GetCurrentUser {
|
||||||
currentUser {
|
currentUser {
|
||||||
id
|
...UserQueryFragment
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
email
|
|
||||||
canImpersonate
|
|
||||||
supportUserHash
|
|
||||||
workspaceMember {
|
|
||||||
id
|
|
||||||
name {
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
colorScheme
|
|
||||||
avatarUrl
|
|
||||||
locale
|
|
||||||
}
|
|
||||||
defaultWorkspace {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
logo
|
|
||||||
domainName
|
|
||||||
inviteHash
|
|
||||||
allowImpersonation
|
|
||||||
subscriptionStatus
|
|
||||||
activationStatus
|
|
||||||
featureFlags {
|
|
||||||
id
|
|
||||||
key
|
|
||||||
value
|
|
||||||
workspaceId
|
|
||||||
}
|
|
||||||
currentCacheVersion
|
|
||||||
currentBillingSubscription {
|
|
||||||
id
|
|
||||||
status
|
|
||||||
interval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
workspaces {
|
|
||||||
workspace {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
logo
|
|
||||||
domainName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
${UserQueryFragmentFragmentDoc}`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __useGetCurrentUserQuery__
|
* __useGetCurrentUserQuery__
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
{ loc: AppPath.Verify, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
{ loc: AppPath.Verify, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
||||||
|
|
||||||
@@ -55,6 +57,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.Invite, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.Invite, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -65,6 +68,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingUserCreation, res: undefined },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -75,6 +79,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingWorkspaceActivation, res: undefined },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingWorkspaceActivation, res: undefined },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
||||||
|
|
||||||
@@ -85,9 +90,21 @@ const testCases = [
|
|||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingProfileCreation, res: undefined },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingProfileCreation, res: undefined },
|
||||||
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
||||||
|
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Incomplete, res: AppPath.PlanRequired },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Canceled, res: '/settings/billing' },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Unpaid, res: '/settings/billing' },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.PastDue, res: undefined },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingSyncEmail, res: undefined },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
||||||
|
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Incomplete, res: undefined },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Incomplete, res: undefined },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Canceled, res: undefined },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Canceled, res: undefined },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Unpaid, res: undefined },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Unpaid, res: undefined },
|
||||||
@@ -95,6 +112,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -105,6 +123,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingWorkspaceActivation, res: undefined },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingWorkspaceActivation, res: undefined },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
||||||
|
|
||||||
@@ -115,6 +134,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Index, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
{ loc: AppPath.Index, status: OnboardingStatus.Completed, res: defaultHomePagePath },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
{ loc: AppPath.Index, status: OnboardingStatus.CompletedWithoutSubscription, res: defaultHomePagePath },
|
||||||
|
|
||||||
@@ -125,6 +145,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -135,6 +156,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -145,6 +167,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -155,6 +178,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -165,6 +189,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -175,6 +200,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -185,6 +211,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -195,6 +222,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -205,6 +233,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
|
|
||||||
@@ -215,6 +244,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingUserCreation, res: AppPath.SignInUp },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingWorkspaceActivation, res: AppPath.CreateWorkspace },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingProfileCreation, res: AppPath.CreateProfile },
|
||||||
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingSyncEmail, res: AppPath.SyncEmails },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.Completed, res: undefined },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.Completed, res: undefined },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.CompletedWithoutSubscription, res: undefined },
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export const usePageChangeEffectNavigateLocation = () => {
|
|||||||
isMatchingOngoingUserCreationRoute ||
|
isMatchingOngoingUserCreationRoute ||
|
||||||
isMatchingLocation(AppPath.CreateWorkspace) ||
|
isMatchingLocation(AppPath.CreateWorkspace) ||
|
||||||
isMatchingLocation(AppPath.CreateProfile) ||
|
isMatchingLocation(AppPath.CreateProfile) ||
|
||||||
|
isMatchingLocation(AppPath.SyncEmails) ||
|
||||||
isMatchingLocation(AppPath.PlanRequired) ||
|
isMatchingLocation(AppPath.PlanRequired) ||
|
||||||
isMatchingLocation(AppPath.PlanRequiredSuccess);
|
isMatchingLocation(AppPath.PlanRequiredSuccess);
|
||||||
|
|
||||||
@@ -71,6 +72,13 @@ export const usePageChangeEffectNavigateLocation = () => {
|
|||||||
return AppPath.CreateProfile;
|
return AppPath.CreateProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
onboardingStatus === OnboardingStatus.OngoingSyncEmail &&
|
||||||
|
!isMatchingLocation(AppPath.SyncEmails)
|
||||||
|
) {
|
||||||
|
return AppPath.SyncEmails;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
onboardingStatus === OnboardingStatus.Completed &&
|
onboardingStatus === OnboardingStatus.Completed &&
|
||||||
isMatchingOnboardingRoute &&
|
isMatchingOnboardingRoute &&
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
export enum CalendarChannelVisibility {
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
Everything = 'SHARE_EVERYTHING',
|
|
||||||
Metadata = 'METADATA',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CalendarChannel = {
|
export type CalendarChannel = {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { InboxSettingsVisibilityValue } from '@/settings/accounts/components/SettingsAccountsInboxVisibilitySettingsCard';
|
import { MessageChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
export type MessageChannel = {
|
export type MessageChannel = {
|
||||||
id: string;
|
id: string;
|
||||||
handle: string;
|
handle: string;
|
||||||
isContactAutoCreationEnabled?: boolean;
|
isContactAutoCreationEnabled?: boolean;
|
||||||
isSyncEnabled: boolean;
|
isSyncEnabled: boolean;
|
||||||
visibility: InboxSettingsVisibilityValue;
|
visibility: MessageChannelVisibility;
|
||||||
syncStatus: string;
|
syncStatus: string;
|
||||||
__typename: 'MessageChannel';
|
__typename: 'MessageChannel';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEv
|
|||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { Card } from '@/ui/layout/card/components/Card';
|
import { Card } from '@/ui/layout/card/components/Card';
|
||||||
import { CardContent } from '@/ui/layout/card/components/CardContent';
|
import { CardContent } from '@/ui/layout/card/components/CardContent';
|
||||||
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
import { TimelineCalendarEvent } from '~/generated-metadata/graphql';
|
import { TimelineCalendarEvent } from '~/generated-metadata/graphql';
|
||||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
@@ -118,7 +119,8 @@ export const CalendarEventRow = ({
|
|||||||
const isCurrentWorkspaceMemberAttending = calendarEvent.participants?.some(
|
const isCurrentWorkspaceMemberAttending = calendarEvent.participants?.some(
|
||||||
({ workspaceMemberId }) => workspaceMemberId === currentWorkspaceMember?.id,
|
({ workspaceMemberId }) => workspaceMemberId === currentWorkspaceMember?.id,
|
||||||
);
|
);
|
||||||
const showTitle = calendarEvent.visibility === 'SHARE_EVERYTHING';
|
const showTitle =
|
||||||
|
calendarEvent.visibility === CalendarChannelVisibility.ShareEverything;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer
|
<StyledContainer
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { act, renderHook } from '@testing-library/react';
|
|||||||
|
|
||||||
import { useCalendarEvents } from '@/activities/calendar/hooks/useCalendarEvents';
|
import { useCalendarEvents } from '@/activities/calendar/hooks/useCalendarEvents';
|
||||||
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
||||||
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
const calendarEvents: CalendarEvent[] = [
|
const calendarEvents: CalendarEvent[] = [
|
||||||
{
|
{
|
||||||
@@ -9,7 +10,7 @@ const calendarEvents: CalendarEvent[] = [
|
|||||||
externalCreatedAt: '2024-02-17T20:45:43.854Z',
|
externalCreatedAt: '2024-02-17T20:45:43.854Z',
|
||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
startsAt: '2024-02-17T21:45:27.822Z',
|
startsAt: '2024-02-17T21:45:27.822Z',
|
||||||
visibility: 'METADATA',
|
visibility: CalendarChannelVisibility.Metadata,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -17,7 +18,7 @@ const calendarEvents: CalendarEvent[] = [
|
|||||||
externalCreatedAt: '2024-02-18T19:43:37.854Z',
|
externalCreatedAt: '2024-02-18T19:43:37.854Z',
|
||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
startsAt: '2024-02-18T21:43:27.754Z',
|
startsAt: '2024-02-18T21:43:27.754Z',
|
||||||
visibility: 'SHARE_EVERYTHING',
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -25,7 +26,7 @@ const calendarEvents: CalendarEvent[] = [
|
|||||||
externalCreatedAt: '2024-02-19T20:45:20.854Z',
|
externalCreatedAt: '2024-02-19T20:45:20.854Z',
|
||||||
isFullDay: true,
|
isFullDay: true,
|
||||||
startsAt: '2024-02-19T22:05:27.653Z',
|
startsAt: '2024-02-19T22:05:27.653Z',
|
||||||
visibility: 'METADATA',
|
visibility: CalendarChannelVisibility.Metadata,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -33,7 +34,7 @@ const calendarEvents: CalendarEvent[] = [
|
|||||||
externalCreatedAt: '2024-02-20T20:45:12.854Z',
|
externalCreatedAt: '2024-02-20T20:45:12.854Z',
|
||||||
isFullDay: true,
|
isFullDay: true,
|
||||||
startsAt: '2024-02-20T23:15:23.150Z',
|
startsAt: '2024-02-20T23:15:23.150Z',
|
||||||
visibility: 'SHARE_EVERYTHING',
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
|
import { CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
|
||||||
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
// TODO: use backend CalendarEvent type when ready
|
// TODO: use backend CalendarEvent type when ready
|
||||||
export type CalendarEvent = {
|
export type CalendarEvent = {
|
||||||
@@ -15,7 +16,7 @@ export type CalendarEvent = {
|
|||||||
location?: string;
|
location?: string;
|
||||||
startsAt: string;
|
startsAt: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
visibility: 'METADATA' | 'SHARE_EVERYTHING';
|
visibility: CalendarChannelVisibility;
|
||||||
calendarEventParticipants?: CalendarEventParticipant[];
|
calendarEventParticipants?: CalendarEventParticipant[];
|
||||||
__typename: 'CalendarEvent';
|
__typename: 'CalendarEvent';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,18 +8,22 @@ import { useEmailThread } from '@/activities/emails/hooks/useEmailThread';
|
|||||||
import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/states/lastViewableEmailThreadIdState';
|
import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/states/lastViewableEmailThreadIdState';
|
||||||
import { CardContent } from '@/ui/layout/card/components/CardContent';
|
import { CardContent } from '@/ui/layout/card/components/CardContent';
|
||||||
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||||
import { TimelineThread } from '~/generated/graphql';
|
import { MessageChannelVisibility, TimelineThread } from '~/generated/graphql';
|
||||||
import { formatToHumanReadableDate } from '~/utils';
|
import { formatToHumanReadableDate } from '~/utils';
|
||||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||||
|
|
||||||
const StyledCardContent = styled(CardContent)<{ visibility: string }>`
|
const StyledCardContent = styled(CardContent)<{
|
||||||
|
visibility: MessageChannelVisibility;
|
||||||
|
}>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
height: ${({ theme }) => theme.spacing(12)};
|
height: ${({ theme }) => theme.spacing(12)};
|
||||||
padding: ${({ theme }) => theme.spacing(0, 4)};
|
padding: ${({ theme }) => theme.spacing(0, 4)};
|
||||||
cursor: ${({ visibility }) =>
|
cursor: ${({ visibility }) =>
|
||||||
visibility === 'share_everything' ? 'pointer' : 'default'};
|
visibility === MessageChannelVisibility.ShareEverything
|
||||||
|
? 'pointer'
|
||||||
|
: 'default'};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledHeading = styled.div<{ unread: boolean }>`
|
const StyledHeading = styled.div<{ unread: boolean }>`
|
||||||
@@ -78,8 +82,6 @@ const StyledReceivedAt = styled.div`
|
|||||||
padding: ${({ theme }) => theme.spacing(0, 1)};
|
padding: ${({ theme }) => theme.spacing(0, 1)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export type EmailThreadVisibility = 'metadata' | 'subject' | 'share_everything';
|
|
||||||
|
|
||||||
type EmailThreadPreviewProps = {
|
type EmailThreadPreviewProps = {
|
||||||
divider?: boolean;
|
divider?: boolean;
|
||||||
thread: TimelineThread;
|
thread: TimelineThread;
|
||||||
@@ -93,7 +95,7 @@ export const EmailThreadPreview = ({
|
|||||||
|
|
||||||
const { openEmailThread } = useEmailThread();
|
const { openEmailThread } = useEmailThread();
|
||||||
|
|
||||||
const visibility = thread.visibility as EmailThreadVisibility;
|
const visibility = thread.visibility;
|
||||||
|
|
||||||
const senderNames =
|
const senderNames =
|
||||||
thread.firstParticipant.displayName +
|
thread.firstParticipant.displayName +
|
||||||
@@ -126,7 +128,7 @@ export const EmailThreadPreview = ({
|
|||||||
.getValue();
|
.getValue();
|
||||||
|
|
||||||
const canOpen =
|
const canOpen =
|
||||||
thread.visibility === 'share_everything' &&
|
thread.visibility === MessageChannelVisibility.ShareEverything &&
|
||||||
(!clickJustTriggeredEmailDrawerClose ||
|
(!clickJustTriggeredEmailDrawerClose ||
|
||||||
emailThreadIdWhenEmailThreadWasClosed !== thread.id);
|
emailThreadIdWhenEmailThreadWasClosed !== thread.id);
|
||||||
|
|
||||||
@@ -183,13 +185,15 @@ export const EmailThreadPreview = ({
|
|||||||
</StyledHeading>
|
</StyledHeading>
|
||||||
|
|
||||||
<StyledSubjectAndBody>
|
<StyledSubjectAndBody>
|
||||||
{visibility !== 'metadata' && (
|
{visibility !== MessageChannelVisibility.Metadata && (
|
||||||
<StyledSubject>{thread.subject}</StyledSubject>
|
<StyledSubject>{thread.subject}</StyledSubject>
|
||||||
)}
|
)}
|
||||||
{visibility === 'share_everything' && (
|
{visibility === MessageChannelVisibility.ShareEverything && (
|
||||||
<StyledBody>{thread.lastMessageBody}</StyledBody>
|
<StyledBody>{thread.lastMessageBody}</StyledBody>
|
||||||
)}
|
)}
|
||||||
{visibility !== 'share_everything' && <EmailThreadNotShared />}
|
{visibility !== MessageChannelVisibility.ShareEverything && (
|
||||||
|
<EmailThreadNotShared />
|
||||||
|
)}
|
||||||
</StyledSubjectAndBody>
|
</StyledSubjectAndBody>
|
||||||
<StyledReceivedAt>
|
<StyledReceivedAt>
|
||||||
{formatToHumanReadableDate(thread.lastMessageReceivedAt)}
|
{formatToHumanReadableDate(thread.lastMessageReceivedAt)}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { renderHook } from '@testing-library/react';
|
|||||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
||||||
|
import { CurrentUser, currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import {
|
import {
|
||||||
CurrentWorkspace,
|
CurrentWorkspace,
|
||||||
@@ -20,6 +21,13 @@ const billing = {
|
|||||||
billingUrl: 'testing.com',
|
billingUrl: 'testing.com',
|
||||||
isBillingEnabled: true,
|
isBillingEnabled: true,
|
||||||
};
|
};
|
||||||
|
const currentUser = {
|
||||||
|
id: '1',
|
||||||
|
email: 'test@test',
|
||||||
|
supportUserHash: '1',
|
||||||
|
canImpersonate: false,
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
|
} as CurrentUser;
|
||||||
const currentWorkspace = {
|
const currentWorkspace = {
|
||||||
activationStatus: 'active',
|
activationStatus: 'active',
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -27,7 +35,7 @@ const currentWorkspace = {
|
|||||||
currentBillingSubscription: {
|
currentBillingSubscription: {
|
||||||
status: 'trialing',
|
status: 'trialing',
|
||||||
},
|
},
|
||||||
};
|
} as CurrentWorkspace;
|
||||||
const currentWorkspaceMember = {
|
const currentWorkspaceMember = {
|
||||||
id: '1',
|
id: '1',
|
||||||
locale: '',
|
locale: '',
|
||||||
@@ -46,12 +54,14 @@ const renderHooks = () => {
|
|||||||
const setCurrentWorkspaceMember = useSetRecoilState(
|
const setCurrentWorkspaceMember = useSetRecoilState(
|
||||||
currentWorkspaceMemberState,
|
currentWorkspaceMemberState,
|
||||||
);
|
);
|
||||||
|
const setCurrentUser = useSetRecoilState(currentUserState);
|
||||||
const setTokenPair = useSetRecoilState(tokenPairState);
|
const setTokenPair = useSetRecoilState(tokenPairState);
|
||||||
const setVerifyPending = useSetRecoilState(isVerifyPendingState);
|
const setVerifyPending = useSetRecoilState(isVerifyPendingState);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onboardingStatus,
|
onboardingStatus,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
@@ -77,6 +87,7 @@ describe('useOnboardingStatus', () => {
|
|||||||
const {
|
const {
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
} = result.current;
|
} = result.current;
|
||||||
@@ -84,10 +95,11 @@ describe('useOnboardingStatus', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
subscriptionStatus: 'incomplete',
|
subscriptionStatus: 'incomplete',
|
||||||
} as CurrentWorkspace);
|
});
|
||||||
setCurrentWorkspaceMember(currentWorkspaceMember);
|
setCurrentWorkspaceMember(currentWorkspaceMember);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -99,6 +111,7 @@ describe('useOnboardingStatus', () => {
|
|||||||
const {
|
const {
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
} = result.current;
|
} = result.current;
|
||||||
@@ -106,10 +119,11 @@ describe('useOnboardingStatus', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
subscriptionStatus: 'canceled',
|
subscriptionStatus: 'canceled',
|
||||||
} as CurrentWorkspace);
|
});
|
||||||
setCurrentWorkspaceMember({
|
setCurrentWorkspaceMember({
|
||||||
...currentWorkspaceMember,
|
...currentWorkspaceMember,
|
||||||
name: {
|
name: {
|
||||||
@@ -124,16 +138,18 @@ describe('useOnboardingStatus', () => {
|
|||||||
|
|
||||||
it('should return "ongoing_workspace_activation"', async () => {
|
it('should return "ongoing_workspace_activation"', async () => {
|
||||||
const { result } = renderHooks();
|
const { result } = renderHooks();
|
||||||
const { setTokenPair, setBilling, setCurrentWorkspace } = result.current;
|
const { setTokenPair, setBilling, setCurrentUser, setCurrentWorkspace } =
|
||||||
|
result.current;
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
activationStatus: 'inactive',
|
activationStatus: 'inactive',
|
||||||
subscriptionStatus: 'active',
|
subscriptionStatus: 'active',
|
||||||
} as CurrentWorkspace);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.current.onboardingStatus).toBe(
|
expect(result.current.onboardingStatus).toBe(
|
||||||
@@ -146,6 +162,7 @@ describe('useOnboardingStatus', () => {
|
|||||||
const {
|
const {
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
} = result.current;
|
} = result.current;
|
||||||
@@ -153,21 +170,56 @@ describe('useOnboardingStatus', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
subscriptionStatus: 'active',
|
subscriptionStatus: 'active',
|
||||||
} as CurrentWorkspace);
|
});
|
||||||
setCurrentWorkspaceMember(currentWorkspaceMember);
|
setCurrentWorkspaceMember(currentWorkspaceMember);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.current.onboardingStatus).toBe('ongoing_profile_creation');
|
expect(result.current.onboardingStatus).toBe('ongoing_profile_creation');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return "ongoing_sync_email"', async () => {
|
||||||
|
const { result } = renderHooks();
|
||||||
|
const {
|
||||||
|
setTokenPair,
|
||||||
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
|
setCurrentWorkspace,
|
||||||
|
setCurrentWorkspaceMember,
|
||||||
|
} = result.current;
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
setTokenPair(tokenPair);
|
||||||
|
setBilling(billing);
|
||||||
|
setCurrentUser({
|
||||||
|
...currentUser,
|
||||||
|
state: { skipSyncEmailOnboardingStep: false },
|
||||||
|
});
|
||||||
|
setCurrentWorkspace({
|
||||||
|
...currentWorkspace,
|
||||||
|
subscriptionStatus: 'active',
|
||||||
|
});
|
||||||
|
setCurrentWorkspaceMember({
|
||||||
|
...currentWorkspaceMember,
|
||||||
|
name: {
|
||||||
|
firstName: 'John',
|
||||||
|
lastName: 'Doe',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.onboardingStatus).toBe('ongoing_sync_email');
|
||||||
|
});
|
||||||
|
|
||||||
it('should return "completed"', async () => {
|
it('should return "completed"', async () => {
|
||||||
const { result } = renderHooks();
|
const { result } = renderHooks();
|
||||||
const {
|
const {
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
} = result.current;
|
} = result.current;
|
||||||
@@ -175,10 +227,11 @@ describe('useOnboardingStatus', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
subscriptionStatus: 'active',
|
subscriptionStatus: 'active',
|
||||||
} as CurrentWorkspace);
|
});
|
||||||
setCurrentWorkspaceMember({
|
setCurrentWorkspaceMember({
|
||||||
...currentWorkspaceMember,
|
...currentWorkspaceMember,
|
||||||
name: {
|
name: {
|
||||||
@@ -196,6 +249,7 @@ describe('useOnboardingStatus', () => {
|
|||||||
const {
|
const {
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
} = result.current;
|
} = result.current;
|
||||||
@@ -203,10 +257,11 @@ describe('useOnboardingStatus', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
subscriptionStatus: 'past_due',
|
subscriptionStatus: 'past_due',
|
||||||
} as CurrentWorkspace);
|
});
|
||||||
setCurrentWorkspaceMember({
|
setCurrentWorkspaceMember({
|
||||||
...currentWorkspaceMember,
|
...currentWorkspaceMember,
|
||||||
name: {
|
name: {
|
||||||
@@ -224,6 +279,7 @@ describe('useOnboardingStatus', () => {
|
|||||||
const {
|
const {
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
} = result.current;
|
} = result.current;
|
||||||
@@ -231,10 +287,11 @@ describe('useOnboardingStatus', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
subscriptionStatus: 'unpaid',
|
subscriptionStatus: 'unpaid',
|
||||||
} as CurrentWorkspace);
|
});
|
||||||
setCurrentWorkspaceMember({
|
setCurrentWorkspaceMember({
|
||||||
...currentWorkspaceMember,
|
...currentWorkspaceMember,
|
||||||
name: {
|
name: {
|
||||||
@@ -252,6 +309,7 @@ describe('useOnboardingStatus', () => {
|
|||||||
const {
|
const {
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
setBilling,
|
setBilling,
|
||||||
|
setCurrentUser,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
} = result.current;
|
} = result.current;
|
||||||
@@ -259,6 +317,7 @@ describe('useOnboardingStatus', () => {
|
|||||||
act(() => {
|
act(() => {
|
||||||
setTokenPair(tokenPair);
|
setTokenPair(tokenPair);
|
||||||
setBilling(billing);
|
setBilling(billing);
|
||||||
|
setCurrentUser(currentUser);
|
||||||
setCurrentWorkspace({
|
setCurrentWorkspace({
|
||||||
...currentWorkspace,
|
...currentWorkspace,
|
||||||
subscriptionStatus: 'trialing',
|
subscriptionStatus: 'trialing',
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { billingState } from '@/client-config/states/billingState';
|
import { billingState } from '@/client-config/states/billingState';
|
||||||
@@ -14,12 +15,14 @@ export const useOnboardingStatus = (): OnboardingStatus | undefined => {
|
|||||||
const billing = useRecoilValue(billingState);
|
const billing = useRecoilValue(billingState);
|
||||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||||
|
const currentUser = useRecoilValue(currentUserState);
|
||||||
const isLoggedIn = useIsLogged();
|
const isLoggedIn = useIsLogged();
|
||||||
|
|
||||||
return getOnboardingStatus({
|
return getOnboardingStatus({
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
currentWorkspaceMember,
|
currentWorkspaceMember,
|
||||||
currentWorkspace,
|
currentWorkspace,
|
||||||
|
currentUser,
|
||||||
isBillingEnabled: billing?.isBillingEnabled || false,
|
isBillingEnabled: billing?.isBillingEnabled || false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { User } from '~/generated/graphql';
|
|||||||
|
|
||||||
export type CurrentUser = Pick<
|
export type CurrentUser = Pick<
|
||||||
User,
|
User,
|
||||||
'id' | 'email' | 'supportUserHash' | 'canImpersonate'
|
'id' | 'email' | 'supportUserHash' | 'canImpersonate' | 'state'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export const currentUserState = createState<CurrentUser | null>({
|
export const currentUserState = createState<CurrentUser | null>({
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { CurrentUser } from '@/auth/states/currentUserState';
|
||||||
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
|
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
|
||||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ describe('getOnboardingStatus', () => {
|
|||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
currentWorkspaceMember: null,
|
currentWorkspaceMember: null,
|
||||||
currentWorkspace: null,
|
currentWorkspace: null,
|
||||||
|
currentUser: null,
|
||||||
isBillingEnabled: false,
|
isBillingEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -19,6 +21,9 @@ describe('getOnboardingStatus', () => {
|
|||||||
id: '1',
|
id: '1',
|
||||||
activationStatus: 'inactive',
|
activationStatus: 'inactive',
|
||||||
} as CurrentWorkspace,
|
} as CurrentWorkspace,
|
||||||
|
currentUser: {
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
|
} as CurrentUser,
|
||||||
isBillingEnabled: false,
|
isBillingEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -32,6 +37,28 @@ describe('getOnboardingStatus', () => {
|
|||||||
id: '1',
|
id: '1',
|
||||||
activationStatus: 'active',
|
activationStatus: 'active',
|
||||||
} as CurrentWorkspace,
|
} as CurrentWorkspace,
|
||||||
|
currentUser: {
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
|
} as CurrentUser,
|
||||||
|
isBillingEnabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const ongoingSyncEmail = getOnboardingStatus({
|
||||||
|
isLoggedIn: true,
|
||||||
|
currentWorkspaceMember: {
|
||||||
|
id: '1',
|
||||||
|
name: {
|
||||||
|
firstName: 'John',
|
||||||
|
lastName: 'Doe',
|
||||||
|
},
|
||||||
|
} as WorkspaceMember,
|
||||||
|
currentWorkspace: {
|
||||||
|
id: '1',
|
||||||
|
activationStatus: 'active',
|
||||||
|
} as CurrentWorkspace,
|
||||||
|
currentUser: {
|
||||||
|
state: { skipSyncEmailOnboardingStep: false },
|
||||||
|
} as CurrentUser,
|
||||||
isBillingEnabled: false,
|
isBillingEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -48,6 +75,9 @@ describe('getOnboardingStatus', () => {
|
|||||||
id: '1',
|
id: '1',
|
||||||
activationStatus: 'active',
|
activationStatus: 'active',
|
||||||
} as CurrentWorkspace,
|
} as CurrentWorkspace,
|
||||||
|
currentUser: {
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
|
} as CurrentUser,
|
||||||
isBillingEnabled: false,
|
isBillingEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -65,6 +95,9 @@ describe('getOnboardingStatus', () => {
|
|||||||
activationStatus: 'active',
|
activationStatus: 'active',
|
||||||
subscriptionStatus: 'incomplete',
|
subscriptionStatus: 'incomplete',
|
||||||
} as CurrentWorkspace,
|
} as CurrentWorkspace,
|
||||||
|
currentUser: {
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
|
} as CurrentUser,
|
||||||
isBillingEnabled: true,
|
isBillingEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,6 +115,9 @@ describe('getOnboardingStatus', () => {
|
|||||||
activationStatus: 'active',
|
activationStatus: 'active',
|
||||||
subscriptionStatus: 'incomplete',
|
subscriptionStatus: 'incomplete',
|
||||||
} as CurrentWorkspace,
|
} as CurrentWorkspace,
|
||||||
|
currentUser: {
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
|
} as CurrentUser,
|
||||||
isBillingEnabled: false,
|
isBillingEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -99,12 +135,16 @@ describe('getOnboardingStatus', () => {
|
|||||||
activationStatus: 'active',
|
activationStatus: 'active',
|
||||||
subscriptionStatus: 'canceled',
|
subscriptionStatus: 'canceled',
|
||||||
} as CurrentWorkspace,
|
} as CurrentWorkspace,
|
||||||
|
currentUser: {
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
|
} as CurrentUser,
|
||||||
isBillingEnabled: true,
|
isBillingEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(ongoingUserCreation).toBe('ongoing_user_creation');
|
expect(ongoingUserCreation).toBe('ongoing_user_creation');
|
||||||
expect(ongoingWorkspaceActivation).toBe('ongoing_workspace_activation');
|
expect(ongoingWorkspaceActivation).toBe('ongoing_workspace_activation');
|
||||||
expect(ongoingProfileCreation).toBe('ongoing_profile_creation');
|
expect(ongoingProfileCreation).toBe('ongoing_profile_creation');
|
||||||
|
expect(ongoingSyncEmail).toBe('ongoing_sync_email');
|
||||||
expect(completed).toBe('completed');
|
expect(completed).toBe('completed');
|
||||||
expect(incomplete).toBe('incomplete');
|
expect(incomplete).toBe('incomplete');
|
||||||
expect(canceled).toBe('canceled');
|
expect(canceled).toBe('canceled');
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { CurrentUser } from '@/auth/states/currentUserState';
|
||||||
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
|
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
|
||||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ export enum OnboardingStatus {
|
|||||||
OngoingUserCreation = 'ongoing_user_creation',
|
OngoingUserCreation = 'ongoing_user_creation',
|
||||||
OngoingWorkspaceActivation = 'ongoing_workspace_activation',
|
OngoingWorkspaceActivation = 'ongoing_workspace_activation',
|
||||||
OngoingProfileCreation = 'ongoing_profile_creation',
|
OngoingProfileCreation = 'ongoing_profile_creation',
|
||||||
|
OngoingSyncEmail = 'ongoing_sync_email',
|
||||||
Completed = 'completed',
|
Completed = 'completed',
|
||||||
CompletedWithoutSubscription = 'completed_without_subscription',
|
CompletedWithoutSubscription = 'completed_without_subscription',
|
||||||
}
|
}
|
||||||
@@ -17,6 +19,7 @@ export const getOnboardingStatus = ({
|
|||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
currentWorkspaceMember,
|
currentWorkspaceMember,
|
||||||
currentWorkspace,
|
currentWorkspace,
|
||||||
|
currentUser,
|
||||||
isBillingEnabled,
|
isBillingEnabled,
|
||||||
}: {
|
}: {
|
||||||
isLoggedIn: boolean;
|
isLoggedIn: boolean;
|
||||||
@@ -25,6 +28,7 @@ export const getOnboardingStatus = ({
|
|||||||
'createdAt' | 'updatedAt' | 'userId' | 'userEmail' | '__typename'
|
'createdAt' | 'updatedAt' | 'userId' | 'userEmail' | '__typename'
|
||||||
> | null;
|
> | null;
|
||||||
currentWorkspace: CurrentWorkspace | null;
|
currentWorkspace: CurrentWorkspace | null;
|
||||||
|
currentUser: CurrentUser | null;
|
||||||
isBillingEnabled: boolean;
|
isBillingEnabled: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
if (!isLoggedIn) {
|
if (!isLoggedIn) {
|
||||||
@@ -33,7 +37,7 @@ export const getOnboardingStatus = ({
|
|||||||
|
|
||||||
// After SignInUp, the user should have a current workspace assigned.
|
// After SignInUp, the user should have a current workspace assigned.
|
||||||
// If not, it indicates that the data is still being requested.
|
// If not, it indicates that the data is still being requested.
|
||||||
if (!currentWorkspace) {
|
if (!currentWorkspace || !currentUser) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +59,10 @@ export const getOnboardingStatus = ({
|
|||||||
return OnboardingStatus.OngoingProfileCreation;
|
return OnboardingStatus.OngoingProfileCreation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!currentUser.state.skipSyncEmailOnboardingStep) {
|
||||||
|
return OnboardingStatus.OngoingSyncEmail;
|
||||||
|
}
|
||||||
|
|
||||||
if (isBillingEnabled && currentWorkspace.subscriptionStatus === 'canceled') {
|
if (isBillingEnabled && currentWorkspace.subscriptionStatus === 'canceled') {
|
||||||
return OnboardingStatus.Canceled;
|
return OnboardingStatus.Canceled;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -292,6 +292,66 @@ export const getObjectMetadataItemsMock = () => {
|
|||||||
updatedAt: '2023-11-30T11:13:15.206Z',
|
updatedAt: '2023-11-30T11:13:15.206Z',
|
||||||
fields: [],
|
fields: [],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
__typename: 'object',
|
||||||
|
id: '3aac4582-f677-4d7d-acd5-3e33a039acdd',
|
||||||
|
dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1',
|
||||||
|
nameSingular: 'connectedAccount',
|
||||||
|
namePlural: 'connectedAccounts',
|
||||||
|
labelSingular: 'Connected Account',
|
||||||
|
labelPlural: 'Connected Accounts',
|
||||||
|
description: 'A connected account',
|
||||||
|
icon: 'IconAt',
|
||||||
|
isCustom: false,
|
||||||
|
isRemote: false,
|
||||||
|
isActive: true,
|
||||||
|
isSystem: true,
|
||||||
|
createdAt: '2024-06-01T14:55:04.039Z',
|
||||||
|
updatedAt: '2024-06-01T14:55:04.039Z',
|
||||||
|
labelIdentifierFieldMetadataId: null,
|
||||||
|
imageIdentifierFieldMetadataId: null,
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'object',
|
||||||
|
id: '3aac4582-f677-4d7d-acd5-3e33a039acde',
|
||||||
|
dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1',
|
||||||
|
nameSingular: 'messageChannel',
|
||||||
|
namePlural: 'messageChannels',
|
||||||
|
labelSingular: 'Message Channel',
|
||||||
|
labelPlural: 'Message Channels',
|
||||||
|
description: 'A message channel',
|
||||||
|
icon: 'IconAt',
|
||||||
|
isCustom: false,
|
||||||
|
isRemote: false,
|
||||||
|
isActive: true,
|
||||||
|
isSystem: true,
|
||||||
|
createdAt: '2024-06-01T14:55:04.039Z',
|
||||||
|
updatedAt: '2024-06-01T14:55:04.039Z',
|
||||||
|
labelIdentifierFieldMetadataId: null,
|
||||||
|
imageIdentifierFieldMetadataId: null,
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'object',
|
||||||
|
id: '3aac4582-f677-4d7d-acd5-3e33a039acdf',
|
||||||
|
dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1',
|
||||||
|
nameSingular: 'calendarChannel',
|
||||||
|
namePlural: 'calendarChannels',
|
||||||
|
labelSingular: 'Calendar Channel',
|
||||||
|
labelPlural: 'Calendar Channels',
|
||||||
|
description: 'A calendar channel',
|
||||||
|
icon: 'IconAt',
|
||||||
|
isCustom: false,
|
||||||
|
isRemote: false,
|
||||||
|
isActive: true,
|
||||||
|
isSystem: true,
|
||||||
|
createdAt: '2024-06-01T14:55:04.039Z',
|
||||||
|
updatedAt: '2024-06-01T14:55:04.039Z',
|
||||||
|
labelIdentifierFieldMetadataId: null,
|
||||||
|
imageIdentifierFieldMetadataId: null,
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
__typename: 'object',
|
__typename: 'object',
|
||||||
id: '20202020-cae9-4ff4-9579-f7d9fe44c937',
|
id: '20202020-cae9-4ff4-9579-f7d9fe44c937',
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { onboardingSyncEmailsOptions } from '@/onboarding/components/onboardingSyncEmailsOptions';
|
||||||
|
import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard';
|
||||||
|
import { MessageChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
|
type OnboardingSyncEmailsSettingsCardProps = {
|
||||||
|
onChange: (nextValue: MessageChannelVisibility) => void;
|
||||||
|
value?: MessageChannelVisibility;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OnboardingSyncEmailsSettingsCard = ({
|
||||||
|
onChange,
|
||||||
|
value = MessageChannelVisibility.ShareEverything,
|
||||||
|
}: OnboardingSyncEmailsSettingsCardProps) => (
|
||||||
|
<SettingsAccountsRadioSettingsCard
|
||||||
|
options={onboardingSyncEmailsOptions}
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { SettingsAccountsVisibilitySettingCardMedia } from '@/settings/accounts/components/SettingsAccountsVisibilitySettingCardMedia';
|
||||||
|
import { MessageChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
|
const StyledCardMedia = styled(SettingsAccountsVisibilitySettingCardMedia)`
|
||||||
|
width: ${({ theme }) => theme.spacing(10)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const onboardingSyncEmailsOptions = [
|
||||||
|
{
|
||||||
|
title: 'Everything',
|
||||||
|
description:
|
||||||
|
'Your emails and events content will be shared with your team.',
|
||||||
|
value: MessageChannelVisibility.ShareEverything,
|
||||||
|
cardMedia: (
|
||||||
|
<StyledCardMedia metadata="active" subject="active" body="active" />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Subject and metadata',
|
||||||
|
description:
|
||||||
|
'Your email subjects and meeting titles will be shared with your team.',
|
||||||
|
value: MessageChannelVisibility.Subject,
|
||||||
|
cardMedia: (
|
||||||
|
<StyledCardMedia metadata="active" subject="active" body="inactive" />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Metadata',
|
||||||
|
description:
|
||||||
|
'Only the timestamp & participants will be shared with your team.',
|
||||||
|
value: MessageChannelVisibility.Metadata,
|
||||||
|
cardMedia: (
|
||||||
|
<StyledCardMedia metadata="active" subject="inactive" body="inactive" />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const SKIP_SYNC_EMAIL_ONBOARDING_STEP = gql`
|
||||||
|
mutation SkipSyncEmailOnboardingStep {
|
||||||
|
skipSyncEmailOnboardingStep {
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CalendarChannelVisibility } from '@/accounts/types/CalendarChannel';
|
|
||||||
import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard';
|
import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard';
|
||||||
import { SettingsAccountsVisibilitySettingCardMedia } from '@/settings/accounts/components/SettingsAccountsVisibilitySettingCardMedia';
|
import { SettingsAccountsVisibilitySettingCardMedia } from '@/settings/accounts/components/SettingsAccountsVisibilitySettingCardMedia';
|
||||||
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
type SettingsAccountsEventVisibilitySettingsCardProps = {
|
type SettingsAccountsEventVisibilitySettingsCardProps = {
|
||||||
onChange: (nextValue: CalendarChannelVisibility) => void;
|
onChange: (nextValue: CalendarChannelVisibility) => void;
|
||||||
@@ -17,7 +17,7 @@ const eventSettingsVisibilityOptions = [
|
|||||||
{
|
{
|
||||||
title: 'Everything',
|
title: 'Everything',
|
||||||
description: 'The whole event details will be shared with your team.',
|
description: 'The whole event details will be shared with your team.',
|
||||||
value: CalendarChannelVisibility.Everything,
|
value: CalendarChannelVisibility.ShareEverything,
|
||||||
cardMedia: <StyledCardMedia subject="active" body="active" />,
|
cardMedia: <StyledCardMedia subject="active" body="active" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -30,7 +30,7 @@ const eventSettingsVisibilityOptions = [
|
|||||||
|
|
||||||
export const SettingsAccountsEventVisibilitySettingsCard = ({
|
export const SettingsAccountsEventVisibilitySettingsCard = ({
|
||||||
onChange,
|
onChange,
|
||||||
value = CalendarChannelVisibility.Everything,
|
value = CalendarChannelVisibility.ShareEverything,
|
||||||
}: SettingsAccountsEventVisibilitySettingsCardProps) => (
|
}: SettingsAccountsEventVisibilitySettingsCardProps) => (
|
||||||
<SettingsAccountsRadioSettingsCard
|
<SettingsAccountsRadioSettingsCard
|
||||||
options={eventSettingsVisibilityOptions}
|
options={eventSettingsVisibilityOptions}
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard';
|
import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard';
|
||||||
import { SettingsAccountsVisibilitySettingCardMedia } from '@/settings/accounts/components/SettingsAccountsVisibilitySettingCardMedia';
|
import { SettingsAccountsVisibilitySettingCardMedia } from '@/settings/accounts/components/SettingsAccountsVisibilitySettingCardMedia';
|
||||||
|
import { MessageChannelVisibility } from '~/generated/graphql';
|
||||||
export enum InboxSettingsVisibilityValue {
|
|
||||||
Everything = 'share_everything',
|
|
||||||
SubjectMetadata = 'subject',
|
|
||||||
Metadata = 'metadata',
|
|
||||||
}
|
|
||||||
|
|
||||||
type SettingsAccountsInboxVisibilitySettingsCardProps = {
|
type SettingsAccountsInboxVisibilitySettingsCardProps = {
|
||||||
onChange: (nextValue: InboxSettingsVisibilityValue) => void;
|
onChange: (nextValue: MessageChannelVisibility) => void;
|
||||||
value?: InboxSettingsVisibilityValue;
|
value?: MessageChannelVisibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
const inboxSettingsVisibilityOptions = [
|
const inboxSettingsVisibilityOptions = [
|
||||||
{
|
{
|
||||||
title: 'Everything',
|
title: 'Everything',
|
||||||
description: 'Subject, body and attachments will be shared with your team.',
|
description: 'Subject, body and attachments will be shared with your team.',
|
||||||
value: InboxSettingsVisibilityValue.Everything,
|
value: MessageChannelVisibility.ShareEverything,
|
||||||
cardMedia: (
|
cardMedia: (
|
||||||
<SettingsAccountsVisibilitySettingCardMedia
|
<SettingsAccountsVisibilitySettingCardMedia
|
||||||
metadata="active"
|
metadata="active"
|
||||||
@@ -28,7 +23,7 @@ const inboxSettingsVisibilityOptions = [
|
|||||||
{
|
{
|
||||||
title: 'Subject and metadata',
|
title: 'Subject and metadata',
|
||||||
description: 'Subject and metadata will be shared with your team.',
|
description: 'Subject and metadata will be shared with your team.',
|
||||||
value: InboxSettingsVisibilityValue.SubjectMetadata,
|
value: MessageChannelVisibility.Subject,
|
||||||
cardMedia: (
|
cardMedia: (
|
||||||
<SettingsAccountsVisibilitySettingCardMedia
|
<SettingsAccountsVisibilitySettingCardMedia
|
||||||
metadata="active"
|
metadata="active"
|
||||||
@@ -40,7 +35,7 @@ const inboxSettingsVisibilityOptions = [
|
|||||||
{
|
{
|
||||||
title: 'Metadata',
|
title: 'Metadata',
|
||||||
description: 'Timestamp and participants will be shared with your team.',
|
description: 'Timestamp and participants will be shared with your team.',
|
||||||
value: InboxSettingsVisibilityValue.Metadata,
|
value: MessageChannelVisibility.Metadata,
|
||||||
cardMedia: (
|
cardMedia: (
|
||||||
<SettingsAccountsVisibilitySettingCardMedia
|
<SettingsAccountsVisibilitySettingCardMedia
|
||||||
metadata="active"
|
metadata="active"
|
||||||
@@ -53,7 +48,7 @@ const inboxSettingsVisibilityOptions = [
|
|||||||
|
|
||||||
export const SettingsAccountsInboxVisibilitySettingsCard = ({
|
export const SettingsAccountsInboxVisibilitySettingsCard = ({
|
||||||
onChange,
|
onChange,
|
||||||
value = InboxSettingsVisibilityValue.Everything,
|
value = MessageChannelVisibility.ShareEverything,
|
||||||
}: SettingsAccountsInboxVisibilitySettingsCardProps) => (
|
}: SettingsAccountsInboxVisibilitySettingsCardProps) => (
|
||||||
<SettingsAccountsRadioSettingsCard
|
<SettingsAccountsRadioSettingsCard
|
||||||
options={inboxSettingsVisibilityOptions}
|
options={inboxSettingsVisibilityOptions}
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ export const SettingsAccountsListEmptyStateCard = ({
|
|||||||
}: SettingsAccountsListEmptyStateCardProps) => {
|
}: SettingsAccountsListEmptyStateCardProps) => {
|
||||||
const { triggerGoogleApisOAuth } = useTriggerGoogleApisOAuth();
|
const { triggerGoogleApisOAuth } = useTriggerGoogleApisOAuth();
|
||||||
|
|
||||||
|
const handleOnClick = async () => {
|
||||||
|
await triggerGoogleApisOAuth();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<StyledHeader>{label || 'No connected account'}</StyledHeader>
|
<StyledHeader>{label || 'No connected account'}</StyledHeader>
|
||||||
@@ -35,7 +39,7 @@ export const SettingsAccountsListEmptyStateCard = ({
|
|||||||
Icon={IconGoogle}
|
Icon={IconGoogle}
|
||||||
title="Connect with Google"
|
title="Connect with Google"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={triggerGoogleApisOAuth}
|
onClick={handleOnClick}
|
||||||
/>
|
/>
|
||||||
</StyledBody>
|
</StyledBody>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export const SettingsAccountsRadioSettingsCard = <
|
|||||||
options,
|
options,
|
||||||
value,
|
value,
|
||||||
}: SettingsAccountsRadioSettingsCardProps<Option>) => (
|
}: SettingsAccountsRadioSettingsCardProps<Option>) => (
|
||||||
<Card>
|
<Card rounded>
|
||||||
{options.map((option, index) => (
|
{options.map((option, index) => (
|
||||||
<StyledCardContent
|
<StyledCardContent
|
||||||
key={option.value}
|
key={option.value}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const SettingsAccountsToggleSettingCard = ({
|
|||||||
onToggle,
|
onToggle,
|
||||||
title,
|
title,
|
||||||
}: SettingsAccountsToggleSettingCardProps) => (
|
}: SettingsAccountsToggleSettingCardProps) => (
|
||||||
<Card>
|
<Card rounded>
|
||||||
<StyledCardContent onClick={() => onToggle(!value)}>
|
<StyledCardContent onClick={() => onToggle(!value)}>
|
||||||
{cardMedia}
|
{cardMedia}
|
||||||
<StyledTitle>{title}</StyledTitle>
|
<StyledTitle>{title}</StyledTitle>
|
||||||
|
|||||||
@@ -1,21 +1,47 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||||
import { useGenerateTransientTokenMutation } from '~/generated/graphql';
|
import {
|
||||||
|
CalendarChannelVisibility,
|
||||||
|
MessageChannelVisibility,
|
||||||
|
useGenerateTransientTokenMutation,
|
||||||
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
export const useTriggerGoogleApisOAuth = () => {
|
export const useTriggerGoogleApisOAuth = () => {
|
||||||
const [generateTransientToken] = useGenerateTransientTokenMutation();
|
const [generateTransientToken] = useGenerateTransientTokenMutation();
|
||||||
|
|
||||||
const triggerGoogleApisOAuth = useCallback(async () => {
|
const triggerGoogleApisOAuth = useCallback(
|
||||||
const authServerUrl = REACT_APP_SERVER_BASE_URL;
|
async (
|
||||||
|
redirectLocation?: AppPath,
|
||||||
|
messageVisibility?: MessageChannelVisibility,
|
||||||
|
calendarVisibility?: CalendarChannelVisibility,
|
||||||
|
) => {
|
||||||
|
const authServerUrl = REACT_APP_SERVER_BASE_URL;
|
||||||
|
|
||||||
const transientToken = await generateTransientToken();
|
const transientToken = await generateTransientToken();
|
||||||
|
|
||||||
const token =
|
const token =
|
||||||
transientToken.data?.generateTransientToken.transientToken.token;
|
transientToken.data?.generateTransientToken.transientToken.token;
|
||||||
|
|
||||||
window.location.href = `${authServerUrl}/auth/google-apis?transientToken=${token}`;
|
let params = `transientToken=${token}`;
|
||||||
}, [generateTransientToken]);
|
|
||||||
|
params += redirectLocation
|
||||||
|
? `&redirectLocation=${encodeURIComponent(redirectLocation)}`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
params += calendarVisibility
|
||||||
|
? `&calendarVisibility=${calendarVisibility}`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
params += messageVisibility
|
||||||
|
? `&messageVisibility=${messageVisibility}`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
window.location.href = `${authServerUrl}/auth/google-apis?${params}`;
|
||||||
|
},
|
||||||
|
[generateTransientToken],
|
||||||
|
);
|
||||||
|
|
||||||
return { triggerGoogleApisOAuth };
|
return { triggerGoogleApisOAuth };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export enum AppPath {
|
|||||||
// Onboarding
|
// Onboarding
|
||||||
CreateWorkspace = '/create/workspace',
|
CreateWorkspace = '/create/workspace',
|
||||||
CreateProfile = '/create/profile',
|
CreateProfile = '/create/profile',
|
||||||
|
SyncEmails = '/sync/emails',
|
||||||
PlanRequired = '/plan-required',
|
PlanRequired = '/plan-required',
|
||||||
PlanRequiredSuccess = '/plan-required/payment-success',
|
PlanRequiredSuccess = '/plan-required/payment-success',
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
const StyledCard = styled.div<{ fullWidth?: boolean }>`
|
const StyledCard = styled.div<{ fullWidth?: boolean; rounded?: boolean }>`
|
||||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
border-radius: ${({ theme, rounded }) =>
|
||||||
|
rounded ? theme.border.radius.md : theme.border.radius.sm};
|
||||||
color: ${({ theme }) => theme.font.color.secondary};
|
color: ${({ theme }) => theme.font.color.secondary};
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};
|
width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingUserCreation, res: false },
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingUserCreation, res: false },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingWorkspaceActivation, res: false },
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingWorkspaceActivation, res: false },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingProfileCreation, res: false },
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingProfileCreation, res: false },
|
||||||
|
{ loc: AppPath.Verify, status: OnboardingStatus.OngoingSyncEmail, res: false },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.Verify, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.Verify, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.Verify, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.SignInUp, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.SignInUp, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.Invite, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.Completed, res: true },
|
{ loc: AppPath.Invite, status: OnboardingStatus.Completed, res: true },
|
||||||
{ loc: AppPath.Invite, status: OnboardingStatus.CompletedWithoutSubscription, res: true },
|
{ loc: AppPath.Invite, status: OnboardingStatus.CompletedWithoutSubscription, res: true },
|
||||||
|
|
||||||
@@ -76,6 +79,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.Completed, res: true },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.Completed, res: true },
|
||||||
{ loc: AppPath.ResetPassword, status: OnboardingStatus.CompletedWithoutSubscription, res: true },
|
{ loc: AppPath.ResetPassword, status: OnboardingStatus.CompletedWithoutSubscription, res: true },
|
||||||
|
|
||||||
@@ -86,6 +90,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.CreateWorkspace, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -96,9 +101,21 @@ const testCases = [
|
|||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.CreateProfile, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.CreateProfile, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Incomplete, res: true },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Canceled, res: false },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Unpaid, res: false },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.PastDue, res: false },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.Completed, res: false },
|
||||||
|
{ loc: AppPath.SyncEmails, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Incomplete, res: true },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Incomplete, res: true },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Canceled, res: true },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Canceled, res: true },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Unpaid, res: false },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Unpaid, res: false },
|
||||||
@@ -106,6 +123,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.PlanRequired, status: OnboardingStatus.CompletedWithoutSubscription, res: true },
|
{ loc: AppPath.PlanRequired, status: OnboardingStatus.CompletedWithoutSubscription, res: true },
|
||||||
|
|
||||||
@@ -116,6 +134,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.PlanRequiredSuccess, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -126,6 +145,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Index, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.Index, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.Index, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.Index, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.Index, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -136,6 +156,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.TasksPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.TasksPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -146,6 +167,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.OpportunitiesPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -156,6 +178,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.RecordIndexPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -166,6 +189,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.RecordShowPage, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -176,6 +200,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.SettingsCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -186,6 +211,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.DevelopersCatchAll, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -196,6 +222,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.Impersonate, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.Impersonate, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -206,6 +233,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.Authorize, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.Authorize, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.Authorize, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -216,6 +244,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.NotFoundWildcard, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
|
|
||||||
@@ -226,6 +255,7 @@ const testCases = [
|
|||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingUserCreation, res: true },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingUserCreation, res: true },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingWorkspaceActivation, res: true },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingProfileCreation, res: true },
|
||||||
|
{ loc: AppPath.NotFound, status: OnboardingStatus.OngoingSyncEmail, res: true },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.Completed, res: false },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.Completed, res: false },
|
||||||
{ loc: AppPath.NotFound, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
{ loc: AppPath.NotFound, status: OnboardingStatus.CompletedWithoutSubscription, res: false },
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ export const useShowAuthModal = () => {
|
|||||||
OnboardingStatus.Incomplete === onboardingStatus ||
|
OnboardingStatus.Incomplete === onboardingStatus ||
|
||||||
OnboardingStatus.OngoingUserCreation === onboardingStatus ||
|
OnboardingStatus.OngoingUserCreation === onboardingStatus ||
|
||||||
OnboardingStatus.OngoingProfileCreation === onboardingStatus ||
|
OnboardingStatus.OngoingProfileCreation === onboardingStatus ||
|
||||||
OnboardingStatus.OngoingWorkspaceActivation === onboardingStatus
|
OnboardingStatus.OngoingWorkspaceActivation === onboardingStatus ||
|
||||||
|
OnboardingStatus.OngoingSyncEmail === onboardingStatus
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useQuery } from '@apollo/client';
|
|
||||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
@@ -7,9 +6,8 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMembe
|
|||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { isCurrentUserLoadedState } from '@/auth/states/isCurrentUserLoadingState';
|
import { isCurrentUserLoadedState } from '@/auth/states/isCurrentUserLoadingState';
|
||||||
import { workspacesState } from '@/auth/states/workspaces';
|
import { workspacesState } from '@/auth/states/workspaces';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
|
||||||
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||||
import { User } from '~/generated/graphql';
|
import { useGetCurrentUserQuery } from '~/generated/graphql';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
export const UserProviderEffect = () => {
|
export const UserProviderEffect = () => {
|
||||||
@@ -26,9 +24,7 @@ export const UserProviderEffect = () => {
|
|||||||
currentWorkspaceMemberState,
|
currentWorkspaceMemberState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { loading: queryLoading, data: queryData } = useQuery<{
|
const { loading: queryLoading, data: queryData } = useGetCurrentUserQuery({
|
||||||
currentUser: User;
|
|
||||||
}>(GET_CURRENT_USER, {
|
|
||||||
skip: isCurrentUserLoaded,
|
skip: isCurrentUserLoaded,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ export const USER_QUERY_FRAGMENT = gql`
|
|||||||
email
|
email
|
||||||
canImpersonate
|
canImpersonate
|
||||||
supportUserHash
|
supportUserHash
|
||||||
|
state {
|
||||||
|
skipSyncEmailOnboardingStep
|
||||||
|
}
|
||||||
workspaceMember {
|
workspaceMember {
|
||||||
id
|
id
|
||||||
name {
|
name {
|
||||||
|
|||||||
@@ -4,52 +4,7 @@ import { gql } from '@apollo/client';
|
|||||||
export const GET_CURRENT_USER = gql`
|
export const GET_CURRENT_USER = gql`
|
||||||
query GetCurrentUser {
|
query GetCurrentUser {
|
||||||
currentUser {
|
currentUser {
|
||||||
id
|
...UserQueryFragment
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
email
|
|
||||||
canImpersonate
|
|
||||||
supportUserHash
|
|
||||||
workspaceMember {
|
|
||||||
id
|
|
||||||
name {
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
colorScheme
|
|
||||||
avatarUrl
|
|
||||||
locale
|
|
||||||
}
|
|
||||||
defaultWorkspace {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
logo
|
|
||||||
domainName
|
|
||||||
inviteHash
|
|
||||||
allowImpersonation
|
|
||||||
subscriptionStatus
|
|
||||||
activationStatus
|
|
||||||
featureFlags {
|
|
||||||
id
|
|
||||||
key
|
|
||||||
value
|
|
||||||
workspaceId
|
|
||||||
}
|
|
||||||
currentCacheVersion
|
|
||||||
currentBillingSubscription {
|
|
||||||
id
|
|
||||||
status
|
|
||||||
interval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
workspaces {
|
|
||||||
workspace {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
logo
|
|
||||||
domainName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
@@ -16,7 +15,6 @@ import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
|||||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '@/object-metadata/graphql/queries';
|
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '@/object-metadata/graphql/queries';
|
||||||
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
|
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
|
||||||
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
|
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
|
||||||
import { AppPath } from '@/types/AppPath';
|
|
||||||
import { Loader } from '@/ui/feedback/loader/components/Loader';
|
import { Loader } from '@/ui/feedback/loader/components/Loader';
|
||||||
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';
|
||||||
@@ -47,8 +45,6 @@ const validationSchema = z
|
|||||||
type Form = z.infer<typeof validationSchema>;
|
type Form = z.infer<typeof validationSchema>;
|
||||||
|
|
||||||
export const CreateWorkspace = () => {
|
export const CreateWorkspace = () => {
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const { enqueueSnackBar } = useSnackBar();
|
const { enqueueSnackBar } = useSnackBar();
|
||||||
const onboardingStatus = useOnboardingStatus();
|
const onboardingStatus = useOnboardingStatus();
|
||||||
|
|
||||||
@@ -88,10 +84,6 @@ export const CreateWorkspace = () => {
|
|||||||
if (isDefined(result.errors)) {
|
if (isDefined(result.errors)) {
|
||||||
throw result.errors ?? new Error('Unknown error');
|
throw result.errors ?? new Error('Unknown error');
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
navigate(AppPath.CreateProfile);
|
|
||||||
}, 20);
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
enqueueSnackBar(error?.message, {
|
enqueueSnackBar(error?.message, {
|
||||||
variant: SnackBarVariant.Error,
|
variant: SnackBarVariant.Error,
|
||||||
@@ -102,7 +94,6 @@ export const CreateWorkspace = () => {
|
|||||||
activateWorkspace,
|
activateWorkspace,
|
||||||
setIsCurrentUserLoaded,
|
setIsCurrentUserLoaded,
|
||||||
apolloMetadataClient,
|
apolloMetadataClient,
|
||||||
navigate,
|
|
||||||
enqueueSnackBar,
|
enqueueSnackBar,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
94
packages/twenty-front/src/pages/onboarding/SyncEmails.tsx
Normal file
94
packages/twenty-front/src/pages/onboarding/SyncEmails.tsx
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
import { IconGoogle } from 'twenty-ui';
|
||||||
|
|
||||||
|
import { SubTitle } from '@/auth/components/SubTitle';
|
||||||
|
import { Title } from '@/auth/components/Title';
|
||||||
|
import { isCurrentUserLoadedState } from '@/auth/states/isCurrentUserLoadingState';
|
||||||
|
import { OnboardingSyncEmailsSettingsCard } from '@/onboarding/components/OnboardingSyncEmailsSettingsCard';
|
||||||
|
import { useTriggerGoogleApisOAuth } from '@/settings/accounts/hooks/useTriggerGoogleApisOAuth';
|
||||||
|
import { AppPath } from '@/types/AppPath';
|
||||||
|
import { MainButton } from '@/ui/input/button/components/MainButton';
|
||||||
|
import { ActionLink } from '@/ui/navigation/link/components/ActionLink';
|
||||||
|
import {
|
||||||
|
CalendarChannelVisibility,
|
||||||
|
MessageChannelVisibility,
|
||||||
|
useSkipSyncEmailOnboardingStepMutation,
|
||||||
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
|
const StyledSyncEmailsContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
margin: ${({ theme }) => theme.spacing(8)} 0;
|
||||||
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledActionLinkContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin: ${({ theme }) => theme.spacing(3)} 0 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const SyncEmails = () => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { triggerGoogleApisOAuth } = useTriggerGoogleApisOAuth();
|
||||||
|
const setIsCurrentUserLoaded = useSetRecoilState(isCurrentUserLoadedState);
|
||||||
|
const [visibility, setVisibility] = useState<MessageChannelVisibility>(
|
||||||
|
MessageChannelVisibility.ShareEverything,
|
||||||
|
);
|
||||||
|
const [skipSyncEmailOnboardingStepMutation] =
|
||||||
|
useSkipSyncEmailOnboardingStepMutation();
|
||||||
|
|
||||||
|
const handleButtonClick = async () => {
|
||||||
|
const calendarChannelVisibility =
|
||||||
|
visibility === MessageChannelVisibility.ShareEverything
|
||||||
|
? CalendarChannelVisibility.ShareEverything
|
||||||
|
: CalendarChannelVisibility.Metadata;
|
||||||
|
|
||||||
|
await triggerGoogleApisOAuth(
|
||||||
|
AppPath.Index,
|
||||||
|
visibility,
|
||||||
|
calendarChannelVisibility,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const continueWithoutSync = async () => {
|
||||||
|
await skipSyncEmailOnboardingStepMutation();
|
||||||
|
setIsCurrentUserLoaded(false);
|
||||||
|
navigate(AppPath.Index);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSubmitting = false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Title withMarginTop={false}>Emails and Calendar</Title>
|
||||||
|
<SubTitle>
|
||||||
|
Sync your Emails and Calendar with Twenty. Choose your privacy settings.
|
||||||
|
</SubTitle>
|
||||||
|
<StyledSyncEmailsContainer>
|
||||||
|
<OnboardingSyncEmailsSettingsCard
|
||||||
|
value={visibility}
|
||||||
|
onChange={setVisibility}
|
||||||
|
/>
|
||||||
|
</StyledSyncEmailsContainer>
|
||||||
|
<MainButton
|
||||||
|
title="Sync with Google"
|
||||||
|
onClick={handleButtonClick}
|
||||||
|
width={200}
|
||||||
|
Icon={() => <IconGoogle size={theme.icon.size.sm} />}
|
||||||
|
disabled={isSubmitting}
|
||||||
|
/>
|
||||||
|
<StyledActionLinkContainer>
|
||||||
|
<ActionLink onClick={continueWithoutSync}>
|
||||||
|
Continue without sync
|
||||||
|
</ActionLink>
|
||||||
|
</StyledActionLinkContainer>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -5,6 +5,7 @@ import { graphql, HttpResponse } from 'msw';
|
|||||||
|
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
||||||
|
import { ChooseYourPlan } from '~/pages/onboarding/ChooseYourPlan';
|
||||||
import {
|
import {
|
||||||
PageDecorator,
|
PageDecorator,
|
||||||
PageDecoratorArgs,
|
PageDecoratorArgs,
|
||||||
@@ -13,10 +14,8 @@ import { graphqlMocks } from '~/testing/graphqlMocks';
|
|||||||
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
||||||
import { sleep } from '~/testing/sleep';
|
import { sleep } from '~/testing/sleep';
|
||||||
|
|
||||||
import { ChooseYourPlan } from '../ChooseYourPlan';
|
|
||||||
|
|
||||||
const meta: Meta<PageDecoratorArgs> = {
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
title: 'Pages/Auth/ChooseYourPlan',
|
title: 'Pages/Onboarding/ChooseYourPlan',
|
||||||
component: ChooseYourPlan,
|
component: ChooseYourPlan,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: { routePath: AppPath.PlanRequired },
|
args: { routePath: AppPath.PlanRequired },
|
||||||
@@ -5,6 +5,7 @@ import { graphql, HttpResponse } from 'msw';
|
|||||||
|
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
||||||
|
import { CreateProfile } from '~/pages/onboarding/CreateProfile';
|
||||||
import {
|
import {
|
||||||
PageDecorator,
|
PageDecorator,
|
||||||
PageDecoratorArgs,
|
PageDecoratorArgs,
|
||||||
@@ -12,10 +13,8 @@ import {
|
|||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
||||||
|
|
||||||
import { CreateProfile } from '../CreateProfile';
|
|
||||||
|
|
||||||
const meta: Meta<PageDecoratorArgs> = {
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
title: 'Pages/Auth/CreateProfile',
|
title: 'Pages/Onboarding/CreateProfile',
|
||||||
component: CreateProfile,
|
component: CreateProfile,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: { routePath: AppPath.CreateProfile },
|
args: { routePath: AppPath.CreateProfile },
|
||||||
@@ -7,6 +7,7 @@ import { useSetRecoilState } from 'recoil';
|
|||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
||||||
|
import { CreateWorkspace } from '~/pages/onboarding/CreateWorkspace';
|
||||||
import {
|
import {
|
||||||
PageDecorator,
|
PageDecorator,
|
||||||
PageDecoratorArgs,
|
PageDecoratorArgs,
|
||||||
@@ -14,10 +15,8 @@ import {
|
|||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
||||||
|
|
||||||
import { CreateWorkspace } from '../CreateWorkspace';
|
|
||||||
|
|
||||||
const meta: Meta<PageDecoratorArgs> = {
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
title: 'Pages/Auth/CreateWorkspace',
|
title: 'Pages/Onboarding/CreateWorkspace',
|
||||||
component: CreateWorkspace,
|
component: CreateWorkspace,
|
||||||
decorators: [
|
decorators: [
|
||||||
(Story) => {
|
(Story) => {
|
||||||
@@ -5,6 +5,7 @@ import { graphql, HttpResponse } from 'msw';
|
|||||||
|
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
||||||
|
import { PaymentSuccess } from '~/pages/onboarding/PaymentSuccess';
|
||||||
import {
|
import {
|
||||||
PageDecorator,
|
PageDecorator,
|
||||||
PageDecoratorArgs,
|
PageDecoratorArgs,
|
||||||
@@ -12,10 +13,8 @@ import {
|
|||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
||||||
|
|
||||||
import { PaymentSuccess } from '../PaymentSuccess';
|
|
||||||
|
|
||||||
const meta: Meta<PageDecoratorArgs> = {
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
title: 'Pages/Auth/PaymentSuccess',
|
title: 'Pages/Onboarding/PaymentSuccess',
|
||||||
component: PaymentSuccess,
|
component: PaymentSuccess,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: { routePath: AppPath.PlanRequiredSuccess },
|
args: { routePath: AppPath.PlanRequiredSuccess },
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { within } from '@storybook/test';
|
||||||
|
import { graphql, HttpResponse } from 'msw';
|
||||||
|
|
||||||
|
import { AppPath } from '~/modules/types/AppPath';
|
||||||
|
import { GET_CURRENT_USER } from '~/modules/users/graphql/queries/getCurrentUser';
|
||||||
|
import { SyncEmails } from '~/pages/onboarding/SyncEmails';
|
||||||
|
import {
|
||||||
|
PageDecorator,
|
||||||
|
PageDecoratorArgs,
|
||||||
|
} from '~/testing/decorators/PageDecorator';
|
||||||
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
|
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
|
||||||
|
|
||||||
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
|
title: 'Pages/Onboarding/SyncEmails',
|
||||||
|
component: SyncEmails,
|
||||||
|
decorators: [PageDecorator],
|
||||||
|
args: { routePath: AppPath.SyncEmails },
|
||||||
|
parameters: {
|
||||||
|
msw: {
|
||||||
|
handlers: [
|
||||||
|
graphql.query(getOperationName(GET_CURRENT_USER) ?? '', () => {
|
||||||
|
return HttpResponse.json({
|
||||||
|
data: {
|
||||||
|
currentUser: mockedOnboardingUsersData[0],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
graphqlMocks.handlers,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export type Story = StoryObj<typeof SyncEmails>;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
await canvas.findByText('Emails and Calendar');
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -17,10 +17,8 @@ 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 { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||||
import {
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
TimelineCalendarEvent,
|
import { TimelineCalendarEvent } from '~/generated-metadata/graphql';
|
||||||
TimelineCalendarEventVisibility,
|
|
||||||
} from '~/generated-metadata/graphql';
|
|
||||||
|
|
||||||
export const SettingsAccountsCalendars = () => {
|
export const SettingsAccountsCalendars = () => {
|
||||||
const calendarSettingsEnabled = false;
|
const calendarSettingsEnabled = false;
|
||||||
@@ -79,7 +77,7 @@ export const SettingsAccountsCalendars = () => {
|
|||||||
isCanceled: false,
|
isCanceled: false,
|
||||||
location: '',
|
location: '',
|
||||||
title: 'Onboarding call',
|
title: 'Onboarding call',
|
||||||
visibility: TimelineCalendarEventVisibility.ShareEverything,
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ import { useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { H2Title, IconRefresh, IconSettings, IconUser } from 'twenty-ui';
|
import { H2Title, IconRefresh, IconSettings, IconUser } from 'twenty-ui';
|
||||||
|
|
||||||
import {
|
import { CalendarChannel } from '@/accounts/types/CalendarChannel';
|
||||||
CalendarChannel,
|
|
||||||
CalendarChannelVisibility,
|
|
||||||
} from '@/accounts/types/CalendarChannel';
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||||
@@ -21,6 +18,7 @@ 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 { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||||
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
const StyledCardMedia = styled(SettingsAccountsCardMedia)`
|
const StyledCardMedia = styled(SettingsAccountsCardMedia)`
|
||||||
height: ${({ theme }) => theme.spacing(6)};
|
height: ${({ theme }) => theme.spacing(6)};
|
||||||
|
|||||||
@@ -8,16 +8,14 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
|
|||||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||||
import { SettingsAccountsCardMedia } from '@/settings/accounts/components/SettingsAccountsCardMedia';
|
import { SettingsAccountsCardMedia } from '@/settings/accounts/components/SettingsAccountsCardMedia';
|
||||||
import {
|
import { SettingsAccountsInboxVisibilitySettingsCard } from '@/settings/accounts/components/SettingsAccountsInboxVisibilitySettingsCard';
|
||||||
InboxSettingsVisibilityValue,
|
|
||||||
SettingsAccountsInboxVisibilitySettingsCard,
|
|
||||||
} from '@/settings/accounts/components/SettingsAccountsInboxVisibilitySettingsCard';
|
|
||||||
import { SettingsAccountsToggleSettingCard } from '@/settings/accounts/components/SettingsAccountsToggleSettingCard';
|
import { SettingsAccountsToggleSettingCard } from '@/settings/accounts/components/SettingsAccountsToggleSettingCard';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
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 { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||||
|
import { MessageChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
export const SettingsAccountsEmailsInboxSettings = () => {
|
export const SettingsAccountsEmailsInboxSettings = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@@ -33,7 +31,7 @@ export const SettingsAccountsEmailsInboxSettings = () => {
|
|||||||
objectNameSingular: CoreObjectNameSingular.MessageChannel,
|
objectNameSingular: CoreObjectNameSingular.MessageChannel,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleVisibilityChange = (value: InboxSettingsVisibilityValue) => {
|
const handleVisibilityChange = (value: MessageChannelVisibility) => {
|
||||||
updateOneRecord({
|
updateOneRecord({
|
||||||
idToUpdate: messageChannelId,
|
idToUpdate: messageChannelId,
|
||||||
updateOneRecordInput: {
|
updateOneRecordInput: {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Meta, StoryObj } from '@storybook/react';
|
|||||||
import { within } from '@storybook/test';
|
import { within } from '@storybook/test';
|
||||||
import { graphql, HttpResponse } from 'msw';
|
import { graphql, HttpResponse } from 'msw';
|
||||||
|
|
||||||
|
import { MessageChannelVisibility } from '~/generated/graphql';
|
||||||
import { SettingsAccountsEmailsInboxSettings } from '~/pages/settings/accounts/SettingsAccountsEmailsInboxSettings';
|
import { SettingsAccountsEmailsInboxSettings } from '~/pages/settings/accounts/SettingsAccountsEmailsInboxSettings';
|
||||||
import {
|
import {
|
||||||
PageDecorator,
|
PageDecorator,
|
||||||
@@ -26,7 +27,7 @@ const meta: Meta<PageDecoratorArgs> = {
|
|||||||
data: {
|
data: {
|
||||||
messageChannel: {
|
messageChannel: {
|
||||||
id: '1',
|
id: '1',
|
||||||
visibility: 'share_everything',
|
visibility: MessageChannelVisibility.ShareEverything,
|
||||||
messageThreads: { edges: [] },
|
messageThreads: { edges: [] },
|
||||||
createdAt: '2021-08-27T12:00:00Z',
|
createdAt: '2021-08-27T12:00:00Z',
|
||||||
type: 'email',
|
type: 'email',
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { addDays, subHours, subMonths } from 'date-fns';
|
import { addDays, subHours, subMonths } from 'date-fns';
|
||||||
|
|
||||||
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
|
||||||
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
|
|
||||||
export const mockedCalendarEvents: CalendarEvent[] = [
|
export const mockedCalendarEvents: CalendarEvent[] = [
|
||||||
{
|
{
|
||||||
@@ -9,7 +10,7 @@ export const mockedCalendarEvents: CalendarEvent[] = [
|
|||||||
id: '9a6b35f1-6078-415b-9540-f62671bb81d0',
|
id: '9a6b35f1-6078-415b-9540-f62671bb81d0',
|
||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
startsAt: addDays(new Date().setHours(10, 0), 1).toISOString(),
|
startsAt: addDays(new Date().setHours(10, 0), 1).toISOString(),
|
||||||
visibility: 'METADATA',
|
visibility: CalendarChannelVisibility.Metadata,
|
||||||
calendarEventParticipants: [
|
calendarEventParticipants: [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -43,7 +44,7 @@ export const mockedCalendarEvents: CalendarEvent[] = [
|
|||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
startsAt: new Date(new Date().setHours(18, 0)).toISOString(),
|
startsAt: new Date(new Date().setHours(18, 0)).toISOString(),
|
||||||
title: 'Bug solving',
|
title: 'Bug solving',
|
||||||
visibility: 'SHARE_EVERYTHING',
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -53,7 +54,7 @@ export const mockedCalendarEvents: CalendarEvent[] = [
|
|||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
startsAt: new Date(new Date().setHours(15, 15)).toISOString(),
|
startsAt: new Date(new Date().setHours(15, 15)).toISOString(),
|
||||||
title: 'Onboarding Follow-Up Call',
|
title: 'Onboarding Follow-Up Call',
|
||||||
visibility: 'SHARE_EVERYTHING',
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -63,7 +64,7 @@ export const mockedCalendarEvents: CalendarEvent[] = [
|
|||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
startsAt: new Date(new Date().setHours(10, 0)).toISOString(),
|
startsAt: new Date(new Date().setHours(10, 0)).toISOString(),
|
||||||
title: 'Onboarding Call',
|
title: 'Onboarding Call',
|
||||||
visibility: 'SHARE_EVERYTHING',
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -71,7 +72,7 @@ export const mockedCalendarEvents: CalendarEvent[] = [
|
|||||||
id: '5a792d11-259a-4099-af51-59eb85e15d83',
|
id: '5a792d11-259a-4099-af51-59eb85e15d83',
|
||||||
isFullDay: true,
|
isFullDay: true,
|
||||||
startsAt: subMonths(new Date().setHours(8, 0), 1).toISOString(),
|
startsAt: subMonths(new Date().setHours(8, 0), 1).toISOString(),
|
||||||
visibility: 'METADATA',
|
visibility: CalendarChannelVisibility.Metadata,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -81,7 +82,7 @@ export const mockedCalendarEvents: CalendarEvent[] = [
|
|||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
startsAt: subMonths(new Date().setHours(14, 0), 3).toISOString(),
|
startsAt: subMonths(new Date().setHours(14, 0), 3).toISOString(),
|
||||||
title: 'Alan x Garry',
|
title: 'Alan x Garry',
|
||||||
visibility: 'SHARE_EVERYTHING',
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
__typename: 'CalendarEvent',
|
__typename: 'CalendarEvent',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
ObjectEdge,
|
ObjectEdge,
|
||||||
ObjectMetadataItemsQuery,
|
ObjectMetadataItemsQuery,
|
||||||
} from '~/generated-metadata/graphql';
|
} from '~/generated-metadata/graphql';
|
||||||
|
import { CalendarChannelVisibility, MessageChannelVisibility } from "~/generated/graphql";
|
||||||
|
|
||||||
// This file is not designed to be manually edited.
|
// This file is not designed to be manually edited.
|
||||||
// It's an extract from the dev seeded environment metadata call
|
// It's an extract from the dev seeded environment metadata call
|
||||||
@@ -2924,20 +2925,20 @@ export const mockedStandardObjectMetadataQueryResult: ObjectMetadataItemsQuery =
|
|||||||
isNullable: false,
|
isNullable: false,
|
||||||
createdAt: '2024-04-08T12:48:49.538Z',
|
createdAt: '2024-04-08T12:48:49.538Z',
|
||||||
updatedAt: '2024-04-08T12:48:49.538Z',
|
updatedAt: '2024-04-08T12:48:49.538Z',
|
||||||
defaultValue: "'SHARE_EVERYTHING'",
|
defaultValue: `'${CalendarChannelVisibility.ShareEverything}'`,
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
id: 'b60eeb97-c67b-4d01-b647-1143d58ed49f',
|
id: 'b60eeb97-c67b-4d01-b647-1143d58ed49f',
|
||||||
color: 'green',
|
color: 'green',
|
||||||
label: 'Metadata',
|
label: 'Metadata',
|
||||||
value: 'METADATA',
|
value: CalendarChannelVisibility.Metadata,
|
||||||
position: 0,
|
position: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '7064c804-deb0-4f65-b7d6-3fe4df9a474c',
|
id: '7064c804-deb0-4f65-b7d6-3fe4df9a474c',
|
||||||
color: 'orange',
|
color: 'orange',
|
||||||
label: 'Share Everything',
|
label: 'Share Everything',
|
||||||
value: 'SHARE_EVERYTHING',
|
value: CalendarChannelVisibility.ShareEverything,
|
||||||
position: 1,
|
position: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -7044,27 +7045,27 @@ export const mockedStandardObjectMetadataQueryResult: ObjectMetadataItemsQuery =
|
|||||||
isNullable: false,
|
isNullable: false,
|
||||||
createdAt: '2024-04-08T12:48:49.538Z',
|
createdAt: '2024-04-08T12:48:49.538Z',
|
||||||
updatedAt: '2024-04-08T12:48:49.538Z',
|
updatedAt: '2024-04-08T12:48:49.538Z',
|
||||||
defaultValue: "'share_everything'",
|
defaultValue: `'${MessageChannelVisibility.ShareEverything}'`,
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
id: '112e7633-0451-4f7e-bc79-f988b78fabb8',
|
id: '112e7633-0451-4f7e-bc79-f988b78fabb8',
|
||||||
color: 'green',
|
color: 'green',
|
||||||
label: 'Metadata',
|
label: 'Metadata',
|
||||||
value: 'metadata',
|
value: MessageChannelVisibility.Metadata,
|
||||||
position: 0,
|
position: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '148143c4-882d-4c94-b8db-ead6f4581ab1',
|
id: '148143c4-882d-4c94-b8db-ead6f4581ab1',
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
label: 'Subject',
|
label: 'Subject',
|
||||||
value: 'subject',
|
value: MessageChannelVisibility.Subject,
|
||||||
position: 1,
|
position: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '9bf90844-93cf-4c0a-95e9-02f7d5fa397f',
|
id: '9bf90844-93cf-4c0a-95e9-02f7d5fa397f',
|
||||||
color: 'orange',
|
color: 'orange',
|
||||||
label: 'Share Everything',
|
label: 'Share Everything',
|
||||||
value: 'share_everything',
|
value: MessageChannelVisibility.ShareEverything,
|
||||||
position: 2,
|
position: 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import {
|
import { CalendarChannelVisibility } from '~/generated/graphql';
|
||||||
TimelineCalendarEvent,
|
import { TimelineCalendarEvent } from '~/generated-metadata/graphql';
|
||||||
TimelineCalendarEventVisibility,
|
|
||||||
} from '~/generated-metadata/graphql';
|
|
||||||
|
|
||||||
export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
|
export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
|
||||||
{
|
{
|
||||||
@@ -18,7 +16,7 @@ export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
|
|||||||
},
|
},
|
||||||
conferenceSolution: 'GOOGLE_MEET',
|
conferenceSolution: 'GOOGLE_MEET',
|
||||||
isCanceled: false,
|
isCanceled: false,
|
||||||
visibility: TimelineCalendarEventVisibility.ShareEverything,
|
visibility: CalendarChannelVisibility.ShareEverything,
|
||||||
isFullDay: false,
|
isFullDay: false,
|
||||||
participants: [
|
participants: [
|
||||||
{
|
{
|
||||||
@@ -58,7 +56,7 @@ export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
|
|||||||
},
|
},
|
||||||
conferenceSolution: 'GOOGLE_MEET',
|
conferenceSolution: 'GOOGLE_MEET',
|
||||||
isCanceled: false,
|
isCanceled: false,
|
||||||
visibility: TimelineCalendarEventVisibility.Metadata,
|
visibility: CalendarChannelVisibility.Metadata,
|
||||||
participants: [
|
participants: [
|
||||||
{
|
{
|
||||||
__typename: 'TimelineCalendarEventParticipant',
|
__typename: 'TimelineCalendarEventParticipant',
|
||||||
@@ -87,7 +85,7 @@ export const mockedTimelineCalendarEvents: TimelineCalendarEvent[] = [
|
|||||||
},
|
},
|
||||||
conferenceSolution: 'GOOGLE_MEET',
|
conferenceSolution: 'GOOGLE_MEET',
|
||||||
isCanceled: false,
|
isCanceled: false,
|
||||||
visibility: TimelineCalendarEventVisibility.Metadata,
|
visibility: CalendarChannelVisibility.Metadata,
|
||||||
participants: [
|
participants: [
|
||||||
{
|
{
|
||||||
__typename: 'TimelineCalendarEventParticipant',
|
__typename: 'TimelineCalendarEventParticipant',
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ type MockedUser = Pick<
|
|||||||
| 'canImpersonate'
|
| 'canImpersonate'
|
||||||
| '__typename'
|
| '__typename'
|
||||||
| 'supportUserHash'
|
| 'supportUserHash'
|
||||||
|
| 'state'
|
||||||
> & {
|
> & {
|
||||||
workspaceMember: WorkspaceMember | null;
|
workspaceMember: WorkspaceMember | null;
|
||||||
locale: string;
|
locale: string;
|
||||||
@@ -92,6 +93,7 @@ export const mockedUsersData: Array<MockedUser> = [
|
|||||||
defaultWorkspace: mockDefaultWorkspace,
|
defaultWorkspace: mockDefaultWorkspace,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
workspaces: [{ workspace: mockDefaultWorkspace }],
|
workspaces: [{ workspace: mockDefaultWorkspace }],
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6c',
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6c',
|
||||||
@@ -114,6 +116,7 @@ export const mockedUsersData: Array<MockedUser> = [
|
|||||||
defaultWorkspace: mockDefaultWorkspace,
|
defaultWorkspace: mockDefaultWorkspace,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
workspaces: [{ workspace: mockDefaultWorkspace }],
|
workspaces: [{ workspace: mockDefaultWorkspace }],
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -140,6 +143,7 @@ export const mockedOnboardingUsersData: Array<MockedUser> = [
|
|||||||
defaultWorkspace: mockDefaultWorkspace,
|
defaultWorkspace: mockDefaultWorkspace,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
workspaces: [{ workspace: mockDefaultWorkspace }],
|
workspaces: [{ workspace: mockDefaultWorkspace }],
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d',
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d',
|
||||||
@@ -155,5 +159,6 @@ export const mockedOnboardingUsersData: Array<MockedUser> = [
|
|||||||
},
|
},
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
workspaces: [{ workspace: mockDefaultWorkspace }],
|
workspaces: [{ workspace: mockDefaultWorkspace }],
|
||||||
|
state: { skipSyncEmailOnboardingStep: true },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ import { StopDataSeedDemoWorkspaceCronCommand } from 'src/database/commands/data
|
|||||||
import { WorkspaceAddTotalCountCommand } from 'src/database/commands/workspace-add-total-count.command';
|
import { WorkspaceAddTotalCountCommand } from 'src/database/commands/workspace-add-total-count.command';
|
||||||
import { DataSeedDemoWorkspaceCommand } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace-command';
|
import { DataSeedDemoWorkspaceCommand } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace-command';
|
||||||
import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module';
|
import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module';
|
||||||
import { UpdateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/0-20-update-message-channel-sync-status-enum.command';
|
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { UpdateMessageChannelVisibilityEnumCommand } from 'src/database/commands/update-message-channel-visibility-enum.command';
|
||||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module';
|
import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module';
|
||||||
|
import { UpdateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/0-20-update-message-channel-sync-status-enum.command';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@@ -45,6 +46,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
|||||||
ConfirmationQuestion,
|
ConfirmationQuestion,
|
||||||
StartDataSeedDemoWorkspaceCronCommand,
|
StartDataSeedDemoWorkspaceCronCommand,
|
||||||
StopDataSeedDemoWorkspaceCronCommand,
|
StopDataSeedDemoWorkspaceCronCommand,
|
||||||
|
UpdateMessageChannelVisibilityEnumCommand,
|
||||||
UpdateMessageChannelSyncStatusEnumCommand,
|
UpdateMessageChannelSyncStatusEnumCommand,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Logger } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
|
||||||
|
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||||
|
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
|
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
|
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
||||||
|
|
||||||
|
interface UpdateMessageChannelVisibilityEnumCommandOptions {
|
||||||
|
workspaceId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Command({
|
||||||
|
name: 'migrate-0.20:update-message-channel-visibility-enum',
|
||||||
|
description:
|
||||||
|
'Change the messageChannel visibility type and update records.visibility',
|
||||||
|
})
|
||||||
|
export class UpdateMessageChannelVisibilityEnumCommand extends CommandRunner {
|
||||||
|
private readonly logger = new Logger(
|
||||||
|
UpdateMessageChannelVisibilityEnumCommand.name,
|
||||||
|
);
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(Workspace, 'core')
|
||||||
|
private readonly workspaceRepository: Repository<Workspace>,
|
||||||
|
@InjectRepository(FieldMetadataEntity, 'metadata')
|
||||||
|
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||||
|
private readonly typeORMService: TypeORMService,
|
||||||
|
private readonly dataSourceService: DataSourceService,
|
||||||
|
private readonly workspaceCacheVersionService: WorkspaceCacheVersionService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Option({
|
||||||
|
flags: '-w, --workspace-id [workspace_id]',
|
||||||
|
description: 'workspace id. Command runs on all workspaces if not provided',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
parseWorkspaceId(value: string): string {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(
|
||||||
|
_passedParam: string[],
|
||||||
|
options: UpdateMessageChannelVisibilityEnumCommandOptions,
|
||||||
|
): Promise<void> {
|
||||||
|
let workspaceIds: string[] = [];
|
||||||
|
|
||||||
|
if (options.workspaceId) {
|
||||||
|
workspaceIds = [options.workspaceId];
|
||||||
|
} else {
|
||||||
|
workspaceIds = (await this.workspaceRepository.find()).map(
|
||||||
|
(workspace) => workspace.id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workspaceIds.length) {
|
||||||
|
this.logger.log(chalk.yellow('No workspace found'));
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.logger.log(
|
||||||
|
chalk.green(`Running command on ${workspaceIds.length} workspaces`),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const workspaceId of workspaceIds) {
|
||||||
|
const dataSourceMetadatas =
|
||||||
|
await this.dataSourceService.getDataSourcesMetadataFromWorkspaceId(
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const dataSourceMetadata of dataSourceMetadatas) {
|
||||||
|
const workspaceDataSource =
|
||||||
|
await this.typeORMService.connectToDataSource(dataSourceMetadata);
|
||||||
|
|
||||||
|
if (workspaceDataSource) {
|
||||||
|
const queryRunner = workspaceDataSource.createQueryRunner();
|
||||||
|
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
const newMessageChannelVisibilities = Object.values(
|
||||||
|
MessageChannelVisibility,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "${dataSourceMetadata.schema}"."messageChannel_visibility_enum" RENAME TO "messageChannel_visibility_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "${
|
||||||
|
dataSourceMetadata.schema
|
||||||
|
}"."messageChannel_visibility_enum" AS ENUM ('${newMessageChannelVisibilities.join(
|
||||||
|
"','",
|
||||||
|
)}')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" TYPE text`,
|
||||||
|
);
|
||||||
|
for (const newMessageChannelVisibility of newMessageChannelVisibilities) {
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE "${
|
||||||
|
dataSourceMetadata.schema
|
||||||
|
}"."messageChannel" SET "visibility" = '${newMessageChannelVisibility}' WHERE "visibility" = '${newMessageChannelVisibility.toLowerCase()}'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" TYPE "${dataSourceMetadata.schema}"."messageChannel_visibility_enum" USING "visibility"::text::"${dataSourceMetadata.schema}"."messageChannel_visibility_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" SET DEFAULT '${MessageChannelVisibility.SHARE_EVERYTHING}'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "${dataSourceMetadata.schema}"."messageChannel_visibility_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
this.logger.log(
|
||||||
|
chalk.red(`Running command on workspace ${workspaceId} failed`),
|
||||||
|
);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.workspaceCacheVersionService.incrementVersion(workspaceId);
|
||||||
|
|
||||||
|
const visibilityFieldsMetadata = await this.fieldMetadataRepository.find({
|
||||||
|
where: { name: 'visibility', workspaceId },
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const visibilityFieldMetadata of visibilityFieldsMetadata) {
|
||||||
|
const newOptions = visibilityFieldMetadata.options.map((option) => {
|
||||||
|
return { ...option, value: option.value.toUpperCase() };
|
||||||
|
});
|
||||||
|
|
||||||
|
const newDefaultValue =
|
||||||
|
typeof visibilityFieldMetadata.defaultValue === 'string'
|
||||||
|
? visibilityFieldMetadata.defaultValue.toUpperCase()
|
||||||
|
: visibilityFieldMetadata.defaultValue;
|
||||||
|
|
||||||
|
await this.fieldMetadataRepository.update(visibilityFieldMetadata.id, {
|
||||||
|
defaultValue: newDefaultValue,
|
||||||
|
options: newOptions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.log(
|
||||||
|
chalk.green(`Running command on workspace ${workspaceId} done`),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.log(chalk.green(`Command completed!`));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
|
|
||||||
import { DEV_SEED_CONNECTED_ACCOUNT_IDS } from 'src/database/typeorm-seeds/workspace/connected-account';
|
import { DEV_SEED_CONNECTED_ACCOUNT_IDS } from 'src/database/typeorm-seeds/workspace/connected-account';
|
||||||
|
import { CalendarChannelVisibility } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||||
|
|
||||||
const tableName = 'calendarChannel';
|
const tableName = 'calendarChannel';
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ export const seedCalendarChannels = async (
|
|||||||
id: '59efdefe-a40f-4faf-bb9f-c6f9945b8203',
|
id: '59efdefe-a40f-4faf-bb9f-c6f9945b8203',
|
||||||
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.TIM,
|
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.TIM,
|
||||||
handle: 'tim@apple.com',
|
handle: 'tim@apple.com',
|
||||||
visibility: 'SHARE_EVERYTHING',
|
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||||
isContactAutoCreationEnabled: true,
|
isContactAutoCreationEnabled: true,
|
||||||
isSyncEnabled: true,
|
isSyncEnabled: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
|
|
||||||
import { DEV_SEED_CONNECTED_ACCOUNT_IDS } from 'src/database/typeorm-seeds/workspace/connected-account';
|
import { DEV_SEED_CONNECTED_ACCOUNT_IDS } from 'src/database/typeorm-seeds/workspace/connected-account';
|
||||||
import { MessageChannelSyncStage } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
import {
|
||||||
|
MessageChannelSyncStage,
|
||||||
|
MessageChannelVisibility,
|
||||||
|
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
|
|
||||||
const tableName = 'messageChannel';
|
const tableName = 'messageChannel';
|
||||||
|
|
||||||
@@ -41,8 +44,8 @@ export const seedMessageChannel = async (
|
|||||||
type: 'email',
|
type: 'email',
|
||||||
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.TIM,
|
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.TIM,
|
||||||
handle: 'tim@apple.dev',
|
handle: 'tim@apple.dev',
|
||||||
visibility: 'share_everything',
|
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||||
syncStage: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
|
syncSubStatus: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: DEV_SEED_MESSAGE_CHANNEL_IDS.JONY,
|
id: DEV_SEED_MESSAGE_CHANNEL_IDS.JONY,
|
||||||
@@ -53,8 +56,8 @@ export const seedMessageChannel = async (
|
|||||||
type: 'email',
|
type: 'email',
|
||||||
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.JONY,
|
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.JONY,
|
||||||
handle: 'jony.ive@apple.dev',
|
handle: 'jony.ive@apple.dev',
|
||||||
visibility: 'share_everything',
|
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||||
syncStage: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
|
syncSubStatus: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: DEV_SEED_MESSAGE_CHANNEL_IDS.PHIL,
|
id: DEV_SEED_MESSAGE_CHANNEL_IDS.PHIL,
|
||||||
@@ -65,8 +68,8 @@ export const seedMessageChannel = async (
|
|||||||
type: 'email',
|
type: 'email',
|
||||||
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.PHIL,
|
connectedAccountId: DEV_SEED_CONNECTED_ACCOUNT_IDS.PHIL,
|
||||||
handle: 'phil.schiler@apple.dev',
|
handle: 'phil.schiler@apple.dev',
|
||||||
visibility: 'share_everything',
|
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||||
syncStage: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
|
syncSubStatus: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.execute();
|
.execute();
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddKeyValuePairTable1717425967770 implements MigrationInterface {
|
||||||
|
name = 'AddKeyValuePairTable1717425967770';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "core"."keyValuePair" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "userId" uuid, "workspaceId" uuid, "key" text NOT NULL, "value" text, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, CONSTRAINT "IndexOnKeyUserIdWorkspaceIdUnique" UNIQUE ("key", "userId", "workspaceId"), CONSTRAINT "PK_c5a1ca828435d3eaf8f9361ed4b" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "core"."keyValuePair" ADD CONSTRAINT "FK_0dae35d1c0fbdda6495be4ae71a" FOREIGN KEY ("userId") REFERENCES "core"."user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "core"."keyValuePair" ADD CONSTRAINT "FK_c137e3d8b3980901e114941daa2" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "core"."keyValuePair" DROP CONSTRAINT "FK_c137e3d8b3980901e114941daa2"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "core"."keyValuePair" DROP CONSTRAINT "FK_0dae35d1c0fbdda6495be4ae71a"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "core"."keyValuePair"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-
|
|||||||
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||||
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
|
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
|
||||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||||
|
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
||||||
@@ -29,6 +30,7 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
|||||||
Workspace,
|
Workspace,
|
||||||
UserWorkspace,
|
UserWorkspace,
|
||||||
AppToken,
|
AppToken,
|
||||||
|
KeyValuePair,
|
||||||
FeatureFlagEntity,
|
FeatureFlagEntity,
|
||||||
BillingSubscription,
|
BillingSubscription,
|
||||||
BillingSubscriptionItem,
|
BillingSubscriptionItem,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repos
|
|||||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||||
import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||||
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
|
import { UserStateModule } from 'src/engine/core-modules/user-state/user-state.module';
|
||||||
|
|
||||||
import { AuthResolver } from './auth.resolver';
|
import { AuthResolver } from './auth.resolver';
|
||||||
|
|
||||||
@@ -63,6 +64,7 @@ const jwtModule = JwtModule.registerAsync({
|
|||||||
]),
|
]),
|
||||||
HttpModule,
|
HttpModule,
|
||||||
UserWorkspaceModule,
|
UserWorkspaceModule,
|
||||||
|
UserStateModule,
|
||||||
],
|
],
|
||||||
controllers: [
|
controllers: [
|
||||||
GoogleAuthController,
|
GoogleAuthController,
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/strategies/googl
|
|||||||
import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-apis.service';
|
import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-apis.service';
|
||||||
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
||||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
|
import { UserStateService } from 'src/engine/core-modules/user-state/user-state.service';
|
||||||
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
|
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||||
|
import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository';
|
||||||
|
|
||||||
@Controller('auth/google-apis')
|
@Controller('auth/google-apis')
|
||||||
export class GoogleAPIsAuthController {
|
export class GoogleAPIsAuthController {
|
||||||
@@ -22,6 +26,9 @@ export class GoogleAPIsAuthController {
|
|||||||
private readonly googleAPIsService: GoogleAPIsService,
|
private readonly googleAPIsService: GoogleAPIsService,
|
||||||
private readonly tokenService: TokenService,
|
private readonly tokenService: TokenService,
|
||||||
private readonly environmentService: EnvironmentService,
|
private readonly environmentService: EnvironmentService,
|
||||||
|
private readonly userStateService: UserStateService,
|
||||||
|
@InjectObjectMetadataRepository(WorkspaceMemberWorkspaceEntity)
|
||||||
|
private readonly workspaceMemberService: WorkspaceMemberRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@@ -39,7 +46,15 @@ export class GoogleAPIsAuthController {
|
|||||||
) {
|
) {
|
||||||
const { user } = req;
|
const { user } = req;
|
||||||
|
|
||||||
const { email, accessToken, refreshToken, transientToken } = user;
|
const {
|
||||||
|
email,
|
||||||
|
accessToken,
|
||||||
|
refreshToken,
|
||||||
|
transientToken,
|
||||||
|
redirectLocation,
|
||||||
|
calendarVisibility,
|
||||||
|
messageVisibility,
|
||||||
|
} = user;
|
||||||
|
|
||||||
const { workspaceMemberId, workspaceId } =
|
const { workspaceMemberId, workspaceId } =
|
||||||
await this.tokenService.verifyTransientToken(transientToken);
|
await this.tokenService.verifyTransientToken(transientToken);
|
||||||
@@ -62,10 +77,25 @@ export class GoogleAPIsAuthController {
|
|||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
accessToken,
|
accessToken,
|
||||||
refreshToken,
|
refreshToken,
|
||||||
|
calendarVisibility,
|
||||||
|
messageVisibility,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const userId = (
|
||||||
|
await this.workspaceMemberService.find(workspaceMemberId, workspaceId)
|
||||||
|
)?.userId;
|
||||||
|
|
||||||
|
if (userId) {
|
||||||
|
await this.userStateService.skipSyncEmailOnboardingStep(
|
||||||
|
userId,
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return res.redirect(
|
return res.redirect(
|
||||||
`${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`,
|
`${this.environmentService.get('FRONT_BASE_URL')}${
|
||||||
|
redirectLocation || '/settings/accounts'
|
||||||
|
}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,26 @@ export class GoogleAPIsOauthGuard extends AuthGuard('google-apis') {
|
|||||||
async canActivate(context: ExecutionContext) {
|
async canActivate(context: ExecutionContext) {
|
||||||
const request = context.switchToHttp().getRequest();
|
const request = context.switchToHttp().getRequest();
|
||||||
const transientToken = request.query.transientToken;
|
const transientToken = request.query.transientToken;
|
||||||
|
const redirectLocation = request.query.redirectLocation;
|
||||||
|
const calendarVisibility = request.query.calendarVisibility;
|
||||||
|
const messageVisibility = request.query.messageVisibility;
|
||||||
|
|
||||||
if (transientToken && typeof transientToken === 'string') {
|
if (transientToken && typeof transientToken === 'string') {
|
||||||
request.params.transientToken = transientToken;
|
request.params.transientToken = transientToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (redirectLocation && typeof redirectLocation === 'string') {
|
||||||
|
request.params.redirectLocation = redirectLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calendarVisibility && typeof calendarVisibility === 'string') {
|
||||||
|
request.params.calendarVisibility = calendarVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messageVisibility && typeof messageVisibility === 'string') {
|
||||||
|
request.params.messageVisibility = messageVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
const activate = (await super.canActivate(context)) as boolean;
|
const activate = (await super.canActivate(context)) as boolean;
|
||||||
|
|
||||||
return activate;
|
return activate;
|
||||||
|
|||||||
@@ -58,8 +58,16 @@ export class GoogleAPIsService {
|
|||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
accessToken: string;
|
accessToken: string;
|
||||||
refreshToken: string;
|
refreshToken: string;
|
||||||
|
calendarVisibility: CalendarChannelVisibility | undefined;
|
||||||
|
messageVisibility: MessageChannelVisibility | undefined;
|
||||||
}) {
|
}) {
|
||||||
const { handle, workspaceId, workspaceMemberId } = input;
|
const {
|
||||||
|
handle,
|
||||||
|
workspaceId,
|
||||||
|
workspaceMemberId,
|
||||||
|
calendarVisibility,
|
||||||
|
messageVisibility,
|
||||||
|
} = input;
|
||||||
|
|
||||||
const dataSourceMetadata =
|
const dataSourceMetadata =
|
||||||
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||||
@@ -104,7 +112,8 @@ export class GoogleAPIsService {
|
|||||||
connectedAccountId: newOrExistingConnectedAccountId,
|
connectedAccountId: newOrExistingConnectedAccountId,
|
||||||
type: MessageChannelType.EMAIL,
|
type: MessageChannelType.EMAIL,
|
||||||
handle,
|
handle,
|
||||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
visibility:
|
||||||
|
messageVisibility || MessageChannelVisibility.SHARE_EVERYTHING,
|
||||||
},
|
},
|
||||||
workspaceId,
|
workspaceId,
|
||||||
manager,
|
manager,
|
||||||
@@ -116,7 +125,9 @@ export class GoogleAPIsService {
|
|||||||
id: v4(),
|
id: v4(),
|
||||||
connectedAccountId: newOrExistingConnectedAccountId,
|
connectedAccountId: newOrExistingConnectedAccountId,
|
||||||
handle,
|
handle,
|
||||||
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
visibility:
|
||||||
|
calendarVisibility ||
|
||||||
|
CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||||
},
|
},
|
||||||
workspaceId,
|
workspaceId,
|
||||||
manager,
|
manager,
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { Strategy, VerifyCallback } from 'passport-google-oauth20';
|
|||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
|
||||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
|
import { CalendarChannelVisibility } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||||
|
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
|
|
||||||
export type GoogleAPIsRequest = Omit<
|
export type GoogleAPIsRequest = Omit<
|
||||||
Request,
|
Request,
|
||||||
@@ -19,6 +21,9 @@ export type GoogleAPIsRequest = Omit<
|
|||||||
accessToken: string;
|
accessToken: string;
|
||||||
refreshToken: string;
|
refreshToken: string;
|
||||||
transientToken: string;
|
transientToken: string;
|
||||||
|
redirectLocation?: string;
|
||||||
|
calendarVisibility?: CalendarChannelVisibility;
|
||||||
|
messageVisibility?: MessageChannelVisibility;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,6 +69,9 @@ export class GoogleAPIsStrategy extends PassportStrategy(
|
|||||||
prompt: 'consent',
|
prompt: 'consent',
|
||||||
state: JSON.stringify({
|
state: JSON.stringify({
|
||||||
transientToken: req.params.transientToken,
|
transientToken: req.params.transientToken,
|
||||||
|
redirectLocation: req.params.redirectLocation,
|
||||||
|
calendarVisibility: req.params.calendarVisibility,
|
||||||
|
messageVisibility: req.params.messageVisibility,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,6 +100,9 @@ export class GoogleAPIsStrategy extends PassportStrategy(
|
|||||||
accessToken,
|
accessToken,
|
||||||
refreshToken,
|
refreshToken,
|
||||||
transientToken: state.transientToken,
|
transientToken: state.transientToken,
|
||||||
|
redirectLocation: state.redirectLocation,
|
||||||
|
calendarVisibility: state.calendarVisibility,
|
||||||
|
messageVisibility: state.messageVisibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
done(null, user);
|
done(null, user);
|
||||||
|
|||||||
@@ -2,15 +2,11 @@ import { ObjectType, Field, registerEnumType } from '@nestjs/graphql';
|
|||||||
|
|
||||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||||
import { TimelineCalendarEventParticipant } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-event-participant.dto';
|
import { TimelineCalendarEventParticipant } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-event-participant.dto';
|
||||||
|
import { CalendarChannelVisibility } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||||
|
|
||||||
export enum TimelineCalendarEventVisibility {
|
registerEnumType(CalendarChannelVisibility, {
|
||||||
METADATA = 'METADATA',
|
name: 'CalendarChannelVisibility',
|
||||||
SHARE_EVERYTHING = 'SHARE_EVERYTHING',
|
description: 'Visibility of the calendar channel',
|
||||||
}
|
|
||||||
|
|
||||||
registerEnumType(TimelineCalendarEventVisibility, {
|
|
||||||
name: 'TimelineCalendarEventVisibility',
|
|
||||||
description: 'Visibility of the calendar event',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ObjectType('LinkMetadata')
|
@ObjectType('LinkMetadata')
|
||||||
@@ -57,6 +53,6 @@ export class TimelineCalendarEvent {
|
|||||||
@Field(() => [TimelineCalendarEventParticipant])
|
@Field(() => [TimelineCalendarEventParticipant])
|
||||||
participants: TimelineCalendarEventParticipant[];
|
participants: TimelineCalendarEventParticipant[];
|
||||||
|
|
||||||
@Field(() => TimelineCalendarEventVisibility)
|
@Field(() => CalendarChannelVisibility)
|
||||||
visibility: TimelineCalendarEventVisibility;
|
visibility: CalendarChannelVisibility;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { Any } from 'typeorm';
|
|||||||
import omit from 'lodash.omit';
|
import omit from 'lodash.omit';
|
||||||
|
|
||||||
import { TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE } from 'src/engine/core-modules/calendar/constants/calendar.constants';
|
import { TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE } from 'src/engine/core-modules/calendar/constants/calendar.constants';
|
||||||
import { TimelineCalendarEventVisibility } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-event.dto';
|
|
||||||
import { TimelineCalendarEventsWithTotal } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-events-with-total.dto';
|
import { TimelineCalendarEventsWithTotal } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-events-with-total.dto';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||||
import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-event.workspace-entity';
|
import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-event.workspace-entity';
|
||||||
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';
|
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';
|
||||||
|
import { CalendarChannelVisibility } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TimelineCalendarEventService {
|
export class TimelineCalendarEventService {
|
||||||
@@ -107,8 +107,8 @@ export class TimelineCalendarEventService {
|
|||||||
const visibility = event.calendarChannelEventAssociations.some(
|
const visibility = event.calendarChannelEventAssociations.some(
|
||||||
(association) => association.calendarChannel.visibility === 'METADATA',
|
(association) => association.calendarChannel.visibility === 'METADATA',
|
||||||
)
|
)
|
||||||
? TimelineCalendarEventVisibility.METADATA
|
? CalendarChannelVisibility.METADATA
|
||||||
: TimelineCalendarEventVisibility.SHARE_EVERYTHING;
|
: CalendarChannelVisibility.SHARE_EVERYTHING;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...omit(event, [
|
...omit(event, [
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import { Field, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
Entity,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
Relation,
|
||||||
|
Unique,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||||
|
|
||||||
|
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
|
||||||
|
@Entity({ name: 'keyValuePair', schema: 'core' })
|
||||||
|
@ObjectType('KeyValuePair')
|
||||||
|
@Unique('IndexOnKeyUserIdWorkspaceIdUnique', ['key', 'userId', 'workspaceId'])
|
||||||
|
export class KeyValuePair {
|
||||||
|
@IDField(() => UUIDScalarType)
|
||||||
|
@PrimaryGeneratedColumn('uuid')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, (user) => user.keyValuePairs, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn({ name: 'userId' })
|
||||||
|
user: Relation<User>;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Workspace, (workspace) => workspace.keyValuePairs, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn({ name: 'workspaceId' })
|
||||||
|
workspace: Relation<Workspace>;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
workspaceId: string;
|
||||||
|
|
||||||
|
@Field(() => String)
|
||||||
|
@Column({ nullable: false, type: 'text' })
|
||||||
|
key: string;
|
||||||
|
|
||||||
|
@Field(() => String, { nullable: true })
|
||||||
|
@Column({ nullable: true, type: 'text' })
|
||||||
|
value: string;
|
||||||
|
|
||||||
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
|
updatedAt: Date;
|
||||||
|
|
||||||
|
@Column({ nullable: true, type: 'timestamptz' })
|
||||||
|
deletedAt: Date | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql';
|
||||||
|
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
||||||
|
|
||||||
|
import { KeyValuePairService } from 'src/engine/core-modules/key-value-pair/key-value-pair.service';
|
||||||
|
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
|
||||||
|
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
NestjsQueryGraphQLModule.forFeature({
|
||||||
|
imports: [
|
||||||
|
NestjsQueryTypeOrmModule.forFeature([KeyValuePair], 'core'),
|
||||||
|
TypeORMModule,
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
exports: [KeyValuePairService],
|
||||||
|
providers: [KeyValuePairService],
|
||||||
|
})
|
||||||
|
export class KeyValuePairModule {}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
|
||||||
|
import { UserStates } from 'src/engine/core-modules/user-state/enums/user-states.enum';
|
||||||
|
import { UserStateEmailSyncValues } from 'src/engine/core-modules/user-state/enums/user-state-email-sync-values.enum';
|
||||||
|
|
||||||
|
export enum KeyValueTypes {
|
||||||
|
USER_STATE = 'USER_STATE',
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyValuePairs = {
|
||||||
|
[KeyValueTypes.USER_STATE]: {
|
||||||
|
[UserStates.SYNC_EMAIL_ONBOARDING_STEP]: UserStateEmailSyncValues;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export class KeyValuePairService<TYPE extends keyof KeyValuePairs> {
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(KeyValuePair, 'core')
|
||||||
|
private readonly keyValuePairRepository: Repository<KeyValuePair>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async get<K extends keyof KeyValuePairs[TYPE]>(
|
||||||
|
userId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
key: K,
|
||||||
|
) {
|
||||||
|
return await this.keyValuePairRepository.findOne({
|
||||||
|
where: {
|
||||||
|
userId,
|
||||||
|
workspaceId,
|
||||||
|
key: key as string,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async set<K extends keyof KeyValuePairs[TYPE]>(
|
||||||
|
userId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
key: K,
|
||||||
|
value: KeyValuePairs[TYPE][K],
|
||||||
|
) {
|
||||||
|
await this.keyValuePairRepository.upsert(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
workspaceId,
|
||||||
|
key: key as string,
|
||||||
|
value: value as string,
|
||||||
|
},
|
||||||
|
{ conflictPaths: ['userId', 'workspaceId', 'key'] },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
import { ObjectType, Field } from '@nestjs/graphql';
|
import { ObjectType, Field, registerEnumType } from '@nestjs/graphql';
|
||||||
|
|
||||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||||
import { TimelineThreadParticipant } from 'src/engine/core-modules/messaging/dtos/timeline-thread-participant.dto';
|
import { TimelineThreadParticipant } from 'src/engine/core-modules/messaging/dtos/timeline-thread-participant.dto';
|
||||||
|
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
|
|
||||||
|
registerEnumType(MessageChannelVisibility, {
|
||||||
|
name: 'MessageChannelVisibility',
|
||||||
|
description: 'Visibility of the message channel',
|
||||||
|
});
|
||||||
|
|
||||||
@ObjectType('TimelineThread')
|
@ObjectType('TimelineThread')
|
||||||
export class TimelineThread {
|
export class TimelineThread {
|
||||||
@@ -11,8 +17,8 @@ export class TimelineThread {
|
|||||||
@Field()
|
@Field()
|
||||||
read: boolean;
|
read: boolean;
|
||||||
|
|
||||||
@Field()
|
@Field(() => MessageChannelVisibility)
|
||||||
visibility: string;
|
visibility: MessageChannelVisibility;
|
||||||
|
|
||||||
@Field()
|
@Field()
|
||||||
firstParticipant: TimelineThreadParticipant;
|
firstParticipant: TimelineThreadParticipant;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { TIMELINE_THREADS_DEFAULT_PAGE_SIZE } from 'src/engine/core-modules/messaging/constants/messaging.constants';
|
import { TIMELINE_THREADS_DEFAULT_PAGE_SIZE } from 'src/engine/core-modules/messaging/constants/messaging.constants';
|
||||||
import { TimelineThreadsWithTotal } from 'src/engine/core-modules/messaging/dtos/timeline-threads-with-total.dto';
|
import { TimelineThreadsWithTotal } from 'src/engine/core-modules/messaging/dtos/timeline-threads-with-total.dto';
|
||||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
|
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
|
|
||||||
type TimelineThreadParticipant = {
|
type TimelineThreadParticipant = {
|
||||||
personId: string;
|
personId: string;
|
||||||
@@ -352,7 +353,7 @@ export class TimelineMessagingService {
|
|||||||
const threadVisibility:
|
const threadVisibility:
|
||||||
| {
|
| {
|
||||||
id: string;
|
id: string;
|
||||||
visibility: 'metadata' | 'subject' | 'share_everything';
|
visibility: MessageChannelVisibility;
|
||||||
}[]
|
}[]
|
||||||
| undefined = await this.workspaceDataSourceService.executeRawQuery(
|
| undefined = await this.workspaceDataSourceService.executeRawQuery(
|
||||||
`
|
`
|
||||||
@@ -372,11 +373,11 @@ export class TimelineMessagingService {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const visibilityValues = ['metadata', 'subject', 'share_everything'];
|
const visibilityValues = Object.values(MessageChannelVisibility);
|
||||||
|
|
||||||
const threadVisibilityByThreadIdForWhichWorkspaceMemberIsNotInParticipants:
|
const threadVisibilityByThreadIdForWhichWorkspaceMemberIsNotInParticipants:
|
||||||
| {
|
| {
|
||||||
[key: string]: 'metadata' | 'subject' | 'share_everything';
|
[key: string]: MessageChannelVisibility;
|
||||||
}
|
}
|
||||||
| undefined = threadVisibility?.reduce(
|
| undefined = threadVisibility?.reduce(
|
||||||
(threadVisibilityAcc, threadVisibility) => {
|
(threadVisibilityAcc, threadVisibility) => {
|
||||||
@@ -385,7 +386,8 @@ export class TimelineMessagingService {
|
|||||||
Math.max(
|
Math.max(
|
||||||
visibilityValues.indexOf(threadVisibility.visibility),
|
visibilityValues.indexOf(threadVisibility.visibility),
|
||||||
visibilityValues.indexOf(
|
visibilityValues.indexOf(
|
||||||
threadVisibilityAcc[threadVisibility.id] ?? 'metadata',
|
threadVisibilityAcc[threadVisibility.id] ??
|
||||||
|
MessageChannelVisibility.METADATA,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
@@ -396,7 +398,7 @@ export class TimelineMessagingService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const threadVisibilityByThreadId: {
|
const threadVisibilityByThreadId: {
|
||||||
[key: string]: 'metadata' | 'subject' | 'share_everything';
|
[key: string]: MessageChannelVisibility;
|
||||||
} = messageThreadIds.reduce((threadVisibilityAcc, messageThreadId) => {
|
} = messageThreadIds.reduce((threadVisibilityAcc, messageThreadId) => {
|
||||||
// If the workspace member is not in the participants of the thread, use the visibility value from the query
|
// If the workspace member is not in the participants of the thread, use the visibility value from the query
|
||||||
threadVisibilityAcc[messageThreadId] =
|
threadVisibilityAcc[messageThreadId] =
|
||||||
@@ -405,8 +407,8 @@ export class TimelineMessagingService {
|
|||||||
)
|
)
|
||||||
? threadVisibilityByThreadIdForWhichWorkspaceMemberIsNotInParticipants?.[
|
? threadVisibilityByThreadIdForWhichWorkspaceMemberIsNotInParticipants?.[
|
||||||
messageThreadId
|
messageThreadId
|
||||||
] ?? 'metadata'
|
] ?? MessageChannelVisibility.METADATA
|
||||||
: 'share_everything';
|
: MessageChannelVisibility.SHARE_EVERYTHING;
|
||||||
|
|
||||||
return threadVisibilityAcc;
|
return threadVisibilityAcc;
|
||||||
}, {});
|
}, {});
|
||||||
@@ -461,7 +463,9 @@ export class TimelineMessagingService {
|
|||||||
lastTwoParticipants,
|
lastTwoParticipants,
|
||||||
lastMessageReceivedAt: thread.lastMessageReceivedAt,
|
lastMessageReceivedAt: thread.lastMessageReceivedAt,
|
||||||
lastMessageBody: thread.lastMessageBody,
|
lastMessageBody: thread.lastMessageBody,
|
||||||
visibility: threadVisibilityByThreadId?.[messageThreadId] ?? 'metadata',
|
visibility:
|
||||||
|
threadVisibilityByThreadId?.[messageThreadId] ??
|
||||||
|
MessageChannelVisibility.METADATA,
|
||||||
subject: threadSubject,
|
subject: threadSubject,
|
||||||
numberOfMessagesInThread: numberOfMessages,
|
numberOfMessagesInThread: numberOfMessages,
|
||||||
participantCount: threadActiveParticipants.length,
|
participantCount: threadActiveParticipants.length,
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { UserState } from 'src/engine/core-modules/user-state/dtos/user-state.dto';
|
||||||
|
|
||||||
|
export const DEFAULT_USER_STATE: UserState = {
|
||||||
|
skipSyncEmailOnboardingStep: true,
|
||||||
|
};
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { Field, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
export class SkipSyncEmailOnboardingStep {
|
||||||
|
@Field(() => Boolean, {
|
||||||
|
description: 'Boolean that confirms query was dispatched',
|
||||||
|
})
|
||||||
|
success: boolean;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { Field, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
@ObjectType('UserState')
|
||||||
|
export class UserState {
|
||||||
|
@Field(() => Boolean, { nullable: true })
|
||||||
|
skipSyncEmailOnboardingStep: boolean | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export enum UserStateEmailSyncValues {
|
||||||
|
SKIPPED = 'SKIPPED',
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export enum UserStates {
|
||||||
|
SYNC_EMAIL_ONBOARDING_STEP = 'SYNC_EMAIL_ONBOARDING_STEP',
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { UserStateService } from 'src/engine/core-modules/user-state/user-state.service';
|
||||||
|
import { UserStateResolver } from 'src/engine/core-modules/user-state/user-state.resolver';
|
||||||
|
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
|
||||||
|
import { KeyValuePairModule } from 'src/engine/core-modules/key-value-pair/key-value-pair.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [DataSourceModule, KeyValuePairModule],
|
||||||
|
exports: [UserStateService],
|
||||||
|
providers: [UserStateService, UserStateResolver],
|
||||||
|
})
|
||||||
|
export class UserStateModule {}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { UseGuards } from '@nestjs/common';
|
||||||
|
import { Mutation, Resolver } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
|
import { UserState } from 'src/engine/core-modules/user-state/dtos/user-state.dto';
|
||||||
|
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { UserStateService } from 'src/engine/core-modules/user-state/user-state.service';
|
||||||
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { SkipSyncEmailOnboardingStep } from 'src/engine/core-modules/user-state/dtos/skip-sync-email.entity-onboarding-step';
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Resolver(() => UserState)
|
||||||
|
export class UserStateResolver {
|
||||||
|
constructor(private readonly userStateService: UserStateService) {}
|
||||||
|
|
||||||
|
@Mutation(() => SkipSyncEmailOnboardingStep)
|
||||||
|
async skipSyncEmailOnboardingStep(
|
||||||
|
@AuthUser() user: User,
|
||||||
|
@AuthWorkspace() workspace: Workspace,
|
||||||
|
): Promise<SkipSyncEmailOnboardingStep> {
|
||||||
|
return await this.userStateService.skipSyncEmailOnboardingStep(
|
||||||
|
user.id,
|
||||||
|
workspace.id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
|
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||||
|
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { UserState } from 'src/engine/core-modules/user-state/dtos/user-state.dto';
|
||||||
|
import {
|
||||||
|
KeyValuePairService,
|
||||||
|
KeyValueTypes,
|
||||||
|
} from 'src/engine/core-modules/key-value-pair/key-value-pair.service';
|
||||||
|
import { UserStates } from 'src/engine/core-modules/user-state/enums/user-states.enum';
|
||||||
|
import { UserStateEmailSyncValues } from 'src/engine/core-modules/user-state/enums/user-state-email-sync-values.enum';
|
||||||
|
import { SkipSyncEmailOnboardingStep } from 'src/engine/core-modules/user-state/dtos/skip-sync-email.entity-onboarding-step';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserStateService {
|
||||||
|
constructor(
|
||||||
|
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
||||||
|
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
||||||
|
private readonly keyValuePairService: KeyValuePairService<KeyValueTypes.USER_STATE>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async getUserState(user: User, workspace: Workspace): Promise<UserState> {
|
||||||
|
const connectedAccounts =
|
||||||
|
await this.connectedAccountRepository.getAllByUserId(
|
||||||
|
user.id,
|
||||||
|
workspace.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (connectedAccounts?.length) {
|
||||||
|
return {
|
||||||
|
skipSyncEmailOnboardingStep: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const skipSyncEmail = await this.keyValuePairService.get(
|
||||||
|
user.id,
|
||||||
|
workspace.id,
|
||||||
|
UserStates.SYNC_EMAIL_ONBOARDING_STEP,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
skipSyncEmailOnboardingStep:
|
||||||
|
!!skipSyncEmail &&
|
||||||
|
skipSyncEmail.value === UserStateEmailSyncValues.SKIPPED,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async skipSyncEmailOnboardingStep(
|
||||||
|
userId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
): Promise<SkipSyncEmailOnboardingStep> {
|
||||||
|
await this.keyValuePairService.set(
|
||||||
|
userId,
|
||||||
|
workspaceId,
|
||||||
|
UserStates.SYNC_EMAIL_ONBOARDING_STEP,
|
||||||
|
UserStateEmailSyncValues.SKIPPED,
|
||||||
|
);
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,14 +2,13 @@ import { Test, TestingModule } from '@nestjs/testing';
|
|||||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
|
|
||||||
|
import { UserService } from 'src/engine/core-modules/user/services/user.service';
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||||
import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service';
|
import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service';
|
||||||
|
|
||||||
import { UserService } from './user.service';
|
|
||||||
|
|
||||||
describe('UserService', () => {
|
describe('UserService', () => {
|
||||||
let service: UserService;
|
let service: UserService;
|
||||||
|
|
||||||
@@ -17,6 +17,8 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
|||||||
import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto';
|
import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto';
|
||||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||||
|
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
|
||||||
|
import { UserState } from 'src/engine/core-modules/user-state/dtos/user-state.dto';
|
||||||
|
|
||||||
@Entity({ name: 'user', schema: 'core' })
|
@Entity({ name: 'user', schema: 'core' })
|
||||||
@ObjectType('User')
|
@ObjectType('User')
|
||||||
@@ -100,10 +102,18 @@ export class User {
|
|||||||
})
|
})
|
||||||
appTokens: Relation<AppToken[]>;
|
appTokens: Relation<AppToken[]>;
|
||||||
|
|
||||||
|
@OneToMany(() => KeyValuePair, (keyValuePair) => keyValuePair.user, {
|
||||||
|
cascade: true,
|
||||||
|
})
|
||||||
|
keyValuePairs: Relation<KeyValuePair[]>;
|
||||||
|
|
||||||
@Field(() => WorkspaceMember, { nullable: true })
|
@Field(() => WorkspaceMember, { nullable: true })
|
||||||
workspaceMember: Relation<WorkspaceMember>;
|
workspaceMember: Relation<WorkspaceMember>;
|
||||||
|
|
||||||
@Field(() => [UserWorkspace])
|
@Field(() => [UserWorkspace])
|
||||||
@OneToMany(() => UserWorkspace, (userWorkspace) => userWorkspace.user)
|
@OneToMany(() => UserWorkspace, (userWorkspace) => userWorkspace.user)
|
||||||
workspaces: Relation<UserWorkspace[]>;
|
workspaces: Relation<UserWorkspace[]>;
|
||||||
|
|
||||||
|
@Field(() => UserState, { nullable: false })
|
||||||
|
state: UserState;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s
|
|||||||
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
||||||
import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module';
|
import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module';
|
||||||
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
|
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
|
||||||
|
import { UserStateModule } from 'src/engine/core-modules/user-state/user-state.module';
|
||||||
|
|
||||||
import { userAutoResolverOpts } from './user.auto-resolver-opts';
|
import { userAutoResolverOpts } from './user.auto-resolver-opts';
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ import { UserService } from './services/user.service';
|
|||||||
}),
|
}),
|
||||||
DataSourceModule,
|
DataSourceModule,
|
||||||
FileUploadModule,
|
FileUploadModule,
|
||||||
|
UserStateModule,
|
||||||
WorkspaceModule,
|
WorkspaceModule,
|
||||||
],
|
],
|
||||||
exports: [UserService],
|
exports: [UserService],
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
Resolver,
|
|
||||||
Query,
|
|
||||||
Args,
|
Args,
|
||||||
Parent,
|
|
||||||
ResolveField,
|
|
||||||
Mutation,
|
Mutation,
|
||||||
|
Parent,
|
||||||
|
Query,
|
||||||
|
ResolveField,
|
||||||
|
Resolver,
|
||||||
} from '@nestjs/graphql';
|
} from '@nestjs/graphql';
|
||||||
import { UseGuards } from '@nestjs/common';
|
import { UseGuards } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
@@ -17,6 +17,7 @@ import { Repository } from 'typeorm';
|
|||||||
import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface';
|
import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface';
|
||||||
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
|
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
|
||||||
|
|
||||||
|
import { UserService } from 'src/engine/core-modules/user/services/user.service';
|
||||||
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
||||||
@@ -26,8 +27,11 @@ import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
|||||||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto';
|
import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto';
|
||||||
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
import { UserService } from './services/user.service';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { UserState } from 'src/engine/core-modules/user-state/dtos/user-state.dto';
|
||||||
|
import { UserStateService } from 'src/engine/core-modules/user-state/user-state.service';
|
||||||
|
import { DEFAULT_USER_STATE } from 'src/engine/core-modules/user-state/constants/default-user-state';
|
||||||
|
|
||||||
const getHMACKey = (email?: string, key?: string | null) => {
|
const getHMACKey = (email?: string, key?: string | null) => {
|
||||||
if (!email || !key) return null;
|
if (!email || !key) return null;
|
||||||
@@ -43,6 +47,7 @@ export class UserResolver {
|
|||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(User, 'core')
|
@InjectRepository(User, 'core')
|
||||||
private readonly userRepository: Repository<User>,
|
private readonly userRepository: Repository<User>,
|
||||||
|
private readonly userStateService: UserStateService,
|
||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
private readonly environmentService: EnvironmentService,
|
private readonly environmentService: EnvironmentService,
|
||||||
private readonly fileUploadService: FileUploadService,
|
private readonly fileUploadService: FileUploadService,
|
||||||
@@ -113,4 +118,16 @@ export class UserResolver {
|
|||||||
// Proceed with user deletion
|
// Proceed with user deletion
|
||||||
return this.userService.deleteUser(userId);
|
return this.userService.deleteUser(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResolveField(() => UserState)
|
||||||
|
async state(
|
||||||
|
@Parent() user: User,
|
||||||
|
@AuthWorkspace() workspace: Workspace,
|
||||||
|
): Promise<UserState> {
|
||||||
|
if (!user || !workspace) {
|
||||||
|
return DEFAULT_USER_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.userStateService.getUserState(user, workspace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { BillingSubscription } from 'src/engine/core-modules/billing/entities/bi
|
|||||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||||
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
||||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||||
|
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
|
||||||
|
|
||||||
@Entity({ name: 'workspace', schema: 'core' })
|
@Entity({ name: 'workspace', schema: 'core' })
|
||||||
@ObjectType('Workspace')
|
@ObjectType('Workspace')
|
||||||
@@ -63,6 +64,11 @@ export class Workspace {
|
|||||||
})
|
})
|
||||||
appTokens: Relation<AppToken[]>;
|
appTokens: Relation<AppToken[]>;
|
||||||
|
|
||||||
|
@OneToMany(() => KeyValuePair, (keyValuePair) => keyValuePair.workspace, {
|
||||||
|
cascade: true,
|
||||||
|
})
|
||||||
|
keyValuePairs: Relation<KeyValuePair[]>;
|
||||||
|
|
||||||
@OneToMany(() => User, (user) => user.defaultWorkspace)
|
@OneToMany(() => User, (user) => user.defaultWorkspace)
|
||||||
users: Relation<User[]>;
|
users: Relation<User[]>;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,15 @@ export class WorkspaceDataSourceService {
|
|||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async checkSchemaExists(workspaceId: string) {
|
||||||
|
const dataSource =
|
||||||
|
await this.dataSourceService.getDataSourcesMetadataFromWorkspaceId(
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return dataSource.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public async connectedToWorkspaceDataSourceAndReturnMetadata(
|
public async connectedToWorkspaceDataSourceAndReturnMetadata(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
): Promise<{ dataSource: DataSource; dataSourceMetadata: DataSourceEntity }> {
|
): Promise<{ dataSource: DataSource; dataSourceMetadata: DataSourceEntity }> {
|
||||||
|
|||||||
@@ -62,6 +62,41 @@ export class ConnectedAccountRepository {
|
|||||||
return connectedAccounts;
|
return connectedAccounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getAllByUserId(
|
||||||
|
userId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<ObjectRecord<ConnectedAccountWorkspaceEntity>[] | undefined> {
|
||||||
|
const schemaExists =
|
||||||
|
await this.workspaceDataSourceService.checkSchemaExists(workspaceId);
|
||||||
|
|
||||||
|
if (!schemaExists) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const workspaceMember = (
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}."workspaceMember" WHERE "userId" = $1`,
|
||||||
|
[userId],
|
||||||
|
workspaceId,
|
||||||
|
transactionManager,
|
||||||
|
)
|
||||||
|
)?.[0];
|
||||||
|
|
||||||
|
if (!workspaceMember) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.getAllByWorkspaceMemberId(
|
||||||
|
workspaceMember.id,
|
||||||
|
workspaceId,
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public async getAllByHandleAndWorkspaceMemberId(
|
public async getAllByHandleAndWorkspaceMemberId(
|
||||||
handle: string,
|
handle: string,
|
||||||
workspaceMemberId: string,
|
workspaceMemberId: string,
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ export enum MessageChannelSyncStage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum MessageChannelVisibility {
|
export enum MessageChannelVisibility {
|
||||||
METADATA = 'metadata',
|
METADATA = 'METADATA',
|
||||||
SUBJECT = 'subject',
|
SUBJECT = 'SUBJECT',
|
||||||
SHARE_EVERYTHING = 'share_everything',
|
SHARE_EVERYTHING = 'SHARE_EVERYTHING',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MessageChannelType {
|
export enum MessageChannelType {
|
||||||
|
|||||||
@@ -28,6 +28,20 @@ export class WorkspaceMemberRepository {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async find(workspaceMemberId: string, workspaceId: string) {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const workspaceMembers =
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}."workspaceMember" WHERE "id" = $1`,
|
||||||
|
[workspaceMemberId],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return workspaceMembers?.[0];
|
||||||
|
}
|
||||||
|
|
||||||
public async getByIdOrFail(
|
public async getByIdOrFail(
|
||||||
userId: string,
|
userId: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
--twentycrm-gray-0-14: #ffffff23;
|
--twentycrm-gray-0-14: #ffffff23;
|
||||||
|
|
||||||
/* Blues */
|
/* Blues */
|
||||||
--twentycrm-blue-accent-90: #141a25,
|
--twentycrm-blue-accent-90: #141a25;
|
||||||
--twentycrm-blue-accent-10: #f5f9fd,
|
--twentycrm-blue-accent-10: #f5f9fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.dark {
|
:root.dark {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const MyComponent = () => {
|
|||||||
<Button
|
<Button
|
||||||
className
|
className
|
||||||
Icon={null}
|
Icon={null}
|
||||||
title="Click Me"
|
title="Title"
|
||||||
fullWidth={false}
|
fullWidth={false}
|
||||||
variant="primary"
|
variant="primary"
|
||||||
size="medium"
|
size="medium"
|
||||||
@@ -140,7 +140,7 @@ export const MyComponent = () => {
|
|||||||
<FloatingButton
|
<FloatingButton
|
||||||
className
|
className
|
||||||
Icon={IconSearch}
|
Icon={IconSearch}
|
||||||
title="Click Me"
|
title="Title"
|
||||||
size="medium"
|
size="medium"
|
||||||
position="standalone"
|
position="standalone"
|
||||||
applyShadow={true}
|
applyShadow={true}
|
||||||
@@ -322,7 +322,7 @@ export const MyComponent = () => {
|
|||||||
return <LightButton
|
return <LightButton
|
||||||
className
|
className
|
||||||
icon={null}
|
icon={null}
|
||||||
title="Click Me"
|
title="Title"
|
||||||
accent="secondary"
|
accent="secondary"
|
||||||
active={false}
|
active={false}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
@@ -367,7 +367,7 @@ export const MyComponent = () => {
|
|||||||
className
|
className
|
||||||
testId="test1"
|
testId="test1"
|
||||||
Icon={IconSearch}
|
Icon={IconSearch}
|
||||||
title="Click Me"
|
title="Title"
|
||||||
size="small"
|
size="small"
|
||||||
accent="secondary"
|
accent="secondary"
|
||||||
active={true}
|
active={true}
|
||||||
|
|||||||
Reference in New Issue
Block a user