From 6d402064310c477b3de43cf0a3d4caf05d741a91 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Wed, 11 Nov 2020 14:52:22 +0100 Subject: [PATCH] Dashboard: remove usage of Legacyforms (#28707) * refactor(dashboard): remove usage of legacyform components in sharemodal * refactor(dashboard): replace legacyform components * refactor(dashboard): remove ng-if and correct typo in content of sharesnapshot * feat(grafana-ui): set displayName prop for Switch component * refactor(dashboard): migrate TimePickerSettings legacyform components * refactor(queryoptions): migrate switch and input to nextgen components * refactor(sharesnapshot): prefer InlineFieldRow over gf-form-group * refactor(shareembed): styling fixes * refactor(timepickersettings): prefer double bang over nullish coalescing operator * fix(grafana-ui): switch uses id prop if passed in * feat: connect labels and switches with ids --- .../src/components/Switch/Switch.tsx | 7 ++- .../DashboardSettings/TimePickerSettings.tsx | 11 ++-- .../components/ShareModal/ShareEmbed.tsx | 37 ++++++------ .../components/ShareModal/ShareExport.tsx | 13 ++-- .../components/ShareModal/ShareLink.tsx | 40 +++++++------ .../components/ShareModal/ShareSnapshot.tsx | 49 ++++++++------- .../dashboard/panel_editor/QueryOptions.tsx | 60 ++++++++----------- 7 files changed, 102 insertions(+), 115 deletions(-) diff --git a/packages/grafana-ui/src/components/Switch/Switch.tsx b/packages/grafana-ui/src/components/Switch/Switch.tsx index bd59ad02cbd..108f7974370 100644 --- a/packages/grafana-ui/src/components/Switch/Switch.tsx +++ b/packages/grafana-ui/src/components/Switch/Switch.tsx @@ -70,20 +70,19 @@ export const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => { transition: transform 0.2s cubic-bezier(0.19, 1, 0.22, 1); } } - } `, }; }); export const Switch = React.forwardRef( - ({ value, checked, disabled = false, onChange, ...inputProps }, ref) => { + ({ value, checked, disabled = false, onChange, id, ...inputProps }, ref) => { if (checked) { deprecationWarning('Switch', 'checked prop', 'value'); } const theme = useTheme(); const styles = getSwitchStyles(theme); - const switchIdRef = useRef(uniqueId('switch-')); + const switchIdRef = useRef(id ? id : uniqueId('switch-')); return (
@@ -103,3 +102,5 @@ export const Switch = React.forwardRef( ); } ); + +Switch.displayName = 'Switch'; diff --git a/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx index 244bae5c440..217c714d4a2 100644 --- a/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { Input, LegacyForms, TimeZonePicker, Tooltip } from '@grafana/ui'; +import { InlineField, Input, Switch, TimeZonePicker, Tooltip } from '@grafana/ui'; import { rangeUtil, TimeZone } from '@grafana/data'; import isEmpty from 'lodash/isEmpty'; import { selectors } from '@grafana/e2e-selectors'; @@ -87,12 +87,9 @@ export class TimePickerSettings extends PureComponent {
- + + +
diff --git a/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx b/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx index fe2544b4cad..15fee2c307a 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx @@ -1,6 +1,5 @@ import React, { PureComponent } from 'react'; -import { LegacyForms, Icon } from '@grafana/ui'; -const { Select, Switch } = LegacyForms; +import { Select, Switch, Icon, InlineField } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { buildIframeHtml } from './utils'; @@ -82,24 +81,24 @@ export class ShareEmbed extends PureComponent {
- - -
- - +
-

The html code below can be pasted and included in another web page. Unless anonymous access is enabled, the user viewing that page need to be signed into grafana for the graph to load. diff --git a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx index 31f17c9d526..d6c23f88b6e 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx @@ -1,7 +1,6 @@ import React, { PureComponent } from 'react'; import { saveAs } from 'file-saver'; -import { Button, LegacyForms, Icon } from '@grafana/ui'; -const { Switch } = LegacyForms; +import { Button, InlineField, Switch, Icon } from '@grafana/ui'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal'; import { appEvents } from 'app/core/core'; @@ -93,13 +92,9 @@ export class ShareExport extends PureComponent {

- - + + +
-
+
Did you make a mistake?{' '} delete snapshot. @@ -291,8 +296,8 @@ export class ShareSnapshot extends PureComponent { return (

- The snapshot has now been deleted. If it you have already accessed it once, It might take up to an hour before - it is removed from browser caches or CDN caches. + The snapshot has now been deleted. If you have already accessed it once, it might take up to an hour before it + is removed from browser caches or CDN caches.

); diff --git a/public/app/features/dashboard/panel_editor/QueryOptions.tsx b/public/app/features/dashboard/panel_editor/QueryOptions.tsx index 3e990ed8a3a..89421689d4c 100644 --- a/public/app/features/dashboard/panel_editor/QueryOptions.tsx +++ b/public/app/features/dashboard/panel_editor/QueryOptions.tsx @@ -5,15 +5,7 @@ import React, { PureComponent, ChangeEvent, FocusEvent } from 'react'; import { rangeUtil, PanelData, DataSourceApi } from '@grafana/data'; // Components -import { - EventsWithValidation, - LegacyInputStatus, - LegacyForms, - ValidationEvents, - InlineFormLabel, - stylesFactory, -} from '@grafana/ui'; -const { Switch, Input } = LegacyForms; +import { Switch, Input, InlineField, InlineFormLabel, stylesFactory } from '@grafana/ui'; // Types import { PanelModel } from '../state'; @@ -21,18 +13,11 @@ import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOp import { config } from 'app/core/config'; import { css } from 'emotion'; -const timeRangeValidationEvents: ValidationEvents = { - [EventsWithValidation.onBlur]: [ - { - rule: value => { - if (!value) { - return true; - } - return rangeUtil.isValidTimeSpan(value); - }, - errorMessage: 'Not a valid timespan', - }, - ], +const timeRangeValidation = (value: string) => { + if (!value) { + return true; + } + return rangeUtil.isValidTimeSpan(value); }; const emptyToNull = (value: string) => { @@ -53,6 +38,8 @@ interface State { interval: string; hideTimeOverride: boolean; isOpen: boolean; + relativeTimeIsValid: boolean; + timeShiftIsValid: boolean; } export class QueryOptions extends PureComponent { @@ -67,6 +54,8 @@ export class QueryOptions extends PureComponent { interval: props.panel.interval || '', hideTimeOverride: props.panel.hideTimeOverride || false, isOpen: false, + relativeTimeIsValid: true, + timeShiftIsValid: true, }; } @@ -82,26 +71,30 @@ export class QueryOptions extends PureComponent { }); }; - onOverrideTime = (event: FocusEvent, status: LegacyInputStatus) => { + onOverrideTime = (event: FocusEvent) => { const { value } = event.target; const { panel } = this.props; const emptyToNullValue = emptyToNull(value); + const isValid = timeRangeValidation(value); - if (status === LegacyInputStatus.Valid && panel.timeFrom !== emptyToNullValue) { + if (isValid && panel.timeFrom !== emptyToNullValue) { panel.timeFrom = emptyToNullValue; panel.refresh(); } + this.setState({ relativeTimeIsValid: isValid }); }; - onTimeShift = (event: FocusEvent, status: LegacyInputStatus) => { + onTimeShift = (event: FocusEvent) => { const { value } = event.target; const { panel } = this.props; const emptyToNullValue = emptyToNull(value); + const isValid = timeRangeValidation(value); - if (status === LegacyInputStatus.Valid && panel.timeShift !== emptyToNullValue) { + if (isValid && panel.timeShift !== emptyToNullValue) { panel.timeShift = emptyToNullValue; panel.refresh(); } + this.setState({ timeShiftIsValid: isValid }); }; onToggleTimeOverride = () => { @@ -301,7 +294,7 @@ export class QueryOptions extends PureComponent { } render() { - const { hideTimeOverride } = this.state; + const { hideTimeOverride, relativeTimeIsValid, timeShiftIsValid } = this.state; const { relativeTime, timeShift, isOpen } = this.state; const styles = getStyles(); @@ -327,8 +320,7 @@ export class QueryOptions extends PureComponent { placeholder="1h" onChange={this.onRelativeTimeChange} onBlur={this.onOverrideTime} - validationEvents={timeRangeValidationEvents} - hideErrorMessage={true} + invalid={!relativeTimeIsValid} value={relativeTime} />
@@ -341,19 +333,15 @@ export class QueryOptions extends PureComponent { placeholder="1h" onChange={this.onTimeShiftChange} onBlur={this.onTimeShift} - validationEvents={timeRangeValidationEvents} - hideErrorMessage={true} + invalid={!timeShiftIsValid} value={timeShift} />
{(timeShift || relativeTime) && (
- + + +
)}