useLokiLabels.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { useState, useEffect } from 'react';
  2. import LokiLanguageProvider from 'app/plugins/datasource/loki/language_provider';
  3. import { CascaderOption } from 'app/plugins/datasource/loki/components/LokiQueryFieldForm';
  4. import { useRefMounted } from 'app/core/hooks/useRefMounted';
  5. /**
  6. *
  7. * @param languageProvider
  8. * @param languageProviderInitialised
  9. * @param activeOption rc-cascader provided option used to fetch option's values that hasn't been loaded yet
  10. *
  11. * @description Fetches missing labels and enables labels refresh
  12. */
  13. export const useLokiLabels = (
  14. languageProvider: LokiLanguageProvider,
  15. languageProviderInitialised: boolean,
  16. activeOption: CascaderOption[]
  17. ) => {
  18. const mounted = useRefMounted();
  19. // State
  20. const [logLabelOptions, setLogLabelOptions] = useState([]);
  21. const [shouldTryRefreshLabels, setRefreshLabels] = useState(false);
  22. // Async
  23. const fetchOptionValues = async option => {
  24. await languageProvider.fetchLabelValues(option);
  25. if (mounted.current) {
  26. setLogLabelOptions(languageProvider.logLabelOptions);
  27. }
  28. };
  29. const tryLabelsRefresh = async () => {
  30. await languageProvider.refreshLogLabels();
  31. if (mounted.current) {
  32. setRefreshLabels(false);
  33. setLogLabelOptions(languageProvider.logLabelOptions);
  34. }
  35. };
  36. // Effects
  37. // This effect performs loading of options that hasn't been loaded yet
  38. // It's a subject of activeOption state change only. This is because of specific behavior or rc-cascader
  39. // https://github.com/react-component/cascader/blob/master/src/Cascader.jsx#L165
  40. useEffect(() => {
  41. if (languageProviderInitialised) {
  42. const targetOption = activeOption[activeOption.length - 1];
  43. if (targetOption) {
  44. const nextOptions = logLabelOptions.map(option => {
  45. if (option.value === targetOption.value) {
  46. return {
  47. ...option,
  48. loading: true,
  49. };
  50. }
  51. return option;
  52. });
  53. setLogLabelOptions(nextOptions); // to set loading
  54. fetchOptionValues(targetOption.value);
  55. }
  56. }
  57. }, [activeOption]);
  58. // This effect is performed on shouldTryRefreshLabels state change only.
  59. // Since shouldTryRefreshLabels is reset AFTER the labels are refreshed we are secured in case of trying to refresh
  60. // when previous refresh hasn't finished yet
  61. useEffect(() => {
  62. if (shouldTryRefreshLabels) {
  63. tryLabelsRefresh();
  64. }
  65. }, [shouldTryRefreshLabels]);
  66. return {
  67. logLabelOptions,
  68. setLogLabelOptions,
  69. refreshLabels: () => setRefreshLabels(true),
  70. };
  71. };