Files
grafana/public/app/features/dashboard-scene/scene/PanelTimeRange.tsx
Ashley Harrison 47f8717149 React: Use new JSX transform (#88802)
* update eslint, tsconfig + esbuild to handle new jsx transform

* remove thing that breaks the new jsx transform

* remove react imports

* adjust grafana-icons build

* is this the correct syntax?

* try this

* well this was much easier than expected...

* change grafana-plugin-configs webpack config

* fixes

* fix lockfile

* fix 2 more violations

* use path.resolve instead of require.resolve

* remove react import

* fix react imports

* more fixes

* remove React import

* remove import React from docs

* remove another react import
2024-06-25 12:43:47 +01:00

123 lines
4.0 KiB
TypeScript

import { css } from '@emotion/css';
import { dateMath, getDefaultTimeRange, GrafanaTheme2, rangeUtil, TimeRange } from '@grafana/data';
import {
SceneComponentProps,
sceneGraph,
SceneTimeRangeLike,
SceneTimeRangeState,
SceneTimeRangeTransformerBase,
} from '@grafana/scenes';
import { Icon, PanelChrome, TimePickerTooltip, Tooltip, useStyles2 } from '@grafana/ui';
import { TimeOverrideResult } from 'app/features/dashboard/utils/panel';
export interface PanelTimeRangeState extends SceneTimeRangeState {
timeFrom?: string;
timeShift?: string;
hideTimeOverride?: boolean;
timeInfo?: string;
}
export class PanelTimeRange extends SceneTimeRangeTransformerBase<PanelTimeRangeState> implements SceneTimeRangeLike {
public static Component = PanelTimeRangeRenderer;
public constructor(state: Partial<PanelTimeRangeState> = {}) {
super({
...state,
// This time range is not valid until activation
from: 'now-6h',
to: 'now',
value: getDefaultTimeRange(),
});
this.addActivationHandler(() => this._onActivate());
}
private _onActivate() {
this._subs.add(
this.subscribeToState((n, p) => {
// Listen to own changes and update time info when required
if (n.timeFrom !== p.timeFrom || n.timeShift !== p.timeShift) {
const { timeInfo, timeRange } = this.getTimeOverride(this.getAncestorTimeRange().state.value);
this.setState({ timeInfo, value: timeRange });
}
})
);
}
protected ancestorTimeRangeChanged(timeRange: SceneTimeRangeState): void {
const overrideResult = this.getTimeOverride(timeRange.value);
this.setState({ value: overrideResult.timeRange, timeInfo: overrideResult.timeInfo });
}
private getTimeOverride(parentTimeRange: TimeRange): TimeOverrideResult {
const { timeFrom, timeShift } = this.state;
const newTimeData = { timeInfo: '', timeRange: parentTimeRange };
if (timeFrom) {
const timeFromInterpolated = sceneGraph.interpolate(this, this.state.timeFrom);
const timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
if (timeFromInfo.invalid) {
newTimeData.timeInfo = 'invalid time override';
return newTimeData;
}
// Only evaluate if the timeFrom if parent time is relative
if (rangeUtil.isRelativeTimeRange(parentTimeRange.raw)) {
newTimeData.timeInfo = timeFromInfo.display;
newTimeData.timeRange = {
from: dateMath.parse(timeFromInfo.from)!,
to: dateMath.parse(timeFromInfo.to)!,
raw: { from: timeFromInfo.from, to: timeFromInfo.to },
};
}
}
if (timeShift) {
const timeShiftInterpolated = sceneGraph.interpolate(this, this.state.timeShift);
const timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
if (timeShiftInfo.invalid) {
newTimeData.timeInfo = 'invalid timeshift';
return newTimeData;
}
const timeShift = '-' + timeShiftInterpolated;
newTimeData.timeInfo += ' timeshift ' + timeShift;
const from = dateMath.parseDateMath(timeShift, newTimeData.timeRange.from, false)!;
const to = dateMath.parseDateMath(timeShift, newTimeData.timeRange.to, true)!;
newTimeData.timeRange = { from, to, raw: { from, to } };
}
return newTimeData;
}
}
function PanelTimeRangeRenderer({ model }: SceneComponentProps<PanelTimeRange>) {
const { timeInfo, hideTimeOverride } = model.useState();
const styles = useStyles2(getStyles);
if (!timeInfo || hideTimeOverride) {
return null;
}
return (
<Tooltip content={<TimePickerTooltip timeRange={model.state.value} timeZone={model.getTimeZone()} />}>
<PanelChrome.TitleItem className={styles.timeshift}>
<Icon name="clock-nine" size="sm" /> {timeInfo}
</PanelChrome.TitleItem>
</Tooltip>
);
}
const getStyles = (theme: GrafanaTheme2) => {
return {
timeshift: css({
color: theme.colors.text.link,
gap: theme.spacing(0.5),
whiteSpace: 'nowrap',
}),
};
};