Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dynamic dates for webhookGraphDataUsage #7720

Merged
merged 8 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/twenty-front/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export enum CaptchaDriverType {

export type ClientConfig = {
__typename?: 'ClientConfig';
analyticsEnabled: Scalars['Boolean'];
api: ApiConfig;
authProviders: AuthProviders;
billing: Billing;
Expand Down Expand Up @@ -1599,7 +1600,7 @@ export type UpdateBillingSubscriptionMutation = { __typename?: 'Mutation', updat
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 }, 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 }, api: { __typename?: 'ApiConfig', mutationMaximumAffectedRecords: number } } };
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, signUpDisabled: boolean, debugMode: boolean, analyticsEnabled: boolean, chromeExtensionId?: string | null, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean }, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, billingFreeTrialDurationInDays?: number | null }, 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 }, api: { __typename?: 'ApiConfig', mutationMaximumAffectedRecords: number } } };

export type SkipSyncEmailOnboardingStepMutationVariables = Exact<{ [key: string]: never; }>;

Expand Down Expand Up @@ -2765,6 +2766,7 @@ export const GetClientConfigDocument = gql`
signInPrefilled
signUpDisabled
debugMode
analyticsEnabled
support {
supportDriver
supportFrontChatId
Expand Down
6 changes: 4 additions & 2 deletions packages/twenty-front/src/modules/auth/hooks/useAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {
import { isDefined } from '~/utils/isDefined';

import { currentWorkspaceMembersState } from '@/auth/states/currentWorkspaceMembersStates';
import { DateFormat } from '@/localization/constants/DateFormat';
import { TimeFormat } from '@/localization/constants/TimeFormat';
import { dateTimeFormatState } from '@/localization/states/dateTimeFormatState';
import { detectDateFormat } from '@/localization/utils/detectDateFormat';
import { detectTimeFormat } from '@/localization/utils/detectTimeFormat';
Expand Down Expand Up @@ -143,12 +145,12 @@ export const useAuth = () => {
? getDateFormatFromWorkspaceDateFormat(
user.workspaceMember.dateFormat,
)
: detectDateFormat(),
: DateFormat[detectDateFormat()],
timeFormat: isDefined(user.workspaceMember.timeFormat)
? getTimeFormatFromWorkspaceTimeFormat(
user.workspaceMember.timeFormat,
)
: detectTimeFormat(),
: TimeFormat[detectTimeFormat()],
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { useEffect } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';

import { apiConfigState } from '@/client-config/states/apiConfigState';
import { authProvidersState } from '@/client-config/states/authProvidersState';
import { billingState } from '@/client-config/states/billingState';
import { captchaProviderState } from '@/client-config/states/captchaProviderState';
import { chromeExtensionIdState } from '@/client-config/states/chromeExtensionIdState';
import { isAnalyticsEnabledState } from '@/client-config/states/isAnalyticsEnabledState';
import { isClientConfigLoadedState } from '@/client-config/states/isClientConfigLoadedState';
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
import { isSignInPrefilledState } from '@/client-config/states/isSignInPrefilledState';
import { isSignUpDisabledState } from '@/client-config/states/isSignUpDisabledState';
import { sentryConfigState } from '@/client-config/states/sentryConfigState';
import { supportChatState } from '@/client-config/states/supportChatState';
import { useEffect } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { useGetClientConfigQuery } from '~/generated/graphql';
import { isDefined } from '~/utils/isDefined';

export const ClientConfigProviderEffect = () => {
const setAuthProviders = useSetRecoilState(authProvidersState);
const setIsDebugMode = useSetRecoilState(isDebugModeState);
const setIsAnalyticsEnabled = useSetRecoilState(isAnalyticsEnabledState);

const setIsSignInPrefilled = useSetRecoilState(isSignInPrefilledState);
const setIsSignUpDisabled = useSetRecoilState(isSignUpDisabledState);
Expand Down Expand Up @@ -50,6 +51,7 @@ export const ClientConfigProviderEffect = () => {
magicLink: false,
});
setIsDebugMode(data?.clientConfig.debugMode);
setIsAnalyticsEnabled(data?.clientConfig.analyticsEnabled);
setIsSignInPrefilled(data?.clientConfig.signInPrefilled);
setIsSignUpDisabled(data?.clientConfig.signUpDisabled);

Expand Down Expand Up @@ -84,6 +86,7 @@ export const ClientConfigProviderEffect = () => {
setCaptchaProvider,
setChromeExtensionId,
setApiConfig,
setIsAnalyticsEnabled,
]);

return <></>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const GET_CLIENT_CONFIG = gql`
signInPrefilled
signUpDisabled
debugMode
analyticsEnabled
support {
supportDriver
supportFrontChatId
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createState } from 'twenty-ui';

export const isAnalyticsEnabledState = createState<boolean>({
key: 'isAnalyticsEnabled',
defaultValue: false,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DateFormat } from '@/localization/constants/DateFormat';

type DateFormatWithoutYear = {
[K in keyof typeof DateFormat]: string;
};
export const DATE_FORMAT_WITHOUT_YEAR: DateFormatWithoutYear = {
SYSTEM: 'SYSTEM',
MONTH_FIRST: 'MMM d',
DAY_FIRST: 'd MMM',
YEAR_FIRST: 'MMM d',
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { DateFormat } from '@/localization/constants/DateFormat';
import { detectDateFormat } from '@/localization/utils/detectDateFormat';

describe('detectDateFormat', () => {
it('should return DateFormat.MONTH_FIRST if the detected format starts with month', () => {
it('should return MONTH_FIRST if the detected format starts with month', () => {
// Mock the Intl.DateTimeFormat to return a specific format
const mockDateTimeFormat = jest.fn().mockReturnValue({
formatToParts: () => [
Expand All @@ -16,10 +15,10 @@ describe('detectDateFormat', () => {

const result = detectDateFormat();

expect(result).toBe(DateFormat.MONTH_FIRST);
expect(result).toBe('MONTH_FIRST');
});

it('should return DateFormat.DAY_FIRST if the detected format starts with day', () => {
it('should return DAY_FIRST if the detected format starts with day', () => {
// Mock the Intl.DateTimeFormat to return a specific format
const mockDateTimeFormat = jest.fn().mockReturnValue({
formatToParts: () => [
Expand All @@ -32,10 +31,10 @@ describe('detectDateFormat', () => {

const result = detectDateFormat();

expect(result).toBe(DateFormat.DAY_FIRST);
expect(result).toBe('DAY_FIRST');
});

it('should return DateFormat.YEAR_FIRST if the detected format starts with year', () => {
it('should return YEAR_FIRST if the detected format starts with year', () => {
// Mock the Intl.DateTimeFormat to return a specific format
const mockDateTimeFormat = jest.fn().mockReturnValue({
formatToParts: () => [
Expand All @@ -48,10 +47,10 @@ describe('detectDateFormat', () => {

const result = detectDateFormat();

expect(result).toBe(DateFormat.YEAR_FIRST);
expect(result).toBe('YEAR_FIRST');
});

it('should return DateFormat.MONTH_FIRST by default if the detected format does not match any specific order', () => {
it('should return MONTH_FIRST by default if the detected format does not match any specific order', () => {
// Mock the Intl.DateTimeFormat to return a specific format
const mockDateTimeFormat = jest.fn().mockReturnValue({
formatToParts: () => [
Expand All @@ -64,6 +63,6 @@ describe('detectDateFormat', () => {

const result = detectDateFormat();

expect(result).toBe(DateFormat.MONTH_FIRST);
expect(result).toBe('MONTH_FIRST');
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { TimeFormat } from '@/localization/constants/TimeFormat';
import { detectTimeFormat } from '@/localization/utils/detectTimeFormat';

describe('detectTimeFormat', () => {
it('should return TimeFormat.HOUR_12 if the hour format is 12-hour', () => {
it('should return HOUR_12 if the hour format is 12-hour', () => {
// Mock the resolvedOptions method to return hour12 as true
const mockResolvedOptions = jest.fn(() => ({ hour12: true }));
Intl.DateTimeFormat = jest.fn().mockImplementation(() => ({
Expand All @@ -11,11 +10,11 @@ describe('detectTimeFormat', () => {

const result = detectTimeFormat();

expect(result).toBe(TimeFormat.HOUR_12);
expect(result).toBe('HOUR_12');
expect(mockResolvedOptions).toHaveBeenCalled();
});

it('should return TimeFormat.HOUR_24 if the hour format is 24-hour', () => {
it('should return HOUR_24 if the hour format is 24-hour', () => {
// Mock the resolvedOptions method to return hour12 as false
const mockResolvedOptions = jest.fn(() => ({ hour12: false }));
Intl.DateTimeFormat = jest.fn().mockImplementation(() => ({
Expand All @@ -24,7 +23,7 @@ describe('detectTimeFormat', () => {

const result = detectTimeFormat();

expect(result).toBe(TimeFormat.HOUR_24);
expect(result).toBe('HOUR_24');
expect(mockResolvedOptions).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { detectDateFormat } from '@/localization/utils/detectDateFormat';
import { formatDateISOStringToDateTimeSimplified } from '@/localization/utils/formatDateISOStringToDateTimeSimplified';
import { formatInTimeZone } from 'date-fns-tz';
// Mock the imported modules
jest.mock('@/localization/utils/detectDateFormat');
jest.mock('date-fns-tz');

describe('formatDateISOStringToDateTimeSimplified', () => {
const mockDate = new Date('2023-08-15T10:30:00Z');
const mockTimeZone = 'America/New_York';
const mockTimeFormat = 'HH:mm';

beforeEach(() => {
jest.resetAllMocks();
});

it('should format the date correctly when DATE_FORMAT is MONTH_FIRST', () => {
detectDateFormat.mockReturnValue('MONTH_FIRST');
formatInTimeZone.mockReturnValue('Oct 15 · 06:30');

const result = formatDateISOStringToDateTimeSimplified(
mockDate,
mockTimeZone,
mockTimeFormat,
);

expect(detectDateFormat).toHaveBeenCalled();
expect(formatInTimeZone).toHaveBeenCalledWith(
mockDate,
mockTimeZone,
'MMM d · HH:mm',
);
expect(result).toBe('Oct 15 · 06:30');
});

it('should format the date correctly when DATE_FORMAT is DAY_FIRST', () => {
detectDateFormat.mockReturnValue('DAY_FIRST');
formatInTimeZone.mockReturnValue('15 Oct · 06:30');

const result = formatDateISOStringToDateTimeSimplified(
mockDate,
mockTimeZone,
mockTimeFormat,
);

expect(detectDateFormat).toHaveBeenCalled();
expect(formatInTimeZone).toHaveBeenCalledWith(
mockDate,
mockTimeZone,
'd MMM · HH:mm',
);
expect(result).toBe('15 Oct · 06:30');
});

it('should use the provided time format', () => {
detectDateFormat.mockReturnValue('MONTH_FIRST');
formatInTimeZone.mockReturnValue('Oct 15 · 6:30 AM');

const result = formatDateISOStringToDateTimeSimplified(
mockDate,
mockTimeZone,
'h:mm aa',
);

expect(formatInTimeZone).toHaveBeenCalledWith(
mockDate,
mockTimeZone,
'MMM d · h:mm aa',
);
expect(result).toBe('Oct 15 · 6:30 AM');
});

it('should handle different time zones', () => {
detectDateFormat.mockReturnValue('MONTH_FIRST');
formatInTimeZone.mockReturnValue('Oct 16 · 02:30');

const result = formatDateISOStringToDateTimeSimplified(
mockDate,
'Asia/Tokyo',
mockTimeFormat,
);

expect(formatInTimeZone).toHaveBeenCalledWith(
mockDate,
'Asia/Tokyo',
'MMM d · HH:mm',
);
expect(result).toBe('Oct 16 · 02:30');
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DateFormat } from '@/localization/constants/DateFormat';

export const detectDateFormat = (): DateFormat => {
export const detectDateFormat = (): keyof typeof DateFormat => {
const date = new Date();
const formatter = new Intl.DateTimeFormat(navigator.language);
const parts = formatter.formatToParts(date);
Expand All @@ -9,9 +9,9 @@ export const detectDateFormat = (): DateFormat => {
.filter((part) => ['year', 'month', 'day'].includes(part.type))
.map((part) => part.type);

if (partOrder[0] === 'month') return DateFormat.MONTH_FIRST;
if (partOrder[0] === 'day') return DateFormat.DAY_FIRST;
if (partOrder[0] === 'year') return DateFormat.YEAR_FIRST;
if (partOrder[0] === 'month') return 'MONTH_FIRST';
if (partOrder[0] === 'day') return 'DAY_FIRST';
if (partOrder[0] === 'year') return 'YEAR_FIRST';

return DateFormat.MONTH_FIRST;
return 'MONTH_FIRST';
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { TimeFormat } from '@/localization/constants/TimeFormat';
import { isDefined } from '~/utils/isDefined';

export const detectTimeFormat = () => {
export const detectTimeFormat = (): keyof typeof TimeFormat => {
const isHour12 = Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
}).resolvedOptions().hour12;

if (isDefined(isHour12) && isHour12) {
return TimeFormat.HOUR_12;
return 'HOUR_12';
}

return TimeFormat.HOUR_24;
return 'HOUR_24';
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { DATE_FORMAT_WITHOUT_YEAR } from '@/localization/constants/DateFormatWithoutYear';
import { TimeFormat } from '@/localization/constants/TimeFormat';
import { detectDateFormat } from '@/localization/utils/detectDateFormat';
import { formatInTimeZone } from 'date-fns-tz';

export const formatDateISOStringToDateTimeSimplified = (
date: Date,
timeZone: string,
timeFormat: TimeFormat,
) => {
const simplifiedDateFormat = DATE_FORMAT_WITHOUT_YEAR[detectDateFormat()];

return formatInTimeZone(
date,
timeZone,
`${simplifiedDateFormat} · ${timeFormat}`,
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const getDateFormatFromWorkspaceDateFormat = (
) => {
switch (workspaceDateFormat) {
case WorkspaceMemberDateFormatEnum.System:
return detectDateFormat();
return DateFormat[detectDateFormat()];
case WorkspaceMemberDateFormatEnum.MonthFirst:
return DateFormat.MONTH_FIRST;
case WorkspaceMemberDateFormatEnum.DayFirst:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const getTimeFormatFromWorkspaceTimeFormat = (
) => {
switch (workspaceTimeFormat) {
case WorkspaceMemberTimeFormatEnum.System:
return detectTimeFormat();
return TimeFormat[detectTimeFormat()];
case WorkspaceMemberTimeFormatEnum.Hour_24:
return TimeFormat.HOUR_24;
case WorkspaceMemberTimeFormatEnum.Hour_12:
Expand Down
Loading
Loading