Skip to content

Commit a38d548

Browse files
committed
improvement(settings): right-align timezone picker, order by popularity, drop tooltip
1 parent 4ec26a0 commit a38d548

2 files changed

Lines changed: 37 additions & 26 deletions

File tree

apps/sim/app/workspace/[workspaceId]/settings/components/general/general.tsx

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { ANONYMOUS_USER_ID } from '@/lib/auth/constants'
2727
import { getEnv, isTruthy } from '@/lib/core/config/env'
2828
import { isHosted } from '@/lib/core/config/feature-flags'
2929
import { handleKeyboardActivation } from '@/lib/core/utils/keyboard'
30-
import { getBrowserTimezone, getSupportedTimezones } from '@/lib/core/utils/timezone'
30+
import { getBrowserTimezone, getTimezonesByPopularity } from '@/lib/core/utils/timezone'
3131
import { getBaseUrl } from '@/lib/core/utils/urls'
3232
import { SettingsSection } from '@/app/workspace/[workspaceId]/settings/components/settings-section/settings-section'
3333
import { useProfilePictureUpload } from '@/app/workspace/[workspaceId]/settings/hooks/use-profile-picture-upload'
@@ -42,8 +42,11 @@ import { clearUserData } from '@/stores'
4242

4343
const logger = createLogger('General')
4444

45-
/** IANA zones for the timezone picker; labels drop underscores so search reads naturally. */
46-
const TIMEZONE_OPTIONS = getSupportedTimezones().map((tz) => ({
45+
/**
46+
* IANA zones for the timezone picker, ordered most-popular first; labels drop
47+
* underscores so search reads naturally.
48+
*/
49+
const TIMEZONE_OPTIONS = getTimezonesByPopularity().map((tz) => ({
4750
label: tz.replace(/_/g, ' '),
4851
value: tz,
4952
}))
@@ -419,28 +422,19 @@ export function General() {
419422
</div>
420423

421424
<div className='flex items-center justify-between gap-4'>
422-
<div className='flex items-center gap-1.5'>
423-
<Label>Timezone</Label>
424-
<Tooltip.Root>
425-
<Tooltip.Trigger asChild>
426-
<Info className='size-[14px] cursor-default text-[var(--text-muted)]' />
427-
</Tooltip.Trigger>
428-
<Tooltip.Content side='bottom' align='start'>
429-
<p>The timezone scheduled tasks run in. Defaults to this device's zone.</p>
430-
</Tooltip.Content>
431-
</Tooltip.Root>
425+
<Label>Timezone</Label>
426+
<div className='w-[260px] flex-shrink-0'>
427+
<ChipCombobox
428+
align='start'
429+
dropdownWidth={260}
430+
searchable
431+
searchPlaceholder='Search timezones'
432+
value={settings?.timezone ?? getBrowserTimezone()}
433+
onChange={handleTimezoneChange}
434+
placeholder='Select timezone'
435+
options={TIMEZONE_OPTIONS}
436+
/>
432437
</div>
433-
<ChipCombobox
434-
className='min-w-0 max-w-[260px]'
435-
align='start'
436-
dropdownWidth={260}
437-
searchable
438-
searchPlaceholder='Search timezones'
439-
value={settings?.timezone ?? getBrowserTimezone()}
440-
onChange={handleTimezoneChange}
441-
placeholder='Select timezone'
442-
options={TIMEZONE_OPTIONS}
443-
/>
444438
</div>
445439

446440
<div className='flex items-center justify-between'>

apps/sim/lib/core/utils/timezone.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/**
2-
* A curated fallback for runtimes without `Intl.supportedValuesOf` (e.g. Safari
3-
* < 15.4), so the timezone picker is never an empty dead-end.
2+
* The most-used zones, ranked by popularity. Doubles as the popularity prefix
3+
* for {@link getTimezonesByPopularity} and as a curated fallback for runtimes
4+
* without `Intl.supportedValuesOf` (e.g. Safari < 15.4), so the timezone picker
5+
* is never an empty dead-end.
46
*/
57
const COMMON_TIMEZONES = [
68
'UTC',
@@ -38,6 +40,21 @@ export function getSupportedTimezones(): string[] {
3840
return zones.includes('UTC') ? zones : ['UTC', ...zones]
3941
}
4042

43+
/**
44+
* Supported timezones ordered by popularity: the most-used zones
45+
* ({@link COMMON_TIMEZONES}) first, in ranked order, followed by every
46+
* remaining zone alphabetically. For the picker, where the zones people
47+
* actually pick should surface above the long alphabetical tail.
48+
*/
49+
export function getTimezonesByPopularity(): string[] {
50+
const supported = getSupportedTimezones()
51+
const supportedSet = new Set(supported)
52+
const popular = COMMON_TIMEZONES.filter((tz) => supportedSet.has(tz))
53+
const popularSet = new Set(popular)
54+
const rest = supported.filter((tz) => !popularSet.has(tz)).sort((a, b) => a.localeCompare(b))
55+
return [...popular, ...rest]
56+
}
57+
4158
/**
4259
* An instant's wall-clock time in `timeZone` as a naive `yyyy-MM-ddTHH:mm`
4360
* string. Lets callers reason about a user's local date/time without UTC — e.g.

0 commit comments

Comments
 (0)