diff --git a/app/javascript/dashboard/constants/globals.js b/app/javascript/dashboard/constants/globals.js index b8014ce6c..5a6033472 100644 --- a/app/javascript/dashboard/constants/globals.js +++ b/app/javascript/dashboard/constants/globals.js @@ -61,3 +61,7 @@ export default { }, }; export const DEFAULT_REDIRECT_URL = '/app/'; + +export const ONBOARDING_STEP_NAMES = { + INVITE: 'invite_team', +}; diff --git a/app/javascript/v3/helpers/BrowserHelper.js b/app/javascript/v3/helpers/BrowserHelper.js new file mode 100644 index 000000000..92dba2035 --- /dev/null +++ b/app/javascript/v3/helpers/BrowserHelper.js @@ -0,0 +1,13 @@ +export const getBrowserLocale = enabledLanguages => { + const localeWithVariant = window.navigator.language.replace('-', '_'); + const localeWithoutVariant = localeWithVariant.split('_')[0]; + return enabledLanguages.find( + lang => + lang.iso_639_1_code === localeWithVariant || + lang.iso_639_1_code === localeWithoutVariant + )?.iso_639_1_code; +}; + +export const getBrowserTimezone = () => { + return Intl.DateTimeFormat().resolvedOptions().timeZone; +}; diff --git a/app/javascript/v3/helpers/OnboardingHelper.js b/app/javascript/v3/helpers/OnboardingHelper.js new file mode 100644 index 000000000..1de90ed24 --- /dev/null +++ b/app/javascript/v3/helpers/OnboardingHelper.js @@ -0,0 +1,15 @@ +export const findMatchingOption = (value, options, defaultValue) => { + const match = options.find( + option => option.value === value || option === value + ); + return match ? match.value || match : defaultValue; +}; + +export const findCompanySizeMatch = (options, size) => { + return ( + options.find(option => { + const upperLimit = option.value.split('-')[1]?.split('+')[0]; + return size < (upperLimit ? Number(upperLimit) : Infinity); + })?.value || this.companySizeOptions[0].value + ); +}; diff --git a/app/javascript/v3/helpers/specs/BrowserHelper.spec.js b/app/javascript/v3/helpers/specs/BrowserHelper.spec.js new file mode 100644 index 000000000..f175f6b0a --- /dev/null +++ b/app/javascript/v3/helpers/specs/BrowserHelper.spec.js @@ -0,0 +1,43 @@ +import { getBrowserLocale, getBrowserTimezone } from '../BrowserHelper'; + +describe('getBrowserLocale', () => { + it('should return the correct locale code when an exact match is found', () => { + // Mock window.navigator.language + Object.defineProperty(window.navigator, 'language', { + value: 'en-US', + configurable: true, + }); + + const languages = [{ iso_639_1_code: 'en' }, { iso_639_1_code: 'en-US' }]; + expect(getBrowserLocale(languages)).toBe('en-US'); + }); + + it('should return the correct locale code when only a partial match is found', () => { + Object.defineProperty(window.navigator, 'language', { + value: 'en-GB', + configurable: true, + }); + + const languages = [{ iso_639_1_code: 'en' }, { iso_639_1_code: 'fr' }]; + expect(getBrowserLocale(languages)).toBe('en'); + }); + + it('should return undefined when no match is found', () => { + Object.defineProperty(window.navigator, 'language', { + value: 'es-ES', + configurable: true, + }); + + const languages = [{ iso_639_1_code: 'en' }, { iso_639_1_code: 'fr' }]; + expect(getBrowserLocale(languages)).toBeUndefined(); + }); +}); + +describe('getBrowserTimezone', () => { + it('should return the current browser timezone', () => { + // This test assumes the environment's timezone is set. + // It's a basic test as getBrowserTimezone relies on Intl API. + const timezone = getBrowserTimezone(); + expect(timezone).toBe(Intl.DateTimeFormat().resolvedOptions().timeZone); + }); +}); diff --git a/app/javascript/v3/helpers/specs/OnboardingHelper.spec.js b/app/javascript/v3/helpers/specs/OnboardingHelper.spec.js new file mode 100644 index 000000000..4d36d70ea --- /dev/null +++ b/app/javascript/v3/helpers/specs/OnboardingHelper.spec.js @@ -0,0 +1,35 @@ +import { findMatchingOption, findCompanySizeMatch } from '../OnboardingHelper'; + +describe('findMatchingOption', () => { + const options = [{ value: 'option1' }, { value: 'option2' }]; + + it('should return the matching option', () => { + expect(findMatchingOption('option1', options, 'default')).toBe('option1'); + }); + + it('should return the default value when no match is found', () => { + expect(findMatchingOption('nonExistingOption', options, 'default')).toBe( + 'default' + ); + }); +}); + +describe('findCompanySizeMatch', () => { + const mockCompanySizeOptions = [ + { value: '1-10' }, + { value: '11-50' }, + { value: '51-500' }, + { value: '501-1000' }, + { value: '1001+' }, + ]; + + it('should return the correct company size range', () => { + const size = 25; + expect(findCompanySizeMatch(size, mockCompanySizeOptions)).toBe('11-50'); + }); + + it('should return the first company size range when no match is found', () => { + const size = 1500; + expect(findCompanySizeMatch(size, mockCompanySizeOptions)).toBe('1-10'); + }); +}); diff --git a/app/javascript/v3/views/auth/signup/Index.vue b/app/javascript/v3/views/auth/signup/Index.vue index 30e8911f8..52580f664 100644 --- a/app/javascript/v3/views/auth/signup/Index.vue +++ b/app/javascript/v3/views/auth/signup/Index.vue @@ -1,5 +1,5 @@