diff --git a/superset-frontend/.storybook/shared/Expandable.tsx b/superset-frontend/.storybook/shared/Expandable.tsx index 37b177f325b..cea87063bd7 100644 --- a/superset-frontend/.storybook/shared/Expandable.tsx +++ b/superset-frontend/.storybook/shared/Expandable.tsx @@ -17,45 +17,32 @@ * under the License. */ -import { Component, ReactNode } from 'react'; +import { useState, useCallback, ReactNode } from 'react'; export type Props = { children: ReactNode; expandableWhat?: string; }; -type State = { - open: boolean; -}; +export default function Expandable({ children, expandableWhat }: Props) { + const [open, setOpen] = useState(false); -export default class Expandable extends Component { - constructor(props: Props) { - super(props); - this.state = { open: false }; - this.handleToggle = this.handleToggle.bind(this); - } + const handleToggle = useCallback(() => { + setOpen(prevOpen => !prevOpen); + }, []); - handleToggle() { - this.setState(({ open }) => ({ open: !open })); - } - - render() { - const { open } = this.state; - const { children, expandableWhat } = this.props; - - return ( -
- -
-
- {open ? children : null} -
- ); - } + return ( +
+ +
+
+ {open ? children : null} +
+ ); } diff --git a/superset-frontend/.storybook/shared/VerifyCORS.tsx b/superset-frontend/.storybook/shared/VerifyCORS.tsx index 78fb78c6fb2..1803439bbb5 100644 --- a/superset-frontend/.storybook/shared/VerifyCORS.tsx +++ b/superset-frontend/.storybook/shared/VerifyCORS.tsx @@ -17,8 +17,8 @@ * under the License. */ -import { Component, ReactNode } from 'react'; -import { t } from '@apache-superset/core/translation'; +import { useState, useEffect, useCallback, useRef, ReactNode } from 'react'; +import { t } from '@apache-superset/core'; import { SupersetClient, Method, @@ -36,12 +36,6 @@ export type Props = { postPayload?: string; }; -type State = { - didVerify: boolean; - error?: Error | SupersetApiError; - payload?: object; -}; - export const renderError = (error: Error) => (
The following error occurred, make sure you have
@@ -54,29 +48,37 @@ export const renderError = (error: Error) => (
); -export default class VerifyCORS extends Component { - constructor(props: Props) { - super(props); - this.state = { didVerify: false }; - this.handleVerify = this.handleVerify.bind(this); - } +export default function VerifyCORS({ + children, + endpoint, + host, + method, + postPayload, +}: Props): JSX.Element { + const [didVerify, setDidVerify] = useState(false); + const [error, setError] = useState( + undefined, + ); + const [payload, setPayload] = useState(undefined); - componentDidUpdate(prevProps: Props) { - const { endpoint, host, postPayload, method } = this.props; + const prevPropsRef = useRef({ endpoint, host, postPayload, method }); + + useEffect(() => { + const prevProps = prevPropsRef.current; if ( - (this.state.didVerify || this.state.error) && + (didVerify || error) && (prevProps.endpoint !== endpoint || prevProps.host !== host || prevProps.postPayload !== postPayload || prevProps.method !== method) ) { - // eslint-disable-next-line react/no-did-update-set-state - this.setState({ didVerify: false, error: undefined }); + setDidVerify(false); + setError(undefined); } - } + prevPropsRef.current = { endpoint, host, postPayload, method }; + }, [endpoint, host, postPayload, method, didVerify, error]); - handleVerify() { - const { endpoint, host, postPayload, method } = this.props; + const handleVerify = useCallback(() => { SupersetClient.reset(); SupersetClient.configure({ credentials: 'include', @@ -94,43 +96,40 @@ export default class VerifyCORS extends Component { } return { error: 'Must provide valid endpoint and payload.' }; }) - .then(result => - this.setState({ didVerify: true, error: undefined, payload: result }), - ) - .catch(error => this.setState({ error })); - } + .then(result => { + setDidVerify(true); + setError(undefined); + setPayload(result); + }) + .catch(err => setError(err)); + }, [endpoint, host, method, postPayload]); - render() { - const { didVerify, error, payload } = this.state; - const { children } = this.props; - - return didVerify ? ( - children({ payload }) - ) : ( -
-
- This example requires CORS requests from this domain.
-
- 1) enable CORS requests in your Superset App from{' '} - {`${window.location.origin}`} -
- 2) configure your Superset App host name below
- 3) click below to verify authentication. You may debug CORS further - using the `@superset-ui/connection` story.
-
- -
-
-
- - {error && ( -
- -
- )} + return didVerify ? ( + <>{children({ payload })} + ) : ( +
+
+ This example requires CORS requests from this domain.
+
+ 1) enable CORS requests in your Superset App from{' '} + {`${window.location.origin}`} +
+ 2) configure your Superset App host name below
+ 3) click below to verify authentication. You may debug CORS further + using the `@superset-ui/connection` story.
+
+ +
+
- ); - } + + {error && ( +
+ +
+ )} +
+ ); } diff --git a/superset-frontend/.storybook/shared/createQueryStory.tsx b/superset-frontend/.storybook/shared/createQueryStory.tsx index 3a322e57345..e047201d3f2 100644 --- a/superset-frontend/.storybook/shared/createQueryStory.tsx +++ b/superset-frontend/.storybook/shared/createQueryStory.tsx @@ -22,6 +22,7 @@ import { ChartDataProvider, SupersetClient, } from '@superset-ui/core'; +import { supersetTheme } from '@apache-superset/core/ui'; import Expandable from './Expandable'; import VerifyCORS, { renderError } from './VerifyCORS'; @@ -64,6 +65,7 @@ export default function createQueryStory({ return ( <> ( ( ( {size => ( ( ( ( ( ( - + ); withNoResults.storyName = 'With no results'; withNoResults.args = { @@ -221,7 +234,12 @@ export const withNoResultsAndMedium = ({ width: string; height: string; }) => ( - + ); withNoResultsAndMedium.storyName = 'With no results and medium'; @@ -241,7 +259,12 @@ export const withNoResultsAndSmall = ({ width: string; height: string; }) => ( - + ); withNoResultsAndSmall.storyName = 'With no results and small'; withNoResultsAndSmall.args = { diff --git a/superset-frontend/packages/superset-ui-core/src/number-format/stories/NumberFormat.stories.tsx b/superset-frontend/packages/superset-ui-core/src/number-format/stories/NumberFormat.stories.tsx index 718a1f17cfb..f473a8f8df2 100644 --- a/superset-frontend/packages/superset-ui-core/src/number-format/stories/NumberFormat.stories.tsx +++ b/superset-frontend/packages/superset-ui-core/src/number-format/stories/NumberFormat.stories.tsx @@ -17,126 +17,108 @@ * under the License. */ -import { PureComponent } from 'react'; +import { useState, useCallback } from 'react'; import { formatNumber } from '@superset-ui/core'; -interface NumberFormatValidatorState { - formatString: string; - testValues: (number | null | undefined)[]; -} +const testValues: (number | null | undefined)[] = [ + 987654321, + 12345.6789, + 3000, + 400.14, + 70.00002, + 1, + 0, + -1, + -70.00002, + -400.14, + -3000, + -12345.6789, + -987654321, + Number.POSITIVE_INFINITY, + Number.NEGATIVE_INFINITY, + NaN, + null, + undefined, +]; -class NumberFormatValidator extends PureComponent< - Record, - NumberFormatValidatorState -> { - state: NumberFormatValidatorState = { - formatString: '.3~s', - testValues: [ - 987654321, - 12345.6789, - 3000, - 400.14, - 70.00002, - 1, - 0, - -1, - -70.00002, - -400.14, - -3000, - -12345.6789, - -987654321, - Number.POSITIVE_INFINITY, - Number.NEGATIVE_INFINITY, - NaN, - null, - undefined, - ], - }; +function NumberFormatValidator() { + const [formatString, setFormatString] = useState('.3~s'); - constructor(props: Record) { - super(props); + const handleFormatChange = useCallback( + (event: React.ChangeEvent) => { + setFormatString(event.target.value); + }, + [], + ); - this.handleFormatChange = this.handleFormatChange.bind(this); - } - - handleFormatChange(event: React.ChangeEvent) { - this.setState({ - formatString: event.target.value, - }); - } - - render() { - const { formatString, testValues } = this.state; - - return ( -
-
-
-

- This @superset-ui/number-format package enriches{' '} - d3-format - to handle invalid formats as well as edge case values. Use the - validator below to preview outputs from the specified format - string. See - - D3 Format Reference - - for how to write a D3 format string. -

-
-
-
-
-
-
-
- {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} - -
-
-
-
-
-
-
- - - - - - - - - {testValues.map((v, index) => ( - - - - - ))} - -
Input (number)Formatted output (string)
- {`${v}`} - - "{formatNumber(formatString, v)}" -
-
+ return ( +
+
+
+

+ This @superset-ui/number-format package enriches{' '} + d3-format + to handle invalid formats as well as edge case values. Use the + validator below to preview outputs from the specified format string. + See + + D3 Format Reference + + for how to write a D3 format string. +

- ); - } +
+
+
+
+
+ {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} + +
+
+
+
+
+
+
+ + + + + + + + + {testValues.map((v, index) => ( + + + + + ))} + +
Input (number)Formatted output (string)
+ {`${v}`} + + "{formatNumber(formatString, v)}" +
+
+
+
+ ); } export default { diff --git a/superset-frontend/packages/superset-ui-core/src/time-format/stories/TimeFormat.stories.tsx b/superset-frontend/packages/superset-ui-core/src/time-format/stories/TimeFormat.stories.tsx index 2798113b587..34ee21dee46 100644 --- a/superset-frontend/packages/superset-ui-core/src/time-format/stories/TimeFormat.stories.tsx +++ b/superset-frontend/packages/superset-ui-core/src/time-format/stories/TimeFormat.stories.tsx @@ -17,115 +17,96 @@ * under the License. */ -import { PureComponent } from 'react'; +import { useState, useCallback } from 'react'; import { formatTime } from '@superset-ui/core'; -interface TimeFormatValidatorState { - formatString: string; - testValues: (Date | number | null | undefined)[]; -} +const testValues: (Date | number | null | undefined)[] = [ + new Date(Date.UTC(1986, 5, 14, 8, 30, 53)), + new Date(Date.UTC(2001, 9, 27, 13, 45, 2, 678)), + new Date(Date.UTC(2009, 1, 1, 0, 0, 0)), + new Date(Date.UTC(2018, 1, 1, 10, 20, 33)), + 0, + null, + undefined, +]; -class TimeFormatValidator extends PureComponent< - Record, - TimeFormatValidatorState -> { - state: TimeFormatValidatorState = { - formatString: '%Y-%m-%d %H:%M:%S', - testValues: [ - new Date(Date.UTC(1986, 5, 14, 8, 30, 53)), - new Date(Date.UTC(2001, 9, 27, 13, 45, 2, 678)), - new Date(Date.UTC(2009, 1, 1, 0, 0, 0)), - new Date(Date.UTC(2018, 1, 1, 10, 20, 33)), - 0, - null, - undefined, - ], - }; +function TimeFormatValidator() { + const [formatString, setFormatString] = useState('%Y-%m-%d %H:%M:%S'); - constructor(props: Record) { - super(props); - this.handleFormatChange = this.handleFormatChange.bind(this); - } + const handleFormatChange = useCallback( + (event: React.ChangeEvent) => { + setFormatString(event.target.value); + }, + [], + ); - handleFormatChange(event: React.ChangeEvent) { - this.setState({ - formatString: event.target.value, - }); - } - - render() { - const { formatString, testValues } = this.state; - - return ( -
-
-
-

- This @superset-ui/time-format package enriches - d3-time-format to handle invalid formats as well as - edge case values. Use the validator below to preview outputs from - the specified format string. See   - - D3 Time Format Reference - -  for how to write a D3 time format string. -

-
-
-
-
-
-
-
- {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} - -
-
-
-
-
-
-
- - - - - - - - - {testValues.map((v, index) => ( - - - - - ))} - -
Input (time)Formatted output (string)
- - {v instanceof Date ? v.toUTCString() : `${v}`} - - - "{formatTime(formatString, v)}" -
-
+ return ( +
+
+
+

+ This @superset-ui/time-format package enriches + d3-time-format to handle invalid formats as well as + edge case values. Use the validator below to preview outputs from + the specified format string. See   + + D3 Time Format Reference + +  for how to write a D3 time format string. +

- ); - } +
+
+
+
+
+ {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} + +
+
+
+
+
+
+
+ + + + + + + + + {testValues.map((v, index) => ( + + + + + ))} + +
Input (time)Formatted output (string)
+ {v instanceof Date ? v.toUTCString() : `${v}`} + + "{formatTime(formatString, v)}" +
+
+
+
+ ); } export default { diff --git a/superset-frontend/plugins/legacy-plugin-chart-calendar/src/stories/LegacyPluginChartCalendar.stories.tsx b/superset-frontend/plugins/legacy-plugin-chart-calendar/src/stories/LegacyPluginChartCalendar.stories.tsx index a2a685e205a..6a8f0dd0e6d 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-calendar/src/stories/LegacyPluginChartCalendar.stories.tsx +++ b/superset-frontend/plugins/legacy-plugin-chart-calendar/src/stories/LegacyPluginChartCalendar.stories.tsx @@ -18,6 +18,7 @@ */ import { SuperChart } from '@superset-ui/core'; +import { supersetTheme } from '@apache-superset/core/ui'; import CalendarChartPlugin from '@superset-ui/legacy-plugin-chart-calendar'; import data from './data'; import { dummyDatasource, withResizableChartDemo } from '@storybook-shared'; @@ -100,6 +101,7 @@ export const Basic = ({ height: number; }) => ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( export const nullInTheMiddle = () => ( ( export const fixedRange = () => ( ( export const noFixedRange = () => ( ( ( ( ( ( ( ( ( ( ( ( forecastEnabled || !!row.Boston); return ( forecastEnabled || !!row.Boston); return ( ( ( ( ( ( ( ( ( ( ( ( ( diff --git a/superset-frontend/plugins/plugin-chart-word-cloud/src/stories/WordCloud.stories.tsx b/superset-frontend/plugins/plugin-chart-word-cloud/src/stories/WordCloud.stories.tsx index 89a747c09c7..abc4a6a8162 100644 --- a/superset-frontend/plugins/plugin-chart-word-cloud/src/stories/WordCloud.stories.tsx +++ b/superset-frontend/plugins/plugin-chart-word-cloud/src/stories/WordCloud.stories.tsx @@ -18,6 +18,7 @@ */ import { SuperChart } from '@superset-ui/core'; +import { supersetTheme } from '@apache-superset/core/ui'; import { WordCloudChartPlugin } from '@superset-ui/plugin-chart-word-cloud'; import { withResizableChartDemo } from '@storybook-shared'; import data from './data'; @@ -74,6 +75,7 @@ export const Basic = ({ height: number; }) => ( ( chartType="filter_range" width={width} height={height} + theme={supersetTheme} queriesData={[{ data: [{ min: 10, max: 100 }] }]} filterState={{ value: [10, 70] }} formData={{ diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.stories.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.stories.tsx index 30bc333a799..a052d63fc3f 100644 --- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.stories.tsx +++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.stories.tsx @@ -19,6 +19,7 @@ import { action } from '@storybook/addon-actions'; import { SuperChart, getChartTransformPropsRegistry } from '@superset-ui/core'; import { mockQueryDataForCountries } from 'spec/fixtures/mockNativeFilters'; +import { supersetTheme } from '@apache-superset/core/ui'; import SelectFilterPlugin from './index'; import transformProps from './transformProps'; @@ -52,6 +53,7 @@ export const Select = ({ chartType="filter_select" width={width} height={height} + theme={supersetTheme} queriesData={[{ data: mockQueryDataForCountries }]} formData={{ adhoc_filters: [],