The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/features/panel/state/actions.ts

160 lines
4.7 KiB

import { DataTransformerConfig, FieldConfigSource, getPanelOptionsWithDefaults } from '@grafana/data';
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import { getLibraryPanel } from 'app/features/library-panels/state/api';
import { LibraryElementDTO } from 'app/features/library-panels/types';
import { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError';
Plugins: remove deprecated code (components) (#41686) * refactor(plugins): use routes specific to the new plugins/admin * refactor(plugins): remove unused pages (PluginList, PluginItem) * refactor(plugins): remove PluginPage * refactor(plugins): remove UpdatePluginModal * refactor(plugins): move AppConfigWrapper under plugins/admin * refactor(plugins): move PluginDashboards under plugins/admin * refactor(plugins): rename the "specs" folder to "tests" * refactor(plugins): move test files to /tests folder * refactor(plugins): move AppRootPage into a /components folder * refactor(plugins): move PluginsErrorsInfo into a /plugins folder * refactor(plugins): move PluginSettingsCache into a /components folder * refactor(plugins): move PluginStateInfo into a /plugins folder * refactor(plugins): move AppRootPage.test.tsx next to the tested component * refactor(plugins): remove old snapshot tests * fix(plugins): fix tests * refactor(plugins/admin): move & rename PluginSettingsCache * fix(plugins): fix a few rebase issues * Plugins: remove deprecated code (state handling) (#41739) * refactor(plugins): use the plugins/admin reducer only * refactor(plugins): remove tests for the deprecated plugins reducer * refactor(plugins): remove tests for the deprecated plugins selectors * refactor(plugins/state): add a short comment note to selectors * feat(plugins/state): add a selector for selecting errors * feat(plugins/state): add a hook for getting plugin errors * refactor(plugins): udpate the PluginsErrorsInfo component to use the new state selectors * refactor(plugins/state): remove the old (deprecated) selectors * refactor(plugins/state): use the new actions under /admin * refactor(plugins/state): remove old (deprecated) reducers and actions * refactor(plugins): update component definition * fix(plugins): remove unnecessary {children} prop for PluginsErrorsInfo * Plugins: show / hide install controls based on the `pluginAdminEnabled` flag (#41749) * docs(plugins): update documentation for the `plugin_admin_enabled` flag * refactor(InstallControls): move the main component to a named module * feat(plugins): use the `pluginAdminEnable` flag to hide / show install controls in the UI * test(plugins): add tests for enabling/disabling install controls
4 years ago
import { loadPanelPlugin } from 'app/features/plugins/admin/state/actions';
import { ThunkResult } from 'app/types';
import { PanelOptionsChangedEvent, PanelQueriesChangedEvent } from 'app/types/events';
import { changePanelKey, panelModelAndPluginReady, removePanel } from './reducers';
export function initPanelState(panel: PanelModel): ThunkResult<void> {
return async (dispatch, getStore) => {
if (panel.libraryPanel?.uid && !('model' in panel.libraryPanel)) {
// this will call init with a loaded libary panel if it loads succesfully
dispatch(loadLibraryPanelAndUpdate(panel));
return;
}
let pluginToLoad = panel.type;
let plugin = getStore().plugins.panels[pluginToLoad];
if (!plugin) {
try {
plugin = await dispatch(loadPanelPlugin(pluginToLoad));
} catch (e) {
// When plugin not found
plugin = getPanelPluginNotFound(pluginToLoad, pluginToLoad === 'row');
}
}
if (!panel.plugin) {
panel.pluginLoaded(plugin);
}
dispatch(panelModelAndPluginReady({ key: panel.key, plugin }));
};
}
export function cleanUpPanelState(panelKey: string): ThunkResult<void> {
return (dispatch) => {
dispatch(removePanel({ key: panelKey }));
};
}
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
4 years ago
export interface ChangePanelPluginAndOptionsArgs {
panel: PanelModel;
pluginId: string;
options?: any;
fieldConfig?: FieldConfigSource;
transformations?: DataTransformerConfig[];
}
export function changePanelPlugin({
panel,
pluginId,
options,
fieldConfig,
}: ChangePanelPluginAndOptionsArgs): ThunkResult<void> {
return async (dispatch, getStore) => {
// ignore action is no change
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
4 years ago
if (panel.type === pluginId && !options && !fieldConfig) {
return;
}
const store = getStore();
let plugin = store.plugins.panels[pluginId];
if (!plugin) {
plugin = await dispatch(loadPanelPlugin(pluginId));
}
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
4 years ago
if (panel.type !== pluginId) {
panel.changePlugin(plugin);
}
if (options || fieldConfig) {
const newOptions = getPanelOptionsWithDefaults({
plugin,
currentOptions: options || panel.options,
currentFieldConfig: fieldConfig || panel.fieldConfig,
isAfterPluginChange: false,
});
panel.options = newOptions.options;
panel.fieldConfig = newOptions.fieldConfig;
panel.configRev++;
}
panel.generateNewKey();
dispatch(panelModelAndPluginReady({ key: panel.key, plugin }));
};
}
export function changeToLibraryPanel(panel: PanelModel, libraryPanel: LibraryElementDTO): ThunkResult<void> {
return async (dispatch, getStore) => {
const newPluginId = libraryPanel.model.type;
const oldType = panel.type;
// Update model but preserve gridPos & id
panel.restoreModel({
...libraryPanel.model,
gridPos: panel.gridPos,
id: panel.id,
libraryPanel: libraryPanel,
});
// a new library panel usually means new queries, clear any current result
panel.getQueryRunner().clearLastResult();
// Handle plugin change
if (oldType !== newPluginId) {
const store = getStore();
let plugin = store.plugins.panels[newPluginId];
if (!plugin) {
plugin = await dispatch(loadPanelPlugin(newPluginId));
}
panel.pluginLoaded(plugin);
panel.generateNewKey();
await dispatch(panelModelAndPluginReady({ key: panel.key, plugin }));
} else {
// Even if the plugin is the same, we want to change the key
// to force a rerender
const oldKey = panel.key;
panel.generateNewKey();
dispatch(changePanelKey({ oldKey, newKey: panel.key }));
}
panel.configRev = 0;
panel.hasSavedPanelEditChange = true;
panel.refresh();
panel.events.publish(PanelQueriesChangedEvent);
panel.events.publish(PanelOptionsChangedEvent);
};
}
export function loadLibraryPanelAndUpdate(panel: PanelModel): ThunkResult<void> {
return async (dispatch) => {
const uid = panel.libraryPanel!.uid!;
try {
const libPanel = await getLibraryPanel(uid, true);
panel.initLibraryPanel(libPanel);
dispatch(initPanelState(panel));
} catch (ex) {
console.log('ERROR: ', ex);
dispatch(
panelModelAndPluginReady({
key: panel.key,
plugin: getPanelPluginNotFound('Unable to load library panel: ' + uid, false),
})
);
}
};
}