From 441e87d4d46ab49ad12c8cc52e6562a5652349a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 24 Mar 2020 15:44:13 +0100 Subject: [PATCH] NewPanelEdit: Adding repeating options (#22984) * NewPanelEdit: Adding repeating options * Added all repeat options * reduce strict null errors --- .../DataLinksInlineEditor.tsx | 2 +- .../PanelEditor/GeneralPanelOptions.tsx | 105 ++++++++++++++++++ .../PanelEditor/OptionsPaneContent.tsx | 62 +---------- .../components/PanelEditor/state/actions.ts | 12 +- .../dashboard/dashgrid/DashboardPanel.tsx | 2 +- .../dashboard/dashgrid/PanelChromeAngular.tsx | 2 +- .../dashgrid/PanelHeader/PanelHeader.tsx | 4 +- .../features/dashboard/utils/getPanelMenu.ts | 4 +- scripts/ci-frontend-metrics.sh | 2 +- 9 files changed, 127 insertions(+), 68 deletions(-) create mode 100644 public/app/features/dashboard/components/PanelEditor/GeneralPanelOptions.tsx diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx index 976bb0d5fd8..5f00ff9f2b2 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx @@ -101,7 +101,7 @@ export const DataLinksInlineEditor: React.FC = ({ li - Add data link + Add link diff --git a/public/app/features/dashboard/components/PanelEditor/GeneralPanelOptions.tsx b/public/app/features/dashboard/components/PanelEditor/GeneralPanelOptions.tsx new file mode 100644 index 00000000000..95c34c264f5 --- /dev/null +++ b/public/app/features/dashboard/components/PanelEditor/GeneralPanelOptions.tsx @@ -0,0 +1,105 @@ +import React, { useMemo, FC } from 'react'; +import { PanelModel } from '../../state'; +import { SelectableValue } from '@grafana/data'; +import { Forms, DataLinksInlineEditor } from '@grafana/ui'; +import { OptionsGroup } from './OptionsGroup'; +import { getPanelLinksVariableSuggestions } from '../../../panel/panellinks/link_srv'; +import { getVariables } from '../../../variables/state/selectors'; + +export const GeneralPanelOptions: FC<{ + panel: PanelModel; + onPanelConfigChange: (configKey: string, value: any) => void; +}> = ({ panel, onPanelConfigChange }) => { + 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 })); + + return ( +
+ + + onPanelConfigChange('title', e.currentTarget.value)} /> + + + onPanelConfigChange('description', e.currentTarget.value)} + /> + + + onPanelConfigChange('transparent', e.currentTarget.checked)} + /> + + + + onPanelConfigChange('links', links)} + suggestions={linkVariablesSuggestions} + data={[]} + /> + + + + onPanelConfigChange('repeat', value.value)} + options={variableOptions} + /> + + {panel.repeat && ( + + onPanelConfigChange('repeatDirection', value)} + /> + + )} + + {panel.repeat && panel.repeatDirection === 'h' && ( + + onPanelConfigChange('maxPerRow', value.value)} + /> + + )} + +
+ ); +}; + +function getVariableOptions(): Array> { + 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; +} diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneContent.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneContent.tsx index fdfe9195327..6840999ac93 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneContent.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneContent.tsx @@ -1,22 +1,11 @@ -import React, { useCallback, useState, useMemo } from 'react'; +import React, { useCallback, useState } from 'react'; import { FieldConfigSource, GrafanaTheme, PanelData, PanelPlugin } from '@grafana/data'; import { DashboardModel, PanelModel } from '../../state'; -import { - CustomScrollbar, - stylesFactory, - Tab, - TabContent, - TabsBar, - useTheme, - Forms, - DataLinksInlineEditor, - Container, -} from '@grafana/ui'; +import { CustomScrollbar, stylesFactory, Tab, TabContent, TabsBar, useTheme, Container } from '@grafana/ui'; import { DefaultFieldConfigEditor, OverrideFieldConfigEditor } from './FieldConfigEditor'; import { AngularPanelOptions } from './AngularPanelOptions'; import { css } from 'emotion'; -import { OptionsGroup } from './OptionsGroup'; -import { getPanelLinksVariableSuggestions } from '../../../panel/panellinks/link_srv'; +import { GeneralPanelOptions } from './GeneralPanelOptions'; export const OptionsPaneContent: React.FC<{ plugin?: PanelPlugin; @@ -30,7 +19,6 @@ export const OptionsPaneContent: React.FC<{ const theme = useTheme(); const styles = getStyles(theme); - const linkVariablesSuggestions = useMemo(() => getPanelLinksVariableSuggestions(), []); const renderFieldOptions = useCallback( (plugin: PanelPlugin) => { const fieldConfig = panel.getFieldConfig(); @@ -53,6 +41,7 @@ export const OptionsPaneContent: React.FC<{ }, [data, plugin, panel, onFieldConfigsChange] ); + const renderFieldOverrideOptions = useCallback( (plugin: PanelPlugin) => { const fieldConfig = panel.getFieldConfig(); @@ -98,47 +87,6 @@ export const OptionsPaneContent: React.FC<{ [data, plugin, panel, onFieldConfigsChange] ); - const renderPanelSettings = useCallback(() => { - console.log(panel.transparent); - return ( -
- - <> - - onPanelConfigChange('title', e.currentTarget.value)} - /> - - - onPanelConfigChange('description', e.currentTarget.value)} - /> - - - onPanelConfigChange('transparent', e.currentTarget.checked)} - /> - - - - - onPanelConfigChange('links', links)} - suggestions={linkVariablesSuggestions} - data={data.series} - /> - - -
TODO
-
-
- ); - }, [data, plugin, panel, onFieldConfigsChange]); - const [activeTab, setActiveTab] = useState('defaults'); return ( @@ -154,7 +102,7 @@ export const OptionsPaneContent: React.FC<{ {activeTab === 'defaults' && renderFieldOptions(plugin)} {activeTab === 'overrides' && renderFieldOverrideOptions(plugin)} - {activeTab === 'panel' && renderPanelSettings()} + {activeTab === 'panel' && } diff --git a/public/app/features/dashboard/components/PanelEditor/state/actions.ts b/public/app/features/dashboard/components/PanelEditor/state/actions.ts index 1b9124438a3..79c4c37486b 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/actions.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/actions.ts @@ -35,6 +35,7 @@ export function panelEditorCleanUp(): ThunkResult { return (dispatch, getStore) => { const dashboard = getStore().dashboard.getModel(); const { getPanel, getSourcePanel, querySubscription, shouldDiscardChanges } = getStore().panelEditorNew; + if (!shouldDiscardChanges) { const panel = getPanel(); const modifiedSaveModel = panel.getSaveModel(); @@ -47,7 +48,7 @@ export function panelEditorCleanUp(): ThunkResult { sourcePanel.restoreModel(modifiedSaveModel); if (panelTypeChanged) { - dispatch(panelModelAndPluginReady({ panelId: sourcePanel.id, plugin: panel.plugin })); + dispatch(panelModelAndPluginReady({ panelId: sourcePanel.id, plugin: panel.plugin! })); } // Resend last query result on source panel query runner @@ -57,8 +58,13 @@ export function panelEditorCleanUp(): ThunkResult { }, 20); } - dashboard.exitPanelEditor(); - querySubscription.unsubscribe(); + if (dashboard) { + dashboard.exitPanelEditor(); + } + + if (querySubscription) { + querySubscription.unsubscribe(); + } dispatch(cleanUpEditPanel()); dispatch(closeCompleted()); diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index 5ed258cde57..d9a0a14ea39 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -29,7 +29,7 @@ export interface OwnProps { } export interface ConnectedProps { - plugin?: PanelPlugin; + plugin?: PanelPlugin | null; } export interface DispatchProps { diff --git a/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx b/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx index 1dd7bb66582..b419b95e1ab 100644 --- a/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx @@ -31,7 +31,7 @@ interface OwnProps { } interface ConnectedProps { - angularComponent: AngularComponent; + angularComponent?: AngularComponent | null; } interface DispatchProps { diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx index 2859481cfd0..e08ce67fbef 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx @@ -22,7 +22,7 @@ export interface Props { title?: string; description?: string; scopedVars?: ScopedVars; - angularComponent?: AngularComponent; + angularComponent?: AngularComponent | null; links?: DataLink[]; error?: string; isFullscreen: boolean; @@ -108,7 +108,7 @@ export class PanelHeader extends Component { return ( {notice.inspect ? ( -
this.openInspect(e, notice.inspect)}> +
this.openInspect(e, notice.inspect!)}>
) : ( diff --git a/public/app/features/dashboard/utils/getPanelMenu.ts b/public/app/features/dashboard/utils/getPanelMenu.ts index 0f638d905b9..abac2f624ac 100644 --- a/public/app/features/dashboard/utils/getPanelMenu.ts +++ b/public/app/features/dashboard/utils/getPanelMenu.ts @@ -15,7 +15,7 @@ import { PanelCtrl } from '../../panel/panel_ctrl'; export function getPanelMenu( dashboard: DashboardModel, panel: PanelModel, - angularComponent?: AngularComponent + angularComponent?: AngularComponent | null ): PanelMenuItem[] { const onViewPanel = (event: React.MouseEvent) => { event.preventDefault(); @@ -127,7 +127,7 @@ export function getPanelMenu( shortcut: 'p s', }); - if (contextSrv.hasAccessToExplore() && !panel.plugin.meta.skipDataQuery) { + if (contextSrv.hasAccessToExplore() && !(panel.plugin && panel.plugin.meta.skipDataQuery)) { menu.push({ text: 'Explore', iconClassName: 'gicon gicon-explore', diff --git a/scripts/ci-frontend-metrics.sh b/scripts/ci-frontend-metrics.sh index 748d1a3aeea..6b066307a90 100755 --- a/scripts/ci-frontend-metrics.sh +++ b/scripts/ci-frontend-metrics.sh @@ -3,7 +3,7 @@ echo -e "Collecting code stats (typescript errors & more)" -ERROR_COUNT_LIMIT=816 +ERROR_COUNT_LIMIT=812 DIRECTIVES_LIMIT=172 CONTROLLERS_LIMIT=139