2020-04-05 07:09:43 -05:00
|
|
|
import React, { FC, useMemo } from 'react';
|
|
|
|
import { PanelModel, DashboardModel } from '../../state';
|
|
|
|
import { SelectableValue, PanelPlugin, FieldConfigSource, PanelData } from '@grafana/data';
|
|
|
|
import { Forms, Select, DataLinksInlineEditor, Input } from '@grafana/ui';
|
|
|
|
import { OptionsGroup } from './OptionsGroup';
|
|
|
|
import { getPanelLinksVariableSuggestions } from '../../../panel/panellinks/link_srv';
|
|
|
|
import { getVariables } from '../../../variables/state/selectors';
|
|
|
|
import { PanelOptionsEditor } from './PanelOptionsEditor';
|
|
|
|
import { AngularPanelOptions } from '../../panel_editor/AngularPanelOptions';
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
panel: PanelModel;
|
|
|
|
plugin: PanelPlugin;
|
|
|
|
data: PanelData;
|
|
|
|
dashboard: DashboardModel;
|
|
|
|
onPanelConfigChange: (configKey: string, value: any) => void;
|
|
|
|
onPanelOptionsChanged: (options: any) => void;
|
|
|
|
onFieldConfigsChange: (config: FieldConfigSource) => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const PanelOptionsTab: FC<Props> = ({
|
|
|
|
panel,
|
|
|
|
plugin,
|
|
|
|
data,
|
|
|
|
dashboard,
|
|
|
|
onPanelConfigChange,
|
|
|
|
onPanelOptionsChanged,
|
|
|
|
onFieldConfigsChange,
|
|
|
|
}) => {
|
|
|
|
const elements: JSX.Element[] = [];
|
|
|
|
const linkVariablesSuggestions = useMemo(() => getPanelLinksVariableSuggestions(), []);
|
|
|
|
|
|
|
|
const variableOptions = getVariableOptions();
|
|
|
|
const directionOptions = [
|
|
|
|
{ label: 'Horizontal', value: 'h' },
|
|
|
|
{ label: 'Vertical', value: 'v' },
|
|
|
|
];
|
|
|
|
|
|
|
|
const maxPerRowOptions = [2, 3, 4, 6, 8, 12].map(value => ({ label: value.toString(), value }));
|
|
|
|
|
|
|
|
// Fist common panel settings Title, description
|
|
|
|
elements.push(
|
|
|
|
<OptionsGroup title="Basic" key="basic settings">
|
|
|
|
<Forms.Field label="Panel title">
|
|
|
|
<Input defaultValue={panel.title} onBlur={e => onPanelConfigChange('title', e.currentTarget.value)} />
|
|
|
|
</Forms.Field>
|
|
|
|
<Forms.Field label="Description" description="Panel description supports markdown and links.">
|
|
|
|
<Forms.TextArea
|
|
|
|
defaultValue={panel.description}
|
|
|
|
onBlur={e => onPanelConfigChange('description', e.currentTarget.value)}
|
|
|
|
/>
|
|
|
|
</Forms.Field>
|
|
|
|
<Forms.Field label="Transparent" description="Display panel without background.">
|
|
|
|
<Forms.Switch
|
|
|
|
value={panel.transparent}
|
|
|
|
onChange={e => onPanelConfigChange('transparent', e.currentTarget.checked)}
|
|
|
|
/>
|
|
|
|
</Forms.Field>
|
|
|
|
</OptionsGroup>
|
|
|
|
);
|
|
|
|
|
|
|
|
// Old legacy react editor
|
|
|
|
if (plugin.editor && panel && !plugin.optionEditors) {
|
|
|
|
elements.push(
|
|
|
|
<OptionsGroup title="Display" key="legacy react editor">
|
|
|
|
<plugin.editor
|
|
|
|
data={data}
|
|
|
|
options={panel.getOptions()}
|
|
|
|
onOptionsChange={onPanelOptionsChanged}
|
|
|
|
fieldConfig={panel.getFieldConfig()}
|
|
|
|
onFieldConfigChange={onFieldConfigsChange}
|
|
|
|
/>
|
|
|
|
</OptionsGroup>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plugin.optionEditors && panel) {
|
|
|
|
elements.push(
|
|
|
|
<OptionsGroup title="Display" key="panel plugin options">
|
|
|
|
<PanelOptionsEditor
|
|
|
|
key="panel options"
|
|
|
|
options={panel.getOptions()}
|
|
|
|
onChange={onPanelOptionsChanged}
|
|
|
|
plugin={plugin}
|
|
|
|
/>
|
|
|
|
</OptionsGroup>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plugin.angularPanelCtrl) {
|
2020-04-08 00:47:15 -05:00
|
|
|
elements.push(<AngularPanelOptions panel={panel} dashboard={dashboard} plugin={plugin} />);
|
2020-04-05 07:09:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
elements.push(
|
2020-04-05 08:21:53 -05:00
|
|
|
<OptionsGroup title="Panel links" key="panel links" defaultToClosed={true}>
|
|
|
|
<DataLinksInlineEditor
|
|
|
|
links={panel.links}
|
|
|
|
onChange={links => onPanelConfigChange('links', links)}
|
|
|
|
suggestions={linkVariablesSuggestions}
|
|
|
|
data={[]}
|
|
|
|
/>
|
|
|
|
</OptionsGroup>
|
|
|
|
);
|
|
|
|
|
|
|
|
elements.push(
|
|
|
|
<OptionsGroup title="Panel repeats" key="panel repeats" defaultToClosed={true}>
|
|
|
|
<Forms.Field
|
|
|
|
label="Repeat by variable"
|
|
|
|
description="Repeat this panel for each value in the selected variable.
|
2020-04-05 07:09:43 -05:00
|
|
|
This is not visible while in edit mode. You need to go back to dashboard and then update the variable or
|
|
|
|
reload the dashboard."
|
2020-04-05 08:21:53 -05:00
|
|
|
>
|
|
|
|
<Select
|
|
|
|
value={panel.repeat}
|
|
|
|
onChange={value => onPanelConfigChange('repeat', value.value)}
|
|
|
|
options={variableOptions}
|
|
|
|
/>
|
|
|
|
</Forms.Field>
|
|
|
|
{panel.repeat && (
|
|
|
|
<Forms.Field label="Repeat direction">
|
|
|
|
<Forms.RadioButtonGroup
|
|
|
|
options={directionOptions}
|
|
|
|
value={panel.repeatDirection || 'h'}
|
|
|
|
onChange={value => onPanelConfigChange('repeatDirection', value)}
|
|
|
|
/>
|
|
|
|
</Forms.Field>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{panel.repeat && panel.repeatDirection === 'h' && (
|
|
|
|
<Forms.Field label="Max per row">
|
2020-04-05 07:09:43 -05:00
|
|
|
<Select
|
2020-04-05 08:21:53 -05:00
|
|
|
options={maxPerRowOptions}
|
|
|
|
value={panel.maxPerRow}
|
|
|
|
onChange={value => onPanelConfigChange('maxPerRow', value.value)}
|
2020-04-05 07:09:43 -05:00
|
|
|
/>
|
|
|
|
</Forms.Field>
|
2020-04-05 08:21:53 -05:00
|
|
|
)}
|
|
|
|
</OptionsGroup>
|
2020-04-05 07:09:43 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
return <>{elements}</>;
|
|
|
|
};
|
|
|
|
|
|
|
|
function getVariableOptions(): Array<SelectableValue<string>> {
|
|
|
|
const options = getVariables().map((item: any) => {
|
|
|
|
return { label: item.name, value: item.name };
|
|
|
|
});
|
|
|
|
|
|
|
|
if (options.length === 0) {
|
|
|
|
options.unshift({
|
|
|
|
label: 'No template variables found',
|
|
|
|
value: null,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
options.unshift({
|
|
|
|
label: 'Disable repeating',
|
|
|
|
value: null,
|
|
|
|
});
|
|
|
|
|
|
|
|
return options;
|
|
|
|
}
|