mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
* Added RefreshButton * Added RefreshSelect * Added RefreshSelectButton * Added RefreshPicker * Removed the magic string Paused * Minor style changes and using Off instead of Pause * Added HeadlessSelect * Added HeadlessSelect story * Added SelectButton * Removed RefreshSelectButton * Added TimePicker and moved ClickOutsideWrapper to ui/components * Added TimePickerPopOver * Added react-calendar * Missed yarn lock file * Added inputs to popover * Added TimePicker and RefreshPicker to DashNav * Moved TimePicker and RefreshPicker to app/core * Added react-calendar to app and removed from ui/components * Fixed PopOver onClick * Moved everything back to ui components because of typings problems * Exporing RefreshPicker and TimePicker * Added Apply and inputs * Added typings * Added TimePickerInput and logic * Fixed parsing of string to Moments * Fixed range string * Styling and connecting the calendars and inputs * Changed Calendar styling * Added backward forward and zoom * Fixed responsive styles * Moved TimePicker and RefreshPicker into app core * Renamed menuIsOpen to isOpen * Changed from className={} to className="" * Moved Popover to TimePickerOptionGroup * Renamed all PopOver to Popover * Renamed popOver to popover and some minor refactorings * Renamed files with git mv * Added ButtonSelect and refactored RefreshPicker * Refactored TimePicker to use new ButtonSelect * Removed HeadlessSelect as suggested * fix: Fix typings and misc errors after rebase * wip: Enable time picker on dashboard and add tooltip * Merge branch 'master' into hugoh/new-timepicker-and-unified-component # Conflicts: # packages/grafana-ui/package.json # packages/grafana-ui/src/components/Input/Input.test.tsx # packages/grafana-ui/src/components/Input/Input.tsx # packages/grafana-ui/src/utils/validate.ts # public/app/features/dashboard/panel_editor/QueryOptions.tsx # yarn.lock * fix: Snapshot update * Move TimePicker default options into the TimePicker as statics, pass the tooltipContent down the line when wanted and wrap the button in a tooltip element * fix: Override internal state prop if we provide one in a prop * Updated snapshots * Let dashnav control refreshPicker state * feat: Add a stringToMs function * wip: RefreshPicker * wip: Move RefreshPicker to @grafana/ui * wip: Move TimePicker to @grafana/ui * wip: Remove comments * wip: Add refreshPicker to explore * wip: Use default intervals if the prop is missing * wip: Nicer way of setting defaults * fix: Control the select component * wip: Add onMoveForward/onMoveBack * Remove code related to the new time picker and refresh picker from dashnav * Fix: Typings after merge * chore: Minor fix after merge * chore: Remove _.map usage * chore: Moved refresh-picker logic out of the refresh picker since it will work a little differently in explore and dashboards until we have replaced the TimeSrv * feat: Add an Interval component to @grafana/ui * chore: Remove intervalId from redux state and move setInterval logic from ExploreToolbar to its own Interval component * feat: Add refreshInterval to Explore's URL state * feat: Pick up refreshInterval from url on page load * fix: Set default refreshInterval when no value can be retained from URL * fix: Update test initial state with refreshInterval * fix: Handle URLs before RefreshPicker * fix: Move RefreshInterval to url position 3 since the segments can take multiple positions * fix: A better way of detecting urls without RefreshInterval in Explore * chore: Some Explore typings * fix: Attach refresh picker to interval picker * chore: Sass fix for refresh button border radius * fix: Remove refreshInterval from URL * fix: Intervals now start when previous interval is finished * fix: Use clearTimeout instead of clearInterval * fix: Make sure there's a delay set before adding a timeout when we have slow explore queries * wip: Add refresh picker to dashboard * feat: Add util for removing keys with empty values * feat: RefreshPicker in dashboards and tmp rem out old RefreshPicker * fix: Remove the jumpy:ness in the refreshpicker * Changed placement and made it hide when your in dashboard settings * chore: Move logic related to refresh picker out of DashNav to its own component * feat: Add tooltip to refreshpicker * fix: Fix bug with refreshpicker not updating when setting to 'off' * fix: Make it possible to override refresh intervals using the dashboard intervals * chore: Change name of Interval to SetInterval to align with ecmascripts naming since its basically the same but declarative and async * fix: Use default intervals when auto refresh is empty in dashboard settings * fix: Hide time/interval picker when hidden is true on the model, such as on the home dashboard * fix: Interval picker will have to handle location changes since timeSrv wont * RefreshPicker: Refactoring refresh picker * RefreshPicker: minor refactoring
190 lines
5.1 KiB
TypeScript
190 lines
5.1 KiB
TypeScript
import _ from 'lodash';
|
|
import angular from 'angular';
|
|
import moment from 'moment';
|
|
|
|
import * as rangeUtil from 'app/core/utils/rangeutil';
|
|
|
|
export class TimePickerCtrl {
|
|
static tooltipFormat = 'MMM D, YYYY HH:mm:ss';
|
|
static defaults = {
|
|
time_options: ['5m', '15m', '1h', '6h', '12h', '24h', '2d', '7d', '30d'],
|
|
refresh_intervals: ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'],
|
|
};
|
|
|
|
dashboard: any;
|
|
panel: any;
|
|
absolute: any;
|
|
timeRaw: any;
|
|
editTimeRaw: any;
|
|
tooltip: string;
|
|
rangeString: string;
|
|
timeOptions: any;
|
|
refresh: any;
|
|
isUtc: boolean;
|
|
firstDayOfWeek: number;
|
|
isOpen: boolean;
|
|
isAbsolute: boolean;
|
|
|
|
/** @ngInject */
|
|
constructor(private $scope, private $rootScope, private timeSrv) {
|
|
this.$scope.ctrl = this;
|
|
|
|
$rootScope.onAppEvent('shift-time-forward', () => this.move(1), $scope);
|
|
$rootScope.onAppEvent('shift-time-backward', () => this.move(-1), $scope);
|
|
$rootScope.onAppEvent('closeTimepicker', this.openDropdown.bind(this), $scope);
|
|
|
|
this.dashboard.on('refresh', this.onRefresh.bind(this), $scope);
|
|
|
|
// init options
|
|
this.panel = this.dashboard.timepicker;
|
|
_.defaults(this.panel, TimePickerCtrl.defaults);
|
|
this.firstDayOfWeek = moment.localeData().firstDayOfWeek();
|
|
|
|
// init time stuff
|
|
this.onRefresh();
|
|
}
|
|
|
|
onRefresh() {
|
|
const time = angular.copy(this.timeSrv.timeRange());
|
|
const timeRaw = angular.copy(time.raw);
|
|
|
|
if (!this.dashboard.isTimezoneUtc()) {
|
|
time.from.local();
|
|
time.to.local();
|
|
if (moment.isMoment(timeRaw.from)) {
|
|
timeRaw.from.local();
|
|
}
|
|
if (moment.isMoment(timeRaw.to)) {
|
|
timeRaw.to.local();
|
|
}
|
|
this.isUtc = false;
|
|
} else {
|
|
this.isUtc = true;
|
|
}
|
|
|
|
this.rangeString = rangeUtil.describeTimeRange(timeRaw);
|
|
this.absolute = { fromJs: time.from.toDate(), toJs: time.to.toDate() };
|
|
this.tooltip = this.dashboard.formatDate(time.from) + ' <br>to<br>';
|
|
this.tooltip += this.dashboard.formatDate(time.to);
|
|
this.timeRaw = timeRaw;
|
|
this.isAbsolute = moment.isMoment(this.timeRaw.to);
|
|
}
|
|
|
|
zoom(factor) {
|
|
this.$rootScope.appEvent('zoom-out', 2);
|
|
}
|
|
|
|
move(direction) {
|
|
const range = this.timeSrv.timeRange();
|
|
|
|
const timespan = (range.to.valueOf() - range.from.valueOf()) / 2;
|
|
let to, from;
|
|
if (direction === -1) {
|
|
to = range.to.valueOf() - timespan;
|
|
from = range.from.valueOf() - timespan;
|
|
} else if (direction === 1) {
|
|
to = range.to.valueOf() + timespan;
|
|
from = range.from.valueOf() + timespan;
|
|
if (to > Date.now() && range.to < Date.now()) {
|
|
to = Date.now();
|
|
from = range.from.valueOf();
|
|
}
|
|
} else {
|
|
to = range.to.valueOf();
|
|
from = range.from.valueOf();
|
|
}
|
|
|
|
this.timeSrv.setTime({ from: moment.utc(from), to: moment.utc(to) });
|
|
}
|
|
|
|
openDropdown() {
|
|
if (this.isOpen) {
|
|
this.closeDropdown();
|
|
return;
|
|
}
|
|
|
|
this.onRefresh();
|
|
this.editTimeRaw = this.timeRaw;
|
|
this.timeOptions = rangeUtil.getRelativeTimesList(this.panel, this.rangeString);
|
|
this.refresh = {
|
|
value: this.dashboard.refresh,
|
|
options: this.panel.refresh_intervals.map((interval: any) => {
|
|
return { text: interval, value: interval };
|
|
}),
|
|
};
|
|
|
|
this.refresh.options.unshift({ text: 'off' });
|
|
this.isOpen = true;
|
|
this.$rootScope.appEvent('timepickerOpen');
|
|
}
|
|
|
|
closeDropdown() {
|
|
this.isOpen = false;
|
|
this.$rootScope.appEvent('timepickerClosed');
|
|
}
|
|
|
|
applyCustom() {
|
|
if (this.refresh.value !== this.dashboard.refresh) {
|
|
this.timeSrv.setAutoRefresh(this.refresh.value);
|
|
}
|
|
|
|
this.timeSrv.setTime(this.editTimeRaw);
|
|
this.closeDropdown();
|
|
}
|
|
|
|
absoluteFromChanged() {
|
|
this.editTimeRaw.from = this.getAbsoluteMomentForTimezone(this.absolute.fromJs);
|
|
}
|
|
|
|
absoluteToChanged() {
|
|
this.editTimeRaw.to = this.getAbsoluteMomentForTimezone(this.absolute.toJs);
|
|
}
|
|
|
|
getAbsoluteMomentForTimezone(jsDate) {
|
|
return this.dashboard.isTimezoneUtc() ? moment(jsDate).utc() : moment(jsDate);
|
|
}
|
|
|
|
setRelativeFilter(timespan) {
|
|
const range = { from: timespan.from, to: timespan.to };
|
|
|
|
if (this.panel.nowDelay && range.to === 'now') {
|
|
range.to = 'now-' + this.panel.nowDelay;
|
|
}
|
|
|
|
this.timeSrv.setTime(range);
|
|
this.closeDropdown();
|
|
}
|
|
}
|
|
|
|
export function settingsDirective() {
|
|
return {
|
|
restrict: 'E',
|
|
templateUrl: 'public/app/features/dashboard/components/TimePicker/settings.html',
|
|
controller: TimePickerCtrl,
|
|
bindToController: true,
|
|
controllerAs: 'ctrl',
|
|
scope: {
|
|
dashboard: '=',
|
|
},
|
|
};
|
|
}
|
|
|
|
export function timePickerDirective() {
|
|
return {
|
|
restrict: 'E',
|
|
templateUrl: 'public/app/features/dashboard/components/TimePicker/template.html',
|
|
controller: TimePickerCtrl,
|
|
bindToController: true,
|
|
controllerAs: 'ctrl',
|
|
scope: {
|
|
dashboard: '=',
|
|
},
|
|
};
|
|
}
|
|
|
|
angular.module('grafana.directives').directive('gfTimePickerSettings', settingsDirective);
|
|
angular.module('grafana.directives').directive('gfTimePicker', timePickerDirective);
|
|
|
|
import { inputDateDirective } from './validation';
|
|
angular.module('grafana.directives').directive('inputDatetime', inputDateDirective);
|