This is an automated email from the ASF dual-hosted git repository. rusackas pushed a commit to branch chore/enable-additional-oxlint-rules in repository https://gitbox.apache.org/repos/asf/superset.git
commit c9929fcc130199ec2fd43942ef3b86546d830cf4 Author: Evan Rusackas <[email protected]> AuthorDate: Fri Feb 20 17:01:38 2026 -0800 chore(frontend): enable additional oxlint rules for better code hygiene Enable 17 new oxlint rules that enforce best practices: **Zero-violation rules (enabled as errors):** - eslint/no-useless-constructor - Remove empty constructors - eslint/no-else-return - Unnecessary else after return - eslint/no-array-constructor - Use [] instead of new Array() - eslint/no-new-wrappers - Don't use new String/Number/Boolean() - eslint/no-regex-spaces - Use {n} instead of multiple spaces - eslint/no-object-constructor - Use {} instead of new Object() - unicorn/no-length-as-slice-end - Don't pass .length to .slice() end - unicorn/no-useless-spread - Remove unnecessary spreads - unicorn/no-thenable - Don't export .then on non-Promises - unicorn/escape-case - Consistent escape character casing **Small fix rules (auto-fixed violations):** - unicorn/prefer-array-flat-map - Use .flatMap() instead of .map().flat() - unicorn/prefer-array-some - Use .some() instead of .findIndex() !== -1 - unicorn/throw-new-error - Use throw new Error() not throw Error() - unicorn/prefer-negative-index - Use .at(-1) for negative indices - unicorn/prefer-math-trunc - Use Math.trunc() instead of | 0 Also adds the oxc plugin to enable additional rule coverage (193 -> 205 rules). Co-Authored-By: Claude Opus 4.5 <[email protected]> --- superset-frontend/oxlint.json | 25 ++- .../src/shared-controls/mixins.tsx | 4 +- .../src/shared-controls/sharedControls.tsx | 14 +- .../src/components/MetadataBar/ContentConfig.tsx | 2 +- .../src/components/MetadataBar/MetadataBar.tsx | 4 +- .../src/TTestTable.tsx | 2 +- .../src/controlPanel.tsx | 48 +++--- .../src/transformProps.ts | 172 ++++++++++----------- .../src/components/Handlebars/HandlebarsViewer.tsx | 2 +- .../plugin-chart-table/src/DataTable/DataTable.tsx | 1 + .../plugin-chart-table/src/controlPanel.tsx | 48 +++--- .../plugin-chart-table/src/transformProps.ts | 164 ++++++++++---------- superset-frontend/scripts/check-custom-rules.js | 6 +- .../src/SqlLab/reducers/getInitialState.ts | 2 +- .../src/components/DatabaseSelector/index.tsx | 4 +- .../src/components/GridTable/Header.tsx | 5 +- superset-frontend/src/components/ListView/utils.ts | 5 +- .../src/components/MessageToasts/reducers.ts | 2 +- .../RefreshFrequency/RefreshFrequencySelect.tsx | 4 +- .../components/nativeFilters/FilterBar/state.ts | 2 +- .../FiltersConfigForm/FiltersConfigForm.tsx | 2 +- .../src/dashboard/util/getOverwriteItems.ts | 2 +- .../src/dashboard/util/isValidChild.test.ts | 2 +- .../AnnotationLayerControl/AnnotationLayer.tsx | 2 +- .../controls/SelectAsyncControl/index.tsx | 2 +- .../explore/components/controls/SelectControl.tsx | 2 +- superset-frontend/src/views/CRUD/utils.tsx | 25 ++- 27 files changed, 281 insertions(+), 272 deletions(-) diff --git a/superset-frontend/oxlint.json b/superset-frontend/oxlint.json index 942965a865..6fa1bbf125 100644 --- a/superset-frontend/oxlint.json +++ b/superset-frontend/oxlint.json @@ -1,6 +1,14 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", - "plugins": ["import", "react", "jest", "jsx-a11y", "typescript", "unicorn"], + "plugins": [ + "import", + "react", + "jest", + "jsx-a11y", + "typescript", + "unicorn", + "oxc" + ], "env": { "browser": true, "node": true, @@ -73,6 +81,12 @@ "as-needed", { "requireReturnForObjectLiteral": false } ], + "no-useless-constructor": "error", + "no-else-return": "error", + "no-array-constructor": "error", + "no-new-wrappers": "error", + "no-regex-spaces": "error", + "no-object-constructor": "error", // === Import plugin rules === "import/no-unresolved": "error", @@ -256,6 +270,15 @@ "unicorn/no-new-array": "error", "unicorn/no-invalid-remove-event-listener": "error", "unicorn/no-useless-length-check": "error", + "unicorn/no-length-as-slice-end": "error", + "unicorn/no-useless-spread": "error", + "unicorn/no-thenable": "error", + "unicorn/escape-case": "error", + "unicorn/prefer-array-flat-map": "error", + "unicorn/prefer-array-some": "error", + "unicorn/throw-new-error": "error", + "unicorn/prefer-negative-index": "error", + "unicorn/prefer-math-trunc": "error", "unicorn/filename-case": "off", "unicorn/prevent-abbreviations": "off", "unicorn/no-null": "off", diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/mixins.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/mixins.tsx index 19310b83c8..6587723cc7 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/mixins.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/mixins.tsx @@ -80,9 +80,9 @@ export const datePickerInAdhocFilterMixin: Pick< // 2) there was a time filter in adhoc filters if ( state?.controls?.time_range?.value || - ensureIsArray(control.value).findIndex( + ensureIsArray(control.value).some( (flt: any) => flt?.operator === 'TEMPORAL_RANGE', - ) > -1 + ) ) { return undefined; } diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx index 0b9953b95a..bf087565ab 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx @@ -443,14 +443,12 @@ const order_by_cols: SharedControlConfig<'SelectControl'> = { default: [], shouldMapStateToProps: () => true, mapStateToProps: ({ datasource }) => ({ - choices: (datasource?.columns || []) - .map(col => - [true, false].map(asc => [ - JSON.stringify([col.column_name, asc]), - `${getColumnLabel(col.column_name)} [${asc ? 'asc' : 'desc'}]`, - ]), - ) - .flat(), + choices: (datasource?.columns || []).flatMap(col => + [true, false].map(asc => [ + JSON.stringify([col.column_name, asc]), + `${getColumnLabel(col.column_name)} [${asc ? 'asc' : 'desc'}]`, + ]), + ), }), resetOnHide: false, }; diff --git a/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/ContentConfig.tsx b/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/ContentConfig.tsx index a4a9f14f40..1291538200 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/ContentConfig.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/ContentConfig.tsx @@ -132,7 +132,7 @@ const config = (contentType: ContentType) => { }; default: - throw Error(`Invalid type provided: ${type}`); + throw new Error(`Invalid type provided: ${type}`); } }; diff --git a/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx b/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx index 3f0f0e3a07..ccfca5028c 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx @@ -187,10 +187,10 @@ const MetadataBar = ({ items, tooltipPlacement = 'top' }: MetadataBarProps) => { const sortedItems = uniqueItems.sort((a, b) => ORDER[a.type] - ORDER[b.type]); const count = sortedItems.length; if (count < MIN_NUMBER_ITEMS) { - throw Error('The minimum number of items for the metadata bar is 2.'); + throw new Error('The minimum number of items for the metadata bar is 2.'); } if (count > MAX_NUMBER_ITEMS) { - throw Error('The maximum number of items for the metadata bar is 6.'); + throw new Error('The maximum number of items for the metadata bar is 6.'); } const onResize = useCallback( diff --git a/superset-frontend/plugins/legacy-plugin-chart-paired-t-test/src/TTestTable.tsx b/superset-frontend/plugins/legacy-plugin-chart-paired-t-test/src/TTestTable.tsx index abc2a2ccff..95922fd32d 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-paired-t-test/src/TTestTable.tsx +++ b/superset-frontend/plugins/legacy-plugin-chart-paired-t-test/src/TTestTable.tsx @@ -181,7 +181,7 @@ class TTestTable extends Component<TTestTableProps, TTestTableState> { const { control, liftValues, pValues } = this.state; if (!Array.isArray(groups) || groups.length === 0) { - throw Error('Group by param is required'); + throw new Error('Group by param is required'); } // Render column header for each group diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx index a84a466e20..993bdf56f8 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx @@ -87,31 +87,29 @@ function getQueryMode(controls: ControlStateMapping): QueryMode { } const processComparisonColumns = (columns: any[], suffix: string) => - columns - .map(col => { - if (!col.label.includes(suffix)) { - return [ - { - label: `${t('Main')} ${col.label}`, - value: `${t('Main')} ${col.value}`, - }, - { - label: `# ${col.label}`, - value: `# ${col.value}`, - }, - { - label: `△ ${col.label}`, - value: `△ ${col.value}`, - }, - { - label: `% ${col.label}`, - value: `% ${col.value}`, - }, - ]; - } - return []; - }) - .flat(); + columns.flatMap(col => { + if (!col.label.includes(suffix)) { + return [ + { + label: `${t('Main')} ${col.label}`, + value: `${t('Main')} ${col.value}`, + }, + { + label: `# ${col.label}`, + value: `# ${col.value}`, + }, + { + label: `△ ${col.label}`, + value: `△ ${col.value}`, + }, + { + label: `% ${col.label}`, + value: `% ${col.value}`, + }, + ]; + } + return []; + }); /** * Visibility check diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/transformProps.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/transformProps.ts index d793f2c27a..c22b6ff46c 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/transformProps.ts @@ -216,93 +216,91 @@ const processComparisonColumns = ( props: TableChartProps, comparisonSuffix: string, ) => - columns - .map(col => { - const { - datasource: { columnFormats, currencyFormats }, - rawFormData: { column_config: columnConfig = {} }, - } = props; - const savedFormat = columnFormats?.[col.key]; - const savedCurrency = currencyFormats?.[col.key]; - const originalLabel = col.label; - if ( - (col.isMetric || col.isPercentMetric) && - !col.key.includes(comparisonSuffix) && - col.isNumeric - ) { - return [ - { - ...col, - originalLabel, - metricName: col.key, - label: t('Main'), - key: `${t('Main')} ${col.key}`, - config: getComparisonColConfig(t('Main'), col.key, columnConfig), - formatter: getComparisonColFormatter( - t('Main'), - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - { - ...col, - originalLabel, - metricName: col.key, - label: `#`, - key: `# ${col.key}`, - config: getComparisonColConfig(`#`, col.key, columnConfig), - formatter: getComparisonColFormatter( - `#`, - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - { - ...col, - originalLabel, - metricName: col.key, - label: `△`, - key: `△ ${col.key}`, - config: getComparisonColConfig(`△`, col.key, columnConfig), - formatter: getComparisonColFormatter( - `△`, - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - { - ...col, - originalLabel, - metricName: col.key, - label: `%`, - key: `% ${col.key}`, - config: getComparisonColConfig(`%`, col.key, columnConfig), - formatter: getComparisonColFormatter( - `%`, - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - ]; - } - if ( - !col.isMetric && - !col.isPercentMetric && - !col.key.includes(comparisonSuffix) - ) { - return [col]; - } - return []; - }) - .flat(); + columns.flatMap(col => { + const { + datasource: { columnFormats, currencyFormats }, + rawFormData: { column_config: columnConfig = {} }, + } = props; + const savedFormat = columnFormats?.[col.key]; + const savedCurrency = currencyFormats?.[col.key]; + const originalLabel = col.label; + if ( + (col.isMetric || col.isPercentMetric) && + !col.key.includes(comparisonSuffix) && + col.isNumeric + ) { + return [ + { + ...col, + originalLabel, + metricName: col.key, + label: t('Main'), + key: `${t('Main')} ${col.key}`, + config: getComparisonColConfig(t('Main'), col.key, columnConfig), + formatter: getComparisonColFormatter( + t('Main'), + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + { + ...col, + originalLabel, + metricName: col.key, + label: `#`, + key: `# ${col.key}`, + config: getComparisonColConfig(`#`, col.key, columnConfig), + formatter: getComparisonColFormatter( + `#`, + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + { + ...col, + originalLabel, + metricName: col.key, + label: `△`, + key: `△ ${col.key}`, + config: getComparisonColConfig(`△`, col.key, columnConfig), + formatter: getComparisonColFormatter( + `△`, + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + { + ...col, + originalLabel, + metricName: col.key, + label: `%`, + key: `% ${col.key}`, + config: getComparisonColConfig(`%`, col.key, columnConfig), + formatter: getComparisonColFormatter( + `%`, + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + ]; + } + if ( + !col.isMetric && + !col.isPercentMetric && + !col.key.includes(comparisonSuffix) + ) { + return [col]; + } + return []; + }); const serverPageLengthMap = new Map(); diff --git a/superset-frontend/plugins/plugin-chart-handlebars/src/components/Handlebars/HandlebarsViewer.tsx b/superset-frontend/plugins/plugin-chart-handlebars/src/components/Handlebars/HandlebarsViewer.tsx index 006409c6ec..19f2193c51 100644 --- a/superset-frontend/plugins/plugin-chart-handlebars/src/components/Handlebars/HandlebarsViewer.tsx +++ b/superset-frontend/plugins/plugin-chart-handlebars/src/components/Handlebars/HandlebarsViewer.tsx @@ -87,7 +87,7 @@ Handlebars.registerHelper('dateFormat', function (context, block) { Handlebars.registerHelper('stringify', (obj: any, obj2: any) => { // calling without an argument if (obj2 === undefined) - throw Error('Please call with an object. Example: `stringify myObj`'); + throw new Error('Please call with an object. Example: `stringify myObj`'); return isPlainObject(obj) ? JSON.stringify(obj) : String(obj); }); diff --git a/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx b/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx index 553a260859..7bc0e8aa8d 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx @@ -489,6 +489,7 @@ export default typedMemo(function DataTable<D extends object>({ function hashString(s: string): string { let h = 0; for (let i = 0; i < s.length; i += 1) { + // oxlint-disable-next-line unicorn/prefer-math-trunc -- | 0 is intentional for 32-bit integer wrapping in hash h = (h * 31 + s.charCodeAt(i)) | 0; } return String(h); diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx index 7de658c718..c951887175 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx @@ -189,31 +189,29 @@ const percentMetricCalculationControl: ControlConfig<'SelectControl'> = { }; const processComparisonColumns = (columns: any[], suffix: string) => - columns - .map(col => { - if (!col.label.includes(suffix)) { - return [ - { - label: `${t('Main')} ${col.label}`, - value: `${t('Main')} ${col.value}`, - }, - { - label: `# ${col.label}`, - value: `# ${col.value}`, - }, - { - label: `△ ${col.label}`, - value: `△ ${col.value}`, - }, - { - label: `% ${col.label}`, - value: `% ${col.value}`, - }, - ]; - } - return []; - }) - .flat(); + columns.flatMap(col => { + if (!col.label.includes(suffix)) { + return [ + { + label: `${t('Main')} ${col.label}`, + value: `${t('Main')} ${col.value}`, + }, + { + label: `# ${col.label}`, + value: `# ${col.value}`, + }, + { + label: `△ ${col.label}`, + value: `△ ${col.value}`, + }, + { + label: `% ${col.label}`, + value: `% ${col.value}`, + }, + ]; + } + return []; + }); /* Options for row limit control diff --git a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts index 08e832fce6..7edd806cf4 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts @@ -384,89 +384,87 @@ const processComparisonColumns = ( props: TableChartProps, comparisonSuffix: string, ) => - columns - .map(col => { - const { - datasource: { columnFormats, currencyFormats }, - rawFormData: { column_config: columnConfig = {} }, - } = props; - const savedFormat = columnFormats?.[col.key]; - const savedCurrency = currencyFormats?.[col.key]; - const originalLabel = col.label; - if ( - (col.isMetric || col.isPercentMetric) && - !col.key.includes(comparisonSuffix) && - col.isNumeric - ) { - return [ - { - ...col, - originalLabel, - label: t('Main'), - key: `${t('Main')} ${col.key}`, - config: getComparisonColConfig(t('Main'), col.key, columnConfig), - formatter: getComparisonColFormatter( - t('Main'), - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - { - ...col, - originalLabel, - label: `#`, - key: `# ${col.key}`, - config: getComparisonColConfig(`#`, col.key, columnConfig), - formatter: getComparisonColFormatter( - `#`, - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - { - ...col, - originalLabel, - label: `△`, - key: `△ ${col.key}`, - config: getComparisonColConfig(`△`, col.key, columnConfig), - formatter: getComparisonColFormatter( - `△`, - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - { - ...col, - originalLabel, - label: `%`, - key: `% ${col.key}`, - config: getComparisonColConfig(`%`, col.key, columnConfig), - formatter: getComparisonColFormatter( - `%`, - col, - columnConfig, - savedFormat, - savedCurrency, - ), - }, - ]; - } - if ( - !col.isMetric && - !col.isPercentMetric && - !col.key.includes(comparisonSuffix) - ) { - return [col]; - } - return []; - }) - .flat(); + columns.flatMap(col => { + const { + datasource: { columnFormats, currencyFormats }, + rawFormData: { column_config: columnConfig = {} }, + } = props; + const savedFormat = columnFormats?.[col.key]; + const savedCurrency = currencyFormats?.[col.key]; + const originalLabel = col.label; + if ( + (col.isMetric || col.isPercentMetric) && + !col.key.includes(comparisonSuffix) && + col.isNumeric + ) { + return [ + { + ...col, + originalLabel, + label: t('Main'), + key: `${t('Main')} ${col.key}`, + config: getComparisonColConfig(t('Main'), col.key, columnConfig), + formatter: getComparisonColFormatter( + t('Main'), + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + { + ...col, + originalLabel, + label: `#`, + key: `# ${col.key}`, + config: getComparisonColConfig(`#`, col.key, columnConfig), + formatter: getComparisonColFormatter( + `#`, + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + { + ...col, + originalLabel, + label: `△`, + key: `△ ${col.key}`, + config: getComparisonColConfig(`△`, col.key, columnConfig), + formatter: getComparisonColFormatter( + `△`, + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + { + ...col, + originalLabel, + label: `%`, + key: `% ${col.key}`, + config: getComparisonColConfig(`%`, col.key, columnConfig), + formatter: getComparisonColFormatter( + `%`, + col, + columnConfig, + savedFormat, + savedCurrency, + ), + }, + ]; + } + if ( + !col.isMetric && + !col.isPercentMetric && + !col.key.includes(comparisonSuffix) + ) { + return [col]; + } + return []; + }); /** * Automatically set page size based on number of cells. diff --git a/superset-frontend/scripts/check-custom-rules.js b/superset-frontend/scripts/check-custom-rules.js index b0ddfe0625..5606fe9691 100755 --- a/superset-frontend/scripts/check-custom-rules.js +++ b/superset-frontend/scripts/check-custom-rules.js @@ -30,9 +30,9 @@ const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; // ANSI color codes -const RED = '\x1b[31m'; -const YELLOW = '\x1b[33m'; -const RESET = '\x1b[0m'; +const RED = '\x1B[31m'; +const YELLOW = '\x1B[33m'; +const RESET = '\x1B[0m'; let errorCount = 0; let warningCount = 0; diff --git a/superset-frontend/src/SqlLab/reducers/getInitialState.ts b/superset-frontend/src/SqlLab/reducers/getInitialState.ts index d11d32eb75..a594196c5d 100644 --- a/superset-frontend/src/SqlLab/reducers/getInitialState.ts +++ b/superset-frontend/src/SqlLab/reducers/getInitialState.ts @@ -242,7 +242,7 @@ export default function getInitialState({ } }); } - lastUpdatedActiveTab = tabHistory.slice(tabHistory.length - 1)[0] || ''; + lastUpdatedActiveTab = tabHistory.slice(-1)[0] || ''; } } } catch (error) { diff --git a/superset-frontend/src/components/DatabaseSelector/index.tsx b/superset-frontend/src/components/DatabaseSelector/index.tsx index 6660bf8363..47820e475b 100644 --- a/superset-frontend/src/components/DatabaseSelector/index.tsx +++ b/superset-frontend/src/components/DatabaseSelector/index.tsx @@ -304,7 +304,7 @@ export function DatabaseSelector({ if (schemas.length === 1) { changeSchema(schemas[0]); } else if ( - !schemas.find(schemaOption => schemaRef.current === schemaOption.value) + !schemas.some(schemaOption => schemaRef.current === schemaOption.value) ) { changeSchema(undefined); } @@ -345,7 +345,7 @@ export function DatabaseSelector({ } else if (catalogs.length === 1) { changeCatalog(catalogs[0]); } else if ( - !catalogs.find( + !catalogs.some( catalogOption => catalogRef.current === catalogOption.value, ) ) { diff --git a/superset-frontend/src/components/GridTable/Header.tsx b/superset-frontend/src/components/GridTable/Header.tsx index 5b6e341fc0..f47d9432d6 100644 --- a/superset-frontend/src/components/GridTable/Header.tsx +++ b/superset-frontend/src/components/GridTable/Header.tsx @@ -118,8 +118,9 @@ export const Header: React.FC<Params> = ({ ); const onSortChanged = useCallback(() => { - const hasMultiSort = - api.getAllDisplayedColumns().findIndex(c => c.getSortIndex()) !== -1; + const hasMultiSort = api + .getAllDisplayedColumns() + .some(c => c.getSortIndex()); const updatedSortIndex = column.getSortIndex(); sortOption.current = SORT_DIRECTION.indexOf(column.getSort() ?? null); setCurrentSort(column.getSort() ?? null); diff --git a/superset-frontend/src/components/ListView/utils.ts b/superset-frontend/src/components/ListView/utils.ts index 37b15e8780..718f270ca4 100644 --- a/superset-frontend/src/components/ListView/utils.ts +++ b/superset-frontend/src/components/ListView/utils.ts @@ -117,7 +117,7 @@ export function convertFilters(fts: InternalFilter[]): FilterValue[] { (Array.isArray(f.value) && !f.value.length) ), ) - .map(({ value, operator, id }) => { + .flatMap(({ value, operator, id }) => { // handle between filter using 2 api filters if (operator === 'between' && Array.isArray(value)) { return [ @@ -138,8 +138,7 @@ export function convertFilters(fts: InternalFilter[]): FilterValue[] { operator, id, }; - }) - .flat(); + }); } // convertFilters but to handle new decoded rison format diff --git a/superset-frontend/src/components/MessageToasts/reducers.ts b/superset-frontend/src/components/MessageToasts/reducers.ts index 9209164c57..94fa7dc925 100644 --- a/superset-frontend/src/components/MessageToasts/reducers.ts +++ b/superset-frontend/src/components/MessageToasts/reducers.ts @@ -41,7 +41,7 @@ export default function messageToastsReducer( case ADD_TOAST: { const { payload: toast } = action; const result = toasts.slice(); - if (!toast.noDuplicate || !result.find(x => x.text === toast.text)) { + if (!toast.noDuplicate || !result.some(x => x.text === toast.text)) { return [toast, ...toasts]; } return toasts; diff --git a/superset-frontend/src/dashboard/components/RefreshFrequency/RefreshFrequencySelect.tsx b/superset-frontend/src/dashboard/components/RefreshFrequency/RefreshFrequencySelect.tsx index 453a063ed6..25847fab35 100644 --- a/superset-frontend/src/dashboard/components/RefreshFrequency/RefreshFrequencySelect.tsx +++ b/superset-frontend/src/dashboard/components/RefreshFrequency/RefreshFrequencySelect.tsx @@ -81,11 +81,11 @@ export const RefreshFrequencySelect = ({ }: RefreshFrequencySelectProps) => { // Separate radio selection state from value state const [radioSelection, setRadioSelection] = useState(() => - REFRESH_FREQUENCY_OPTIONS.find(opt => opt.value === value) ? value : -1, + REFRESH_FREQUENCY_OPTIONS.some(opt => opt.value === value) ? value : -1, ); const [customValue, setCustomValue] = useState(() => - REFRESH_FREQUENCY_OPTIONS.find(opt => opt.value === value) + REFRESH_FREQUENCY_OPTIONS.some(opt => opt.value === value) ? '' : value.toString(), ); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts index ed6a7634f1..9fd165f99a 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts @@ -141,7 +141,7 @@ export const useInitialization = () => { } if ( - Object.values(filters).find( + Object.values(filters).some( filter => 'requiredFirst' in filter && filter.requiredFirst, ) ) { diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx index 23fa95482d..e7800e583c 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx @@ -1579,7 +1579,7 @@ const FiltersConfigForm = ( prevErroredFilters => { if ( prevErroredFilters.length && - !formValidationFields.find( + !formValidationFields.some( f => f.errors.length > 0, ) ) { diff --git a/superset-frontend/src/dashboard/util/getOverwriteItems.ts b/superset-frontend/src/dashboard/util/getOverwriteItems.ts index 7492b8aeac..f6c7451b68 100644 --- a/superset-frontend/src/dashboard/util/getOverwriteItems.ts +++ b/superset-frontend/src/dashboard/util/getOverwriteItems.ts @@ -31,7 +31,7 @@ function extractValue(object: JsonObject, keyPath: string) { export default function getOverwriteItems(prev: JsonObject, next: JsonObject) { return OVERWRITE_INSPECT_FIELDS.map(keyPath => ({ keyPath, - ...(keyPath.split('.').find(key => JSON_KEYS.has(key)) + ...(keyPath.split('.').some(key => JSON_KEYS.has(key)) ? { oldValue: JSON.stringify(extractValue(prev, keyPath), null, 2) || '{}', diff --git a/superset-frontend/src/dashboard/util/isValidChild.test.ts b/superset-frontend/src/dashboard/util/isValidChild.test.ts index 0fb51d1c88..33af311285 100644 --- a/superset-frontend/src/dashboard/util/isValidChild.test.ts +++ b/superset-frontend/src/dashboard/util/isValidChild.test.ts @@ -145,7 +145,7 @@ describe('isValidChild', () => { const parentType = example[i - 1]; if (typeof parentType !== 'string') - throw TypeError('parent must be string'); + throw new TypeError('parent must be string'); test(`(${exampleIdx})${getIndentation( childDepth, diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx index 9a8613cb96..16b085071c 100644 --- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx +++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx @@ -921,7 +921,7 @@ class AnnotationLayer extends PureComponent< if ( color && color !== AUTOMATIC_COLOR && - !colorScheme.find(x => x.toLowerCase() === color.toLowerCase()) + !colorScheme.some(x => x.toLowerCase() === color.toLowerCase()) ) { colorScheme.push(color); } diff --git a/superset-frontend/src/explore/components/controls/SelectAsyncControl/index.tsx b/superset-frontend/src/explore/components/controls/SelectAsyncControl/index.tsx index 6a12cdc853..c9095b5899 100644 --- a/superset-frontend/src/explore/components/controls/SelectAsyncControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/SelectAsyncControl/index.tsx @@ -90,7 +90,7 @@ const SelectAsyncControl = ({ value || (props.default !== undefined ? props.default : undefined); // safety check - the value is intended to be undefined but null was used - if (currentValue === null && !options.find(o => o.value === null)) { + if (currentValue === null && !options.some(o => o.value === null)) { return undefined; } return currentValue; diff --git a/superset-frontend/src/explore/components/controls/SelectControl.tsx b/superset-frontend/src/explore/components/controls/SelectControl.tsx index 751546c7f5..f13164db20 100644 --- a/superset-frontend/src/explore/components/controls/SelectControl.tsx +++ b/superset-frontend/src/explore/components/controls/SelectControl.tsx @@ -284,7 +284,7 @@ export default class SelectControl extends PureComponent< // safety check - the value is intended to be undefined but null was used if ( currentValue === null && - !this.state.options.find(o => o.value === null) + !this.state.options.some(o => o.value === null) ) { return undefined; } diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx index f234527fa6..9db1ae58ee 100644 --- a/superset-frontend/src/views/CRUD/utils.tsx +++ b/superset-frontend/src/views/CRUD/utils.tsx @@ -480,50 +480,45 @@ export const isAlreadyExists = (payload: any) => export const getPasswordsNeeded = (errors: Record<string, any>[]) => errors - .map(error => + .flatMap(error => Object.entries(error.extra) .filter(([, payload]) => isNeedsPassword(payload)) .map(([fileName]) => fileName), - ) - .flat(); + ); export const getSSHPasswordsNeeded = (errors: Record<string, any>[]) => errors - .map(error => + .flatMap(error => Object.entries(error.extra) .filter(([, payload]) => isNeedsSSHPassword(payload)) .map(([fileName]) => fileName), - ) - .flat(); + ); export const getSSHPrivateKeysNeeded = (errors: Record<string, any>[]) => errors - .map(error => + .flatMap(error => Object.entries(error.extra) .filter(([, payload]) => isNeedsSSHPrivateKey(payload)) .map(([fileName]) => fileName), - ) - .flat(); + ); export const getSSHPrivateKeyPasswordsNeeded = ( errors: Record<string, any>[], ) => errors - .map(error => + .flatMap(error => Object.entries(error.extra) .filter(([, payload]) => isNeedsSSHPrivateKeyPassword(payload)) .map(([fileName]) => fileName), - ) - .flat(); + ); export const getAlreadyExists = (errors: Record<string, any>[]) => errors - .map(error => + .flatMap(error => Object.entries(error.extra) .filter(([, payload]) => isAlreadyExists(payload)) .map(([fileName]) => fileName), - ) - .flat(); + ); export const hasTerminalValidation = (errors: Record<string, any>[]) => errors.some(error => {
