PanelEdit: v8 Panel Edit UX (#32124)

* Initial commit

* Progress

* Update

* Progress

* updates

* Minor fix

* fixed ts issue

* fixed e2e tests

* More explorations

* Making progress

* Panel options and field options unified

* With nested categories

* Starting to find something

* fix paddings

* Progress

* Breakthrough ux layout

* Progress

* Updates

* New way of composing options with search

* added regex search

* Refactoring to react note tree

* Show overrides

* Adding overrides radio button support

* Added popular view

* Separate stat/gauge/bargauge options into value options and display options

* Initial work on getting library panels into viz picker flow

* Fixed issues switching to panel library panel

* Move search input put of LibraryPanelsView

* Changing design again to have content inside boxes

* Style updates

* Refactoring to fix scroll issue

* Option category naming

* Fixed FilterInput issue

* Updated snapshots

* Fix padding

* Updated viz picker design

* Unify library panel an viz picker card

* Updated card with delete action

* Major refactoring back to an object model instead of searching and filtering react node tree

* More refactoring

* Show option category in label when searching

* Nice logic for categories rendering when searching or when only child

* Make getSuggestions more lazy for DataLinksEditor

* Add missing repeat options and handle conditional options

* Prepping options category to be more flexibly and control state from outside

* Added option count to search result

* Minor style tweak

* Added button to close viz picker

* Rewrote overrides to enable searching overrides

* New search engine and tests

* Searching overrides works

* Hide radio buttons while searching

* Added angular options back

* Added memoize for all options so they are not rebuilt for every search key stroke

* Added back support for category counters

* Started unit test work

* Refactoring and base popular options list

* Initial update to e2e test, more coming to add e2e test for search features

* Minor fix

* Review updates

* Fixing category open states

* Unit test progress

* Do not show visualization list mode radio button if library panels is not enabled

* Use boolean

* More unit tests

* Increase library panels per page count and give search focus when switching list mode

* field config change test and search test

* Feedback updates

* Minor tweaks

* Minor refactorings

* More minimal override collapse state
This commit is contained in:
Torkel Ödegaard
2021-03-25 08:33:13 +01:00
committed by GitHub
parent ea186947d2
commit 9d6c8f8512
81 changed files with 2437 additions and 2292 deletions

View File

@@ -5,7 +5,7 @@ import { DataFrame, InterpolateFunction, VariableSuggestionsScope, VariableSugge
import { EventBus } from '../events';
export interface StandardEditorContext<TOptions> {
data?: DataFrame[]; // All results
data: DataFrame[]; // All results
replaceVariables?: InterpolateFunction;
eventBus?: EventBus;
getSuggestions?: (scope?: VariableSuggestionsScope) => VariableSuggestion[];

View File

@@ -58,7 +58,6 @@ export interface FieldConfigSource<TOptions extends object = any> {
export interface FieldOverrideContext extends StandardEditorContext<any> {
field?: Field;
dataFrameIndex?: number; // The index for the selected field frame
data: DataFrame[]; // All results
}
export interface FieldConfigEditorProps<TValue, TSettings>
extends Omit<StandardEditorProps<TValue, TSettings>, 'item'> {

View File

@@ -41,7 +41,7 @@ export interface OptionEditorConfig<TOptions, TSettings = any, TValue = any> {
/**
* Array of strings representing category of the option. First element in the array will make option render as collapsible section.
*/
category?: Array<string | undefined>;
category?: string[];
/**
* Set this value if undefined

View File

@@ -61,18 +61,15 @@ export const Components = {
},
OptionsPane: {
content: 'Panel editor option pane content',
close: 'Page toolbar button Close options pane',
open: 'Page toolbar button Open options pane',
select: 'Panel editor option pane select',
tab: (title: string) => `Panel editor option pane tab ${title}`,
fieldLabel: (type: string) => `${type} field property editor`,
},
// not sure about the naming *DataPane*
DataPane: {
content: 'Panel editor data pane content',
},
FieldOptions: {
propertyEditor: (type: string) => `${type} field property editor`,
},
toggleVizPicker: 'toggle-viz-picker',
toggleVizOptions: 'toggle-viz-options',
},
PanelInspector: {
Data: {

View File

@@ -219,7 +219,7 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC
const closeOptions = (): any =>
isOptionsOpen().then((isOpen: any) => {
if (isOpen) {
e2e.components.PanelEditor.OptionsPane.close().click();
e2e.components.PanelEditor.toggleVizOptions().click();
}
});
@@ -271,7 +271,7 @@ const isOptionsOpen = (): any =>
const openOptions = (): any =>
isOptionsOpen().then((isOpen: any) => {
if (!isOpen) {
e2e.components.PanelEditor.OptionsPane.open().click();
e2e.components.PanelEditor.toggleVizOptions().click();
}
});

View File

@@ -208,6 +208,11 @@ export function getPropertiesForVariant(theme: GrafanaTheme, variant: ButtonVari
outline: none;
text-decoration: underline;
}
&:hover {
color: ${theme.colors.linkExternal};
text-decoration: underline;
}
`,
};

View File

@@ -8,7 +8,7 @@ interface DataLinkEditorModalContentProps {
link: DataLink;
index: number;
data: DataFrame[];
suggestions: VariableSuggestion[];
getSuggestions: () => VariableSuggestion[];
onSave: (index: number, ink: DataLink) => void;
onCancel: (index: number) => void;
}
@@ -16,7 +16,7 @@ interface DataLinkEditorModalContentProps {
export const DataLinkEditorModalContent: FC<DataLinkEditorModalContentProps> = ({
link,
index,
suggestions,
getSuggestions,
onSave,
onCancel,
}) => {
@@ -27,7 +27,7 @@ export const DataLinkEditorModalContent: FC<DataLinkEditorModalContentProps> = (
value={dirtyLink}
index={index}
isLast={false}
suggestions={suggestions}
suggestions={getSuggestions()}
onChange={(index, link) => {
setDirtyLink(link);
}}

View File

@@ -11,11 +11,16 @@ import { DataLinkEditorModalContent } from './DataLinkEditorModalContent';
interface DataLinksInlineEditorProps {
links?: DataLink[];
onChange: (links: DataLink[]) => void;
suggestions: VariableSuggestion[];
getSuggestions: () => VariableSuggestion[];
data: DataFrame[];
}
export const DataLinksInlineEditor: React.FC<DataLinksInlineEditorProps> = ({ links, onChange, suggestions, data }) => {
export const DataLinksInlineEditor: React.FC<DataLinksInlineEditorProps> = ({
links,
onChange,
getSuggestions,
data,
}) => {
const theme = useTheme();
const [editIndex, setEditIndex] = useState<number | null>(null);
const [isNew, setIsNew] = useState(false);
@@ -74,7 +79,6 @@ export const DataLinksInlineEditor: React.FC<DataLinksInlineEditorProps> = ({ li
onEdit={() => setEditIndex(i)}
onRemove={() => onDataLinkRemove(i)}
data={data}
suggestions={suggestions}
/>
);
})}
@@ -95,7 +99,7 @@ export const DataLinksInlineEditor: React.FC<DataLinksInlineEditorProps> = ({ li
data={data}
onSave={onDataLinkChange}
onCancel={onDataLinkCancel}
suggestions={suggestions}
getSuggestions={getSuggestions}
/>
</Modal>
)}

View File

@@ -17,7 +17,6 @@ function setupTestContext(options: Partial<DataLinksListItemProps>) {
onChange: jest.fn(),
onEdit: jest.fn(),
onRemove: jest.fn(),
suggestions: [],
};
const props = { ...defaults, ...options };

View File

@@ -1,6 +1,6 @@
import React, { FC } from 'react';
import { css, cx } from 'emotion';
import { DataFrame, DataLink, GrafanaTheme, VariableSuggestion } from '@grafana/data';
import { DataFrame, DataLink, GrafanaTheme } from '@grafana/data';
import { stylesFactory, useTheme } from '../../../themes';
import { HorizontalGroup, VerticalGroup } from '../../Layout/Layout';
import { IconButton } from '../../IconButton/IconButton';
@@ -12,7 +12,6 @@ export interface DataLinksListItemProps {
onChange: (index: number, link: DataLink) => void;
onEdit: () => void;
onRemove: () => void;
suggestions: VariableSuggestion[];
isEditing?: boolean;
}

View File

@@ -88,7 +88,6 @@ const getInfoBoxStyles = stylesFactory((theme: GrafanaTheme, severity: AlertVari
padding: ${theme.spacing.md};
border-radius: ${theme.border.radius.md};
position: relative;
box-shadow: 0 0 30px 10px rgba(0, 0, 0, ${theme.isLight ? 0.05 : 0.2});
z-index: 0;
&:before {

View File

@@ -17,7 +17,7 @@ export const DataLinksValueEditor: React.FC<FieldConfigEditorProps<DataLink[], D
links={value}
onChange={onChange}
data={context.data}
suggestions={context.getSuggestions ? context.getSuggestions(VariableSuggestionsScope.Values) : []}
getSuggestions={() => (context.getSuggestions ? context.getSuggestions(VariableSuggestionsScope.Values) : [])}
/>
);
};

View File

@@ -8,7 +8,6 @@ export const SliderValueEditor: React.FC<FieldConfigEditorProps<number, SliderFi
item,
}) => {
const { settings } = item;
const initialValue = typeof value === 'number' ? value : typeof value === 'string' ? +value : 0;
return (

View File

@@ -135,7 +135,7 @@ const getStyles = (theme: GrafanaTheme) => {
background: ${theme.colors.dashboardBg};
justify-content: flex-end;
flex-wrap: wrap;
padding: 0 ${spacing.md} ${spacing.sm} ${spacing.md};
padding: 0 ${spacing.sm} ${spacing.sm} ${spacing.md};
`,
toolbarLeft: css`
display: flex;

View File

@@ -221,7 +221,7 @@ export const getStandardFieldConfigs = () => {
category,
};
return [unit, min, max, decimals, displayName, noValue, color, thresholds, mappings, links];
return [unit, min, max, decimals, displayName, color, noValue, thresholds, mappings, links];
};
/**