InspectContent.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import React, { useState } from 'react';
  2. import { CoreApp, DataSourceApi, formattedValueToString, getValueFormat, PanelData, PanelPlugin } from '@grafana/data';
  3. import { getTemplateSrv } from '@grafana/runtime';
  4. import { Drawer, Tab, TabsBar } from '@grafana/ui';
  5. import { InspectDataTab } from 'app/features/inspector/InspectDataTab';
  6. import { InspectErrorTab } from 'app/features/inspector/InspectErrorTab';
  7. import { InspectJSONTab } from 'app/features/inspector/InspectJSONTab';
  8. import { InspectMetadataTab } from 'app/features/inspector/InspectMetadataTab';
  9. import { InspectStatsTab } from 'app/features/inspector/InspectStatsTab';
  10. import { QueryInspector } from 'app/features/inspector/QueryInspector';
  11. import { InspectTab } from 'app/features/inspector/types';
  12. import { GetDataOptions } from '../../../query/state/PanelQueryRunner';
  13. import { DashboardModel, PanelModel } from '../../state';
  14. interface Props {
  15. dashboard: DashboardModel;
  16. panel: PanelModel;
  17. plugin?: PanelPlugin | null;
  18. defaultTab?: InspectTab;
  19. tabs: Array<{ label: string; value: InspectTab }>;
  20. // The last raw response
  21. data?: PanelData;
  22. isDataLoading: boolean;
  23. dataOptions: GetDataOptions;
  24. // If the datasource supports custom metadata
  25. metadataDatasource?: DataSourceApi;
  26. onDataOptionsChange: (options: GetDataOptions) => void;
  27. onClose: () => void;
  28. }
  29. export const InspectContent: React.FC<Props> = ({
  30. panel,
  31. plugin,
  32. dashboard,
  33. tabs,
  34. data,
  35. isDataLoading,
  36. dataOptions,
  37. metadataDatasource,
  38. defaultTab,
  39. onDataOptionsChange,
  40. onClose,
  41. }) => {
  42. const [currentTab, setCurrentTab] = useState(defaultTab ?? InspectTab.Data);
  43. if (!plugin) {
  44. return null;
  45. }
  46. const error = data?.error;
  47. // Validate that the active tab is actually valid and allowed
  48. let activeTab = currentTab;
  49. if (!tabs.find((item) => item.value === currentTab)) {
  50. activeTab = InspectTab.JSON;
  51. }
  52. const title = getTemplateSrv().replace(panel.title, panel.scopedVars, 'text');
  53. return (
  54. <Drawer
  55. title={`Inspect: ${title || 'Panel'}`}
  56. subtitle={data && formatStats(data)}
  57. width="50%"
  58. onClose={onClose}
  59. expandable
  60. scrollableContent
  61. tabs={
  62. <TabsBar>
  63. {tabs.map((t, index) => {
  64. return (
  65. <Tab
  66. key={`${t.value}-${index}`}
  67. label={t.label}
  68. active={t.value === activeTab}
  69. onChangeTab={() => setCurrentTab(t.value || InspectTab.Data)}
  70. />
  71. );
  72. })}
  73. </TabsBar>
  74. }
  75. >
  76. {activeTab === InspectTab.Data && (
  77. <InspectDataTab
  78. panel={panel}
  79. data={data && data.series}
  80. isLoading={isDataLoading}
  81. options={dataOptions}
  82. onOptionsChange={onDataOptionsChange}
  83. timeZone={dashboard.timezone}
  84. app={CoreApp.Dashboard}
  85. />
  86. )}
  87. {data && activeTab === InspectTab.Meta && (
  88. <InspectMetadataTab data={data} metadataDatasource={metadataDatasource} />
  89. )}
  90. {activeTab === InspectTab.JSON && (
  91. <InspectJSONTab panel={panel} dashboard={dashboard} data={data} onClose={onClose} />
  92. )}
  93. {activeTab === InspectTab.Error && <InspectErrorTab error={error} />}
  94. {data && activeTab === InspectTab.Stats && <InspectStatsTab data={data} timeZone={dashboard.getTimezone()} />}
  95. {data && activeTab === InspectTab.Query && (
  96. <QueryInspector panel={panel} data={data.series} onRefreshQuery={() => panel.refresh()} />
  97. )}
  98. </Drawer>
  99. );
  100. };
  101. function formatStats(data: PanelData) {
  102. const { request } = data;
  103. if (!request) {
  104. return '';
  105. }
  106. const queryCount = request.targets.length;
  107. const requestTime = request.endTime ? request.endTime - request.startTime : 0;
  108. const formatted = formattedValueToString(getValueFormat('ms')(requestTime));
  109. return `${queryCount} queries with total query time of ${formatted}`;
  110. }