Compare commits

...

3 Commits

Author SHA1 Message Date
Evan
92b7457d7e test(tag): assert every loadTags call, not just the first
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 20:45:13 -07:00
Evan
286cab64b1 fix(ag-grid-table): drop stale totals arg from useColDefs call
The no-unused-vars cleanup removed the unused `totals` field from
`UseColDefsProps`, but the call site in AgGridTableChart still passed
it, breaking the tsc build (TS2353). Remove the now-invalid argument.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 18:19:28 -07:00
Superset Dev
0e32b0399f chore(lint): upgrade no-unused-vars rule from warn to error
Flip @typescript-eslint/no-unused-vars from "warn" to "error" in
oxlint.json (with argsIgnorePattern/varsIgnorePattern of "^_" and
caughtErrors "none"), and clean up the resulting violations across the
frontend.

Fixes favor proper cleanup over underscore hacks: genuinely dead
imports, variables, and destructured props are removed; parameters are
only "_"-prefixed when their position is required by an external or
callback signature (event handlers, render props, antd validators,
forwardRef, or omit-from-rest destructuring).

Note: the .eslintrc.js half of the prior attempt (#37886) is obsolete
since the frontend migrated to oxlint as the primary linter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-16 15:48:06 -07:00
56 changed files with 91 additions and 138 deletions

View File

@@ -22,7 +22,7 @@ import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import reducerIndex from 'spec/helpers/reducerIndex';
import { Global } from '@emotion/react';
import { App, Layout, Space, Content } from 'antd';
import { App, Layout } from 'antd';
import 'src/theme.ts';
import './storybook.css';

View File

@@ -232,7 +232,14 @@
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrors": "none"
}
],
"@typescript-eslint/prefer-optional-chain": "error",
// === Unicorn rules (bonus coverage) ===

View File

@@ -92,7 +92,7 @@ const MatrixNoDataComponent = () => {
* Individual grid cell component - memoized to prevent unnecessary re-renders
*/
const MatrixifyGridCell = memo(
({ cell, rowHeight, datasource, hooks }: MatrixifyGridCellProps) => {
({ cell, hooks }: MatrixifyGridCellProps) => {
// Use computed title from template (will be empty string if no template)
const cellLabel = cell.title || '';

View File

@@ -118,7 +118,6 @@ interface MatrixifyGridRendererProps {
function MatrixifyGridRenderer({
formData,
datasource,
width,
height,
hooks,
}: MatrixifyGridRendererProps) {
@@ -249,7 +248,7 @@ function MatrixifyGridRenderer({
{/* Row cells for this column group */}
{row
.slice(colGroup.startIdx, colGroup.endIdx)
.map((cell, colIdx) =>
.map(cell =>
cell ? (
<MatrixifyGridCell
key={cell.id}

View File

@@ -33,7 +33,7 @@ export function Label(props: LabelProps) {
onClick,
children,
icon,
id,
id: _id,
...rest
} = props;

View File

@@ -66,7 +66,7 @@ function findMatchingTimezone(
export default function TimezoneSelector({
onTimezoneChange,
timezone,
minWidth = MIN_SELECT_WIDTH,
minWidth: _minWidth = MIN_SELECT_WIDTH,
placeholder,
...rest
}: TimezoneSelectorProps) {

View File

@@ -112,7 +112,7 @@ function Calendar(element: HTMLElement, props: CalendarProps) {
const colorScheme = getSequentialSchemeRegistry().get(linearColorScheme);
const colorScale = colorScheme
? colorScheme.createLinearScale(extents)
: (v: number) => '#ccc'; // fallback if scheme not found
: (_v: number) => '#ccc'; // fallback if scheme not found
const legend = d3Range(steps).map(i => extents[0] + step * i);
const legendColors = legend.map(x => colorScale(x));

View File

@@ -22,7 +22,6 @@ import d3 from 'd3';
import { extent as d3Extent } from 'd3-array';
import {
ValueFormatter,
getNumberFormatter,
getSequentialSchemeRegistry,
CategoricalColorNamespace,
} from '@superset-ui/core';
@@ -187,9 +186,11 @@ function CountryMap(element: HTMLElement, props: CountryMapProps) {
region => region.country_id === d.properties.ISO,
);
hoverPopup.style('display', 'block').html(
`<div><strong>${getNameOfRegion(d)}</strong><br>${result.length > 0 ? formatter(result[0].metric) : ''}</div>`,
);
hoverPopup
.style('display', 'block')
.html(
`<div><strong>${getNameOfRegion(d)}</strong><br>${result.length > 0 ? formatter(result[0].metric) : ''}</div>`,
);
updatePopupPosition();
};

View File

@@ -238,7 +238,6 @@ export default function TableChart<D extends DataRecord = DataRecord>(
defaultAlignPN: alignPositiveNegative,
showCellBars,
colorPositiveNegative,
totals,
columnColorFormatters,
allowRearrangeColumns,
basicColorFormatters,

View File

@@ -16,14 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
import {
styled,
useTheme,
type SupersetTheme,
} from '@apache-superset/core/theme';
import { styled } from '@apache-superset/core/theme';
import { CustomCellRendererProps } from '@superset-ui/core/components/ThemedAgGridReact';
import { BasicColorFormatterType, InputColumn, ValueRange } from '../types';
import { useIsDark } from '../utils/useTableTheme';
const StyledTotalCell = styled.div`
${() => `
@@ -110,13 +105,9 @@ function cellOffset({
function cellBackground({
value,
colorPositiveNegative = false,
isDarkTheme = false,
theme,
}: {
value: number;
colorPositiveNegative: boolean;
isDarkTheme: boolean;
theme: SupersetTheme | null;
}) {
if (!colorPositiveNegative) {
return 'transparent'; // Use transparent background when colorPositiveNegative is false
@@ -153,9 +144,6 @@ export const NumericCellRenderer = (
colorPositiveNegative,
} = params;
const isDarkTheme = useIsDark();
const theme = !colorPositiveNegative ? null : useTheme();
if (node?.rowPinned === 'bottom') {
return <StyledTotalCell>{valueFormatted ?? value}</StyledTotalCell>;
}
@@ -199,8 +187,6 @@ export const NumericCellRenderer = (
const background = cellBackground({
value: value as number,
colorPositiveNegative,
isDarkTheme,
theme,
});
return (

View File

@@ -20,7 +20,7 @@
import { t } from '@apache-superset/core/translation';
import { ColDef } from '@superset-ui/core/components/ThemedAgGridReact';
import { useCallback, useMemo } from 'react';
import { DataRecord, DataRecordValue, JsonObject } from '@superset-ui/core';
import { DataRecordValue, JsonObject } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import { useTheme } from '@apache-superset/core/theme';
import { ColorFormatters } from '@superset-ui/chart-controls';
@@ -61,7 +61,6 @@ type UseColDefsProps = {
defaultAlignPN: boolean;
showCellBars: boolean;
colorPositiveNegative: boolean;
totals: DataRecord | undefined;
columnColorFormatters: ColorFormatters;
allowRearrangeColumns?: boolean;
basicColorFormatters?: { [Key: string]: BasicColorFormatterType }[];
@@ -227,7 +226,6 @@ export const useColDefs = ({
defaultAlignPN,
showCellBars,
colorPositiveNegative,
totals,
columnColorFormatters,
allowRearrangeColumns,
basicColorFormatters,

View File

@@ -23,7 +23,6 @@ import {
getTimeFormatter,
SMART_DATE_VERBOSE_ID,
computeMaxFontSize,
BRAND_COLOR,
BinaryQueryObjectFilterClause,
DTTM_ALIAS,
} from '@superset-ui/core';
@@ -43,14 +42,11 @@ function BigNumberVis({
kickerFontSize = PROPORTION.KICKER,
metricNameFontSize = PROPORTION.METRIC_NAME,
showMetricName = true,
mainColor = BRAND_COLOR,
showTimestamp = false,
showTrendLine = false,
startYAxisAtZero = true,
subheader = '',
subheaderFontSize = PROPORTION.SUBHEADER,
subtitleFontSize = PROPORTION.SUBHEADER,
timeRangeFixed = false,
...props
}: BigNumberVizProps) {
const theme = useTheme();

View File

@@ -372,13 +372,8 @@ const config: ControlPanelConfig = {
description: t(
'Stack in groups, where each group corresponds to a dimension',
),
shouldMapStateToProps: (
prevState,
state,
controlState,
chartState,
) => true,
mapStateToProps: (state, controlState, chartState) => {
shouldMapStateToProps: () => true,
mapStateToProps: state => {
const value: JsonArray = ensureIsArray(
state.controls.groupby?.value,
) as JsonArray;

View File

@@ -102,7 +102,6 @@ export interface TreeNodeRendererProps extends NodeRendererProps<TreeNodeData> {
const TreeNodeRenderer: React.FC<TreeNodeRendererProps> = ({
node,
style,
manuallyOpenedNodes,
loadingNodes,
searchTerm,
catalog,

View File

@@ -183,7 +183,6 @@ function ChartRendererComponent({
onFilterMenuClose = () => BLANK,
initialValues = BLANK,
setControlValue = () => {},
triggerRender = false,
...restProps
}: ChartRendererProps): JSX.Element | null {
const {

View File

@@ -71,7 +71,7 @@ export const ItemSeparator = styled.div<{
export const TreeFolderContainer = styled(TreeItemContainer)<{
isForbiddenDropTarget?: boolean;
}>`
${({ theme, depth, isForbiddenDropTarget, isOverlay }) => `
${({ theme, depth, isForbiddenDropTarget }) => `
margin-top: 0;
margin-bottom: 0;
padding-top: ${theme.paddingSM}px;

View File

@@ -301,9 +301,7 @@ interface CollectionTabTitleProps {
interface ColumnCollectionTableProps {
columns: Column[];
datasource: DatasourceObject;
onColumnsChange: (columns: Column[]) => void;
onDatasourceChange: (datasource: DatasourceObject) => void;
editableColumnName?: boolean;
showExpression?: boolean;
allowAddItem?: boolean;
@@ -520,9 +518,7 @@ function FormContainer({ children }: FormContainerProps): JSX.Element {
function ColumnCollectionTable({
columns,
datasource,
onColumnsChange,
onDatasourceChange,
editableColumnName = false,
showExpression = false,
allowAddItem = false,
@@ -2428,11 +2424,9 @@ class DatasourceEditor extends PureComponent<
columns={this.state.databaseColumns}
filterTerm={this.state.columnSearchTerm}
filterFields={['column_name']}
datasource={datasource}
onColumnsChange={databaseColumns =>
this.setColumns({ databaseColumns })
}
onDatasourceChange={this.onDatasourceChange}
/>
{this.state.metadataLoading && <Loading />}
</StyledTableTabWrapper>
@@ -2474,8 +2468,6 @@ class DatasourceEditor extends PureComponent<
'as the alias in the SQL query.',
),
}}
onDatasourceChange={this.onDatasourceChange}
datasource={datasource}
editableColumnName
showExpression
allowAddItem

View File

@@ -23,7 +23,6 @@ import { ErrorAlert } from './ErrorAlert';
export function FrontendNetworkErrorMessage({
error,
subtitle,
compact,
closable,
}: ErrorMessageComponentProps) {

View File

@@ -45,7 +45,6 @@ export function GridTable<RecordType extends object>({
showRowNumber,
enableActions,
size = GridSize.Middle,
striped,
}: TableProps<RecordType>) {
const theme = useTheme();
const isExternalFilterPresent = useCallback(

View File

@@ -24,7 +24,6 @@ interface CollapsibleModalSectionProps {
sectionKey: string;
title: string;
subtitle?: string;
defaultExpanded?: boolean;
hasErrors?: boolean;
testId?: string;
children: ReactNode;
@@ -41,7 +40,6 @@ export function CollapsibleModalSection({
sectionKey,
title,
subtitle,
defaultExpanded = false,
hasErrors = false,
testId,
children,

View File

@@ -29,8 +29,6 @@ interface ModalFormFieldProps {
bottomSpacing?: boolean;
children: ReactNode;
testId?: string;
validateStatus?: 'success' | 'warning' | 'error' | 'validating';
hasFeedback?: boolean;
}
const StyledFieldContainer = styled.div<{ bottomSpacing: boolean }>`
@@ -125,8 +123,6 @@ export function ModalFormField({
bottomSpacing = true,
children,
testId,
validateStatus,
hasFeedback = false,
}: ModalFormFieldProps) {
return (
<StyledFieldContainer bottomSpacing={bottomSpacing} data-test={testId}>

View File

@@ -32,13 +32,10 @@ interface StandardModalProps {
saveDisabled?: boolean;
saveLoading?: boolean;
saveText?: string;
cancelText?: string;
errorTooltip?: ReactNode;
children: ReactNode;
isEditMode?: boolean;
centered?: boolean;
destroyOnClose?: boolean;
maskClosable?: boolean;
wrapProps?: object;
contentLoading?: boolean;
}
@@ -107,13 +104,10 @@ export function StandardModal({
saveDisabled = false,
saveLoading = false,
saveText,
cancelText,
errorTooltip,
children,
isEditMode = false,
centered = true,
destroyOnClose = true,
maskClosable = false,
wrapProps,
contentLoading = false,
}: StandardModalProps) {

View File

@@ -167,7 +167,7 @@ describe('loadTags', () => {
// Verify all calls include the custom tag filter
calls.forEach(call => {
const { url } = calls[0];
const { url } = call;
const urlObj = new URL(url);
const queryParam = urlObj.searchParams.get('q');
expect(queryParam).not.toBeNull();

View File

@@ -176,7 +176,7 @@ export class QueryResultContext
requestedLimit?: number;
} = {},
) {
const { appliedLimit, appliedLimitingFactor, ...opt } = options;
const { appliedLimit, ...opt } = options;
super(clientId, tab, runAsync, startDttm, opt);
this.remoteId = remoteId;
this.executedSql = executedSql;
@@ -219,7 +219,7 @@ export class QueryErrorResultContext
queryId?: number;
} = {},
) {
const { queryId, executedSql, endDttm, ...opt } = options;
const { executedSql, endDttm, ...opt } = options;
super(clientId, tab, runAsync, startDttm, opt);
this.executedSql = executedSql ?? null;
this.errorMessage = errorMessage;

View File

@@ -114,12 +114,8 @@ function Dashboard({
slices,
activeFilters,
chartConfiguration,
datasources,
ownDataCharts,
layout,
impressionId,
timeout = 60,
userId = '',
children,
}: DashboardProps): JSX.Element {
const context = useContext(PluginContext) as PluginContextType;

View File

@@ -65,18 +65,18 @@ type SaveModalProps = {
function SaveModal({
saveType: initialSaveType = SAVE_TYPE_OVERWRITE,
colorNamespace,
colorScheme,
colorNamespace: _colorNamespace,
colorScheme: _colorScheme,
shouldPersistRefreshFrequency = false,
dashboardTitle,
onSave,
triggerNode,
canOverwrite,
addSuccessToast,
addSuccessToast: _addSuccessToast,
addDangerToast,
dashboardId,
dashboardInfo,
expandedSlices,
expandedSlices: _expandedSlices,
layout,
customCss,
refreshFrequency,

View File

@@ -35,7 +35,7 @@ describe('Divider', () => {
index: 0,
editMode: false,
handleComponentDrop: jest.fn(),
deleteComponent: (id: string, parentId: string) => {},
deleteComponent: (_id: string, _parentId: string) => {},
};
const setup = (overrideProps: Partial<DividerProps> = {}) =>

View File

@@ -117,7 +117,6 @@ interface DraggableTabNodeProps extends React.HTMLAttributes<HTMLDivElement> {
}
const DraggableTabNode: React.FC<Readonly<DraggableTabNodeProps>> = ({
className,
disabled = false,
...props
}) => {
@@ -170,7 +169,6 @@ const TabsRenderer = memo<TabsRendererProps>(
tabBarPaddingLeft = 0,
onTabsReorder,
isEditingTabTitle = false,
onTabTitleEditingChange,
}) => {
const [activeId, setActiveId] = useState<string | null>(null);

View File

@@ -279,7 +279,7 @@ const FilterControls: FC<FilterControlsProps> = ({
);
const customizationRenderer = useCallback(
(item: ChartCustomization | ChartCustomizationDivider, index: number) => {
(item: ChartCustomization | ChartCustomizationDivider, _index: number) => {
if (isChartCustomizationDivider(item)) {
return (
<FilterDivider

View File

@@ -141,8 +141,6 @@ const VerticalFilterBar: FC<VerticalBarProps> = ({
onPendingCustomizationDataMaskChange,
toggleFiltersBar,
width,
clearAllTriggers,
onClearAllComplete,
}) => {
const theme = useTheme();
const [isScrolling, setIsScrolling] = useState(false);

View File

@@ -105,7 +105,7 @@ export function useCustomizationOperations({
);
const handleRearrangeCustomizations = useCallback(
(dragIndex: number, targetIndex: number, id: string) => {
(dragIndex: number, targetIndex: number, _id: string) => {
const newOrderedIds = [...customizationState.orderedIds];
const [removed] = newOrderedIds.splice(dragIndex, 1);
newOrderedIds.splice(targetIndex, 0, removed);

View File

@@ -125,7 +125,7 @@ export function useFilterOperations({
);
const handleRearrangeFilters = useCallback(
(dragIndex: number, targetIndex: number, id: string) => {
(dragIndex: number, targetIndex: number, _id: string) => {
const newOrderedIds = [...filterState.orderedIds];
const [removed] = newOrderedIds.splice(dragIndex, 1);
newOrderedIds.splice(targetIndex, 0, removed);

View File

@@ -60,7 +60,6 @@ export const SamplesPane = ({
queryFormData,
queryForce,
setForceQuery,
isVisible,
canDownload,
}: SamplesPaneProps) => {
const [filterText, setFilterText] = useState('');

View File

@@ -51,7 +51,7 @@ export const ExploreAlert = forwardRef(
type = 'info',
className = '',
}: ControlPanelAlertProps,
ref: RefObject<HTMLDivElement>,
_ref: RefObject<HTMLDivElement>,
) => (
<ErrorAlert
errorType={title}

View File

@@ -892,8 +892,11 @@ function ExploreViewContainer(props: ExploreViewContainerProps) {
setForceQuery: props.actions.setForceQuery,
postChartFormData: props.actions.postChartFormData,
updateQueryFormData: props.actions.updateQueryFormData,
setControlValue: (controlName: string, value: any, chartId: number) =>
props.actions.setControlValue(controlName, value),
setControlValue: (
controlName: string,
value: any,
_chartId: number,
) => props.actions.setControlValue(controlName, value),
}}
can_overwrite={props.can_overwrite}
can_download={props.can_download}

View File

@@ -294,7 +294,7 @@ export default class AdhocFilterEditPopover extends Component<
.filter((item: { sliceIndex: number }) => item.sliceIndex !== -1)
.map(
({
sliceIndex,
sliceIndex: _sliceIndex,
...item
}: {
sliceIndex: number;
@@ -346,12 +346,12 @@ export default class AdhocFilterEditPopover extends Component<
const {
adhocFilter: propsAdhocFilter,
options,
onChange,
onClose,
onResize,
onChange: _onChange,
onClose: _onClose,
onResize: _onResize,
datasource,
partitionColumn,
theme,
theme: _theme,
operators,
requireSave,
...popoverProps

View File

@@ -349,9 +349,9 @@ class AdhocMetricEditPopover extends PureComponent<
savedMetric: propsSavedMetric,
columns,
savedMetricsOptions,
onChange,
onClose,
onResize,
onChange: _onChange,
onClose: _onClose,
onResize: _onResize,
datasource,
isNewMetric,
isLabelModified,

View File

@@ -146,19 +146,19 @@ class TextAreaControl extends Component<TextAreaControlProps> {
// - other control-specific props and explicitly-set props to avoid duplicate/conflicting assignments
const {
theme,
height,
offerEditInModal,
aboveEditorSection,
height: _height,
offerEditInModal: _offerEditInModal,
aboveEditorSection: _aboveEditorSection,
resize,
textAreaStyles,
tooltipOptions,
hotkeys,
debounceDelay,
debounceDelay: _debounceDelay,
language,
initialValue,
readOnly,
name,
onChange,
onChange: _onChange,
value,
minLines: minLinesProp,
maxLines: maxLinesProp,

View File

@@ -1152,7 +1152,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
);
}
})
.catch(e => {
.catch(() => {
addDangerToast(t('There was an error retrieving dashboard tabs.'));
});
}

View File

@@ -306,7 +306,7 @@ export const NotificationMethod: FunctionComponent<NotificationMethodProps> = ({
}
}
})
.catch(e => {
.catch(() => {
// Fallback to slack v1 if slack v2 is not compatible
setUseSlackV1(true);
})

View File

@@ -59,7 +59,7 @@ interface AllEntitiesTableProps {
}
export default function AllEntitiesTable({
search = '',
search: _search = '',
setShowTagModal,
objects,
canEditTag,

View File

@@ -208,7 +208,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
setCurrentAnnotation(data);
};
const onDateChange = (dates: any, dateString: Array<string>) => {
const onDateChange = (dates: any, _dateString: Array<string>) => {
if (!dates?.[0] || !dates?.[1]) {
const data = {
...currentAnnotation,

View File

@@ -1632,7 +1632,7 @@ test('validates fix by testing all form field types clear validation errors', ()
mockClearError();
};
const handleChangeWithValidation = (actionType: any, payload: any) => {
const handleChangeWithValidation = (_actionType: any, _payload: any) => {
handleClearValidationErrors();
};

View File

@@ -359,7 +359,7 @@ const UploadDataModal: FunctionComponent<UploadDataModalProps> = ({
const loadSchemaOptions = useMemo(
() =>
(input = '', page: number, pageSize: number) => {
(_input = '', _page: number, _pageSize: number) => {
if (!currentDatabaseId) {
return Promise.resolve({ data: [], totalCount: 0 });
}
@@ -563,7 +563,7 @@ const UploadDataModal: FunctionComponent<UploadDataModalProps> = ({
}
}, [show]);
const validateUpload = (_: any, value: string) => {
const validateUpload = (_: any, _value: string) => {
if (fileList.length === 0) {
return Promise.reject(t('Uploading a file is required'));
}

View File

@@ -252,9 +252,7 @@ describe('RoleListEditModal', () => {
const mockGet = SupersetClient.get as jest.Mock;
mockGet.mockImplementation(({ endpoint }) => {
if (
endpoint?.includes(
`/api/v1/security/roles/${mockRole.id}/permissions/`,
)
endpoint?.includes(`/api/v1/security/roles/${mockRole.id}/permissions/`)
) {
// Only return permission id=10, not id=20
return Promise.resolve({
@@ -298,9 +296,7 @@ describe('RoleListEditModal', () => {
const mockGet = SupersetClient.get as jest.Mock;
mockGet.mockImplementation(({ endpoint }) => {
if (
endpoint?.includes(
`/api/v1/security/roles/${mockRole.id}/permissions/`,
)
endpoint?.includes(`/api/v1/security/roles/${mockRole.id}/permissions/`)
) {
return Promise.reject(new Error('network error'));
}
@@ -333,7 +329,7 @@ describe('RoleListEditModal', () => {
test('fires warning toast when hydration returns zero rows but IDs were expected', async () => {
const mockGet = SupersetClient.get as jest.Mock;
mockGet.mockImplementation(({ endpoint }) =>
mockGet.mockImplementation(() =>
Promise.resolve({ json: { count: 0, result: [] } }),
);
@@ -371,7 +367,9 @@ describe('RoleListEditModal', () => {
};
mockGet.mockImplementation(({ endpoint }) => {
if (endpoint?.includes(`/api/v1/security/roles/${roleA.id}/permissions/`)) {
if (
endpoint?.includes(`/api/v1/security/roles/${roleA.id}/permissions/`)
) {
return Promise.resolve({
json: {
result: roleA.permission_ids.map(pid => ({
@@ -382,7 +380,9 @@ describe('RoleListEditModal', () => {
},
});
}
if (endpoint?.includes(`/api/v1/security/roles/${roleB.id}/permissions/`)) {
if (
endpoint?.includes(`/api/v1/security/roles/${roleB.id}/permissions/`)
) {
return Promise.resolve({
json: {
result: roleB.permission_ids.map(pid => ({

View File

@@ -85,7 +85,7 @@ const BulkTagModal: FC<BulkTagModalProps> = ({
}
addSuccessToast(t('Tagged %s %ss', tagged.length, resourceName));
})
.catch(err => {
.catch(() => {
addDangerToast(t('Failed to tag items'));
});

View File

@@ -130,7 +130,7 @@ const TagModal: FC<TagModalProps> = ({
setChartsToTag(resourceMap[TaggableResources.Chart]);
setSavedQueriesToTag(resourceMap[TaggableResources.SavedQuery]);
},
(error: Response) => {
(_error: Response) => {
addDangerToast('Error Fetching Tagged Objects');
},
);

View File

@@ -48,7 +48,7 @@ function UserInfoModal({
: {};
const handleFormSubmit = async (values: FormValues) => {
try {
const { confirm_password, ...payload } = values;
const { confirm_password: _confirm_password, ...payload } = values;
await SupersetClient.put({
endpoint: `/api/v1/me/`,
jsonPayload: { ...payload },

View File

@@ -22,7 +22,7 @@ import { SelectOption } from 'src/components/ListView';
import { FormValues } from './types';
export const createUser = async (values: FormValues) => {
const { confirmPassword, ...payload } = values;
const { confirmPassword: _confirmPassword, ...payload } = values;
if (payload.active == null) {
payload.active = false;
}

View File

@@ -155,7 +155,7 @@ function AllEntities() {
setObjects(objects);
setLoading(false);
},
(error: Response) => {
() => {
addDangerToast('Error Fetching Tagged Objects');
setLoading(false);
},
@@ -169,7 +169,7 @@ function AllEntities() {
setTag(tag);
setLoading(false);
},
(error: Response) => {
() => {
addDangerToast(t('Error Fetching Tagged Objects'));
setLoading(false);
},

View File

@@ -69,9 +69,9 @@ const createMockUser = (overrides = {}) => ({
const createMockStore = (initialState: any = {}) =>
configureStore({
reducer: {
user: (state = initialState.user || {}, action: any) => state,
common: (state = initialState.common || {}, action: any) => state,
charts: (state = initialState.charts || {}, action: any) => state,
user: (state = initialState.user || {}, _action: any) => state,
common: (state = initialState.common || {}, _action: any) => state,
charts: (state = initialState.charts || {}, _action: any) => state,
},
preloadedState: initialState,
middleware: getDefaultMiddleware =>

View File

@@ -76,9 +76,10 @@ const createMockUser = (overrides = {}) => ({
const createMockStore = (initialState: any = {}) =>
configureStore({
reducer: {
user: (state = initialState.user || {}, action: any) => state,
common: (state = initialState.common || {}, action: any) => state,
dashboards: (state = initialState.dashboards || {}, action: any) => state,
user: (state = initialState.user || {}, _action: any) => state,
common: (state = initialState.common || {}, _action: any) => state,
dashboards: (state = initialState.dashboards || {}, _action: any) =>
state,
},
preloadedState: initialState,
middleware: getDefaultMiddleware =>

View File

@@ -146,7 +146,7 @@ function GroupsList({ user }: GroupsListProps) {
.then(() => {
deletedGroupsNames.push(group.name);
})
.catch(err => {
.catch(() => {
addDangerToast(t('Error deleting %s', group.name));
}),
),

View File

@@ -168,7 +168,7 @@ function UsersList({ user }: UsersListProps) {
.then(() => {
deletedUserNames.push(user.username);
})
.catch(err => {
.catch(() => {
addDangerToast(t('Error deleting %s', user.username));
}),
),

View File

@@ -31,4 +31,6 @@ interface CodeOverrideOptions {
* Hook for individual deployments to add custom overrides
* @param options - Configuration options for the setup process
*/
export default function setupCodeOverrides(options: CodeOverrideOptions = {}) {}
export default function setupCodeOverrides(
_options: CodeOverrideOptions = {},
) {}

View File

@@ -346,7 +346,7 @@ export class ThemeController {
* @throws {Error} If the user does not have permission to update the theme mode
*/
public setThemeMode(mode: ThemeMode): void {
this.validateModeUpdatePermission(mode);
this.validateModeUpdatePermission();
if (
this.currentMode === mode &&
@@ -530,7 +530,7 @@ export class ThemeController {
let newMode: ThemeMode;
try {
this.validateModeUpdatePermission(this.currentMode);
this.validateModeUpdatePermission();
const hasRequiredTheme = this.isValidThemeMode(this.currentMode);
newMode = hasRequiredTheme
? this.currentMode
@@ -838,10 +838,9 @@ export class ThemeController {
/**
* Validates permission to update mode.
* @param newMode - The new mode to validate
* @throws {Error} If the user does not have permission to update the theme mode
*/
private validateModeUpdatePermission(newMode: ThemeMode): void {
private validateModeUpdatePermission(): void {
// Check if user can set a new theme mode (dark theme must exist)
if (!this.canSetMode())
throw new Error(