grafana/public/app/core/utils/timePicker.ts
Haris Rozajac f285eb6717
Time Range: Copy-paste Time Range (#80107)
* Working copy-paste functionality with validation

* WIP; uses 't c' shortcut to copy time range

* shortcuts working for explore and dashboards

* cleanup

* Don't update url when pasting in explore

* Error handling, sync pane functionality, add to help modal

* cleanup

* add tests

* fix i18n

* Diferrentiate between explore and dashboard paste events; make on error prop generic

* Fix

* extract getting the copied time range logic into a function

* Remove comments

* Make error handling generic; markup for translations

* Additional translation markup

* markup for aria-label

* Fix test

* Replace fireEvent with userEvent

* fix translations to match the standard pattern

* Refactor keybindingSrv and TimeSrv to remove PasteTimeContext

* Fix test

* Remove unneccessary aria labels; update icons; buttons inline
2024-01-18 14:06:27 -07:00

60 lines
1.7 KiB
TypeScript

import { TimeRange, toUtc, AbsoluteTimeRange, RawTimeRange } from '@grafana/data';
type CopiedTimeRangeResult = { range: RawTimeRange; isError: false } | { range: string; isError: true };
export const getShiftedTimeRange = (direction: number, origRange: TimeRange): AbsoluteTimeRange => {
const range = {
from: toUtc(origRange.from),
to: toUtc(origRange.to),
};
const timespan = (range.to.valueOf() - range.from.valueOf()) / 2;
let to: number, from: number;
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.valueOf() < Date.now()) {
to = Date.now();
from = range.from.valueOf();
}
} else {
to = range.to.valueOf();
from = range.from.valueOf();
}
return { from, to };
};
export const getZoomedTimeRange = (range: TimeRange, factor: number): AbsoluteTimeRange => {
const timespan = range.to.valueOf() - range.from.valueOf();
const center = range.to.valueOf() - timespan / 2;
// If the timepsan is 0, zooming out would do nothing, so we force a zoom out to 30s
const newTimespan = timespan === 0 ? 30000 : timespan * factor;
const to = center + newTimespan / 2;
const from = center - newTimespan / 2;
return { from, to };
};
export async function getCopiedTimeRange(): Promise<CopiedTimeRangeResult> {
const raw = await navigator.clipboard.readText();
let range;
try {
range = JSON.parse(raw);
if (!range.from || !range.to) {
return { range: raw, isError: true };
}
return { range, isError: false };
} catch (e) {
return { range: raw, isError: true };
}
}