LogRowContextProvider.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { LogRowModel } from 'app/core/logs_model';
  2. import { LogRowContextQueryResponse, SeriesData, DataQueryResponse, DataQueryError } from '@grafana/ui';
  3. import { useState, useEffect } from 'react';
  4. import useAsync from 'react-use/lib/useAsync';
  5. export interface LogRowContextRows {
  6. before?: Array<string | DataQueryError>;
  7. after?: Array<string | DataQueryError>;
  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, limit: number) => 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<LogRowContextQueryResponse>(null);
  34. const [errors, setErrors] = useState<LogRowContextQueryErrors>(null);
  35. const [hasMoreContextRows, setHasMoreContextRows] = useState({
  36. before: true,
  37. after: true,
  38. });
  39. const { value } = useAsync(async () => {
  40. const context = await getRowContext(row, limit);
  41. return {
  42. data: context.data.map(series => {
  43. if ((series as SeriesData).rows) {
  44. return (series as SeriesData).rows.map(row => row[1]);
  45. } else {
  46. return [series];
  47. }
  48. return [];
  49. }),
  50. };
  51. }, [limit]);
  52. useEffect(() => {
  53. if (value) {
  54. setResult(currentResult => {
  55. let hasMoreLogsBefore = true,
  56. hasMoreLogsAfter = true;
  57. let beforeContextError, afterContextError;
  58. if (currentResult && currentResult.data[0].length === value.data[0].length) {
  59. hasMoreLogsBefore = false;
  60. }
  61. if (currentResult && currentResult.data[1].length === value.data[1].length) {
  62. hasMoreLogsAfter = false;
  63. }
  64. if (value.data[0] && value.data[0].length > 0 && value.data[0][0].message) {
  65. beforeContextError = value.data[0][0].message;
  66. }
  67. if (value.data[1] && value.data[1].length > 0 && value.data[1][0].message) {
  68. afterContextError = value.data[1][0].message;
  69. }
  70. setHasMoreContextRows({
  71. before: hasMoreLogsBefore,
  72. after: hasMoreLogsAfter,
  73. });
  74. setErrors({
  75. before: beforeContextError,
  76. after: afterContextError,
  77. });
  78. return value;
  79. });
  80. }
  81. }, [value]);
  82. return children({
  83. result: {
  84. before: result ? result.data[0] : [],
  85. after: result ? result.data[1] : [],
  86. },
  87. errors,
  88. hasMoreContextRows,
  89. updateLimit: () => setLimit(limit + 10),
  90. });
  91. };