LogRowContextProvider.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { DataQueryResponse, DataQueryError, LogRowModel } from '@grafana/ui';
  2. import { useState, useEffect } from 'react';
  3. import flatten from 'lodash/flatten';
  4. import useAsync from 'react-use/lib/useAsync';
  5. export interface LogRowContextRows {
  6. before?: string[];
  7. after?: string[];
  8. }
  9. export interface LogRowContextQueryErrors {
  10. before?: string;
  11. after?: string;
  12. }
  13. export interface HasMoreContextRows {
  14. before: boolean;
  15. after: boolean;
  16. }
  17. interface LogRowContextProviderProps {
  18. row: LogRowModel;
  19. getRowContext: (row: LogRowModel, options?: any) => Promise<DataQueryResponse>;
  20. children: (props: {
  21. result: LogRowContextRows;
  22. errors: LogRowContextQueryErrors;
  23. hasMoreContextRows: HasMoreContextRows;
  24. updateLimit: () => void;
  25. }) => JSX.Element;
  26. }
  27. export const LogRowContextProvider: React.FunctionComponent<LogRowContextProviderProps> = ({
  28. getRowContext,
  29. row,
  30. children,
  31. }) => {
  32. const [limit, setLimit] = useState(10);
  33. const [result, setResult] = useState<{
  34. data: string[][];
  35. errors: string[];
  36. }>(null);
  37. const [hasMoreContextRows, setHasMoreContextRows] = useState({
  38. before: true,
  39. after: true,
  40. });
  41. const { value } = useAsync(async () => {
  42. const promises = [
  43. getRowContext(row, {
  44. limit,
  45. }),
  46. getRowContext(row, {
  47. limit,
  48. direction: 'FORWARD',
  49. }),
  50. ];
  51. const results: Array<DataQueryResponse | DataQueryError> = await Promise.all(promises.map(p => p.catch(e => e)));
  52. return {
  53. data: results.map(result => {
  54. if ((result as DataQueryResponse).data) {
  55. return (result as DataQueryResponse).data.map(series => {
  56. return series.rows.map(row => row[1]);
  57. });
  58. } else {
  59. return [];
  60. }
  61. }),
  62. errors: results.map(result => {
  63. if ((result as DataQueryError).message) {
  64. return (result as DataQueryError).message;
  65. } else {
  66. return null;
  67. }
  68. }),
  69. };
  70. }, [limit]);
  71. useEffect(() => {
  72. if (value) {
  73. setResult(currentResult => {
  74. let hasMoreLogsBefore = true,
  75. hasMoreLogsAfter = true;
  76. if (currentResult && currentResult.data[0].length === value.data[0].length) {
  77. hasMoreLogsBefore = false;
  78. }
  79. if (currentResult && currentResult.data[1].length === value.data[1].length) {
  80. hasMoreLogsAfter = false;
  81. }
  82. setHasMoreContextRows({
  83. before: hasMoreLogsBefore,
  84. after: hasMoreLogsAfter,
  85. });
  86. return value;
  87. });
  88. }
  89. }, [value]);
  90. return children({
  91. result: {
  92. before: result ? flatten(result.data[0]) : [],
  93. after: result ? flatten(result.data[1]) : [],
  94. },
  95. errors: {
  96. before: result ? result.errors[0] : null,
  97. after: result ? result.errors[1] : null,
  98. },
  99. hasMoreContextRows,
  100. updateLimit: () => setLimit(limit + 10),
  101. });
  102. };