DynamicDashboards: prevent nested repeats based on the same variable (#114953)
This commit is contained in:
+1
-1
@@ -107,7 +107,7 @@ function RowRepeatSelect({ row, dashboard, id }: { row: SceneGridRow; dashboard:
|
||||
<>
|
||||
<RepeatRowSelect2
|
||||
id={id}
|
||||
sceneContext={dashboard}
|
||||
sceneContext={row}
|
||||
repeat={repeatBehavior?.state.variableName}
|
||||
onChange={(repeat) => {
|
||||
if (repeat) {
|
||||
|
||||
+2
-3
@@ -8,7 +8,7 @@ import { Icon, useStyles2 } from '@grafana/ui';
|
||||
import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/constants';
|
||||
import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource';
|
||||
|
||||
import { getQueryRunnerFor, useDashboard, useDashboardState } from '../../../utils/utils';
|
||||
import { getQueryRunnerFor, useDashboardState } from '../../../utils/utils';
|
||||
import { DashboardGridItem } from '../DashboardGridItem';
|
||||
import { RowRepeaterBehavior } from '../RowRepeaterBehavior';
|
||||
|
||||
@@ -18,7 +18,6 @@ import { RowOptionsButton } from './RowOptionsButton';
|
||||
export function RowActionsRenderer({ model }: SceneComponentProps<RowActions>) {
|
||||
const row = model.getParent();
|
||||
const { title, children } = row.useState();
|
||||
const dashboard = useDashboard(model);
|
||||
const { meta, isEditing } = useDashboardState(model);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
@@ -53,7 +52,7 @@ export function RowActionsRenderer({ model }: SceneComponentProps<RowActions>) {
|
||||
<RowOptionsButton
|
||||
title={title}
|
||||
repeat={behaviour instanceof RowRepeaterBehavior ? behaviour.state.variableName : undefined}
|
||||
parent={dashboard}
|
||||
parent={row}
|
||||
onUpdate={(title, repeat) => model.onUpdate(title, repeat)}
|
||||
isUsingDashboardDS={isUsingDashboardDS}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useId, useMemo, useRef } from 'react';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Alert, Input, Switch, TextLink, Field } from '@grafana/ui';
|
||||
import { Alert, Field, Input, Switch, TextLink } from '@grafana/ui';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
import { RepeatRowSelect2 } from 'app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect';
|
||||
@@ -11,7 +11,7 @@ import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSou
|
||||
|
||||
import { useConditionalRenderingEditor } from '../../conditional-rendering/hooks/useConditionalRenderingEditor';
|
||||
import { dashboardEditActions } from '../../edit-pane/shared';
|
||||
import { getQueryRunnerFor, useDashboard } from '../../utils/utils';
|
||||
import { getQueryRunnerFor } from '../../utils/utils';
|
||||
import { useLayoutCategory } from '../layouts-shared/DashboardLayoutSelector';
|
||||
import { generateUniqueTitle, useEditPaneInputAutoFocus } from '../layouts-shared/utils';
|
||||
|
||||
@@ -128,7 +128,6 @@ function FillScreenSwitch({ row, id }: { row: RowItem; id?: string }) {
|
||||
|
||||
function RowRepeatSelect({ row, id }: { row: RowItem; id?: string }) {
|
||||
const { layout } = row.useState();
|
||||
const dashboard = useDashboard(row);
|
||||
|
||||
const isAnyPanelUsingDashboardDS = layout.getVizPanels().some((vizPanel) => {
|
||||
const runner = getQueryRunnerFor(vizPanel);
|
||||
@@ -143,7 +142,7 @@ function RowRepeatSelect({ row, id }: { row: RowItem; id?: string }) {
|
||||
<>
|
||||
<RepeatRowSelect2
|
||||
id={id}
|
||||
sceneContext={dashboard}
|
||||
sceneContext={row}
|
||||
repeat={row.state.repeatByVariable}
|
||||
onChange={(repeat) => row.onChangeRepeat(repeat)}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useMemo, useRef } from 'react';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Alert, Input, Field, TextLink } from '@grafana/ui';
|
||||
import { Alert, Field, Input, TextLink } from '@grafana/ui';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
import { RepeatRowSelect2 } from 'app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect';
|
||||
@@ -11,7 +11,7 @@ import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSou
|
||||
|
||||
import { useConditionalRenderingEditor } from '../../conditional-rendering/hooks/useConditionalRenderingEditor';
|
||||
import { dashboardEditActions } from '../../edit-pane/shared';
|
||||
import { getQueryRunnerFor, useDashboard } from '../../utils/utils';
|
||||
import { getQueryRunnerFor } from '../../utils/utils';
|
||||
import { useLayoutCategory } from '../layouts-shared/DashboardLayoutSelector';
|
||||
import { generateUniqueTitle, useEditPaneInputAutoFocus } from '../layouts-shared/utils';
|
||||
|
||||
@@ -99,7 +99,6 @@ function TabTitleInput({ tab, isNewElement, id }: { tab: TabItem; isNewElement:
|
||||
|
||||
function TabRepeatSelect({ tab, id }: { tab: TabItem; id?: string }) {
|
||||
const { layout } = tab.useState();
|
||||
const dashboard = useDashboard(tab);
|
||||
|
||||
const isAnyPanelUsingDashboardDS = layout.getVizPanels().some((vizPanel) => {
|
||||
const runner = getQueryRunnerFor(vizPanel);
|
||||
@@ -114,7 +113,7 @@ function TabRepeatSelect({ tab, id }: { tab: TabItem; id?: string }) {
|
||||
<>
|
||||
<RepeatRowSelect2
|
||||
id={id}
|
||||
sceneContext={dashboard}
|
||||
sceneContext={tab}
|
||||
repeat={tab.state.repeatByVariable}
|
||||
onChange={(repeat) => tab.onChangeRepeat(repeat)}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { SceneObject, sceneGraph } from '@grafana/scenes';
|
||||
import { LocalValueVariable, SceneObject, sceneGraph } from '@grafana/scenes';
|
||||
import { Combobox, ComboboxOption, Select } from '@grafana/ui';
|
||||
import { useSelector } from 'app/types/store';
|
||||
|
||||
@@ -59,10 +59,18 @@ export const RepeatRowSelect2 = ({ sceneContext, repeat, id, onChange }: Props2)
|
||||
const variables = sceneVars.useState().variables;
|
||||
|
||||
const variableOptions = useMemo(() => {
|
||||
const options: ComboboxOption[] = variables.map((item) => ({
|
||||
label: item.state.name,
|
||||
value: item.state.name,
|
||||
}));
|
||||
const options: ComboboxOption[] = variables
|
||||
.filter((item) => {
|
||||
if (sceneContext.parent) {
|
||||
// filter out local value variables (which are only set on repeated items)
|
||||
return !(sceneGraph.lookupVariable(item.state.name, sceneContext.parent) instanceof LocalValueVariable);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((item) => ({
|
||||
label: item.state.name,
|
||||
value: item.state.name,
|
||||
}));
|
||||
|
||||
options.unshift({
|
||||
label: t('dashboard.repeat-row-select2.variable-options.label.disable-repeating', 'Disable repeating'),
|
||||
@@ -70,7 +78,7 @@ export const RepeatRowSelect2 = ({ sceneContext, repeat, id, onChange }: Props2)
|
||||
});
|
||||
|
||||
return options;
|
||||
}, [variables]);
|
||||
}, [sceneContext, variables]);
|
||||
|
||||
const onSelectChange = useCallback((value: ComboboxOption | null) => value && onChange(value.value), [onChange]);
|
||||
|
||||
@@ -79,7 +87,7 @@ export const RepeatRowSelect2 = ({ sceneContext, repeat, id, onChange }: Props2)
|
||||
return (
|
||||
<Combobox
|
||||
id={id}
|
||||
value={repeat}
|
||||
value={repeat || ''}
|
||||
onChange={onSelectChange}
|
||||
options={variableOptions}
|
||||
disabled={isDisabled}
|
||||
|
||||
Reference in New Issue
Block a user