You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/02/21 01:01:56 UTC
(superset) 01/01: chore(frontend): enable additional oxlint rules for better code hygiene
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 <ev...@rusackas.com>
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 <no...@anthropic.com>
---
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 => {