Canvas: Add all options to inline editor (#52834)

Co-authored-by: nmarrs <nathanielmarrs@gmail.com>
This commit is contained in:
Ryan McKinley 2022-07-27 16:20:39 -07:00 committed by GitHub
parent cb3f7ccd09
commit 8a2d40c2bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 46 additions and 49 deletions

View File

@ -8622,9 +8622,8 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Do not use any type assertions.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"]
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"public/app/plugins/panel/canvas/editor/APIEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],

View File

@ -126,7 +126,7 @@ export class CanvasPanel extends Component<Props, State> {
});
this.setState({ refresh: this.state.refresh + 1 });
// console.log('send changes', root);
activePanelSubject.next({ panel: this });
};
shouldComponentUpdate(nextProps: Props, nextState: State) {

View File

@ -19,7 +19,7 @@ type Props = {
const OFFSET_X = 10;
const OFFSET_Y = 32;
export const InlineEdit = ({ onClose, id, scene }: Props) => {
export function InlineEdit({ onClose, id, scene }: Props) {
const root = scene.root.div!.getBoundingClientRect();
const windowHeight = window.innerHeight;
const windowWidth = window.innerWidth;
@ -96,7 +96,7 @@ export const InlineEdit = ({ onClose, id, scene }: Props) => {
</div>
</Portal>
);
};
}
const getStyles = (theme: GrafanaTheme2) => ({
inlineEditorContainer: css`

View File

@ -1,13 +1,12 @@
import { css } from '@emotion/css';
import { get as lodashGet } from 'lodash';
import React, { useMemo } from 'react';
import { useObservable } from 'react-use';
import { GrafanaTheme2, PanelOptionsEditorBuilder, StandardEditorContext } from '@grafana/data';
import { DataFrame, PanelOptionsEditorBuilder, StandardEditorContext } from '@grafana/data';
import { PanelOptionsSupplier } from '@grafana/data/src/panel/PanelPlugin';
import { NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders';
import { useStyles2 } from '@grafana/ui';
import { FrameState } from 'app/features/canvas/runtime/frame';
import { OptionsPaneCategory } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategory';
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
import { fillOptionsPaneItems } from 'app/features/dashboard/components/PanelEditor/getVisualizationOptions';
import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils';
@ -16,15 +15,13 @@ import { activePanelSubject, InstanceState } from './CanvasPanel';
import { getElementEditor } from './editor/elementEditor';
import { getLayerEditor } from './editor/layerEditor';
export const InlineEditBody = () => {
export function InlineEditBody() {
const activePanel = useObservable(activePanelSubject);
const instanceState = activePanel?.panel.context?.instanceState;
const styles = useStyles2(getStyles);
const pane = useMemo(() => {
const p = activePanel?.panel;
const state: InstanceState = instanceState;
if (!state) {
if (!state || !p) {
return new OptionsPaneCategoryDescriptor({ id: 'root', title: 'root' });
}
@ -46,33 +43,41 @@ export const InlineEditBody = () => {
}
};
return getOptionsPaneCategoryDescriptor({}, supplier);
}, [instanceState]);
return getOptionsPaneCategoryDescriptor(
{
options: p.props.options,
onChange: p.props.onOptionsChange,
data: p.props.data?.series,
},
supplier
);
}, [instanceState, activePanel]);
return <>{pane.categories.map((p) => renderOptionsPaneCategoryDescriptor(p))}</>;
}
// Recursively render options
function renderOptionsPaneCategoryDescriptor(pane: OptionsPaneCategoryDescriptor) {
return (
<div>
<OptionsPaneCategory {...pane.props} key={pane.props.id}>
<div>{pane.items.map((v) => v.render())}</div>
<div>
{pane.categories.map((c) => {
return (
<div key={c.props.id} className={styles.wrap}>
<h5>{c.props.title}</h5>
<div className={styles.item}>{c.items.map((s) => s.render())}</div>
</div>
);
})}
</div>
</div>
{pane.categories.map((c) => renderOptionsPaneCategoryDescriptor(c))}
</OptionsPaneCategory>
);
};
}
interface EditorProps<T> {
onChange: (v: T) => void;
options: T;
data?: DataFrame[];
}
// 🤮🤮🤮🤮 this oddly does not actually do anything, but structure is required. I'll try to clean it up...
function getOptionsPaneCategoryDescriptor<T = any>(
props: any,
props: EditorProps<T>,
supplier: PanelOptionsSupplier<T>
): OptionsPaneCategoryDescriptor {
const context: StandardEditorContext<unknown, unknown> = {
data: props.input,
data: props.data ?? [],
options: props.options,
};
@ -101,13 +106,3 @@ function getOptionsPaneCategoryDescriptor<T = any>(
fillOptionsPaneItems(supplier, access, getOptionsPaneCategory, context);
return root;
}
const getStyles = (theme: GrafanaTheme2) => ({
wrap: css`
border-top: 1px solid ${theme.colors.border.strong};
padding: 10px;
`,
item: css`
padding-left: 10px;
`,
});

View File

@ -1,4 +1,4 @@
import React, { FC, useCallback } from 'react';
import React, { useCallback } from 'react';
import { AppEvents, StandardEditorProps, StandardEditorsRegistryItem, StringFieldConfigSettings } from '@grafana/data';
import { config, getBackendSrv } from '@grafana/runtime';
@ -39,8 +39,9 @@ export const callApi = (api: APIEditorConfig, isTest = false) => {
}
};
export const APIEditor: FC<StandardEditorProps<APIEditorConfig, any, any>> = (props) => {
const { value, context, onChange } = props;
type Props = StandardEditorProps<APIEditorConfig, any, any>;
export function APIEditor({ value, context, onChange }: Props) {
const labelWidth = 9;
const onEndpointChange = useCallback(
@ -117,4 +118,4 @@ export const APIEditor: FC<StandardEditorProps<APIEditorConfig, any, any>> = (pr
) : (
<>Must enable disableSanitizeHtml feature flag to access</>
);
};
}

View File

@ -1,4 +1,4 @@
import React, { FC } from 'react';
import React from 'react';
import { useObservable } from 'react-use';
import { Subject } from 'rxjs';
@ -31,7 +31,9 @@ const verticalOptions: Array<SelectableValue<VerticalConstraint>> = [
{ label: 'Scale', value: VerticalConstraint.Scale },
];
export const PlacementEditor: FC<StandardEditorProps<any, CanvasEditorOptions, PanelOptions>> = ({ item }) => {
type Props = StandardEditorProps<any, CanvasEditorOptions, PanelOptions>;
export function PlacementEditor({ item }: Props) {
const settings = item.settings;
// Will force a rerender whenever the subject changes
@ -136,4 +138,4 @@ export const PlacementEditor: FC<StandardEditorProps<any, CanvasEditorOptions, P
</Field>
</div>
);
};
}