mirror of https://github.com/grafana/grafana.git
Dynamic Dashboards: Add repeat responsive items (#102440)
This commit is contained in:
parent
06545aa770
commit
3ddfa3229a
|
@ -71,19 +71,12 @@ export class VizPanelEditableElement implements EditableDashboardElement, BulkAc
|
||||||
);
|
);
|
||||||
}, [panel]);
|
}, [panel]);
|
||||||
|
|
||||||
const layoutCategory = useMemo(() => {
|
const layoutCategories = useMemo(
|
||||||
if (isDashboardLayoutItem(layoutElement) && layoutElement.getOptions) {
|
() => (isDashboardLayoutItem(layoutElement) && layoutElement.getOptions ? layoutElement.getOptions() : []),
|
||||||
return layoutElement.getOptions();
|
[layoutElement]
|
||||||
}
|
);
|
||||||
return undefined;
|
|
||||||
}, [layoutElement]);
|
|
||||||
|
|
||||||
const categories = [panelOptions];
|
return [panelOptions, ...layoutCategories];
|
||||||
if (layoutCategory) {
|
|
||||||
categories.push(layoutCategory);
|
|
||||||
}
|
|
||||||
|
|
||||||
return categories;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onDelete() {
|
public onDelete() {
|
||||||
|
|
|
@ -84,8 +84,8 @@ export function getPanelFrameOptions(panel: VizPanel): OptionsPaneCategoryDescri
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isDashboardLayoutItem(layoutElement) && layoutElement.getOptions) {
|
if (isDashboardLayoutItem(layoutElement)) {
|
||||||
descriptor.addCategory(layoutElement.getOptions());
|
layoutElement.getOptions?.().forEach((category) => descriptor.addCategory(category));
|
||||||
}
|
}
|
||||||
|
|
||||||
return descriptor;
|
return descriptor;
|
||||||
|
|
|
@ -86,7 +86,7 @@ export class DashboardGridItem
|
||||||
return this.state.variableName ? 'panel-repeater-grid-item' : '';
|
return this.state.variableName ? 'panel-repeater-grid-item' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public getOptions(): OptionsPaneCategoryDescriptor {
|
public getOptions(): OptionsPaneCategoryDescriptor[] {
|
||||||
return getDashboardGridItemOptions(this);
|
return getDashboardGridItemOptions(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,47 +8,44 @@ import { RepeatRowSelect2 } from 'app/features/dashboard/components/RepeatRowSel
|
||||||
|
|
||||||
import { DashboardGridItem } from './DashboardGridItem';
|
import { DashboardGridItem } from './DashboardGridItem';
|
||||||
|
|
||||||
export function getDashboardGridItemOptions(gridItem: DashboardGridItem): OptionsPaneCategoryDescriptor {
|
export function getDashboardGridItemOptions(gridItem: DashboardGridItem): OptionsPaneCategoryDescriptor[] {
|
||||||
const category = new OptionsPaneCategoryDescriptor({
|
const repeatCategory = new OptionsPaneCategoryDescriptor({
|
||||||
title: t('dashboard.default-layout.item-options.repeat.title', 'Repeat options'),
|
title: t('dashboard.default-layout.item-options.repeat.title', 'Repeat options'),
|
||||||
id: 'Repeat options',
|
id: 'Repeat options',
|
||||||
isOpenDefault: false,
|
isOpenDefault: false,
|
||||||
});
|
})
|
||||||
|
.addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.default-layout.item-options.repeat.variable.title', 'Repeat by variable'),
|
||||||
|
description: t(
|
||||||
|
'dashboard.default-layout.item-options.repeat.variable.description',
|
||||||
|
'Repeat this panel for each value in the selected variable. This is not visible while in edit mode. You need to go back to dashboard and then update the variable or reload the dashboard.'
|
||||||
|
),
|
||||||
|
render: () => <RepeatByOption gridItem={gridItem} />,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.default-layout.item-options.repeat.direction.title', 'Repeat direction'),
|
||||||
|
useShowIf: () => {
|
||||||
|
const { variableName } = gridItem.useState();
|
||||||
|
return Boolean(variableName);
|
||||||
|
},
|
||||||
|
render: () => <RepeatDirectionOption gridItem={gridItem} />,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.default-layout.item-options.repeat.max', 'Max per row'),
|
||||||
|
useShowIf: () => {
|
||||||
|
const { variableName, repeatDirection } = gridItem.useState();
|
||||||
|
return Boolean(variableName) && repeatDirection === 'h';
|
||||||
|
},
|
||||||
|
render: () => <MaxPerRowOption gridItem={gridItem} />,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
category.addItem(
|
return [repeatCategory];
|
||||||
new OptionsPaneItemDescriptor({
|
|
||||||
title: t('dashboard.default-layout.item-options.repeat.variable.title', 'Repeat by variable'),
|
|
||||||
description: t(
|
|
||||||
'dashboard.default-layout.item-options.repeat.variable.description',
|
|
||||||
'Repeat this panel for each value in the selected variable. This is not visible while in edit mode. You need to go back to dashboard and then update the variable or reload the dashboard.'
|
|
||||||
),
|
|
||||||
render: () => <RepeatByOption gridItem={gridItem} />,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
category.addItem(
|
|
||||||
new OptionsPaneItemDescriptor({
|
|
||||||
title: t('dashboard.default-layout.item-options.repeat.direction.title', 'Repeat direction'),
|
|
||||||
useShowIf: () => {
|
|
||||||
const { variableName } = gridItem.useState();
|
|
||||||
return Boolean(variableName);
|
|
||||||
},
|
|
||||||
render: () => <RepeatDirectionOption gridItem={gridItem} />,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
category.addItem(
|
|
||||||
new OptionsPaneItemDescriptor({
|
|
||||||
title: t('dashboard.default-layout.item-options.repeat.max', 'Max per row'),
|
|
||||||
useShowIf: () => {
|
|
||||||
const { variableName, repeatDirection } = gridItem.useState();
|
|
||||||
return Boolean(variableName) && repeatDirection === 'h';
|
|
||||||
},
|
|
||||||
render: () => <MaxPerRowOption gridItem={gridItem} />,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return category;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OptionComponentProps {
|
interface OptionComponentProps {
|
||||||
|
|
|
@ -65,7 +65,7 @@ export class ResponsiveGridItem extends SceneObjectBase<ResponsiveGridItemState>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getOptions(): OptionsPaneCategoryDescriptor {
|
public getOptions(): OptionsPaneCategoryDescriptor[] {
|
||||||
return getOptions(this);
|
return getOptions(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,42 @@
|
||||||
|
import { t } from 'app/core/internationalization';
|
||||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
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';
|
||||||
|
|
||||||
import { useConditionalRenderingEditor } from '../../conditional-rendering/ConditionalRenderingEditor';
|
import { useConditionalRenderingEditor } from '../../conditional-rendering/ConditionalRenderingEditor';
|
||||||
|
|
||||||
import { ResponsiveGridItem } from './ResponsiveGridItem';
|
import { ResponsiveGridItem } from './ResponsiveGridItem';
|
||||||
|
|
||||||
export function getOptions(model: ResponsiveGridItem): OptionsPaneCategoryDescriptor {
|
export function getOptions(model: ResponsiveGridItem): OptionsPaneCategoryDescriptor[] {
|
||||||
return useConditionalRenderingEditor(model.state.conditionalRendering)!;
|
const repeatCategory = new OptionsPaneCategoryDescriptor({
|
||||||
|
title: t('dashboard.responsive-layout.item-options.repeat.title', 'Repeat options'),
|
||||||
|
id: 'repeat-options',
|
||||||
|
isOpenDefault: false,
|
||||||
|
}).addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.responsive-layout.item-options.repeat.variable.title', 'Repeat by variable'),
|
||||||
|
description: t(
|
||||||
|
'dashboard.responsive-layout.item-options.repeat.variable.description',
|
||||||
|
'Repeat this panel for each value in the selected variable. This is not visible while in edit mode. You need to go back to dashboard and then update the variable or reload the dashboard.'
|
||||||
|
),
|
||||||
|
render: () => <RepeatByOption item={model} />,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const conditionalRenderingCategory = useConditionalRenderingEditor(model.state.conditionalRendering)!;
|
||||||
|
|
||||||
|
return [repeatCategory, conditionalRenderingCategory];
|
||||||
|
}
|
||||||
|
|
||||||
|
function RepeatByOption({ item }: { item: ResponsiveGridItem }) {
|
||||||
|
const { variableName } = item.useState();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RepeatRowSelect2
|
||||||
|
id="repeat-by-variable-select"
|
||||||
|
sceneContext={item}
|
||||||
|
repeat={variableName}
|
||||||
|
onChange={(value?: string) => item.setRepeatByVariable(value)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,48 +19,61 @@ import { RowItem } from './RowItem';
|
||||||
|
|
||||||
export function getEditOptions(model: RowItem): OptionsPaneCategoryDescriptor[] {
|
export function getEditOptions(model: RowItem): OptionsPaneCategoryDescriptor[] {
|
||||||
const { layout } = model.useState();
|
const { layout } = model.useState();
|
||||||
const rowOptions = useMemo(() => {
|
|
||||||
const editPaneHeaderOptions = new OptionsPaneCategoryDescriptor({ title: '', id: 'row-options' })
|
|
||||||
.addItem(
|
|
||||||
new OptionsPaneItemDescriptor({
|
|
||||||
title: t('dashboard.rows-layout.option.title', 'Title'),
|
|
||||||
render: () => <RowTitleInput row={model} />,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.addItem(
|
|
||||||
new OptionsPaneItemDescriptor({
|
|
||||||
title: t('dashboard.rows-layout.option.height', 'Height'),
|
|
||||||
render: () => <RowHeightSelect row={model} />,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
editPaneHeaderOptions
|
const rowCategory = useMemo(
|
||||||
.addItem(
|
() =>
|
||||||
|
new OptionsPaneCategoryDescriptor({ title: '', id: 'row-options' })
|
||||||
|
.addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.rows-layout.row-options.row.title', 'Title'),
|
||||||
|
render: () => <RowTitleInput row={model} />,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.rows-layout.row-options.row.height', 'Height'),
|
||||||
|
render: () => <RowHeightSelect row={model} />,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.rows-layout.row-options.row.hide-header', 'Hide row header'),
|
||||||
|
render: () => <RowHeaderSwitch row={model} />,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
[model]
|
||||||
|
);
|
||||||
|
|
||||||
|
const repeatCategory = useMemo(
|
||||||
|
() =>
|
||||||
|
new OptionsPaneCategoryDescriptor({
|
||||||
|
title: t('dashboard.rows-layout.row-options.repeat.title', 'Repeat options'),
|
||||||
|
id: 'repeat-options',
|
||||||
|
isOpenDefault: false,
|
||||||
|
}).addItem(
|
||||||
new OptionsPaneItemDescriptor({
|
new OptionsPaneItemDescriptor({
|
||||||
title: t('dashboard.rows-layout.option.repeat', 'Repeat for'),
|
title: t('dashboard.rows-layout.row-options.repeat.variable.title', 'Repeat by variable'),
|
||||||
|
description: t(
|
||||||
|
'dashboard.rows-layout.row-options.repeat.variable.description',
|
||||||
|
'Repeat this row for each value in the selected variable.'
|
||||||
|
),
|
||||||
render: () => <RowRepeatSelect row={model} />,
|
render: () => <RowRepeatSelect row={model} />,
|
||||||
})
|
})
|
||||||
)
|
),
|
||||||
.addItem(
|
[model]
|
||||||
new OptionsPaneItemDescriptor({
|
);
|
||||||
title: t('dashboard.rows-layout.option.hide-header', 'Hide row header'),
|
|
||||||
render: () => <RowHeaderSwitch row={model} />,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return editPaneHeaderOptions;
|
|
||||||
}, [model]);
|
|
||||||
|
|
||||||
const layoutCategory = useLayoutCategory(layout);
|
const layoutCategory = useLayoutCategory(layout);
|
||||||
|
|
||||||
const conditionalRenderingOptions = useMemo(() => {
|
const editOptions = [rowCategory, layoutCategory, repeatCategory];
|
||||||
return useConditionalRenderingEditor(model.state.conditionalRendering);
|
|
||||||
}, [model]);
|
|
||||||
|
|
||||||
const editOptions = [rowOptions, layoutCategory];
|
const conditionalRenderingCategory = useMemo(
|
||||||
|
() => useConditionalRenderingEditor(model.state.conditionalRendering),
|
||||||
|
[model]
|
||||||
|
);
|
||||||
|
|
||||||
if (conditionalRenderingOptions) {
|
if (conditionalRenderingCategory) {
|
||||||
editOptions.push(conditionalRenderingOptions);
|
editOptions.push(conditionalRenderingCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return editOptions;
|
return editOptions;
|
||||||
|
|
|
@ -11,19 +11,22 @@ import { useEditPaneInputAutoFocus } from '../layouts-shared/utils';
|
||||||
import { TabItem } from './TabItem';
|
import { TabItem } from './TabItem';
|
||||||
|
|
||||||
export function getEditOptions(model: TabItem): OptionsPaneCategoryDescriptor[] {
|
export function getEditOptions(model: TabItem): OptionsPaneCategoryDescriptor[] {
|
||||||
const tabOptions = useMemo(() => {
|
|
||||||
return new OptionsPaneCategoryDescriptor({ title: '', id: 'tab-item-options' }).addItem(
|
|
||||||
new OptionsPaneItemDescriptor({
|
|
||||||
title: t('dashboard.tabs-layout.tab-options.title-option', 'Title'),
|
|
||||||
render: () => <TabTitleInput tab={model} />,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}, [model]);
|
|
||||||
|
|
||||||
const { layout } = model.useState();
|
const { layout } = model.useState();
|
||||||
const layoutOptions = useLayoutCategory(layout);
|
|
||||||
|
|
||||||
return [tabOptions, layoutOptions];
|
const tabCategory = useMemo(
|
||||||
|
() =>
|
||||||
|
new OptionsPaneCategoryDescriptor({ title: '', id: 'tab-item-options' }).addItem(
|
||||||
|
new OptionsPaneItemDescriptor({
|
||||||
|
title: t('dashboard.tabs-layout.tab-options.title-option', 'Title'),
|
||||||
|
render: () => <TabTitleInput tab={model} />,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
[model]
|
||||||
|
);
|
||||||
|
|
||||||
|
const layoutCategory = useLayoutCategory(layout);
|
||||||
|
|
||||||
|
return [tabCategory, layoutCategory];
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabTitleInput({ tab }: { tab: TabItem }) {
|
function TabTitleInput({ tab }: { tab: TabItem }) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ export interface DashboardLayoutItem extends SceneObject {
|
||||||
/**
|
/**
|
||||||
* Return layout item options (like repeat, repeat direction, etc. for the default DashboardGridItem)
|
* Return layout item options (like repeat, repeat direction, etc. for the default DashboardGridItem)
|
||||||
*/
|
*/
|
||||||
getOptions?(): OptionsPaneCategoryDescriptor;
|
getOptions?(): OptionsPaneCategoryDescriptor[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When going into panel edit
|
* When going into panel edit
|
||||||
|
|
|
@ -1439,6 +1439,15 @@
|
||||||
},
|
},
|
||||||
"responsive-layout": {
|
"responsive-layout": {
|
||||||
"description": "Panels resize to fit and form uniform grids",
|
"description": "Panels resize to fit and form uniform grids",
|
||||||
|
"item-options": {
|
||||||
|
"repeat": {
|
||||||
|
"title": "Repeat options",
|
||||||
|
"variable": {
|
||||||
|
"description": "Repeat this panel for each value in the selected variable. This is not visible while in edit mode. You need to go back to dashboard and then update the variable or reload the dashboard.",
|
||||||
|
"title": "Repeat by variable"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"name": "Auto grid",
|
"name": "Auto grid",
|
||||||
"options": {
|
"options": {
|
||||||
"columns": "Columns",
|
"columns": "Columns",
|
||||||
|
@ -1453,12 +1462,6 @@
|
||||||
"rows-layout": {
|
"rows-layout": {
|
||||||
"description": "Collapsable panel groups with headings",
|
"description": "Collapsable panel groups with headings",
|
||||||
"name": "Rows",
|
"name": "Rows",
|
||||||
"option": {
|
|
||||||
"height": "Height",
|
|
||||||
"hide-header": "Hide row header",
|
|
||||||
"repeat": "Repeat for",
|
|
||||||
"title": "Title"
|
|
||||||
},
|
|
||||||
"options": {
|
"options": {
|
||||||
"height-expand": "Expand",
|
"height-expand": "Expand",
|
||||||
"height-min": "Min"
|
"height-min": "Min"
|
||||||
|
@ -1482,6 +1485,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"row-options": {
|
"row-options": {
|
||||||
|
"repeat": {
|
||||||
|
"title": "Repeat options",
|
||||||
|
"variable": {
|
||||||
|
"description": "Repeat this row for each value in the selected variable.",
|
||||||
|
"title": "Repeat by variable"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"row": {
|
||||||
|
"height": "Height",
|
||||||
|
"hide-header": "Hide row header",
|
||||||
|
"title": "Title"
|
||||||
|
},
|
||||||
"title-option": "Title"
|
"title-option": "Title"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue