selectors.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import memoizeOne from 'memoize-one';
  2. import { getState } from '../../../store/store';
  3. import { StoreState } from '../../../types';
  4. import { VariableModel } from '../types';
  5. import { toStateKey } from '../utils';
  6. import { getInitialTemplatingState, TemplatingState } from './reducers';
  7. import { KeyedVariableIdentifier, VariablesState } from './types';
  8. export const getVariable = <T extends VariableModel = VariableModel>(
  9. identifier: KeyedVariableIdentifier,
  10. state: StoreState = getState(),
  11. throwWhenMissing = true
  12. ): T => {
  13. const { id, rootStateKey } = identifier;
  14. const variablesState = getVariablesState(rootStateKey, state);
  15. if (!variablesState.variables[id]) {
  16. if (throwWhenMissing) {
  17. throw new Error(`Couldn't find variable with id:${id}`);
  18. }
  19. return undefined as unknown as T;
  20. }
  21. return variablesState.variables[id] as T;
  22. };
  23. function getFilteredVariablesByKey(
  24. filter: (model: VariableModel) => boolean,
  25. key: string,
  26. state: StoreState = getState()
  27. ) {
  28. return Object.values(getVariablesState(key, state).variables)
  29. .filter(filter)
  30. .sort((s1, s2) => s1.index - s2.index);
  31. }
  32. export function getVariablesState(key: string, state: StoreState = getState()): TemplatingState {
  33. return state.templating.keys[toStateKey(key)] ?? getInitialTemplatingState();
  34. }
  35. export function getVariablesByKey(key: string, state: StoreState = getState()): VariableModel[] {
  36. return getFilteredVariablesByKey(defaultVariablesFilter, key, state);
  37. }
  38. function defaultVariablesFilter(variable: VariableModel): boolean {
  39. return variable.type !== 'system';
  40. }
  41. export const getSubMenuVariables = memoizeOne(
  42. (key: string, variables: Record<string, VariableModel>): VariableModel[] => {
  43. return getVariablesByKey(key, getState());
  44. }
  45. );
  46. export const getEditorVariables = (key: string, state: StoreState): VariableModel[] => {
  47. return getVariablesByKey(key, state);
  48. };
  49. export type GetVariables = typeof getVariablesByKey;
  50. export function getNewVariableIndex(key: string, state: StoreState = getState()): number {
  51. return getNextVariableIndex(Object.values(getVariablesState(key, state).variables));
  52. }
  53. export function getNextVariableIndex(variables: VariableModel[]): number {
  54. const sorted = variables.filter(defaultVariablesFilter).sort((v1, v2) => v1.index - v2.index);
  55. return sorted.length > 0 ? sorted[sorted.length - 1].index + 1 : 0;
  56. }
  57. export function getVariablesIsDirty(key: string, state: StoreState = getState()): boolean {
  58. return getVariablesState(key, state).transaction.isDirty;
  59. }
  60. export function getIfExistsLastKey(state: StoreState = getState()): string | undefined {
  61. return state.templating?.lastKey;
  62. }
  63. export function getLastKey(state: StoreState = getState()): string {
  64. if (!state.templating?.lastKey) {
  65. throw new Error('Accessing lastKey without initializing it variables');
  66. }
  67. return state.templating.lastKey;
  68. }
  69. // selectors used by template srv, assumes that lastKey is in state. Needs to change when/if dashboard redux state becomes keyed too.
  70. export function getFilteredVariables(filter: (model: VariableModel) => boolean, state: StoreState = getState()) {
  71. const lastKey = getIfExistsLastKey(state);
  72. if (!lastKey) {
  73. return [];
  74. }
  75. return getFilteredVariablesByKey(filter, lastKey, state);
  76. }
  77. export function getVariables(state: StoreState = getState()) {
  78. const lastKey = getIfExistsLastKey(state);
  79. if (!lastKey) {
  80. return [];
  81. }
  82. return getVariablesByKey(lastKey, state);
  83. }
  84. export function getVariableWithName(name: string, state: StoreState = getState()) {
  85. const lastKey = getIfExistsLastKey(state);
  86. if (!lastKey) {
  87. return;
  88. }
  89. return getVariable({ id: name, rootStateKey: lastKey, type: 'query' }, state, false);
  90. }
  91. export function getInstanceState<Model extends VariableModel = VariableModel>(state: VariablesState, id: string) {
  92. return state[id] as Model;
  93. }