grafana/public/app/features/manage-dashboards/state/actions.ts
Dominik Prokop d2a13c4715
FieldOverride: Support data links via field overrides (#23590)
* Move xss and sanitize packages to grafana-data

* Move text, url and location utils to grafana-data

* Move grafana config types to grafana-data

* Move field display value proxy to grafana-data

* Fix

* Move data links built in vars to grafana-data

* Attach links supplier to when applying field overrides

* Prep tests

* Use links suppliers attached via field overrides

* locationUtil dependencies type

* Move sanitize-url declaration to grafana-data

* Revert "Move sanitize-url declaration to grafana-data"

This reverts commit 11db9f5e55.

* Fix typo

* fix ts vol1

* Remove import from runtime in data.... Make TS happy at the same time ;)

* Lovely TS, please shut up

* Lovely TS, please shut up vol2

* fix tests

* Fixes

* minor refactor

* Attach get links to FieldDisplayValue for seamless usage

* Update packages/grafana-data/src/field/fieldOverrides.ts

* Make storybook build
2020-04-20 07:37:38 +02:00

121 lines
3.7 KiB
TypeScript

import { AppEvents, DataSourceInstanceSettings, DataSourceSelectItem, locationUtil } from '@grafana/data';
import { getBackendSrv } from '@grafana/runtime';
import config from 'app/core/config';
import {
clearDashboard,
setInputs,
setGcomDashboard,
setJsonDashboard,
InputType,
ImportDashboardDTO,
} from './reducers';
import { updateLocation } from 'app/core/actions';
import { ThunkResult } from 'app/types';
import { appEvents } from '../../../core/core';
export function fetchGcomDashboard(id: string): ThunkResult<void> {
return async dispatch => {
try {
const dashboard = await getBackendSrv().get(`/api/gnet/dashboards/${id}`);
dispatch(setGcomDashboard(dashboard));
dispatch(processInputs(dashboard.json));
} catch (error) {
appEvents.emit(AppEvents.alertError, [error.data.message || error]);
}
};
}
export function importDashboardJson(dashboard: any): ThunkResult<void> {
return async dispatch => {
dispatch(setJsonDashboard(dashboard));
dispatch(processInputs(dashboard));
};
}
function processInputs(dashboardJson: any): ThunkResult<void> {
return dispatch => {
if (dashboardJson && dashboardJson.__inputs) {
const inputs: any[] = [];
dashboardJson.__inputs.forEach((input: any) => {
const inputModel: any = {
name: input.name,
label: input.label,
info: input.description,
value: input.value,
type: input.type,
pluginId: input.pluginId,
options: [],
};
if (input.type === InputType.DataSource) {
getDataSourceOptions(input, inputModel);
} else if (!inputModel.info) {
inputModel.info = 'Specify a string constant';
}
inputs.push(inputModel);
});
dispatch(setInputs(inputs));
}
};
}
export function resetDashboard(): ThunkResult<void> {
return dispatch => {
dispatch(clearDashboard());
};
}
export function saveDashboard(importDashboardForm: ImportDashboardDTO): ThunkResult<void> {
return async (dispatch, getState) => {
const dashboard = getState().importDashboard.dashboard;
const inputs = getState().importDashboard.inputs;
let inputsToPersist = [] as any[];
importDashboardForm.dataSources?.forEach((dataSource: DataSourceSelectItem, index: number) => {
const input = inputs.dataSources[index];
inputsToPersist.push({
name: input.name,
type: input.type,
pluginId: input.pluginId,
value: dataSource.value,
});
});
importDashboardForm.constants?.forEach((constant: any, index: number) => {
const input = inputs.constants[index];
inputsToPersist.push({
value: constant,
name: input.name,
type: input.type,
});
});
const result = await getBackendSrv().post('api/dashboards/import', {
dashboard: { ...dashboard, title: importDashboardForm.title, uid: importDashboardForm.uid },
overwrite: true,
inputs: inputsToPersist,
folderId: importDashboardForm.folderId,
});
const dashboardUrl = locationUtil.stripBaseFromUrl(result.importedUrl);
dispatch(updateLocation({ path: dashboardUrl }));
};
}
const getDataSourceOptions = (input: { pluginId: string; pluginName: string }, inputModel: any) => {
const sources = Object.values(config.datasources).filter(
(val: DataSourceInstanceSettings) => val.type === input.pluginId
);
if (sources.length === 0) {
inputModel.info = 'No data sources of type ' + input.pluginName + ' found';
} else if (!inputModel.info) {
inputModel.info = 'Select a ' + input.pluginName + ' data source';
}
inputModel.options = sources.map(val => {
return { name: val.name, value: val.name, meta: val.meta };
});
};