Skip to content

[FEATURE] Add panel-level repeat variable support - #2

Open
adrianSepiol wants to merge 4 commits into
mainfrom
feature/panel-level-repeat
Open

[FEATURE] Add panel-level repeat variable support#2
adrianSepiol wants to merge 4 commits into
mainfrom
feature/panel-level-repeat

Conversation

@adrianSepiol

@adrianSepiol adrianSepiol commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Closes:

Needs:

Description

Adds support for repeat panel based on variable. Has 2 modes 'all' and 'selected'. In 'all' panel is repeated based on all available options. In 'selected' only selected values from dropdown are used.

Screenshots

In below recording you can notice that width of panel is expanded when you select repeat variable and height is used for single tile. If you don't fill 'Max per row' all tiles will be fitted into single row.

Screen.Recording.2026-06-01.at.19.01.28.mov

In this one you can see how the panel will behave in selected mode when the amount of selected values will change. You can enter edit mode only with first panel.

Screen.Recording.2026-06-01.at.19.09.07.mov

It is one tile so you resize, move it as one.

Screen.Recording.2026-06-01.at.19.12.56.mov

Group repeat has priority over panel repeat.

Screen.Recording.2026-06-01.at.19.14.58.mov

Checklist

  • Pull request has a descriptive title and context useful to a reviewer.
  • Pull request title follows the [<catalog_entry>] <commit message> naming convention using one of the
    following catalog_entry values: FEATURE, ENHANCEMENT, BUGFIX, BREAKINGCHANGE, DOC,IGNORE.
  • All commits have DCO signoffs.

UI Changes

  • Changes that impact the UI include screenshots and/or screencasts of the relevant changes.
  • Code follows the UI guidelines.
  • E2E tests are stable and unlikely to be flaky.
    See e2e docs for more details. Common issues include:
    • Is the data inconsistent? You need to mock API requests.
    • Does the time change? You need to use consistent time values or mock time utilities.
    • Does it have loading states? You need to wait for loading to complete.

@adrianSepiol
adrianSepiol force-pushed the feature/panel-level-repeat branch 3 times, most recently from b611f9c to 23fe7b8 Compare June 11, 2026 10:16
@adrianSepiol
adrianSepiol force-pushed the feature/panel-level-repeat branch 11 times, most recently from 9a6a842 to b83e228 Compare July 20, 2026 12:49
@adrianSepiol
adrianSepiol force-pushed the feature/panel-level-repeat branch 3 times, most recently from 7891364 to e32d1fe Compare July 29, 2026 09:46
@adrianSepiol
adrianSepiol force-pushed the feature/panel-level-repeat branch 2 times, most recently from 05dc32e to fe39dc3 Compare August 12, 2026 08:53
Signed-off-by: Adrian Sepiół <a.sepiol@sap.com>
…tainer is narrower than combined gaps, and consolidate VariableDefinitionGroup to plugin-system model

Signed-off-by: Adrian Sepiół <a.sepiol@sap.com>
…ndered panels per repeat variable

Signed-off-by: Adrian Sepiół <a.sepiol@sap.com>
Signed-off-by: Adrian Sepiół <a.sepiol@sap.com>
@adrianSepiol
adrianSepiol force-pushed the feature/panel-level-repeat branch from fe39dc3 to 184c638 Compare August 18, 2026 13:35
@github-actions

Copy link
Copy Markdown

React Doctor found 20 new issues in 18 files · 20 warnings · score 72 / 100 (Needs work) · 1 fixed · vs main

20 warnings

src/components/GridLayout/GridItemContent.tsx

  • ⚠️ L19 Import from a barrel file no-barrel-import

src/components/GridLayout/GridItemRenderer.tsx

  • ⚠️ L18 Import from a barrel file no-barrel-import

src/components/GridLayout/GridLayout.tsx

  • ⚠️ L18 Import from a barrel file no-barrel-import
  • ⚠️ L144 Unstable context provider value jsx-no-constructed-context-values

src/components/GridLayout/RepeatGridItemContent.tsx

  • ⚠️ L94 Unstable context provider value jsx-no-constructed-context-values

src/components/GridLayout/Row.tsx

  • ⚠️ L19 Import from a barrel file no-barrel-import

src/components/LayoutEditor/LayoutEditor.tsx

  • ⚠️ L18 Import from a barrel file no-barrel-import

src/components/LayoutEditor/RepeatVariableEditor.tsx

  • ⚠️ L18 Import from a barrel file no-barrel-import

src/components/Panel/PanelActions.tsx

  • ⚠️ L32 Import from a barrel file no-barrel-import

src/components/Panel/PanelHeader.tsx

  • ⚠️ L20 Import from a barrel file no-barrel-import

src/components/PanelDrawer/PanelDrawer.tsx

  • ⚠️ L32 Import from a barrel file no-barrel-import

src/components/PanelDrawer/PanelQueriesSharedControls.tsx

  • ⚠️ L30 Import from a barrel file no-barrel-import
  • ⚠️ L106 Unstable context provider value jsx-no-constructed-context-values

src/components/PanelSpecEditor/PanelSpecEditor.tsx

  • ⚠️ L20 Import from a barrel file no-barrel-import

src/context/DashboardProvider/DashboardProvider.tsx

  • ⚠️ L25 Import from a barrel file no-barrel-import

src/context/DashboardProvider/duplicate-panel-slice.ts

  • ⚠️ L17 Import from a barrel file no-barrel-import

src/context/DashboardProvider/panel-editor-slice.ts

  • ⚠️ L19 Import from a barrel file no-barrel-import

src/context/useDashboard.tsx

  • ⚠️ L19 Import from a barrel file no-barrel-import

src/utils/repeatLayoutUtils.ts

  • ⚠️ L17 Import from a barrel file no-barrel-import

src/views/ViewDashboard/ViewDashboard.tsx

  • ⚠️ L25 Import from a barrel file no-barrel-import

Reviewed by React Doctor for commit 184c638. See inline comments for fixes.

import { PanelGroupId } from '@perses-dev/plugin-system';
import { ReactElement } from 'react';

import { DEFAULT_MARGIN } from '../../constants';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from "../../constants/grid-layout-config".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs

<VariableContext.Provider
key={`${repeatVariableName}-${value}`}
value={{ state: { ...variables, [repeatVariableName]: { value, loading: false } } }}
value={{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/jsx-no-constructed-context-values (warning)

Every reader of this context redraws on each render because you build its value inline.

Fix → Wrap the context value in useMemo or move it outside the component so consumers do not redraw every render.

Docs

return (
<VariableContext.Provider
key={`${repeatVariableName}-${value}`}
value={{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/jsx-no-constructed-context-values (warning)

Every reader of this context redraws on each render because you build its value inline.

Fix → Wrap the context value in useMemo or move it outside the component so consumers do not redraw every render.

Docs

import { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout';

import { GRID_LAYOUT_COLS, GRID_LAYOUT_SMALL_BREAKPOINT } from '../../constants';
import { DEFAULT_MARGIN, GRID_LAYOUT_COLS, GRID_LAYOUT_SMALL_BREAKPOINT, ROW_HEIGHT } from '../../constants';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from "../../constants/grid-layout-config".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs

import { Control } from 'react-hook-form';
import { Control, useWatch } from 'react-hook-form';

import { useListPanelGroups } from '../../context';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from "../../context/DashboardProvider/dashboard-provider-api".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs


import { PanelGroupItemId } from '../../model';
import { generatePanelKey, insertPanelInLayout, UnpositionedPanelGroupItemLayout } from '../../utils/panelUtils';
import { generatePanelKey, insertPanelInLayout, UnpositionedPanelGroupItemLayout } from '../../utils';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from "../../utils/panelUtils".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs

import { DEFAULT_MAX_PER_ROW, DEFAULT_REPEAT_ALIGNMENT, VariableStateMap } from '@perses-dev/plugin-system';
import { Layout, Layouts } from 'react-grid-layout';

import { DEFAULT_MARGIN, ROW_HEIGHT } from '../constants';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from "../constants/grid-layout-config".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs

import { ReactElement, useMemo } from 'react';
import { Control, Controller, useFormContext, useWatch } from 'react-hook-form';

import { DEFAULT_MAX_PER_ROW, DEFAULT_REPEAT_ALIGNMENT } from '../../constants';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from "../../constants/repeat".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs

import { ReactElement, useCallback } from 'react';
import { ControllerRenderProps, FieldErrors } from 'react-hook-form';

import { DEFAULT_MAX_PER_ROW, DEFAULT_REPEAT_ALIGNMENT } from '../../constants';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from "../../constants/repeat".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs

@@ -18,6 +18,7 @@ import { Control, Controller } from 'react-hook-form';

import { PanelEditorValues, PanelPlugin } from '../../model';
import { useDataQueriesContext, usePlugin } from '../../runtime';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-barrel-import (warning)

This ships extra code to your users & slows page load. Import directly from: "../../runtime/DataQueriesProvider/DataQueriesProvider", "../../runtime/plugin-registry".

Fix → Import from the direct path: import { Button } from './components/Button' instead of ./components

Docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant