reducers.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';
  2. import { PanelPlugin } from '@grafana/data';
  3. import { AngularComponent } from '@grafana/runtime';
  4. export type RootPanelsState = Record<string, PanelState>;
  5. export interface PanelState {
  6. plugin?: PanelPlugin;
  7. angularComponent?: AngularComponent;
  8. instanceState?: any | null;
  9. }
  10. export const initialState: RootPanelsState = {};
  11. const panelsSlice = createSlice({
  12. name: 'panels',
  13. initialState,
  14. reducers: {
  15. panelModelAndPluginReady: (state, action: PayloadAction<PanelModelAndPluginReadyPayload>) => {
  16. if (action.payload.cleanUpKey) {
  17. cleanUpAngularComponent(state[action.payload.cleanUpKey]);
  18. delete state[action.payload.cleanUpKey];
  19. }
  20. state[action.payload.key] = {
  21. plugin: action.payload.plugin,
  22. };
  23. },
  24. changePanelKey: (state, action: PayloadAction<{ oldKey: string; newKey: string }>) => {
  25. state[action.payload.newKey] = state[action.payload.oldKey];
  26. delete state[action.payload.oldKey];
  27. },
  28. removePanel: (state, action: PayloadAction<{ key: string }>) => {
  29. delete state[action.payload.key];
  30. },
  31. removePanels: (state, action: PayloadAction<{ keys: string[] }>) => {
  32. for (const key of action.payload.keys) {
  33. delete state[key];
  34. }
  35. },
  36. setPanelInstanceState: (state, action: PayloadAction<SetPanelInstanceStatePayload>) => {
  37. state[action.payload.key].instanceState = action.payload.value;
  38. },
  39. setPanelAngularComponent: (state, action: PayloadAction<SetPanelAngularComponentPayload>) => {
  40. const panelState = state[action.payload.key];
  41. cleanUpAngularComponent(panelState);
  42. panelState.angularComponent = action.payload.angularComponent;
  43. },
  44. },
  45. });
  46. export function cleanUpAngularComponent(panelState?: Draft<PanelState>) {
  47. if (panelState?.angularComponent) {
  48. panelState.angularComponent.destroy();
  49. }
  50. }
  51. export interface PanelModelAndPluginReadyPayload {
  52. key: string;
  53. plugin: PanelPlugin;
  54. /** Used to cleanup previous state when we change key (used when switching panel plugin) */
  55. cleanUpKey?: string;
  56. }
  57. export interface SetPanelAngularComponentPayload {
  58. key: string;
  59. angularComponent: AngularComponent;
  60. }
  61. export interface SetPanelInstanceStatePayload {
  62. key: string;
  63. value: any;
  64. }
  65. export const {
  66. panelModelAndPluginReady,
  67. setPanelAngularComponent,
  68. setPanelInstanceState,
  69. changePanelKey,
  70. removePanel,
  71. removePanels,
  72. } = panelsSlice.actions;
  73. export const panelsReducer = panelsSlice.reducer;
  74. export default {
  75. panels: panelsReducer,
  76. };