import { css } from '@emotion/css';
import moment, { Moment } from 'moment/moment';
import { ChangeEvent, useState } from 'react';
import { dateTimeAsMoment, getTimeZoneInfo, GrafanaTheme2, isDateTime, SelectableValue } from '@grafana/data';
import {
Button,
Field,
FieldSet,
Input,
Select,
Stack,
Switch,
TimeOfDayPicker,
TimeZonePicker,
useStyles2,
} from '@grafana/ui';
import { TimeZoneOffset } from '@grafana/ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset';
import { TimeZoneTitle } from '@grafana/ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle';
import { t } from 'app/core/internationalization';
import { TimeRegionConfig, TimeRegionMode } from 'app/core/utils/timeRegions';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
interface Props {
value: TimeRegionConfig;
onChange: (value?: TimeRegionConfig) => void;
}
const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'].map((v, idx) => {
return {
label: v,
value: idx + 1,
};
});
export const TimeRegionEditor = ({ value, onChange }: Props) => {
const styles = useStyles2(getStyles);
const timestamp = Date.now();
const timezoneInfo = getTimeZoneInfo(value.timezone ?? 'utc', timestamp);
const isDashboardTimezone = getDashboardSrv().getCurrent()?.getTimezone() === value.timezone;
const [isEditing, setEditing] = useState(false);
const onToggleChangeTimezone = () => {
setEditing(!isEditing);
};
const getTime = (time: string | undefined): Moment | undefined => {
if (!time) {
return undefined;
}
const date = moment();
if (time) {
const match = time.split(':');
date.set('hour', parseInt(match[0], 10));
date.set('minute', parseInt(match[1], 10));
}
return date;
};
const getToPlaceholder = () => {
let placeholder = 'Everyday';
if (value.fromDayOfWeek && !value.toDayOfWeek) {
placeholder = days[value.fromDayOfWeek - 1].label;
}
return placeholder;
};
const renderTimezonePicker = () => {
const timezone = (
<>
>
);
if (isDashboardTimezone) {
return <>Dashboard timezone ({timezone})>;
}
return timezone;
};
const onTimeChange = (v: Moment | undefined, field: string) => {
const time = v ? v.format('HH:mm') : undefined;
if (field === 'from') {
onChange({ ...value, from: time });
} else {
onChange({ ...value, to: time });
}
};
const onTimezoneChange = (v: string | undefined) => {
onChange({ ...value, timezone: v });
};
const onModeChange = (v: TimeRegionMode) => {
onChange({ ...value, mode: v });
};
const onCronExprChange = (v: string) => {
onChange({ ...value, cronExpr: v });
};
const onDurationChange = (v: string) => {
onChange({ ...value, duration: v });
};
const onFromDayOfWeekChange = (v: SelectableValue) => {
const fromDayOfWeek = v ? v.value : undefined;
const toDayOfWeek = v ? value.toDayOfWeek : undefined; // clear if everyday
onChange({ ...value, fromDayOfWeek, toDayOfWeek });
};
const onToDayOfWeekChange = (v: SelectableValue) => {
onChange({ ...value, toDayOfWeek: v ? v.value : undefined });
};
const renderTimezone = () => {
if (isEditing) {
return (
onTimezoneChange(v)}
onBlur={() => setEditing(false)}
openMenuOnFocus={false}
width={100}
autoFocus
/>
);
}
return (
{renderTimezonePicker()}
);
};
const from = getTime(value.from);
const to = getTime(value.to);
return (
);
};
const getStyles = (theme: GrafanaTheme2) => {
return {
wrapper: css({
maxWidth: theme.spacing(60),
marginBottom: theme.spacing(2),
}),
timezoneContainer: css({
padding: '5px',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
fontSize: '12px',
}),
timezone: css({
marginRight: '5px',
}),
};
};