diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js index fdee143bf06..39666417afa 100644 --- a/superset-frontend/.eslintrc.js +++ b/superset-frontend/.eslintrc.js @@ -413,13 +413,6 @@ module.exports = { 'icons/no-fa-icons-usage': 'error', 'i18n-strings/no-template-vars': ['error', true], 'i18n-strings/sentence-case-buttons': 'error', - camelcase: [ - 'error', - { - allow: ['^UNSAFE_'], - properties: 'never', - }, - ], 'class-methods-use-this': 0, curly: 2, 'func-names': 0, diff --git a/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx b/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx index 50169092f48..a9bbda126a4 100644 --- a/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx +++ b/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx @@ -104,10 +104,10 @@ export default class CRUDCollection extends PureComponent< this.toggleExpand = this.toggleExpand.bind(this); } - UNSAFE_componentWillReceiveProps(nextProps: CRUDCollectionProps) { - if (nextProps.collection !== this.props.collection) { + componentDidUpdate(prevProps: CRUDCollectionProps) { + if (this.props.collection !== prevProps.collection) { const { collection, collectionArray } = createKeyedCollection( - nextProps.collection, + this.props.collection, ); this.setState(prevState => ({ collection, diff --git a/superset-frontend/src/dashboard/components/Dashboard.jsx b/superset-frontend/src/dashboard/components/Dashboard.jsx index e1881aa24cf..7d909b5154c 100644 --- a/superset-frontend/src/dashboard/components/Dashboard.jsx +++ b/superset-frontend/src/dashboard/components/Dashboard.jsx @@ -120,15 +120,12 @@ class Dashboard extends PureComponent { this.applyCharts(); } - componentDidUpdate() { + componentDidUpdate(prevProps) { this.applyCharts(); - } + const currentChartIds = getChartIdsFromLayout(prevProps.layout); + const nextChartIds = getChartIdsFromLayout(this.props.layout); - UNSAFE_componentWillReceiveProps(nextProps) { - const currentChartIds = getChartIdsFromLayout(this.props.layout); - const nextChartIds = getChartIdsFromLayout(nextProps.layout); - - if (this.props.dashboardId !== nextProps.dashboardId) { + if (prevProps.dashboardId !== this.props.dashboardId) { // single-page-app navigation check return; } @@ -140,7 +137,7 @@ class Dashboard extends PureComponent { newChartIds.forEach(newChartId => this.props.actions.addSliceToDashboard( newChartId, - getLayoutComponentFromChartId(nextProps.layout, newChartId), + getLayoutComponentFromChartId(this.props.layout, newChartId), ), ); } else if (currentChartIds.length > nextChartIds.length) { diff --git a/superset-frontend/src/dashboard/components/SliceAdder.tsx b/superset-frontend/src/dashboard/components/SliceAdder.tsx index 82c4cae9694..8a53da645fa 100644 --- a/superset-frontend/src/dashboard/components/SliceAdder.tsx +++ b/superset-frontend/src/dashboard/components/SliceAdder.tsx @@ -155,6 +155,23 @@ export function sortByComparator(attr: keyof Slice) { }; } +function getFilteredSortedSlices( + slices: SliceAdderProps['slices'], + searchTerm: string, + sortBy: keyof Slice, + showOnlyMyCharts: boolean, + userId: number, +) { + return Object.values(slices) + .filter(slice => + showOnlyMyCharts + ? slice?.owners?.find(owner => owner.id === userId) || + slice?.created_by?.id === userId + : true, + ) + .filter(createFilter(searchTerm, KEYS_TO_FILTERS)) + .sort(sortByComparator(sortBy)); +} class SliceAdder extends Component { private slicesRequest?: AbortController | Promise; @@ -195,19 +212,20 @@ class SliceAdder extends Component { ); } - UNSAFE_componentWillReceiveProps(nextProps: SliceAdderProps) { + componentDidUpdate(prevProps: SliceAdderProps) { const nextState: SliceAdderState = {} as SliceAdderState; - if (nextProps.lastUpdated !== this.props.lastUpdated) { - nextState.filteredSlices = this.getFilteredSortedSlices( - nextProps.slices, + if (this.props.lastUpdated !== prevProps.lastUpdated) { + nextState.filteredSlices = getFilteredSortedSlices( + this.props.slices, this.state.searchTerm, this.state.sortBy, this.state.showOnlyMyCharts, + this.props.userId, ); } - if (nextProps.selectedSliceIds !== this.props.selectedSliceIds) { - nextState.selectedSliceIdsSet = new Set(nextProps.selectedSliceIds); + if (prevProps.selectedSliceIds !== this.props.selectedSliceIds) { + nextState.selectedSliceIdsSet = new Set(this.props.selectedSliceIds); } if (Object.keys(nextState).length) { @@ -227,23 +245,6 @@ class SliceAdder extends Component { } } - getFilteredSortedSlices( - slices: SliceAdderProps['slices'], - searchTerm: string, - sortBy: keyof Slice, - showOnlyMyCharts: boolean, - ) { - return Object.values(slices) - .filter(slice => - showOnlyMyCharts - ? slice?.owners?.find(owner => owner.id === this.props.userId) || - slice?.created_by?.id === this.props.userId - : true, - ) - .filter(createFilter(searchTerm, KEYS_TO_FILTERS)) - .sort(sortByComparator(sortBy)); - } - handleChange = debounce(value => { this.searchUpdated(value); this.slicesRequest = this.props.fetchSlices( @@ -256,11 +257,12 @@ class SliceAdder extends Component { searchUpdated(searchTerm: string) { this.setState(prevState => ({ searchTerm, - filteredSlices: this.getFilteredSortedSlices( + filteredSlices: getFilteredSortedSlices( this.props.slices, searchTerm, prevState.sortBy, prevState.showOnlyMyCharts, + this.props.userId, ), })); } @@ -268,11 +270,12 @@ class SliceAdder extends Component { handleSelect(sortBy: keyof Slice) { this.setState(prevState => ({ sortBy, - filteredSlices: this.getFilteredSortedSlices( + filteredSlices: getFilteredSortedSlices( this.props.slices, prevState.searchTerm, sortBy, prevState.showOnlyMyCharts, + this.props.userId, ), })); this.slicesRequest = this.props.fetchSlices( @@ -340,11 +343,12 @@ class SliceAdder extends Component { } this.setState(prevState => ({ showOnlyMyCharts, - filteredSlices: this.getFilteredSortedSlices( + filteredSlices: getFilteredSortedSlices( this.props.slices, prevState.searchTerm, prevState.sortBy, showOnlyMyCharts, + this.props.userId, ), })); setItem(LocalStorageKeys.DashboardEditorShowOnlyMyCharts, showOnlyMyCharts); diff --git a/superset-frontend/src/dashboard/components/menu/WithPopoverMenu.tsx b/superset-frontend/src/dashboard/components/menu/WithPopoverMenu.tsx index 2d7005b526d..0bd01bbdc95 100644 --- a/superset-frontend/src/dashboard/components/menu/WithPopoverMenu.tsx +++ b/superset-frontend/src/dashboard/components/menu/WithPopoverMenu.tsx @@ -129,12 +129,12 @@ export default class WithPopoverMenu extends PureComponent< this.handleClick = this.handleClick.bind(this); } - UNSAFE_componentWillReceiveProps(nextProps: WithPopoverMenuProps) { - if (nextProps.editMode && nextProps.isFocused && !this.state.isFocused) { + componentDidUpdate(prevProps: WithPopoverMenuProps) { + if (this.props.editMode && this.props.isFocused && !this.state.isFocused) { document.addEventListener('click', this.handleClick); document.addEventListener('drag', this.handleClick); this.setState({ isFocused: true }); - } else if (this.state.isFocused && !nextProps.editMode) { + } else if (this.state.isFocused && !this.props.editMode) { document.removeEventListener('click', this.handleClick); document.removeEventListener('drag', this.handleClick); this.setState({ isFocused: false }); diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx index dc95723fbce..6a39f78214f 100644 --- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx @@ -107,17 +107,23 @@ class AnnotationLayerControl extends PureComponent { AnnotationLayer.preload(); } - UNSAFE_componentWillReceiveProps(nextProps: Props) { - const { name, annotationError, validationErrors, value } = nextProps; - if (Object.keys(annotationError).length && !validationErrors.length) { - this.props.actions.setControlValue( - name, - value, - Object.keys(annotationError), - ); - } - if (!Object.keys(annotationError).length && validationErrors.length) { - this.props.actions.setControlValue(name, value, []); + componentDidUpdate(prevProps: Props) { + const { name, annotationError, validationErrors, value } = this.props; + if ( + (Object.keys(annotationError).length && !validationErrors.length) || + (!Object.keys(annotationError).length && validationErrors.length) + ) { + if ( + annotationError !== prevProps.annotationError || + validationErrors !== prevProps.validationErrors || + value !== prevProps.value + ) { + this.props.actions.setControlValue( + name, + value, + Object.keys(annotationError), + ); + } } } diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.jsx index b88d0244fb4..095ba00d737 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.jsx +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.jsx @@ -87,10 +87,48 @@ function isDictionaryForAdhocFilter(value) { return value && !(value instanceof AdhocFilter) && value.expressionType; } +function optionsForSelect(props) { + const options = [ + ...props.columns, + ...ensureIsArray(props.selectedMetrics).map( + metric => + metric && + (typeof metric === 'string' + ? { saved_metric_name: metric } + : new AdhocMetric(metric)), + ), + ].filter(option => option); + + return options + .reduce((results, option) => { + if (option.saved_metric_name) { + results.push({ + ...option, + filterOptionName: option.saved_metric_name, + }); + } else if (option.column_name) { + results.push({ + ...option, + filterOptionName: `_col_${option.column_name}`, + }); + } else if (option instanceof AdhocMetric) { + results.push({ + ...option, + filterOptionName: `_adhocmetric_${option.label}`, + }); + } + return results; + }, []) + .sort((a, b) => + (a.saved_metric_name || a.column_name || a.label).localeCompare( + b.saved_metric_name || b.column_name || b.label, + ), + ); +} + class AdhocFilterControl extends Component { constructor(props) { super(props); - this.optionsForSelect = this.optionsForSelect.bind(this); this.onRemoveFilter = this.onRemoveFilter.bind(this); this.onNewFilter = this.onNewFilter.bind(this); this.onFilterEdit = this.onFilterEdit.bind(this); @@ -126,7 +164,7 @@ class AdhocFilterControl extends Component { ); this.state = { values: filters, - options: this.optionsForSelect(this.props), + options: optionsForSelect(this.props), partitionColumn: null, }; } @@ -173,13 +211,13 @@ class AdhocFilterControl extends Component { } } - UNSAFE_componentWillReceiveProps(nextProps) { - if (this.props.columns !== nextProps.columns) { - this.setState({ options: this.optionsForSelect(nextProps) }); + componentDidUpdate(prevProps) { + if (this.props.columns !== prevProps.columns) { + this.setState({ options: optionsForSelect(this.props) }); } - if (this.props.value !== nextProps.value) { + if (this.props.value !== prevProps.value) { this.setState({ - values: (nextProps.value || []).map(filter => + values: (this.props.value || []).map(filter => isDictionaryForAdhocFilter(filter) ? new AdhocFilter(filter) : filter, ), }); @@ -298,45 +336,6 @@ class AdhocFilterControl extends Component { return null; } - optionsForSelect(props) { - const options = [ - ...props.columns, - ...ensureIsArray(props.selectedMetrics).map( - metric => - metric && - (typeof metric === 'string' - ? { saved_metric_name: metric } - : new AdhocMetric(metric)), - ), - ].filter(option => option); - - return options - .reduce((results, option) => { - if (option.saved_metric_name) { - results.push({ - ...option, - filterOptionName: option.saved_metric_name, - }); - } else if (option.column_name) { - results.push({ - ...option, - filterOptionName: `_col_${option.column_name}`, - }); - } else if (option instanceof AdhocMetric) { - results.push({ - ...option, - filterOptionName: `_adhocmetric_${option.label}`, - }); - } - return results; - }, []) - .sort((a, b) => - (a.saved_metric_name || a.column_name || a.label).localeCompare( - b.saved_metric_name || b.column_name || b.label, - ), - ); - } - addNewFilterPopoverTrigger(trigger) { return (