Dashboards: A11y improvements for edit experience (#106321)
* Dashboards: A11y improvements for edit experience * Pass descriptor to render function
This commit is contained in:
@@ -55,22 +55,27 @@ export class VizPanelEditableElement implements EditableDashboardElement, BulkAc
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.viz-panel.options.title-option', 'Title'),
|
||||
id: 'PanelFrameTitle',
|
||||
value: panel.state.title,
|
||||
popularRank: 1,
|
||||
render: () => <PanelFrameTitleInput panel={panel} isNewElement={isNewElement} />,
|
||||
render: (descriptor) => (
|
||||
<PanelFrameTitleInput id={descriptor.props.id} panel={panel} isNewElement={isNewElement} />
|
||||
),
|
||||
})
|
||||
)
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.viz-panel.options.description', 'Description'),
|
||||
id: 'description-text-area',
|
||||
value: panel.state.description,
|
||||
render: () => <PanelDescriptionTextArea panel={panel} />,
|
||||
render: (descriptor) => <PanelDescriptionTextArea id={descriptor.props.id} panel={panel} />,
|
||||
})
|
||||
)
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.viz-panel.options.transparent-background', 'Transparent background'),
|
||||
render: () => <PanelBackgroundSwitch panel={panel} />,
|
||||
id: 'transparent-background',
|
||||
render: (descriptor) => <PanelBackgroundSwitch id={descriptor.props.id} panel={panel} />,
|
||||
})
|
||||
);
|
||||
}, [panel, isNewElement]);
|
||||
|
||||
@@ -37,10 +37,11 @@ export function getPanelFrameOptions(panel: VizPanel): OptionsPaneCategoryDescri
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard-scene.get-panel-frame-options.title.title', 'Title'),
|
||||
id: 'PanelFrameTitle',
|
||||
value: panel.state.title,
|
||||
popularRank: 1,
|
||||
render: function renderTitle() {
|
||||
return <PanelFrameTitleInput panel={panel} />;
|
||||
render: function renderTitle(descriptor) {
|
||||
return <PanelFrameTitleInput id={descriptor.props.id} panel={panel} />;
|
||||
},
|
||||
addon: config.featureToggles.dashgpt && (
|
||||
<GenAIPanelTitleButton
|
||||
@@ -54,9 +55,10 @@ export function getPanelFrameOptions(panel: VizPanel): OptionsPaneCategoryDescri
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard-scene.get-panel-frame-options.title.description', 'Description'),
|
||||
id: 'description-text-area',
|
||||
value: panel.state.description,
|
||||
render: function renderDescription() {
|
||||
return <PanelDescriptionTextArea panel={panel} />;
|
||||
render: function renderDescription(descriptor) {
|
||||
return <PanelDescriptionTextArea id={descriptor.props.id} panel={panel} />;
|
||||
},
|
||||
addon: config.featureToggles.dashgpt && (
|
||||
<GenAIPanelDescriptionButton
|
||||
@@ -69,8 +71,9 @@ export function getPanelFrameOptions(panel: VizPanel): OptionsPaneCategoryDescri
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard-scene.get-panel-frame-options.title.transparent-background', 'Transparent background'),
|
||||
render: function renderTransparent() {
|
||||
return <PanelBackgroundSwitch panel={panel} />;
|
||||
id: 'transparent-background',
|
||||
render: function renderTransparent(descriptor) {
|
||||
return <PanelBackgroundSwitch id={descriptor.props.id} panel={panel} />;
|
||||
},
|
||||
})
|
||||
)
|
||||
@@ -112,7 +115,15 @@ function ScenePanelLinksEditor({ panelLinks }: ScenePanelLinksEditorProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export function PanelFrameTitleInput({ panel, isNewElement }: { panel: VizPanel; isNewElement?: boolean }) {
|
||||
export function PanelFrameTitleInput({
|
||||
panel,
|
||||
isNewElement,
|
||||
id,
|
||||
}: {
|
||||
panel: VizPanel;
|
||||
isNewElement?: boolean;
|
||||
id?: string;
|
||||
}) {
|
||||
const { title } = panel.useState();
|
||||
const notInPanelEdit = panel.getPanelContext().app !== CoreApp.PanelEditor;
|
||||
const [prevTitle, setPrevTitle] = React.useState(panel.state.title);
|
||||
@@ -125,6 +136,7 @@ export function PanelFrameTitleInput({ panel, isNewElement }: { panel: VizPanel;
|
||||
<Input
|
||||
ref={ref}
|
||||
data-testid={selectors.components.PanelEditor.OptionsPane.fieldInput('Title')}
|
||||
id={id}
|
||||
value={title}
|
||||
onFocus={() => setPrevTitle(title)}
|
||||
onBlur={() => editPanelTitleAction(panel, title, prevTitle)}
|
||||
@@ -135,13 +147,13 @@ export function PanelFrameTitleInput({ panel, isNewElement }: { panel: VizPanel;
|
||||
);
|
||||
}
|
||||
|
||||
export function PanelDescriptionTextArea({ panel }: { panel: VizPanel }) {
|
||||
export function PanelDescriptionTextArea({ panel, id }: { panel: VizPanel; id?: string }) {
|
||||
const { description } = panel.useState();
|
||||
const [prevDescription, setPrevDescription] = React.useState(panel.state.description);
|
||||
|
||||
return (
|
||||
<TextArea
|
||||
id="description-text-area"
|
||||
id={id}
|
||||
value={description}
|
||||
onChange={(evt) => panel.setState({ description: evt.currentTarget.value })}
|
||||
onFocus={() => setPrevDescription(panel.state.description)}
|
||||
@@ -157,7 +169,7 @@ export function PanelDescriptionTextArea({ panel }: { panel: VizPanel }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function PanelBackgroundSwitch({ panel }: { panel: VizPanel }) {
|
||||
export function PanelBackgroundSwitch({ panel, id }: { panel: VizPanel; id?: string }) {
|
||||
const { displayMode = 'default' } = panel.useState();
|
||||
|
||||
const onChange = () => {
|
||||
@@ -171,7 +183,7 @@ export function PanelBackgroundSwitch({ panel }: { panel: VizPanel }) {
|
||||
});
|
||||
};
|
||||
|
||||
return <Switch value={displayMode === 'transparent'} id="transparent-background" onChange={onChange} />;
|
||||
return <Switch value={displayMode === 'transparent'} id={id} onChange={onChange} />;
|
||||
}
|
||||
|
||||
function updatePanelTitleState(panel: VizPanel, title: string) {
|
||||
|
||||
@@ -15,11 +15,12 @@ export function getOptions(model: AutoGridItem): OptionsPaneCategoryDescriptor[]
|
||||
}).addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.auto-grid.item-options.repeat.variable.title', 'Repeat by variable'),
|
||||
id: 'repeat-by-variable-select',
|
||||
description: t(
|
||||
'dashboard.auto-grid.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} />,
|
||||
render: (descriptor) => <RepeatByOption id={descriptor.props.id} item={model} />,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -28,12 +29,12 @@ export function getOptions(model: AutoGridItem): OptionsPaneCategoryDescriptor[]
|
||||
return [repeatCategory, conditionalRenderingCategory];
|
||||
}
|
||||
|
||||
function RepeatByOption({ item }: { item: AutoGridItem }) {
|
||||
function RepeatByOption({ item, id }: { item: AutoGridItem; id?: string }) {
|
||||
const { variableName } = item.useState();
|
||||
|
||||
return (
|
||||
<RepeatRowSelect2
|
||||
id="repeat-by-variable-select"
|
||||
id={id}
|
||||
sceneContext={item}
|
||||
repeat={variableName}
|
||||
onChange={(value?: string) => item.setRepeatByVariable(value)}
|
||||
|
||||
+4
-3
@@ -18,11 +18,12 @@ export function getDashboardGridItemOptions(gridItem: DashboardGridItem): Option
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.default-layout.item-options.repeat.variable.title', 'Repeat by variable'),
|
||||
id: 'repeat-by-variable-select',
|
||||
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} />,
|
||||
render: (descriptor) => <RepeatByOption id={descriptor.props.id} gridItem={gridItem} />,
|
||||
})
|
||||
)
|
||||
.addItem(
|
||||
@@ -86,12 +87,12 @@ function MaxPerRowOption({ gridItem }: OptionComponentProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function RepeatByOption({ gridItem }: OptionComponentProps) {
|
||||
function RepeatByOption({ gridItem, id }: OptionComponentProps & { id?: string }) {
|
||||
const { variableName, width } = gridItem.useState();
|
||||
|
||||
return (
|
||||
<RepeatRowSelect2
|
||||
id="repeat-by-variable-select"
|
||||
id={id}
|
||||
sceneContext={gridItem}
|
||||
repeat={variableName}
|
||||
onChange={(value?: string) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ export interface OptionsPaneItemInfo {
|
||||
value?: any;
|
||||
description?: string;
|
||||
popularRank?: number;
|
||||
render: () => React.ReactElement;
|
||||
render: (descriptor: OptionsPaneItemDescriptor) => React.ReactElement;
|
||||
skipField?: boolean;
|
||||
showIf?: () => boolean;
|
||||
/** Hook for controlling visibility */
|
||||
@@ -66,7 +66,7 @@ function OptionsPaneItem({ itemDescriptor, searchQuery }: OptionsPaneItemProps)
|
||||
}
|
||||
|
||||
if (skipField) {
|
||||
return render();
|
||||
return render(itemDescriptor);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -77,7 +77,7 @@ function OptionsPaneItem({ itemDescriptor, searchQuery }: OptionsPaneItemProps)
|
||||
aria-label={selectors.components.PanelEditor.OptionsPane.fieldLabel(key)}
|
||||
htmlFor={id}
|
||||
>
|
||||
{render()}
|
||||
{render(itemDescriptor)}
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,13 +40,14 @@ export function getPanelFrameCategory(props: OptionPaneRenderProps): OptionsPane
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.get-panel-frame-category.title.title', 'Title'),
|
||||
id: 'PanelFrameTitle',
|
||||
value: panel.title,
|
||||
popularRank: 1,
|
||||
render: function renderTitle() {
|
||||
render: function renderTitle(descriptor) {
|
||||
return (
|
||||
<Input
|
||||
data-testid={selectors.components.PanelEditor.OptionsPane.fieldInput('Title')}
|
||||
id="PanelFrameTitle"
|
||||
id={descriptor.props.id}
|
||||
defaultValue={panel.title}
|
||||
onBlur={(e) => onPanelConfigChange('title', e.currentTarget.value)}
|
||||
/>
|
||||
@@ -64,13 +65,14 @@ export function getPanelFrameCategory(props: OptionPaneRenderProps): OptionsPane
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.get-panel-frame-category.title.description', 'Description'),
|
||||
id: 'description-text-area',
|
||||
description: panel.description,
|
||||
value: panel.description,
|
||||
render: function renderDescription() {
|
||||
render: function renderDescription(descriptor) {
|
||||
return (
|
||||
<TextArea
|
||||
data-testid={selectors.components.PanelEditor.OptionsPane.fieldInput('Description')}
|
||||
id="description-text-area"
|
||||
id={descriptor.props.id}
|
||||
defaultValue={panel.description}
|
||||
onBlur={(e) => onPanelConfigChange('description', e.currentTarget.value)}
|
||||
/>
|
||||
@@ -84,12 +86,13 @@ export function getPanelFrameCategory(props: OptionPaneRenderProps): OptionsPane
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.get-panel-frame-category.title.transparent-background', 'Transparent background'),
|
||||
render: function renderTransparent() {
|
||||
id: 'transparent-background',
|
||||
render: function renderTransparent(descriptor) {
|
||||
return (
|
||||
<Switch
|
||||
data-testid={selectors.components.PanelEditor.OptionsPane.fieldInput('Transparent background')}
|
||||
value={panel.transparent}
|
||||
id="transparent-background"
|
||||
id={descriptor.props.id}
|
||||
onChange={(e) => onPanelConfigChange('transparent', e.currentTarget.checked)}
|
||||
/>
|
||||
);
|
||||
@@ -127,12 +130,13 @@ export function getPanelFrameCategory(props: OptionPaneRenderProps): OptionsPane
|
||||
.addItem(
|
||||
new OptionsPaneItemDescriptor({
|
||||
title: t('dashboard.get-panel-frame-category.title.repeat-by-variable', 'Repeat by variable'),
|
||||
id: 'repeat-by-variable-select',
|
||||
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: function renderRepeatOptions() {
|
||||
render: function renderRepeatOptions(descriptor) {
|
||||
return (
|
||||
<RepeatRowSelect
|
||||
id="repeat-by-variable-select"
|
||||
id={descriptor.props.id}
|
||||
repeat={panel.repeat}
|
||||
onChange={(value?: string) => {
|
||||
onPanelConfigChange('repeat', value);
|
||||
|
||||
Reference in New Issue
Block a user