|
|
@ -28,17 +28,18 @@ interface Props { |
|
|
|
|
|
|
|
|
|
|
|
export enum InspectTab { |
|
|
|
export enum InspectTab { |
|
|
|
Data = 'data', |
|
|
|
Data = 'data', |
|
|
|
Raw = 'raw', |
|
|
|
Request = 'request', |
|
|
|
Issue = 'issue', |
|
|
|
Issue = 'issue', |
|
|
|
Meta = 'meta', // When result metadata exists
|
|
|
|
Meta = 'meta', // When result metadata exists
|
|
|
|
Error = 'error', |
|
|
|
Error = 'error', |
|
|
|
|
|
|
|
Stats = 'stats', |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
interface State { |
|
|
|
interface State { |
|
|
|
// The last raw response
|
|
|
|
// The last raw response
|
|
|
|
last: PanelData; |
|
|
|
last: PanelData; |
|
|
|
|
|
|
|
|
|
|
|
// Data frem the last response
|
|
|
|
// Data from the last response
|
|
|
|
data: DataFrame[]; |
|
|
|
data: DataFrame[]; |
|
|
|
|
|
|
|
|
|
|
|
// The selected data frame
|
|
|
|
// The selected data frame
|
|
|
@ -50,7 +51,7 @@ interface State { |
|
|
|
// If the datasource supports custom metadata
|
|
|
|
// If the datasource supports custom metadata
|
|
|
|
metaDS?: DataSourceApi; |
|
|
|
metaDS?: DataSourceApi; |
|
|
|
|
|
|
|
|
|
|
|
stats: { requestTime: number; queries: number; dataSources: number }; |
|
|
|
stats: { requestTime: number; queries: number; dataSources: number; processingTime: number }; |
|
|
|
|
|
|
|
|
|
|
|
drawerWidth: string; |
|
|
|
drawerWidth: string; |
|
|
|
} |
|
|
|
} |
|
|
@ -63,8 +64,8 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
data: [], |
|
|
|
data: [], |
|
|
|
selected: 0, |
|
|
|
selected: 0, |
|
|
|
tab: props.selectedTab || InspectTab.Data, |
|
|
|
tab: props.selectedTab || InspectTab.Data, |
|
|
|
drawerWidth: '40%', |
|
|
|
drawerWidth: '50%', |
|
|
|
stats: { requestTime: 0, queries: 0, dataSources: 0 }, |
|
|
|
stats: { requestTime: 0, queries: 0, dataSources: 0, processingTime: 0 }, |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -90,6 +91,7 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
const targets = lastResult.request?.targets || []; |
|
|
|
const targets = lastResult.request?.targets || []; |
|
|
|
const requestTime = lastResult.request?.endTime ? lastResult.request?.endTime - lastResult.request.startTime : -1; |
|
|
|
const requestTime = lastResult.request?.endTime ? lastResult.request?.endTime - lastResult.request.startTime : -1; |
|
|
|
const dataSources = new Set(targets.map(t => t.datasource)).size; |
|
|
|
const dataSources = new Set(targets.map(t => t.datasource)).size; |
|
|
|
|
|
|
|
const processingTime = lastResult.timings?.dataProcessingTime || -1; |
|
|
|
|
|
|
|
|
|
|
|
// Find the first DataSource wanting to show custom metadata
|
|
|
|
// Find the first DataSource wanting to show custom metadata
|
|
|
|
if (data && targets.length) { |
|
|
|
if (data && targets.length) { |
|
|
@ -123,6 +125,7 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
requestTime, |
|
|
|
requestTime, |
|
|
|
queries: targets.length, |
|
|
|
queries: targets.length, |
|
|
|
dataSources, |
|
|
|
dataSources, |
|
|
|
|
|
|
|
processingTime, |
|
|
|
}, |
|
|
|
}, |
|
|
|
})); |
|
|
|
})); |
|
|
|
} |
|
|
|
} |
|
|
@ -163,11 +166,7 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
if (!metaDS || !metaDS.components?.MetadataInspector) { |
|
|
|
if (!metaDS || !metaDS.components?.MetadataInspector) { |
|
|
|
return <div>No Metadata Inspector</div>; |
|
|
|
return <div>No Metadata Inspector</div>; |
|
|
|
} |
|
|
|
} |
|
|
|
return ( |
|
|
|
return <metaDS.components.MetadataInspector datasource={metaDS} data={data} />; |
|
|
|
<CustomScrollbar> |
|
|
|
|
|
|
|
<metaDS.components.MetadataInspector datasource={metaDS} data={data} /> |
|
|
|
|
|
|
|
</CustomScrollbar> |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
renderDataTab() { |
|
|
|
renderDataTab() { |
|
|
@ -232,32 +231,44 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
renderIssueTab() { |
|
|
|
|
|
|
|
return <CustomScrollbar>TODO: show issue form</CustomScrollbar>; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
renderErrorTab(error?: DataQueryError) { |
|
|
|
renderErrorTab(error?: DataQueryError) { |
|
|
|
if (!error) { |
|
|
|
if (!error) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
if (error.data) { |
|
|
|
if (error.data) { |
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<CustomScrollbar> |
|
|
|
<> |
|
|
|
<h3>{error.data.message}</h3> |
|
|
|
<h3>{error.data.message}</h3> |
|
|
|
<pre> |
|
|
|
<JSONFormatter json={error} open={2} /> |
|
|
|
<code>{error.data.error}</code> |
|
|
|
</> |
|
|
|
</pre> |
|
|
|
|
|
|
|
</CustomScrollbar> |
|
|
|
|
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
return <div>{error.message}</div>; |
|
|
|
return <div>{error.message}</div>; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
renderRawJsonTab(last: PanelData) { |
|
|
|
renderRequestTab() { |
|
|
|
|
|
|
|
return <JSONFormatter json={this.state.last} open={3} />; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
renderStatsTab() { |
|
|
|
|
|
|
|
const { stats } = this.state; |
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<CustomScrollbar> |
|
|
|
<table className="filter-table width-30"> |
|
|
|
<JSONFormatter json={last} open={2} /> |
|
|
|
<tbody> |
|
|
|
</CustomScrollbar> |
|
|
|
<tr> |
|
|
|
|
|
|
|
<td>Query time</td> |
|
|
|
|
|
|
|
<td>{`${stats.requestTime === -1 ? 'N/A' : stats.requestTime + 'ms'}`}</td> |
|
|
|
|
|
|
|
</tr> |
|
|
|
|
|
|
|
<tr> |
|
|
|
|
|
|
|
<td>Data processing time</td> |
|
|
|
|
|
|
|
<td>{`${ |
|
|
|
|
|
|
|
stats.processingTime === -1 |
|
|
|
|
|
|
|
? 'N/A' |
|
|
|
|
|
|
|
: Math.round((stats.processingTime + Number.EPSILON) * 100) / 100 + 'ms' |
|
|
|
|
|
|
|
}`}</td>
|
|
|
|
|
|
|
|
</tr> |
|
|
|
|
|
|
|
</tbody> |
|
|
|
|
|
|
|
</table> |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -270,6 +281,9 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
tabs.push({ label: 'Data', value: InspectTab.Data }); |
|
|
|
tabs.push({ label: 'Data', value: InspectTab.Data }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tabs.push({ label: 'Stats', value: InspectTab.Stats }); |
|
|
|
|
|
|
|
tabs.push({ label: 'Request', value: InspectTab.Request }); |
|
|
|
|
|
|
|
|
|
|
|
if (this.state.metaDS) { |
|
|
|
if (this.state.metaDS) { |
|
|
|
tabs.push({ label: 'Meta Data', value: InspectTab.Meta }); |
|
|
|
tabs.push({ label: 'Meta Data', value: InspectTab.Meta }); |
|
|
|
} |
|
|
|
} |
|
|
@ -278,8 +292,6 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
tabs.push({ label: 'Error', value: InspectTab.Error }); |
|
|
|
tabs.push({ label: 'Error', value: InspectTab.Error }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
tabs.push({ label: 'Raw JSON', value: InspectTab.Raw }); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<InspectHeader |
|
|
|
<InspectHeader |
|
|
|
tabs={tabs} |
|
|
|
tabs={tabs} |
|
|
@ -302,25 +314,13 @@ export class PanelInspector extends PureComponent<Props, State> { |
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<Drawer title={this.drawerHeader} width={drawerWidth} onClose={this.onDismiss}> |
|
|
|
<Drawer title={this.drawerHeader} width={drawerWidth} onClose={this.onDismiss}> |
|
|
|
<TabContent className={styles.tabContent}> |
|
|
|
<TabContent className={styles.tabContent}> |
|
|
|
{tab === InspectTab.Data ? ( |
|
|
|
<CustomScrollbar autoHeightMin="100%"> |
|
|
|
this.renderDataTab() |
|
|
|
{tab === InspectTab.Data && this.renderDataTab()} |
|
|
|
) : ( |
|
|
|
{tab === InspectTab.Meta && this.renderMetadataInspector()} |
|
|
|
<AutoSizer> |
|
|
|
{tab === InspectTab.Request && this.renderRequestTab()} |
|
|
|
{({ width, height }) => { |
|
|
|
{tab === InspectTab.Error && this.renderErrorTab(error)} |
|
|
|
if (width === 0) { |
|
|
|
{tab === InspectTab.Stats && this.renderStatsTab()} |
|
|
|
return null; |
|
|
|
</CustomScrollbar> |
|
|
|
} |
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
<div style={{ width, height }}> |
|
|
|
|
|
|
|
{tab === InspectTab.Meta && this.renderMetadataInspector()} |
|
|
|
|
|
|
|
{tab === InspectTab.Issue && this.renderIssueTab()} |
|
|
|
|
|
|
|
{tab === InspectTab.Raw && this.renderRawJsonTab(last)} |
|
|
|
|
|
|
|
{tab === InspectTab.Error && this.renderErrorTab(error)} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
</AutoSizer> |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
</TabContent> |
|
|
|
</TabContent> |
|
|
|
</Drawer> |
|
|
|
</Drawer> |
|
|
|
); |
|
|
|
); |
|
|
|