mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Logs: Hide filters in log details if the data source doesn't support them (#73230)
* Logs: Hide filters in log details if the data source doesn't support them * Logs Container: use logsQueries prop * Log details: add filters visibility test
This commit is contained in:
parent
5988da1aa8
commit
48c3dc7203
@ -82,8 +82,8 @@ interface Props extends Themeable2 {
|
|||||||
loadLogsVolumeData: () => void;
|
loadLogsVolumeData: () => void;
|
||||||
showContextToggle?: (row?: LogRowModel) => boolean;
|
showContextToggle?: (row?: LogRowModel) => boolean;
|
||||||
onChangeTime: (range: AbsoluteTimeRange) => void;
|
onChangeTime: (range: AbsoluteTimeRange) => void;
|
||||||
onClickFilterLabel: (key: string, value: string) => void;
|
onClickFilterLabel?: (key: string, value: string) => void;
|
||||||
onClickFilterOutLabel: (key: string, value: string) => void;
|
onClickFilterOutLabel?: (key: string, value: string) => void;
|
||||||
onStartScanning?: () => void;
|
onStartScanning?: () => void;
|
||||||
onStopScanning?: () => void;
|
onStopScanning?: () => void;
|
||||||
getRowContext?: (row: LogRowModel, origRow: LogRowModel, options: LogRowContextOptions) => Promise<any>;
|
getRowContext?: (row: LogRowModel, origRow: LogRowModel, options: LogRowContextOptions) => Promise<any>;
|
||||||
@ -95,7 +95,7 @@ interface Props extends Themeable2 {
|
|||||||
eventBus: EventBus;
|
eventBus: EventBus;
|
||||||
panelState?: ExplorePanelsState;
|
panelState?: ExplorePanelsState;
|
||||||
scrollElement?: HTMLDivElement;
|
scrollElement?: HTMLDivElement;
|
||||||
isFilterLabelActive: (key: string, value: string) => Promise<boolean>;
|
isFilterLabelActive?: (key: string, value: string) => Promise<boolean>;
|
||||||
logsFrames?: DataFrame[];
|
logsFrames?: DataFrame[];
|
||||||
range: TimeRange;
|
range: TimeRange;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@ import {
|
|||||||
LogRowContextOptions,
|
LogRowContextOptions,
|
||||||
DataSourceWithLogsContextSupport,
|
DataSourceWithLogsContextSupport,
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
|
hasToggleableQueryFiltersSupport,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
import { getDataSourceSrv } from '@grafana/runtime';
|
||||||
import { DataQuery } from '@grafana/schema';
|
import { DataQuery } from '@grafana/schema';
|
||||||
import { Collapse } from '@grafana/ui';
|
import { Collapse } from '@grafana/ui';
|
||||||
import { StoreState } from 'app/types';
|
import { StoreState } from 'app/types';
|
||||||
@ -55,7 +57,50 @@ interface LogsContainerProps extends PropsFromRedux {
|
|||||||
isFilterLabelActive: (key: string, value: string) => Promise<boolean>;
|
isFilterLabelActive: (key: string, value: string) => Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogsContainer extends PureComponent<LogsContainerProps> {
|
interface LogsContainerState {
|
||||||
|
logDetailsFilterAvailable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogsContainer extends PureComponent<LogsContainerProps, LogsContainerState> {
|
||||||
|
state: LogsContainerState = {
|
||||||
|
logDetailsFilterAvailable: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.checkFiltersAvailability();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: LogsContainerProps) {
|
||||||
|
this.checkFiltersAvailability();
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkFiltersAvailability() {
|
||||||
|
const { logsQueries, datasourceInstance } = this.props;
|
||||||
|
|
||||||
|
if (!logsQueries) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datasourceInstance?.modifyQuery || hasToggleableQueryFiltersSupport(datasourceInstance)) {
|
||||||
|
this.setState({ logDetailsFilterAvailable: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
for (const query of logsQueries) {
|
||||||
|
if (query.datasource) {
|
||||||
|
promises.push(getDataSourceSrv().get(query.datasource));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.all(promises).then((dataSources) => {
|
||||||
|
const logDetailsFilterAvailable = dataSources.some(
|
||||||
|
(ds) => ds.modifyQuery || hasToggleableQueryFiltersSupport(ds)
|
||||||
|
);
|
||||||
|
this.setState({ logDetailsFilterAvailable });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onChangeTime = (absoluteRange: AbsoluteTimeRange) => {
|
onChangeTime = (absoluteRange: AbsoluteTimeRange) => {
|
||||||
const { exploreId, updateTimeRange } = this.props;
|
const { exploreId, updateTimeRange } = this.props;
|
||||||
updateTimeRange({ exploreId, absoluteRange });
|
updateTimeRange({ exploreId, absoluteRange });
|
||||||
@ -153,6 +198,7 @@ class LogsContainer extends PureComponent<LogsContainerProps> {
|
|||||||
logsVolume,
|
logsVolume,
|
||||||
scrollElement,
|
scrollElement,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const { logDetailsFilterAvailable } = this.state;
|
||||||
|
|
||||||
if (!logRows) {
|
if (!logRows) {
|
||||||
return null;
|
return null;
|
||||||
@ -197,8 +243,8 @@ class LogsContainer extends PureComponent<LogsContainerProps> {
|
|||||||
loadingState={loadingState}
|
loadingState={loadingState}
|
||||||
loadLogsVolumeData={() => loadSupplementaryQueryData(exploreId, SupplementaryQueryType.LogsVolume)}
|
loadLogsVolumeData={() => loadSupplementaryQueryData(exploreId, SupplementaryQueryType.LogsVolume)}
|
||||||
onChangeTime={this.onChangeTime}
|
onChangeTime={this.onChangeTime}
|
||||||
onClickFilterLabel={onClickFilterLabel}
|
onClickFilterLabel={logDetailsFilterAvailable ? onClickFilterLabel : undefined}
|
||||||
onClickFilterOutLabel={onClickFilterOutLabel}
|
onClickFilterOutLabel={logDetailsFilterAvailable ? onClickFilterOutLabel : undefined}
|
||||||
onStartScanning={onStartScanning}
|
onStartScanning={onStartScanning}
|
||||||
onStopScanning={onStopScanning}
|
onStopScanning={onStopScanning}
|
||||||
absoluteRange={absoluteRange}
|
absoluteRange={absoluteRange}
|
||||||
@ -217,7 +263,7 @@ class LogsContainer extends PureComponent<LogsContainerProps> {
|
|||||||
panelState={this.props.panelState}
|
panelState={this.props.panelState}
|
||||||
logsFrames={this.props.logsFrames}
|
logsFrames={this.props.logsFrames}
|
||||||
scrollElement={scrollElement}
|
scrollElement={scrollElement}
|
||||||
isFilterLabelActive={this.props.isFilterLabelActive}
|
isFilterLabelActive={logDetailsFilterAvailable ? this.props.isFilterLabelActive : undefined}
|
||||||
range={range}
|
range={range}
|
||||||
/>
|
/>
|
||||||
</LogsCrossFadeTransition>
|
</LogsCrossFadeTransition>
|
||||||
|
@ -47,6 +47,28 @@ describe('LogDetails', () => {
|
|||||||
expect(screen.getByRole('cell', { name: 'key2' })).toBeInTheDocument();
|
expect(screen.getByRole('cell', { name: 'key2' })).toBeInTheDocument();
|
||||||
expect(screen.getByRole('cell', { name: 'label2' })).toBeInTheDocument();
|
expect(screen.getByRole('cell', { name: 'label2' })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
it('should render filter controls when the callbacks are provided', () => {
|
||||||
|
setup(
|
||||||
|
{
|
||||||
|
onClickFilterLabel: () => {},
|
||||||
|
onClickFilterOutLabel: () => {},
|
||||||
|
},
|
||||||
|
{ labels: { key1: 'label1' } }
|
||||||
|
);
|
||||||
|
expect(screen.getByLabelText('Filter for value')).toBeInTheDocument();
|
||||||
|
expect(screen.getByLabelText('Filter out value')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
it('should not render filter controls when the callbacks are not provided', () => {
|
||||||
|
setup(
|
||||||
|
{
|
||||||
|
onClickFilterLabel: undefined,
|
||||||
|
onClickFilterOutLabel: undefined,
|
||||||
|
},
|
||||||
|
{ labels: { key1: 'label1' } }
|
||||||
|
);
|
||||||
|
expect(screen.queryByLabelText('Filter for value')).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByLabelText('Filter out value')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('when log row has error', () => {
|
describe('when log row has error', () => {
|
||||||
it('should not render log level border', () => {
|
it('should not render log level border', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user