grafana/public/app/features/dashboard/utils/panel.ts

150 lines
4.6 KiB
TypeScript
Raw Normal View History

// Store
import store from 'app/core/store';
// Models
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
Inspector: move `Panel JSON` and query inspector to the inspector (#23354) * move Panel JSON to inspector * move Panel JSON to inspector * update test * use stats display options * move query inspector to inspector * open inspector from the queries section * subscribe to results * subscribe to results * open the right tab * apply review feedback * update menus (inspect tabs) * Dashboard: extend dashnav to add custom content (#23433) * Dashlist: Fixed dashlist broken in edit mode (#23426) * Chore: Fix bunch of strict null error to fix master CI (#23443) * Fix bunch of null error * Fix failing test * Another test fix * Docs: Add SQL region annotation examples (#23268) Add region annotation examples for SQL data sources in docs. Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com> * Docs: Update contributing doc to install node@12. (#23450) * NewPanelEdit: Minor style and description tweaks, AND PanelQueryRunner & autoMinMax (#23445) * NewPanelEdit: Minor style and description tweaks * Removed the worst snapshot of all time * ReactTable: adds color text to field options (#23427) * Feature: adds text color field config * Refactor: created an extension point * Refactor: uses HOC for extension instead * Fix: fixes background styling from affecting cells without display.color * Chore: export OptionsUIRegistryBuilder on grafana/data (#23444) * export the ui registry * add to utils index also * DataLinks: Do not full page reload data links links (#23429) * Templating: Fix global variable "__org.id" (#23362) * Fixed global variable __org.id value * correct orgId value * reverted the change as variables moved to new file * Chore: reduce null check errors to 788 (currently over 798) (#23449) * Fixed ts errors so build will succeed * Update packages/grafana-data/src/types/graph.ts Co-Authored-By: Ryan McKinley <ryantxu@gmail.com> * Feedback from code review * Leaving out trivial typing's * Fix error with color being undefined now. * fix test with timezone issue * Fixed test Co-authored-by: Ryan McKinley <ryantxu@gmail.com> Co-authored-by: Torkel Ödegaard <torkel@grafana.com> * Cloudwatch: prefer webIdentity over EC2 role (#23452) * Plugins: add a signature status flag (#23420) * Progress * fixed button * Final touches * now works from edit mode * fix layout * show raw objects * move query inspector buttons to the bottom * update snapshot * Updated design * Made full page reload work * Fixed minor style issue * Updated * More fixes * Removed unused imports * Updated * Moved to data tab out to seperate component * fixed ts issue Co-authored-by: Torkel Ödegaard <torkel@grafana.com> Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com> Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com> Co-authored-by: Alexandre de Verteuil <alexandre@grafana.com> Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com> Co-authored-by: Cyril Tovena <cyril.tovena@gmail.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: Vikky Omkar <vikkyomkar@gmail.com> Co-authored-by: Stephanie Closson <srclosson@gmail.com> Co-authored-by: Dário Nascimento <dfrnascimento@gmail.com>
2020-04-15 09:51:51 -05:00
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import { TimeRange, AppEvents } from '@grafana/data';
// Utils
import { isString as _isString } from 'lodash';
import { rangeUtil } from '@grafana/data';
import { dateMath } from '@grafana/data';
import appEvents from 'app/core/app_events';
import config from 'app/core/config';
// Services
import templateSrv from 'app/features/templating/template_srv';
// Constants
import { LS_PANEL_COPY_KEY, PANEL_BORDER } from 'app/core/constants';
import { CoreEvents } from 'app/types';
import { ShareModal } from 'app/features/dashboard/components/ShareModal';
export const removePanel = (dashboard: DashboardModel, panel: PanelModel, ask: boolean) => {
// confirm deletion
if (ask !== false) {
const text2 = panel.alert ? 'Panel includes an alert rule, removing panel will also remove alert rule' : undefined;
const confirmText = panel.alert ? 'YES' : undefined;
appEvents.emit(CoreEvents.showConfirmModal, {
title: 'Remove Panel',
text: 'Are you sure you want to remove this panel?',
text2: text2,
icon: 'trash-alt',
confirmText: confirmText,
yesText: 'Remove',
onConfirm: () => removePanel(dashboard, panel, false),
});
return;
}
dashboard.removePanel(panel);
};
2018-10-30 08:38:18 -05:00
export const duplicatePanel = (dashboard: DashboardModel, panel: PanelModel) => {
dashboard.duplicatePanel(panel);
};
export const copyPanel = (panel: PanelModel) => {
store.set(LS_PANEL_COPY_KEY, JSON.stringify(panel.getSaveModel()));
appEvents.emit(AppEvents.alertSuccess, ['Panel copied. Open Add Panel to paste']);
};
export const sharePanel = (dashboard: DashboardModel, panel: PanelModel) => {
appEvents.emit(CoreEvents.showModalReact, {
component: ShareModal,
props: {
dashboard: dashboard,
panel: panel,
},
});
};
export const refreshPanel = (panel: PanelModel) => {
panel.refresh();
};
export const toggleLegend = (panel: PanelModel) => {
console.log('Toggle legend is not implemented yet');
// We need to set panel.legend defaults first
// panel.legend.show = !panel.legend.show;
refreshPanel(panel);
};
export interface TimeOverrideResult {
timeRange: TimeRange;
timeInfo: string;
}
export function applyPanelTimeOverrides(panel: PanelModel, timeRange: TimeRange): TimeOverrideResult {
const newTimeData = {
timeInfo: '',
timeRange: timeRange,
};
if (panel.timeFrom) {
const timeFromInterpolated = templateSrv.replace(panel.timeFrom, panel.scopedVars);
const timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
if (timeFromInfo.invalid) {
newTimeData.timeInfo = 'invalid time override';
return newTimeData;
}
if (_isString(timeRange.raw.from)) {
const timeFromDate = dateMath.parse(timeFromInfo.from)!;
newTimeData.timeInfo = timeFromInfo.display;
newTimeData.timeRange = {
from: timeFromDate,
to: dateMath.parse(timeFromInfo.to)!,
raw: {
from: timeFromInfo.from,
to: timeFromInfo.to,
},
};
}
}
if (panel.timeShift) {
const timeShiftInterpolated = templateSrv.replace(panel.timeShift, panel.scopedVars);
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,
},
};
}
if (panel.hideTimeOverride) {
newTimeData.timeInfo = '';
}
return newTimeData;
}
export function getResolution(panel: PanelModel): number {
const htmlEl = document.getElementsByTagName('html')[0];
const width = htmlEl.getBoundingClientRect().width; // https://stackoverflow.com/a/21454625
return panel.maxDataPoints ? panel.maxDataPoints : Math.ceil(width * (panel.gridPos.w / 24));
}
export function calculateInnerPanelHeight(panel: PanelModel, containerHeight: number): number {
const chromePadding = panel.plugin && panel.plugin.noPadding ? 0 : config.theme.panelPadding * 2;
const headerHeight = panel.hasTitle() ? config.theme.panelHeaderHeight : 0;
return containerHeight - headerHeight - chromePadding - PANEL_BORDER;
}