mirror of
https://github.com/apache/superset.git
synced 2026-05-12 19:35:17 +00:00
fix(types): resolve remaining TypeScript CI errors
- Remove unused AdhocFilter import from FiltersConfigForm.tsx - Fix DndMetricSelect.tsx ColumnMeta type cast for AdhocMetric column - Add Operators import and cast operatorId in AdhocFilter/index.ts - Cast operators prop in AdhocFilterControl/index.tsx - Fix deck_slices type access and add parameter types in AdhocFilterEditPopover - Use duplicateWith for creating corrected AdhocFilter instance - Add React import and cast props in DatasourceControl.test.tsx - Add React import and cast props in AdhocFilterEditPopover.test.tsx 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import type React from 'react';
|
||||
import { Route } from 'react-router-dom';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { DatasourceType, JsonObject, SupersetClient } from '@superset-ui/core';
|
||||
@@ -107,37 +108,40 @@ interface TestProps {
|
||||
}
|
||||
|
||||
// Use type assertion for test props since the component is wrapped with withTheme
|
||||
const createProps = (overrides: JsonObject = {}): TestProps => ({
|
||||
hovered: false,
|
||||
type: 'DatasourceControl',
|
||||
label: 'Datasource',
|
||||
default: null,
|
||||
description: null,
|
||||
value: '25__table',
|
||||
form_data: {},
|
||||
datasource: mockDatasource,
|
||||
validationErrors: [],
|
||||
name: 'datasource',
|
||||
actions: {
|
||||
changeDatasource: jest.fn(),
|
||||
setControlValue: jest.fn(),
|
||||
},
|
||||
isEditable: true,
|
||||
user: {
|
||||
createdOn: '2021-04-27T18:12:38.952304',
|
||||
email: 'admin',
|
||||
firstName: 'admin',
|
||||
isActive: true,
|
||||
lastName: 'admin',
|
||||
permissions: {},
|
||||
roles: { Admin: Array(173) },
|
||||
userId: 1,
|
||||
username: 'admin',
|
||||
},
|
||||
onChange: jest.fn(),
|
||||
onDatasourceSave: jest.fn(),
|
||||
...overrides,
|
||||
});
|
||||
// The withTheme HOC makes the props type complex, so we use a cast to bypass the type check
|
||||
type DatasourceControlComponentProps = React.ComponentProps<typeof DatasourceControl>;
|
||||
const createProps = (overrides: JsonObject = {}): DatasourceControlComponentProps =>
|
||||
({
|
||||
hovered: false,
|
||||
type: 'DatasourceControl',
|
||||
label: 'Datasource',
|
||||
default: null,
|
||||
description: null,
|
||||
value: '25__table',
|
||||
form_data: {},
|
||||
datasource: mockDatasource,
|
||||
validationErrors: [],
|
||||
name: 'datasource',
|
||||
actions: {
|
||||
changeDatasource: jest.fn(),
|
||||
setControlValue: jest.fn(),
|
||||
},
|
||||
isEditable: true,
|
||||
user: {
|
||||
createdOn: '2021-04-27T18:12:38.952304',
|
||||
email: 'admin',
|
||||
firstName: 'admin',
|
||||
isActive: true,
|
||||
lastName: 'admin',
|
||||
permissions: {},
|
||||
roles: { Admin: Array(173) },
|
||||
userId: 1,
|
||||
username: 'admin',
|
||||
},
|
||||
onChange: jest.fn(),
|
||||
onDatasourceSave: jest.fn(),
|
||||
...overrides,
|
||||
}) as DatasourceControlComponentProps;
|
||||
|
||||
async function openAndSaveChanges(datasource: TestDatasource) {
|
||||
fetchMock.get(
|
||||
|
||||
@@ -90,7 +90,7 @@ const coerceMetrics = (
|
||||
);
|
||||
if (column) {
|
||||
// Cast to unknown first to handle type mismatch between @superset-ui/core and local AdhocMetric
|
||||
return new AdhocMetric({ ...(metric as unknown as Record<string, unknown>), column });
|
||||
return new AdhocMetric({ ...(metric as unknown as Record<string, unknown>), column: column as unknown as Record<string, unknown> });
|
||||
}
|
||||
}
|
||||
// Cast to unknown first to handle type mismatch between @superset-ui/core and local AdhocMetric
|
||||
@@ -349,9 +349,10 @@ const DndMetricSelect = (props: any) => {
|
||||
droppedItem.type === DndItemType.Column
|
||||
) {
|
||||
const itemValue = droppedItem.value as ColumnMeta;
|
||||
const config: Partial<AdhocMetric> = {
|
||||
// Cast config to handle ColumnMeta/ColumnType mismatch
|
||||
const config = {
|
||||
column: itemValue,
|
||||
};
|
||||
} as Partial<AdhocMetric>;
|
||||
if (itemValue.type_generic === GenericDataType.Numeric) {
|
||||
config.aggregate = AGGREGATES.SUM;
|
||||
} else if (
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
CUSTOM_OPERATORS,
|
||||
DISABLE_INPUT_OPERATORS,
|
||||
OPERATOR_ENUM_TO_OPERATOR_TYPE,
|
||||
Operators,
|
||||
} from 'src/explore/constants';
|
||||
import { translateToSql } from '../utils/translateToSQL';
|
||||
import { Clauses, ExpressionTypes } from '../types';
|
||||
@@ -68,7 +69,7 @@ export default class AdhocFilter {
|
||||
this.operator = adhocFilter.operator?.toUpperCase();
|
||||
this.operatorId = adhocFilter.operatorId;
|
||||
this.comparator = adhocFilter.comparator;
|
||||
if (adhocFilter.operatorId && DISABLE_INPUT_OPERATORS.indexOf(adhocFilter.operatorId) >= 0) {
|
||||
if (adhocFilter.operatorId && DISABLE_INPUT_OPERATORS.indexOf(adhocFilter.operatorId as Operators) >= 0) {
|
||||
this.comparator = undefined;
|
||||
}
|
||||
this.clause = adhocFilter.clause || Clauses.Where;
|
||||
|
||||
@@ -394,13 +394,13 @@ class AdhocFilterControl extends Component<AdhocFilterControlProps, AdhocFilterC
|
||||
addNewFilterPopoverTrigger(trigger: ReactNode): JSX.Element {
|
||||
return (
|
||||
<AdhocFilterPopoverTrigger
|
||||
operators={this.props.operators}
|
||||
operators={this.props.operators as Operators[] | undefined}
|
||||
sections={this.props.sections}
|
||||
adhocFilter={new AdhocFilter({})}
|
||||
datasource={this.props.datasource}
|
||||
datasource={this.props.datasource as Record<string, unknown> || {}}
|
||||
options={this.state.options}
|
||||
onFilterEdit={this.onNewFilter}
|
||||
partitionColumn={this.state.partitionColumn}
|
||||
onFilterEdit={this.onNewFilter as (editedFilter: AdhocFilter) => void}
|
||||
partitionColumn={this.state.partitionColumn ?? undefined}
|
||||
>
|
||||
{trigger}
|
||||
</AdhocFilterPopoverTrigger>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type React from 'react';
|
||||
import { render, screen, fireEvent } from 'spec/helpers/testing-library';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
@@ -70,10 +71,18 @@ const defaultProps = {
|
||||
datasource: {},
|
||||
};
|
||||
|
||||
// Cast props to handle AdhocMetric type in options array
|
||||
type AdhocFilterEditPopoverComponentProps = React.ComponentProps<typeof AdhocFilterEditPopover>;
|
||||
const renderPopover = (props: Partial<typeof defaultProps> = {}) =>
|
||||
render(<AdhocFilterEditPopover {...defaultProps} {...props} />, {
|
||||
useRedux: true, // Add Redux provider for context
|
||||
});
|
||||
render(
|
||||
<AdhocFilterEditPopover
|
||||
{...(defaultProps as unknown as AdhocFilterEditPopoverComponentProps)}
|
||||
{...(props as unknown as Partial<AdhocFilterEditPopoverComponentProps>)}
|
||||
/>,
|
||||
{
|
||||
useRedux: true, // Add Redux provider for context
|
||||
},
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
|
||||
describe('AdhocFilterEditPopover', () => {
|
||||
|
||||
@@ -34,6 +34,7 @@ import columnType from 'src/explore/components/controls/FilterControl/columnType
|
||||
import {
|
||||
POPOVER_INITIAL_HEIGHT,
|
||||
POPOVER_INITIAL_WIDTH,
|
||||
Operators,
|
||||
} from 'src/explore/constants';
|
||||
import rison from 'rison';
|
||||
import { isObject } from 'lodash';
|
||||
@@ -210,9 +211,8 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
}
|
||||
|
||||
onSave() {
|
||||
const hasDeckSlices =
|
||||
this.state.adhocFilter.deck_slices &&
|
||||
this.state.adhocFilter.deck_slices.length > 0;
|
||||
const deckSlices = this.state.adhocFilter.deck_slices as number[] | undefined;
|
||||
const hasDeckSlices = deckSlices && deckSlices.length > 0;
|
||||
|
||||
if (!hasDeckSlices) {
|
||||
this.props.onChange(this.state.adhocFilter);
|
||||
@@ -226,10 +226,9 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
}
|
||||
return item;
|
||||
});
|
||||
const correctedAdhocFilter = {
|
||||
...this.state.adhocFilter,
|
||||
const correctedAdhocFilter = this.state.adhocFilter.duplicateWith({
|
||||
layerFilterScope: selectedLayers,
|
||||
};
|
||||
});
|
||||
this.setState({ hasLayerFilterScopeChanged: false });
|
||||
this.props.onChange(correctedAdhocFilter);
|
||||
this.props.onClose();
|
||||
@@ -261,17 +260,17 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
document.removeEventListener('mousemove', this.onMouseMove);
|
||||
}
|
||||
|
||||
onTabChange(activeKey) {
|
||||
onTabChange(activeKey: string) {
|
||||
this.setState({
|
||||
activeKey,
|
||||
});
|
||||
}
|
||||
|
||||
adjustHeight(heightDifference) {
|
||||
adjustHeight(heightDifference: number) {
|
||||
this.setState(state => ({ height: state.height + heightDifference }));
|
||||
}
|
||||
|
||||
loadLayerOptions(page, pageSize) {
|
||||
loadLayerOptions(page: number, pageSize: number) {
|
||||
const query = rison.encode({
|
||||
columns: ['id', 'slice_name', 'viz_type'],
|
||||
filters: [{ col: 'viz_type', opr: 'sw', value: 'deck' }],
|
||||
@@ -297,7 +296,7 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
};
|
||||
}
|
||||
|
||||
const deckSlices = this.props.adhocFilter?.deck_slices || [];
|
||||
const deckSlices = (this.props.adhocFilter?.deck_slices || []) as number[];
|
||||
|
||||
const list = [
|
||||
{
|
||||
@@ -306,7 +305,7 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
label: 'All',
|
||||
},
|
||||
...response.json.result
|
||||
.map(item => {
|
||||
.map((item: { id: number; slice_name: string }) => {
|
||||
const sliceIndex = deckSlices.indexOf(item.id);
|
||||
return {
|
||||
id: item.id,
|
||||
@@ -315,8 +314,8 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
sliceIndex,
|
||||
};
|
||||
})
|
||||
.filter(item => item.sliceIndex !== -1)
|
||||
.map(({ sliceIndex, ...item }) => item),
|
||||
.filter((item: { sliceIndex: number }) => item.sliceIndex !== -1)
|
||||
.map(({ sliceIndex, ...item }: { sliceIndex: number; id: number; value: number; label: string }) => item),
|
||||
];
|
||||
|
||||
return {
|
||||
@@ -326,24 +325,26 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
});
|
||||
}
|
||||
|
||||
onLayerChange(selectedValue) {
|
||||
let updatedSelectedLayers = selectedValue;
|
||||
onLayerChange(selectedValue: LayerOption[] | number[] | null) {
|
||||
let updatedSelectedLayers: LayerOption[] = selectedValue as LayerOption[] || [];
|
||||
|
||||
if (!selectedValue || selectedValue.length === 0) {
|
||||
updatedSelectedLayers = [{ id: null, value: -1, label: 'All' }];
|
||||
} else if (
|
||||
selectedValue.length > 1 &&
|
||||
selectedValue.some(item => item.value === -1 || item === -1)
|
||||
selectedValue.some((item: LayerOption | number) =>
|
||||
(typeof item === 'object' && item.value === -1) || item === -1
|
||||
)
|
||||
) {
|
||||
const lastItem = selectedValue[selectedValue.length - 1];
|
||||
if (
|
||||
selectedValue[selectedValue.length - 1].value === -1 ||
|
||||
selectedValue[selectedValue.length - 1] === -1
|
||||
(typeof lastItem === 'object' && lastItem.value === -1) ||
|
||||
lastItem === -1
|
||||
) {
|
||||
updatedSelectedLayers = [{ id: null, value: -1, label: 'All' }];
|
||||
} else {
|
||||
updatedSelectedLayers = selectedValue
|
||||
.filter(item => item.value !== -1)
|
||||
.filter(item => item !== -1);
|
||||
updatedSelectedLayers = (selectedValue as LayerOption[])
|
||||
.filter((item: LayerOption) => item.value !== -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,8 +375,8 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
!adhocFilter.equals(propsAdhocFilter) ||
|
||||
hasLayerFilterScopeChanged;
|
||||
|
||||
const hasDeckSlices =
|
||||
adhocFilter.deck_slices && adhocFilter.deck_slices.length > 0;
|
||||
const renderDeckSlices = adhocFilter.deck_slices as number[] | undefined;
|
||||
const hasDeckSlices = renderDeckSlices && renderDeckSlices.length > 0;
|
||||
|
||||
return (
|
||||
<FilterPopoverContentContainer
|
||||
@@ -399,7 +400,7 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
children: (
|
||||
<ErrorBoundary>
|
||||
<AdhocFilterEditPopoverSimpleTabContent
|
||||
operators={operators}
|
||||
operators={operators as Operators[] | undefined}
|
||||
adhocFilter={this.state.adhocFilter}
|
||||
onChange={this.onAdhocFilterChange}
|
||||
options={options}
|
||||
|
||||
Reference in New Issue
Block a user