From a9faab6b09351c1eab3eb0f49a8e5979d6e4abd1 Mon Sep 17 00:00:00 2001 From: Guilherme Caulada Date: Mon, 18 Oct 2021 10:27:14 -0300 Subject: [PATCH] Dashboard: Add week start option to global and dashboard preferences (#40010) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add global week start option to shared preferences * Add default_week_start to configuration docs * Add week start option to dashboards * Add week start argument to tsdb time range parser * Fix strict check issues * Add tests for week start * Change wording on default_week_start documentation Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com> * Update week_start column to be a nullable field Co-authored-by: Emil Tullstedt * Update configuration to include browser option * Update WeekStartPicker container selector Co-authored-by: Hugo Häggmark * Add menuShouldPortal to WeekStartPicker to remove deprecation warning Co-authored-by: Alex Khomenko * Add inputId to WeekStartPicker * Use e2e selector on WeekStartPicker aria-label * Simplify WeekStartPicker onChange condition * Specify value type on WeekStartPicker weekStarts * Remove setWeekStart side effect from reducer * Fix updateLocale failing to reset week start * Store week start as string to handle empty values Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com> Co-authored-by: Emil Tullstedt Co-authored-by: Hugo Häggmark Co-authored-by: Alex Khomenko --- docs/sources/administration/configuration.md | 4 + .../src/datetime/moment_wrapper.ts | 20 +++ .../src/selectors/components.ts | 3 + .../DateTimePickers/WeekStartPicker.story.tsx | 37 ++++++ .../DateTimePickers/WeekStartPicker.tsx | 52 ++++++++ packages/grafana-ui/src/components/index.ts | 1 + pkg/api/dtos/models.go | 1 + pkg/api/dtos/prefs.go | 2 + pkg/api/index.go | 1 + pkg/api/preferences.go | 2 + pkg/models/preferences.go | 2 + .../sqlstore/migrations/preferences_mig.go | 4 + pkg/services/sqlstore/preferences.go | 7 +- pkg/setting/date_formats.go | 12 +- pkg/tsdb/time_range.go | 24 +++- pkg/tsdb/time_range_test.go | 115 ++++++++++++++++++ public/app/app.ts | 2 + .../SharedPreferences/SharedPreferences.tsx | 18 ++- .../GeneralSettings.test.tsx | 1 + .../DashboardSettings/GeneralSettings.tsx | 13 +- .../DashboardSettings/TimePickerSettings.tsx | 11 +- .../dashboard/state/DashboardModel.ts | 2 + .../app/features/dashboard/state/actions.ts | 7 +- .../features/dashboard/state/initDashboard.ts | 11 +- .../features/profile/state/reducers.test.ts | 10 ++ public/app/features/profile/state/reducers.ts | 20 ++- public/app/types/preferences.ts | 1 + 27 files changed, 362 insertions(+), 21 deletions(-) create mode 100644 packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx diff --git a/docs/sources/administration/configuration.md b/docs/sources/administration/configuration.md index 4a9091c2751..f421d8df4de 100644 --- a/docs/sources/administration/configuration.md +++ b/docs/sources/administration/configuration.md @@ -1785,6 +1785,10 @@ Set this to `true` to have date formats automatically derived from your browser Used as the default time zone for user preferences. Can be either `browser` for the browser local time zone or a time zone name from the IANA Time Zone database, such as `UTC` or `Europe/Amsterdam`. +### default_week_start + +Set the default start of the week, valid values are: `saturday`, `sunday`, `monday` or `browser` to use the browser locale to define the first day of the week. Default is `browser`. + ## [expressions] > **Note:** This feature is available in Grafana v7.4 and later versions. diff --git a/packages/grafana-data/src/datetime/moment_wrapper.ts b/packages/grafana-data/src/datetime/moment_wrapper.ts index 03910a31128..80af4900f8e 100644 --- a/packages/grafana-data/src/datetime/moment_wrapper.ts +++ b/packages/grafana-data/src/datetime/moment_wrapper.ts @@ -120,3 +120,23 @@ export const dateTimeForTimeZone = ( return dateTime(input, formatInput); }; + +export const getWeekdayIndex = (day: string) => { + return moment.weekdays().findIndex((wd) => wd.toLowerCase() === day.toLowerCase()); +}; + +export const setWeekStart = (weekStart?: string) => { + const suffix = '-weekStart'; + const language = getLocale().replace(suffix, ''); + const dow = weekStart ? getWeekdayIndex(weekStart) : -1; + if (dow !== -1) { + moment.locale(language + suffix, { + parentLocale: language, + week: { + dow, + }, + }); + } else { + setLocale(language); + } +}; diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index 7267d46db99..037a7a04caa 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -219,6 +219,9 @@ export const Components = { TimeZonePicker: { container: 'Time zone picker select container', }, + WeekStartPicker: { + container: 'Choose starting day of the week', + }, TraceViewer: { spanBar: () => '[data-test-id="SpanBar--wrapper"]', }, diff --git a/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx new file mode 100644 index 00000000000..85742db207e --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { action } from '@storybook/addon-actions'; + +import { WeekStartPicker } from '@grafana/ui'; +import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +export default { + title: 'Pickers and Editors/TimePickers/WeekStartPicker', + component: WeekStartPicker, + decorators: [withCenteredStory], +}; + +export const basic = () => { + return ( + + {(value, updateValue) => { + return ( + { + if (!newValue) { + return; + } + action('on selected')(newValue); + updateValue({ value: newValue }); + }} + /> + ); + }} + + ); +}; diff --git a/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx new file mode 100644 index 00000000000..d48e44e7e5c --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx @@ -0,0 +1,52 @@ +import React, { useCallback } from 'react'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '../Select/Select'; +import { selectors } from '@grafana/e2e-selectors'; + +export interface Props { + onChange: (weekStart: string) => void; + value: string; + width?: number; + autoFocus?: boolean; + onBlur?: () => void; + includeInternal?: boolean; + disabled?: boolean; + inputId?: string; +} + +const weekStarts: Array> = [ + { value: '', label: 'Default' }, + { value: 'saturday', label: 'Saturday' }, + { value: 'sunday', label: 'Sunday' }, + { value: 'monday', label: 'Monday' }, +]; + +export const WeekStartPicker: React.FC = (props) => { + const { onChange, width, autoFocus = false, onBlur, value, disabled = false, inputId } = props; + + const onChangeWeekStart = useCallback( + (selectable: SelectableValue) => { + if (selectable.value !== undefined) { + onChange(selectable.value); + } + }, + [onChange] + ); + + return ( +