mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
LokiContextUi: Add loading indicator (#64167)
add loading indicator to LokiContextUi
This commit is contained in:
@@ -5,7 +5,7 @@ import { useAsync } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, LogRowModel, SelectableValue } from '@grafana/data';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { MultiSelect, Tag, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { LoadingPlaceholder, MultiSelect, Tag, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import LokiLanguageProvider from '../LanguageProvider';
|
||||
import { ContextFilter } from '../types';
|
||||
@@ -35,6 +35,19 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
`,
|
||||
loadingPlaceholder: css`
|
||||
margin-bottom: 0px;
|
||||
float: right;
|
||||
display: inline;
|
||||
margin-left: auto;
|
||||
`,
|
||||
textWrapper: css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`,
|
||||
hidden: css`
|
||||
visibility: hidden;
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,6 +64,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
const [contextFilters, setContextFilters] = useState<ContextFilter[]>([]);
|
||||
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const timerHandle = React.useRef<number>();
|
||||
const previousInitialized = React.useRef<boolean>(false);
|
||||
const previousContextFilters = React.useRef<ContextFilter[]>([]);
|
||||
@@ -75,8 +89,10 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
if (timerHandle.current) {
|
||||
clearTimeout(timerHandle.current);
|
||||
}
|
||||
setLoading(true);
|
||||
timerHandle.current = window.setTimeout(() => {
|
||||
updateFilter(contextFilters);
|
||||
setLoading(false);
|
||||
}, 1500);
|
||||
|
||||
return () => {
|
||||
@@ -134,7 +150,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
|
||||
return (
|
||||
<div className={styles.multiSelectWrapper}>
|
||||
<div>
|
||||
<div className={styles.textWrapper}>
|
||||
{' '}
|
||||
<Tooltip
|
||||
content={
|
||||
@@ -153,6 +169,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
/>
|
||||
</Tooltip>{' '}
|
||||
Select labels to be included in the context query:
|
||||
<LoadingPlaceholder text="" className={`${styles.loadingPlaceholder} ${loading ? '' : styles.hidden}`} />
|
||||
</div>
|
||||
<div>
|
||||
<MultiSelect
|
||||
|
||||
@@ -137,6 +137,7 @@ export class LokiDatasource
|
||||
private streams = new LiveStreams();
|
||||
languageProvider: LanguageProvider;
|
||||
maxLines: number;
|
||||
onContextClose: (() => void) | undefined;
|
||||
|
||||
constructor(
|
||||
private instanceSettings: DataSourceInstanceSettings<LokiOptions>,
|
||||
@@ -789,53 +790,60 @@ export class LokiDatasource
|
||||
}
|
||||
|
||||
getLogRowContextUi(row: LogRowModel, runContextQuery: () => void): React.ReactNode {
|
||||
return LokiContextUi({
|
||||
row,
|
||||
languageProvider: this.languageProvider,
|
||||
onClose: () => {
|
||||
this.prepareContextExpr = this.prepareContextExprWithoutParsedLabels;
|
||||
},
|
||||
updateFilter: (contextFilters: ContextFilter[]) => {
|
||||
this.prepareContextExpr = async (row: LogRowModel, origQuery?: DataQuery) => {
|
||||
await this.languageProvider.start();
|
||||
const labels = this.languageProvider.getLabelKeys();
|
||||
const updateFilter = (contextFilters: ContextFilter[]) => {
|
||||
this.prepareContextExpr = async (row: LogRowModel, origQuery?: DataQuery) => {
|
||||
await this.languageProvider.start();
|
||||
const labels = this.languageProvider.getLabelKeys();
|
||||
|
||||
let expr = contextFilters
|
||||
.map((filter) => {
|
||||
const label = filter.value;
|
||||
if (filter && !filter.fromParser && filter.enabled && labels.includes(label)) {
|
||||
// escape backslashes in label as users can't escape them by themselves
|
||||
return `${label}="${escapeLabelValueInExactSelector(row.labels[label])}"`;
|
||||
}
|
||||
return '';
|
||||
})
|
||||
// Filter empty strings
|
||||
.filter((label) => !!label)
|
||||
.join(',');
|
||||
|
||||
expr = `{${expr}}`;
|
||||
|
||||
const parserContextFilters = contextFilters.filter((filter) => filter.fromParser && filter.enabled);
|
||||
if (parserContextFilters.length) {
|
||||
// we should also filter for labels from parsers, let's find the right parser
|
||||
if (origQuery) {
|
||||
const parser = getParserFromQuery((origQuery as LokiQuery).expr);
|
||||
if (parser) {
|
||||
expr = addParserToQuery(expr, parser);
|
||||
}
|
||||
let expr = contextFilters
|
||||
.map((filter) => {
|
||||
const label = filter.value;
|
||||
if (filter && !filter.fromParser && filter.enabled && labels.includes(label)) {
|
||||
// escape backslashes in label as users can't escape them by themselves
|
||||
return `${label}="${escapeLabelValueInExactSelector(row.labels[label])}"`;
|
||||
}
|
||||
for (const filter of parserContextFilters) {
|
||||
if (filter.enabled) {
|
||||
expr = addLabelToQuery(expr, filter.label, '=', row.labels[filter.label]);
|
||||
}
|
||||
return '';
|
||||
})
|
||||
// Filter empty strings
|
||||
.filter((label) => !!label)
|
||||
.join(',');
|
||||
|
||||
expr = `{${expr}}`;
|
||||
|
||||
const parserContextFilters = contextFilters.filter((filter) => filter.fromParser && filter.enabled);
|
||||
if (parserContextFilters.length) {
|
||||
// we should also filter for labels from parsers, let's find the right parser
|
||||
if (origQuery) {
|
||||
const parser = getParserFromQuery((origQuery as LokiQuery).expr);
|
||||
if (parser) {
|
||||
expr = addParserToQuery(expr, parser);
|
||||
}
|
||||
}
|
||||
for (const filter of parserContextFilters) {
|
||||
if (filter.enabled) {
|
||||
expr = addLabelToQuery(expr, filter.label, '=', row.labels[filter.label]);
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
};
|
||||
if (runContextQuery) {
|
||||
runContextQuery();
|
||||
}
|
||||
},
|
||||
return expr;
|
||||
};
|
||||
if (runContextQuery) {
|
||||
runContextQuery();
|
||||
}
|
||||
};
|
||||
|
||||
// we need to cache this function so that it doesn't get recreated on every render
|
||||
this.onContextClose =
|
||||
this.onContextClose ??
|
||||
(() => {
|
||||
this.prepareContextExpr = this.prepareContextExprWithoutParsedLabels;
|
||||
});
|
||||
|
||||
return LokiContextUi({
|
||||
row,
|
||||
updateFilter,
|
||||
languageProvider: this.languageProvider,
|
||||
onClose: this.onContextClose,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user