diff --git a/packages/grafana-data/src/datetime/index.ts b/packages/grafana-data/src/datetime/index.ts index bbaa4ebd95c..eb58515b652 100644 --- a/packages/grafana-data/src/datetime/index.ts +++ b/packages/grafana-data/src/datetime/index.ts @@ -2,4 +2,5 @@ import * as dateMath from './datemath'; import * as rangeUtil from './rangeutil'; export * from './moment_wrapper'; +export * from './timezones'; export { dateMath, rangeUtil }; diff --git a/packages/grafana-data/src/datetime/timezones.ts b/packages/grafana-data/src/datetime/timezones.ts new file mode 100644 index 00000000000..c9f01072621 --- /dev/null +++ b/packages/grafana-data/src/datetime/timezones.ts @@ -0,0 +1,390 @@ +// List taken from https://stackoverflow.com/questions/38399465/how-to-get-list-of-all-timezones-in-javascript + +export const getTimeZoneGroups = () => { + const europeZones = [ + 'Europe/Amsterdam', + 'Europe/Andorra', + 'Europe/Astrakhan', + 'Europe/Athens', + 'Europe/Belgrade', + 'Europe/Berlin', + 'Europe/Brussels', + 'Europe/Bucharest', + 'Europe/Budapest', + 'Europe/Chisinau', + 'Europe/Copenhagen', + 'Europe/Dublin', + 'Europe/Gibraltar', + 'Europe/Helsinki', + 'Europe/Istanbul', + 'Europe/Kaliningrad', + 'Europe/Kiev', + 'Europe/Kirov', + 'Europe/Lisbon', + 'Europe/London', + 'Europe/Luxembourg', + 'Europe/Madrid', + 'Europe/Malta', + 'Europe/Minsk', + 'Europe/Monaco', + 'Europe/Moscow', + 'Europe/Oslo', + 'Europe/Paris', + 'Europe/Prague', + 'Europe/Riga', + 'Europe/Rome', + 'Europe/Samara', + 'Europe/Saratov', + 'Europe/Simferopol', + 'Europe/Sofia', + 'Europe/Stockholm', + 'Europe/Tallinn', + 'Europe/Tirane', + 'Europe/Ulyanovsk', + 'Europe/Uzhgorod', + 'Europe/Vienna', + 'Europe/Vilnius', + 'Europe/Volgograd', + 'Europe/Warsaw', + 'Europe/Zaporozhye', + 'Europe/Zurich', + ]; + + const africaZones = [ + 'Africa/Abidjan', + 'Africa/Accra', + 'Africa/Algiers', + 'Africa/Bissau', + 'Africa/Cairo', + 'Africa/Casablanca', + 'Africa/Ceuta', + 'Africa/El_Aaiun', + 'Africa/Johannesburg', + 'Africa/Juba', + 'Africa/Khartoum', + 'Africa/Lagos', + 'Africa/Maputo', + 'Africa/Monrovia', + 'Africa/Nairobi', + 'Africa/Ndjamena', + 'Africa/Sao_Tome', + 'Africa/Tripoli', + 'Africa/Tunis', + 'Africa/Windhoek', + ]; + + const asiaZones = [ + 'Asia/Almaty', + 'Asia/Amman', + 'Asia/Anadyr', + 'Asia/Aqtau', + 'Asia/Aqtobe', + 'Asia/Ashgabat', + 'Asia/Atyrau', + 'Asia/Baghdad', + 'Asia/Baku', + 'Asia/Bangkok', + 'Asia/Barnaul', + 'Asia/Beirut', + 'Asia/Bishkek', + 'Asia/Brunei', + 'Asia/Chita', + 'Asia/Choibalsan', + 'Asia/Colombo', + 'Asia/Damascus', + 'Asia/Dhaka', + 'Asia/Dili', + 'Asia/Dubai', + 'Asia/Dushanbe', + 'Asia/Famagusta', + 'Asia/Gaza', + 'Asia/Hebron', + 'Asia/Ho_Chi_Minh', + 'Asia/Hong_Kong', + 'Asia/Hovd', + 'Asia/Irkutsk', + 'Asia/Jakarta', + 'Asia/Jayapura', + 'Asia/Jerusalem', + 'Asia/Kabul', + 'Asia/Kamchatka', + 'Asia/Karachi', + 'Asia/Kathmandu', + 'Asia/Khandyga', + 'Asia/Kolkata', + 'Asia/Krasnoyarsk', + 'Asia/Kuala_Lumpur', + 'Asia/Kuching', + 'Asia/Macau', + 'Asia/Magadan', + 'Asia/Makassar', + 'Asia/Manila', + 'Asia/Nicosia', + 'Asia/Novokuznetsk', + 'Asia/Novosibirsk', + 'Asia/Omsk', + 'Asia/Oral', + 'Asia/Pontianak', + 'Asia/Pyongyang', + 'Asia/Qatar', + 'Asia/Qostanay', + 'Asia/Qyzylorda', + 'Asia/Riyadh', + 'Asia/Sakhalin', + 'Asia/Samarkand', + 'Asia/Seoul', + 'Asia/Shanghai', + 'Asia/Singapore', + 'Asia/Srednekolymsk', + 'Asia/Taipei', + 'Asia/Tashkent', + 'Asia/Tbilisi', + 'Asia/Tehran', + 'Asia/Thimphu', + 'Asia/Tokyo', + 'Asia/Tomsk', + 'Asia/Ulaanbaatar', + 'Asia/Urumqi', + 'Asia/Ust-Nera', + 'Asia/Vladivostok', + 'Asia/Yakutsk', + 'Asia/Yangon', + 'Asia/Yekaterinburg', + 'Asia/Yerevan', + ]; + + const antarcticaZones = [ + 'Antarctica/Casey', + 'Antarctica/Davis', + 'Antarctica/DumontDUrville', + 'Antarctica/Macquarie', + 'Antarctica/Mawson', + 'Antarctica/Palmer', + 'Antarctica/Rothera', + 'Antarctica/Syowa', + 'Antarctica/Troll', + 'Antarctica/Vostok', + ]; + + const americaZones = [ + 'America/Adak', + 'America/Anchorage', + 'America/Araguaina', + 'America/Argentina/Buenos_Aires', + 'America/Argentina/Catamarca', + 'America/Argentina/Cordoba', + 'America/Argentina/Jujuy', + 'America/Argentina/La_Rioja', + 'America/Argentina/Mendoza', + 'America/Argentina/Rio_Gallegos', + 'America/Argentina/Salta', + 'America/Argentina/San_Juan', + 'America/Argentina/San_Luis', + 'America/Argentina/Tucuman', + 'America/Argentina/Ushuaia', + 'America/Asuncion', + 'America/Atikokan', + 'America/Bahia', + 'America/Bahia_Banderas', + 'America/Barbados', + 'America/Belem', + 'America/Belize', + 'America/Blanc-Sablon', + 'America/Boa_Vista', + 'America/Bogota', + 'America/Boise', + 'America/Cambridge_Bay', + 'America/Campo_Grande', + 'America/Cancun', + 'America/Caracas', + 'America/Cayenne', + 'America/Chicago', + 'America/Chihuahua', + 'America/Costa_Rica', + 'America/Creston', + 'America/Cuiaba', + 'America/Curacao', + 'America/Danmarkshavn', + 'America/Dawson', + 'America/Dawson_Creek', + 'America/Denver', + 'America/Detroit', + 'America/Edmonton', + 'America/Eirunepe', + 'America/El_Salvador', + 'America/Fort_Nelson', + 'America/Fortaleza', + 'America/Glace_Bay', + 'America/Godthab', + 'America/Goose_Bay', + 'America/Grand_Turk', + 'America/Guatemala', + 'America/Guayaquil', + 'America/Guyana', + 'America/Halifax', + 'America/Havana', + 'America/Hermosillo', + 'America/Indiana/Indianapolis', + 'America/Indiana/Knox', + 'America/Indiana/Marengo', + 'America/Indiana/Petersburg', + 'America/Indiana/Tell_City', + 'America/Indiana/Vevay', + 'America/Indiana/Vincennes', + 'America/Indiana/Winamac', + 'America/Inuvik', + 'America/Iqaluit', + 'America/Jamaica', + 'America/Juneau', + 'America/Kentucky/Louisville', + 'America/Kentucky/Monticello', + 'America/La_Paz', + 'America/Lima', + 'America/Los_Angeles', + 'America/Maceio', + 'America/Managua', + 'America/Manaus', + 'America/Martinique', + 'America/Matamoros', + 'America/Mazatlan', + 'America/Menominee', + 'America/Merida', + 'America/Metlakatla', + 'America/Mexico_City', + 'America/Miquelon', + 'America/Moncton', + 'America/Monterrey', + 'America/Montevideo', + 'America/Nassau', + 'America/New_York', + 'America/Nipigon', + 'America/Nome', + 'America/Noronha', + 'America/North_Dakota/Beulah', + 'America/North_Dakota/Center', + 'America/North_Dakota/New_Salem', + 'America/Ojinaga', + 'America/Panama', + 'America/Pangnirtung', + 'America/Paramaribo', + 'America/Phoenix', + 'America/Port-au-Prince', + 'America/Port_of_Spain', + 'America/Porto_Velho', + 'America/Puerto_Rico', + 'America/Punta_Arenas', + 'America/Rainy_River', + 'America/Rankin_Inlet', + 'America/Recife', + 'America/Regina', + 'America/Resolute', + 'America/Rio_Branco', + 'America/Santarem', + 'America/Santiago', + 'America/Santo_Domingo', + 'America/Sao_Paulo', + 'America/Scoresbysund', + 'America/Sitka', + 'America/St_Johns', + 'America/Swift_Current', + 'America/Tegucigalpa', + 'America/Thule', + 'America/Thunder_Bay', + 'America/Tijuana', + 'America/Toronto', + 'America/Vancouver', + 'America/Whitehorse', + 'America/Winnipeg', + 'America/Yakutat', + 'America/Yellowknife', + ]; + + const pacificZones = [ + 'Pacific/Apia', + 'Pacific/Auckland', + 'Pacific/Bougainville', + 'Pacific/Chatham', + 'Pacific/Chuuk', + 'Pacific/Easter', + 'Pacific/Efate', + 'Pacific/Enderbury', + 'Pacific/Fakaofo', + 'Pacific/Fiji', + 'Pacific/Funafuti', + 'Pacific/Galapagos', + 'Pacific/Gambier', + 'Pacific/Guadalcanal', + 'Pacific/Guam', + 'Pacific/Honolulu', + 'Pacific/Kiritimati', + 'Pacific/Kosrae', + 'Pacific/Kwajalein', + 'Pacific/Majuro', + 'Pacific/Marquesas', + 'Pacific/Nauru', + 'Pacific/Niue', + 'Pacific/Norfolk', + 'Pacific/Noumea', + 'Pacific/Pago_Pago', + 'Pacific/Palau', + 'Pacific/Pitcairn', + 'Pacific/Pohnpei', + 'Pacific/Port_Moresby', + 'Pacific/Rarotonga', + 'Pacific/Tahiti', + 'Pacific/Tarawa', + 'Pacific/Tongatapu', + 'Pacific/Wake', + 'Pacific/Wallis', + ]; + + const australiaZones = [ + 'Australia/Adelaide', + 'Australia/Brisbane', + 'Australia/Broken_Hill', + 'Australia/Currie', + 'Australia/Darwin', + 'Australia/Eucla', + 'Australia/Hobart', + 'Australia/Lindeman', + 'Australia/Lord_Howe', + 'Australia/Melbourne', + 'Australia/Perth', + 'Australia/Sydney', + ]; + + const atlanticZones = [ + 'Atlantic/Azores', + 'Atlantic/Bermuda', + 'Atlantic/Canary', + 'Atlantic/Cape_Verde', + 'Atlantic/Faroe', + 'Atlantic/Madeira', + 'Atlantic/Reykjavik', + 'Atlantic/South_Georgia', + 'Atlantic/Stanley', + ]; + + const indianZones = [ + 'Indian/Chagos', + 'Indian/Christmas', + 'Indian/Cocos', + 'Indian/Kerguelen', + 'Indian/Mahe', + 'Indian/Maldives', + 'Indian/Mauritius', + 'Indian/Reunion', + ]; + + return [ + { label: 'Africa', options: africaZones }, + { label: 'America', options: americaZones }, + { label: 'Antarctica', options: antarcticaZones }, + { label: 'Asia', options: asiaZones }, + { label: 'Atlantic', options: atlanticZones }, + { label: 'Australia', options: australiaZones }, + { label: 'Europe', options: europeZones }, + { label: 'Indian', options: indianZones }, + { label: 'Pacific', options: pacificZones }, + ]; +}; diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.story.tsx b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.story.tsx new file mode 100644 index 00000000000..8f1dfc41b06 --- /dev/null +++ b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.story.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; + +import { TimeZonePicker } from './TimeZonePicker'; +import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +const TimeZonePickerStories = storiesOf('UI/TimeZonePicker', module); + +TimeZonePickerStories.addDecorator(withCenteredStory); + +TimeZonePickerStories.add('default', () => { + return ( + + {(value, updateValue) => { + return ( + { + action('on selected')(newValue); + updateValue({ value: newValue }); + }} + width={20} + /> + ); + }} + + ); +}); diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx new file mode 100644 index 00000000000..18a4d533a4c --- /dev/null +++ b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx @@ -0,0 +1,41 @@ +import React, { FC } from 'react'; +import { getTimeZoneGroups, SelectableValue } from '@grafana/data'; +import { Select } from '..'; + +interface Props { + value: string; + width?: number; + + onChange: (newValue: string) => void; +} + +export const TimeZonePicker: FC = ({ onChange, value, width }) => { + const timeZoneGroups = getTimeZoneGroups(); + + const groupOptions = timeZoneGroups.map(group => { + const options = group.options.map(timeZone => { + return { + label: timeZone, + value: timeZone.toLowerCase(), + }; + }); + + return { + label: group.label, + options, + }; + }); + + const selectedValue = groupOptions.map(group => { + return group.options.find(option => option.value === value); + }); + + return ( +