}
value={searchQuery}
onChange={model.onSearchQueryChange}
disabled={disableSearch}
/>
{metricNamesStatus.error && (
We are unable to connect to your data source. Double check your data source URL and credentials.
({metricNamesStatus.error})
)}
{showStatus}
);
};
}
function getMetricNamesVariableSet() {
return new SceneVariableSet({
variables: [
new QueryVariable({
name: VAR_METRIC_NAMES,
datasource: trailDS,
hide: VariableHide.hideVariable,
includeAll: true,
defaultToAll: true,
skipUrlSync: true,
refresh: VariableRefresh.onTimeRangeChanged,
query: { query: `label_values(${VAR_FILTERS_EXPR},__name__)`, refId: 'A' },
}),
],
});
}
function getPreviewPanelFor(metric: string, index: number) {
const autoQuery = getAutoQueriesForMetric(metric);
const vizPanel = autoQuery.preview
.vizBuilder()
.setColor({ mode: 'fixed', fixedColor: getColorByIndex(index) })
.setHeaderActions(new SelectMetricAction({ metric, title: 'Select' }))
.build();
return new SceneCSSGridItem({
$variables: new SceneVariableSet({
variables: getVariablesWithMetricConstant(metric),
}),
$behaviors: [hideEmptyPreviews(metric)],
$data: new SceneQueryRunner({
datasource: trailDS,
maxDataPoints: 200,
queries: autoQuery.preview.queries,
}),
body: vizPanel,
});
}
function getCardPanelFor(metric: string) {
return PanelBuilders.text()
.setTitle(metric)
.setHeaderActions(new SelectMetricAction({ metric, title: 'Select' }))
.setOption('content', '')
.build();
}
function getStyles(theme: GrafanaTheme2) {
return {
container: css({
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
}),
headingWrapper: css({
marginBottom: theme.spacing(0.5),
}),
header: css({
flexGrow: 0,
display: 'flex',
gap: theme.spacing(2),
marginBottom: theme.spacing(1),
alignItems: 'flex-end',
}),
statusMessage: css({
fontStyle: 'italic',
marginTop: theme.spacing(7),
textAlign: 'center',
}),
searchField: css({
flexGrow: 1,
marginBottom: 0,
}),
};
}
// Consider any sequence of characters not permitted for metric names as a sepratator
const splitSeparator = /[^a-z0-9_:]+/;
function createSearchRegExp(spaceSeparatedMetricNames?: string) {
if (!spaceSeparatedMetricNames) {
return null;
}
const searchParts = spaceSeparatedMetricNames
?.toLowerCase()
.split(splitSeparator)
.filter((part) => part.length > 0)
.map((part) => `(?=(.*${part}.*))`);
if (searchParts.length === 0) {
return null;
}
const regex = searchParts.join('');
// (?=(.*expr1.*))(?=().*expr2.*))...
// The ?=(...) lookahead allows us to match these in any order.
return new RegExp(regex, 'igy');
}
function useVariableStatus(name: string, sceneObject: SceneObject) {
const variable = sceneGraph.lookupVariable(VAR_METRIC_NAMES, sceneObject);
const useVariableState = useCallback(() => {
if (variable) {
return variable.useState();
}
return undefined;
}, [variable]);
const { error, loading } = useVariableState() || {};
return { isLoading: !!loading, error };
}