mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Query Editor: Ensure dropdown menus position correctly (#69062)
prevent showing menu until options have loaded
This commit is contained in:
parent
6702f07a87
commit
c55c091145
@ -41,6 +41,11 @@ export function LabelFilterItem({
|
|||||||
isLoadingLabelNames?: boolean;
|
isLoadingLabelNames?: boolean;
|
||||||
isLoadingLabelValues?: boolean;
|
isLoadingLabelValues?: boolean;
|
||||||
}>({});
|
}>({});
|
||||||
|
// there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously
|
||||||
|
// see https://github.com/grafana/grafana/issues/63558
|
||||||
|
// instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded
|
||||||
|
const [labelNamesMenuOpen, setLabelNamesMenuOpen] = useState(false);
|
||||||
|
const [labelValuesMenuOpen, setLabelValuesMenuOpen] = useState(false);
|
||||||
|
|
||||||
const isMultiSelect = (operator = item.op) => {
|
const isMultiSelect = (operator = item.op) => {
|
||||||
return operators.find((op) => op.label === operator)?.isMultiValue;
|
return operators.find((op) => op.label === operator)?.isMultiValue;
|
||||||
@ -75,8 +80,13 @@ export function LabelFilterItem({
|
|||||||
onOpenMenu={async () => {
|
onOpenMenu={async () => {
|
||||||
setState({ isLoadingLabelNames: true });
|
setState({ isLoadingLabelNames: true });
|
||||||
const labelNames = await onGetLabelNames(item);
|
const labelNames = await onGetLabelNames(item);
|
||||||
|
setLabelNamesMenuOpen(true);
|
||||||
setState({ labelNames, isLoadingLabelNames: undefined });
|
setState({ labelNames, isLoadingLabelNames: undefined });
|
||||||
}}
|
}}
|
||||||
|
onCloseMenu={() => {
|
||||||
|
setLabelNamesMenuOpen(false);
|
||||||
|
}}
|
||||||
|
isOpen={labelNamesMenuOpen}
|
||||||
isLoading={state.isLoadingLabelNames ?? false}
|
isLoading={state.isLoadingLabelNames ?? false}
|
||||||
options={state.labelNames}
|
options={state.labelNames}
|
||||||
onChange={(change) => {
|
onChange={(change) => {
|
||||||
@ -129,12 +139,17 @@ export function LabelFilterItem({
|
|||||||
if (labelValues.length > PROMETHEUS_QUERY_BUILDER_MAX_RESULTS) {
|
if (labelValues.length > PROMETHEUS_QUERY_BUILDER_MAX_RESULTS) {
|
||||||
labelValues.splice(0, labelValues.length - PROMETHEUS_QUERY_BUILDER_MAX_RESULTS);
|
labelValues.splice(0, labelValues.length - PROMETHEUS_QUERY_BUILDER_MAX_RESULTS);
|
||||||
}
|
}
|
||||||
|
setLabelValuesMenuOpen(true);
|
||||||
setState({
|
setState({
|
||||||
...state,
|
...state,
|
||||||
labelValues,
|
labelValues,
|
||||||
isLoadingLabelValues: undefined,
|
isLoadingLabelValues: undefined,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
onCloseMenu={() => {
|
||||||
|
setLabelValuesMenuOpen(false);
|
||||||
|
}}
|
||||||
|
isOpen={labelValuesMenuOpen}
|
||||||
defaultOptions={state.labelValues}
|
defaultOptions={state.labelValues}
|
||||||
isMulti={isMultiSelect()}
|
isMulti={isMultiSelect()}
|
||||||
isLoading={state.isLoadingLabelValues}
|
isLoading={state.isLoadingLabelValues}
|
||||||
|
@ -39,6 +39,11 @@ export function LabelFilterItem({
|
|||||||
isLoadingLabelNames?: boolean;
|
isLoadingLabelNames?: boolean;
|
||||||
isLoadingLabelValues?: boolean;
|
isLoadingLabelValues?: boolean;
|
||||||
}>({});
|
}>({});
|
||||||
|
// there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously
|
||||||
|
// see https://github.com/grafana/grafana/issues/63558
|
||||||
|
// instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded
|
||||||
|
const [labelNamesMenuOpen, setLabelNamesMenuOpen] = useState(false);
|
||||||
|
const [labelValuesMenuOpen, setLabelValuesMenuOpen] = useState(false);
|
||||||
const CONFLICTING_LABEL_FILTER_ERROR_MESSAGE = 'You have conflicting label filters';
|
const CONFLICTING_LABEL_FILTER_ERROR_MESSAGE = 'You have conflicting label filters';
|
||||||
|
|
||||||
const isMultiSelect = (operator = item.op) => {
|
const isMultiSelect = (operator = item.op) => {
|
||||||
@ -79,8 +84,13 @@ export function LabelFilterItem({
|
|||||||
onOpenMenu={async () => {
|
onOpenMenu={async () => {
|
||||||
setState({ isLoadingLabelNames: true });
|
setState({ isLoadingLabelNames: true });
|
||||||
const labelNames = await onGetLabelNames(item);
|
const labelNames = await onGetLabelNames(item);
|
||||||
|
setLabelNamesMenuOpen(true);
|
||||||
setState({ labelNames, isLoadingLabelNames: undefined });
|
setState({ labelNames, isLoadingLabelNames: undefined });
|
||||||
}}
|
}}
|
||||||
|
onCloseMenu={() => {
|
||||||
|
setLabelNamesMenuOpen(false);
|
||||||
|
}}
|
||||||
|
isOpen={labelNamesMenuOpen}
|
||||||
isLoading={state.isLoadingLabelNames}
|
isLoading={state.isLoadingLabelNames}
|
||||||
options={state.labelNames}
|
options={state.labelNames}
|
||||||
onChange={(change) => {
|
onChange={(change) => {
|
||||||
@ -131,7 +141,12 @@ export function LabelFilterItem({
|
|||||||
labelValues,
|
labelValues,
|
||||||
isLoadingLabelValues: undefined,
|
isLoadingLabelValues: undefined,
|
||||||
});
|
});
|
||||||
|
setLabelValuesMenuOpen(true);
|
||||||
}}
|
}}
|
||||||
|
onCloseMenu={() => {
|
||||||
|
setLabelValuesMenuOpen(false);
|
||||||
|
}}
|
||||||
|
isOpen={labelValuesMenuOpen}
|
||||||
isMulti={isMultiSelect()}
|
isMulti={isMultiSelect()}
|
||||||
isLoading={state.isLoadingLabelValues}
|
isLoading={state.isLoadingLabelValues}
|
||||||
options={getOptions()}
|
options={getOptions()}
|
||||||
|
Loading…
Reference in New Issue
Block a user