This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 6b80135aa28 chore(lint): enforce more strict eslint/oxlint rules
(batch 2) (#37884)
6b80135aa28 is described below
commit 6b80135aa283ee15a1439e69c762e617c990383c
Author: Evan Rusackas <[email protected]>
AuthorDate: Wed Feb 18 22:27:27 2026 -0500
chore(lint): enforce more strict eslint/oxlint rules (batch 2) (#37884)
Co-authored-by: Claude Opus 4.5 <[email protected]>
---
superset-frontend/.eslintrc.js | 10 ++++++++++
superset-frontend/oxlint.json | 4 +++-
.../src/components/Layout/Layout.test.tsx | 8 ++++++--
.../superset-ui-core/src/components/Modal/Modal.tsx | 2 +-
.../plugins/plugin-chart-ag-grid-table/src/buildQuery.ts | 2 +-
.../test/BigNumber/transformProps.test.ts | 16 ++++++++++++----
.../plugins/plugin-chart-table/src/buildQuery.ts | 2 +-
.../src/dashboard/components/nativeFilters/state.ts | 10 ++++------
8 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js
index a2c9b3ae5d7..bf6cb9b6fd6 100644
--- a/superset-frontend/.eslintrc.js
+++ b/superset-frontend/.eslintrc.js
@@ -245,6 +245,16 @@ module.exports = {
// Lodash
'lodash/import-scope': [2, 'member'],
+ // React effect best practices
+ 'react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change':
+ 'error',
+ 'react-you-might-not-need-an-effect/no-chain-state-updates': 'error',
+ 'react-you-might-not-need-an-effect/no-event-handler': 'error',
+ 'react-you-might-not-need-an-effect/no-derived-state': 'error',
+
+ // Storybook
+ 'storybook/prefer-pascal-case': 'error',
+
// File progress
'file-progress/activate': 1,
diff --git a/superset-frontend/oxlint.json b/superset-frontend/oxlint.json
index 50e482ecedd..942965a865d 100644
--- a/superset-frontend/oxlint.json
+++ b/superset-frontend/oxlint.json
@@ -34,7 +34,8 @@
"no-unused-vars": "off",
"no-undef": "error",
"no-prototype-builtins": "off",
- "no-unsafe-optional-chaining": "off",
+ "no-unsafe-optional-chaining": "error",
+ "no-constant-binary-expression": "error",
"no-import-assign": "off",
"no-promise-executor-return": "off",
@@ -254,6 +255,7 @@
// === Unicorn rules (bonus coverage) ===
"unicorn/no-new-array": "error",
"unicorn/no-invalid-remove-event-listener": "error",
+ "unicorn/no-useless-length-check": "error",
"unicorn/filename-case": "off",
"unicorn/prevent-abbreviations": "off",
"unicorn/no-null": "off",
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/Layout/Layout.test.tsx
b/superset-frontend/packages/superset-ui-core/src/components/Layout/Layout.test.tsx
index 88a70ff9e6e..0b24bdbc376 100644
---
a/superset-frontend/packages/superset-ui-core/src/components/Layout/Layout.test.tsx
+++
b/superset-frontend/packages/superset-ui-core/src/components/Layout/Layout.test.tsx
@@ -47,9 +47,10 @@ describe('Layout Component', () => {
});
test('hides Header when headerVisible is false', () => {
+ const headerVisible = false;
render(
<Layout>
- {false && <Layout.Header>Header</Layout.Header>}
+ {headerVisible && <Layout.Header>Header</Layout.Header>}
<Layout.Content>Content Area</Layout.Content>
<Layout.Footer>Ant Design Layout Footer</Layout.Footer>
</Layout>,
@@ -59,11 +60,14 @@ describe('Layout Component', () => {
});
test('hides Footer when footerVisible is false', () => {
+ const footerVisible = false;
render(
<Layout>
<Layout.Header>Header</Layout.Header>
<Layout.Content>Content Area</Layout.Content>
- {false && <Layout.Footer>Ant Design Layout Footer</Layout.Footer>}
+ {footerVisible && (
+ <Layout.Footer>Ant Design Layout Footer</Layout.Footer>
+ )}
</Layout>,
);
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
b/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
index 021341808e0..173ab6f83a2 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
@@ -280,7 +280,7 @@ const CustomModal = ({
const shouldShowMask = !(resizable || draggable);
const onDragStart = (_: DraggableEvent, uiData: DraggableData) => {
- const { clientWidth, clientHeight } = window?.document?.documentElement;
+ const { clientWidth, clientHeight } = document.documentElement;
const targetRect = draggableRef?.current?.getBoundingClientRect();
if (targetRect) {
diff --git
a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/buildQuery.ts
b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/buildQuery.ts
index 9212936686b..8122c86f825 100644
--- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/buildQuery.ts
+++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/buildQuery.ts
@@ -606,7 +606,7 @@ const buildQuery: BuildQuery<TableChartFormData> = (
{
...queryObject,
time_offsets: [],
- row_limit: Number(formData?.row_limit) ?? 0,
+ row_limit: Number(formData?.row_limit ?? 0),
row_offset: 0,
post_processing: [],
is_rowcount: true,
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/test/BigNumber/transformProps.test.ts
b/superset-frontend/plugins/plugin-chart-echarts/test/BigNumber/transformProps.test.ts
index 3c681f281b0..66933c4f813 100644
---
a/superset-frontend/plugins/plugin-chart-echarts/test/BigNumber/transformProps.test.ts
+++
b/superset-frontend/plugins/plugin-chart-echarts/test/BigNumber/transformProps.test.ts
@@ -196,7 +196,9 @@ describe('BigNumberWithTrendline', () => {
showXAxis: true,
},
});
- expect((transformed.echartOptions?.xAxis as any).show).toBe(true);
+ expect((transformed.echartOptions!.xAxis as { show: boolean
}).show).toBe(
+ true,
+ );
});
test('should not show X axis when showXAxis is false', () => {
@@ -207,7 +209,9 @@ describe('BigNumberWithTrendline', () => {
showXAxis: false,
},
});
- expect((transformed.echartOptions?.xAxis as any).show).toBe(false);
+ expect((transformed.echartOptions!.xAxis as { show: boolean
}).show).toBe(
+ false,
+ );
});
test('should show Y axis when showYAxis is true', () => {
@@ -218,7 +222,9 @@ describe('BigNumberWithTrendline', () => {
showYAxis: true,
},
});
- expect((transformed.echartOptions?.yAxis as any).show).toBe(true);
+ expect((transformed.echartOptions!.yAxis as { show: boolean
}).show).toBe(
+ true,
+ );
});
test('should not show Y axis when showYAxis is false', () => {
@@ -229,7 +235,9 @@ describe('BigNumberWithTrendline', () => {
showYAxis: false,
},
});
- expect((transformed.echartOptions?.yAxis as any).show).toBe(false);
+ expect((transformed.echartOptions!.yAxis as { show: boolean
}).show).toBe(
+ false,
+ );
});
});
diff --git a/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
b/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
index 7b3a952d891..c23a8a49c56 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
@@ -347,7 +347,7 @@ const buildQuery: BuildQuery<TableChartFormData> = (
{
...queryObject,
time_offsets: [],
- row_limit: Number(formData?.row_limit) ?? 0,
+ row_limit: Number(formData?.row_limit ?? 0),
row_offset: 0,
post_processing: [],
is_rowcount: true,
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/state.ts
b/superset-frontend/src/dashboard/components/nativeFilters/state.ts
index f95c1bae4ef..ecbb56e47a0 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/state.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/state.ts
@@ -210,10 +210,9 @@ export function useIsFilterInScope() {
if (hasChartsInScope) {
isChartInScope = filter.chartsInScope!.some((chartId: number) => {
const tabParents = selectChartTabParents(chartId);
+ // Note: every() returns true for empty arrays, so length check is
unnecessary
return (
- !tabParents ||
- tabParents.length === 0 ||
- tabParents.every(tab => activeTabs.includes(tab))
+ !tabParents || tabParents.every(tab => activeTabs.includes(tab))
);
});
}
@@ -276,10 +275,9 @@ export function useIsCustomizationInScope() {
customization.chartsInScope.length > 0 &&
customization.chartsInScope.some((chartId: number) => {
const tabParents = selectChartTabParents(chartId);
+ // Note: every() returns true for empty arrays, so length check is
unnecessary
return (
- !tabParents ||
- tabParents.length === 0 ||
- tabParents.every(tab => activeTabs.includes(tab))
+ !tabParents || tabParents.every(tab => activeTabs.includes(tab))
);
});