mirror of
https://github.com/apache/superset.git
synced 2026-05-03 23:14:29 +00:00
Compare commits
5 Commits
fix/postgr
...
fix/no-unu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
366ab0f3fd | ||
|
|
96b2cc9e56 | ||
|
|
66eb994d76 | ||
|
|
0ac2b42ba5 | ||
|
|
0206e7bcab |
@@ -375,7 +375,7 @@ module.exports = {
|
||||
'@typescript-eslint/no-non-null-assertion': 0,
|
||||
'@typescript-eslint/explicit-function-return-type': 0,
|
||||
'@typescript-eslint/explicit-module-boundary-types': 0,
|
||||
'@typescript-eslint/no-unused-vars': 'warn',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'@typescript-eslint/prefer-optional-chain': 'error',
|
||||
|
||||
// Disable base rules that conflict with TS versions
|
||||
|
||||
@@ -23,7 +23,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';
|
||||
|
||||
@@ -238,7 +238,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",
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"error",
|
||||
|
||||
@@ -187,7 +187,7 @@ test('should pass through additional formData properties', () => {
|
||||
});
|
||||
|
||||
test('should handle small cell dimensions', () => {
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} rowHeight={80} />);
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} />);
|
||||
|
||||
const superChart = screen.getByText('SuperChart Mock');
|
||||
const cellContainer = superChart.parentElement?.parentElement;
|
||||
|
||||
@@ -76,8 +76,6 @@ const NoDataMessage = styled.div<{ theme: any }>`
|
||||
|
||||
interface MatrixifyGridCellProps {
|
||||
cell: GridCellData;
|
||||
rowHeight: number;
|
||||
datasource?: any;
|
||||
hooks?: any;
|
||||
}
|
||||
|
||||
@@ -91,7 +89,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 || '';
|
||||
|
||||
@@ -173,11 +171,6 @@ const MatrixifyGridCell = memo(
|
||||
return false;
|
||||
}
|
||||
|
||||
// Re-render if rowHeight changes
|
||||
if (prevProps.rowHeight !== nextProps.rowHeight) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Re-render if cell position changes (shouldn't happen, but just in case)
|
||||
if (prevProps.cell.id !== nextProps.cell.id) {
|
||||
return false;
|
||||
|
||||
@@ -31,8 +31,8 @@ jest.mock('./MatrixifyGridGenerator', () => ({
|
||||
|
||||
// Mock MatrixifyGridCell component
|
||||
jest.mock('./MatrixifyGridCell', () =>
|
||||
// eslint-disable-next-line react/display-name, @typescript-eslint/no-unused-vars
|
||||
({ cell, rowHeight, datasource, hooks }: any) => (
|
||||
// eslint-disable-next-line react/display-name
|
||||
({ cell }: any) => (
|
||||
<div data-testid={`grid-cell-${cell.id}`}>Cell: {cell.id}</div>
|
||||
),
|
||||
);
|
||||
|
||||
@@ -117,8 +117,8 @@ interface MatrixifyGridRendererProps {
|
||||
|
||||
function MatrixifyGridRenderer({
|
||||
formData,
|
||||
datasource,
|
||||
width,
|
||||
datasource: _datasource,
|
||||
width: _width,
|
||||
height,
|
||||
hooks,
|
||||
}: MatrixifyGridRendererProps) {
|
||||
@@ -247,13 +247,11 @@ function MatrixifyGridRenderer({
|
||||
{/* Row cells for this column group */}
|
||||
{row
|
||||
.slice(colGroup.startIdx, colGroup.endIdx)
|
||||
.map((cell, colIdx) =>
|
||||
.map(cell =>
|
||||
cell ? (
|
||||
<MatrixifyGridCell
|
||||
key={cell.id}
|
||||
cell={cell}
|
||||
rowHeight={rowHeight}
|
||||
datasource={datasource}
|
||||
hooks={hooks}
|
||||
/>
|
||||
) : null,
|
||||
|
||||
@@ -33,7 +33,6 @@ export function Label(props: LabelProps) {
|
||||
onClick,
|
||||
children,
|
||||
icon,
|
||||
id,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
|
||||
@@ -34,12 +34,9 @@ import 'dayjs/plugin/timezone';
|
||||
export type TimezoneSelectorProps = {
|
||||
onTimezoneChange: (value: string) => void;
|
||||
timezone?: string | null;
|
||||
minWidth?: string;
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
const MIN_SELECT_WIDTH = '400px';
|
||||
|
||||
function findMatchingTimezone(
|
||||
timezone: string | null | undefined,
|
||||
options: TimezoneOption[],
|
||||
@@ -66,7 +63,6 @@ function findMatchingTimezone(
|
||||
export default function TimezoneSelector({
|
||||
onTimezoneChange,
|
||||
timezone,
|
||||
minWidth = MIN_SELECT_WIDTH,
|
||||
placeholder,
|
||||
...rest
|
||||
}: TimezoneSelectorProps) {
|
||||
|
||||
@@ -40,7 +40,7 @@ export default function createD3NumberFormatter(config: {
|
||||
|
||||
try {
|
||||
formatFunc = formatLocale(locale ?? DEFAULT_D3_FORMAT).format(formatString);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
formatFunc = value => `${value} (Invalid format: ${formatString})`;
|
||||
isInvalid = true;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ export default function extractQueryFields(
|
||||
if (typeof item === 'string') {
|
||||
try {
|
||||
return JSON.parse(item);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error(t('Found invalid orderby options'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ export function initFeatureFlags(featureFlags?: FeatureFlagMap) {
|
||||
export function isFeatureEnabled(feature: FeatureFlag): boolean {
|
||||
try {
|
||||
return !!window.featureFlags[feature as keyof FeatureFlagMap];
|
||||
} catch (error) {
|
||||
} catch {
|
||||
logger.error(`Failed to query feature flag ${feature}`);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -187,7 +187,7 @@ export function isJsonString(str: string): boolean {
|
||||
try {
|
||||
JSON.parse(str);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,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));
|
||||
|
||||
@@ -231,7 +231,6 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||
defaultAlignPN: alignPositiveNegative,
|
||||
showCellBars,
|
||||
colorPositiveNegative,
|
||||
totals,
|
||||
columnColorFormatters,
|
||||
allowRearrangeColumns,
|
||||
basicColorFormatters,
|
||||
|
||||
@@ -512,10 +512,10 @@ const config: ControlPanelConfig = {
|
||||
mapStateToProps(explore, _, chart) {
|
||||
const timeComparisonValue =
|
||||
explore?.controls?.time_compare?.value;
|
||||
const { colnames: _colnames, coltypes: _coltypes } =
|
||||
const { colnames: queryColnames, coltypes: queryColtypes } =
|
||||
chart?.queriesResponse?.[0] ?? {};
|
||||
let colnames: string[] = _colnames || [];
|
||||
let coltypes: GenericDataType[] = _coltypes || [];
|
||||
let colnames: string[] = queryColnames || [];
|
||||
let coltypes: GenericDataType[] = queryColtypes || [];
|
||||
const childColumnMap: Record<string, boolean> = {};
|
||||
const timeComparisonColumnMap: Record<string, boolean> = {};
|
||||
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { styled, useTheme, type SupersetTheme } from '@apache-superset/core/ui';
|
||||
import { styled } from '@apache-superset/core/ui';
|
||||
import { CustomCellRendererProps } from '@superset-ui/core/components/ThemedAgGridReact';
|
||||
import { BasicColorFormatterType, InputColumn, ValueRange } from '../types';
|
||||
import { useIsDark } from '../utils/useTableTheme';
|
||||
|
||||
const StyledTotalCell = styled.div`
|
||||
${() => `
|
||||
@@ -106,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
|
||||
@@ -149,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>;
|
||||
}
|
||||
@@ -195,8 +187,6 @@ export const NumericCellRenderer = (
|
||||
const background = cellBackground({
|
||||
value: value as number,
|
||||
colorPositiveNegative,
|
||||
isDarkTheme,
|
||||
theme,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
import { ColDef } from '@superset-ui/core/components/ThemedAgGridReact';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { DataRecord, DataRecordValue } from '@superset-ui/core';
|
||||
import { DataRecordValue } from '@superset-ui/core';
|
||||
import { GenericDataType } from '@apache-superset/core/api/core';
|
||||
import { ColorFormatters } from '@superset-ui/chart-controls';
|
||||
import { extent as d3Extent, max as d3Max } from 'd3-array';
|
||||
@@ -53,7 +53,6 @@ type UseColDefsProps = {
|
||||
defaultAlignPN: boolean;
|
||||
showCellBars: boolean;
|
||||
colorPositiveNegative: boolean;
|
||||
totals: DataRecord | undefined;
|
||||
columnColorFormatters: ColorFormatters;
|
||||
allowRearrangeColumns?: boolean;
|
||||
basicColorFormatters?: { [Key: string]: BasicColorFormatterType }[];
|
||||
@@ -216,7 +215,6 @@ export const useColDefs = ({
|
||||
defaultAlignPN,
|
||||
showCellBars,
|
||||
colorPositiveNegative,
|
||||
totals,
|
||||
columnColorFormatters,
|
||||
allowRearrangeColumns,
|
||||
basicColorFormatters,
|
||||
|
||||
@@ -52,14 +52,14 @@ function BigNumberVis({
|
||||
kickerFontSize = PROPORTION.KICKER,
|
||||
metricNameFontSize = PROPORTION.METRIC_NAME,
|
||||
showMetricName = true,
|
||||
mainColor = BRAND_COLOR,
|
||||
mainColor: _mainColor = BRAND_COLOR,
|
||||
showTimestamp = false,
|
||||
showTrendLine = false,
|
||||
startYAxisAtZero = true,
|
||||
startYAxisAtZero: _startYAxisAtZero = true,
|
||||
subheader = '',
|
||||
subheaderFontSize = PROPORTION.SUBHEADER,
|
||||
subtitleFontSize = PROPORTION.SUBHEADER,
|
||||
timeRangeFixed = false,
|
||||
timeRangeFixed: _timeRangeFixed = false,
|
||||
...props
|
||||
}: BigNumberVizProps) {
|
||||
const theme = useTheme();
|
||||
|
||||
@@ -213,10 +213,10 @@ const config: ControlPanelConfig = {
|
||||
}
|
||||
return value.label;
|
||||
});
|
||||
const { colnames: _colnames, coltypes: _coltypes } =
|
||||
const { colnames: queryColnames, coltypes: queryColtypes } =
|
||||
chart?.queriesResponse?.[0] ?? {};
|
||||
const colnames: string[] = _colnames || [];
|
||||
const coltypes: GenericDataType[] = _coltypes || [];
|
||||
const colnames: string[] = queryColnames || [];
|
||||
const coltypes: GenericDataType[] = queryColtypes || [];
|
||||
|
||||
return {
|
||||
queryResponse: chart?.queriesResponse?.[0] as
|
||||
|
||||
@@ -341,12 +341,12 @@ const config: ControlPanelConfig = {
|
||||
'Stack in groups, where each group corresponds to a dimension',
|
||||
),
|
||||
shouldMapStateToProps: (
|
||||
prevState,
|
||||
state,
|
||||
controlState,
|
||||
chartState,
|
||||
_prevState,
|
||||
_state,
|
||||
_controlState,
|
||||
_chartState,
|
||||
) => true,
|
||||
mapStateToProps: (state, controlState, chartState) => {
|
||||
mapStateToProps: (state, _controlState, _chartState) => {
|
||||
const value: JsonArray = ensureIsArray(
|
||||
state.controls.groupby?.value,
|
||||
) as JsonArray;
|
||||
|
||||
@@ -106,7 +106,7 @@ const mockGroups = {
|
||||
const createMockPivotData = (rowData: Record<string, number>) =>
|
||||
({
|
||||
rowKeys: Object.keys(rowData).map(key => key.split('.')),
|
||||
getAggregator: (rowKey: string[], colName: string) => ({
|
||||
getAggregator: (rowKey: string[], _colName: string) => ({
|
||||
value: () => rowData[rowKey.join('.')],
|
||||
}),
|
||||
}) as unknown as PivotData;
|
||||
|
||||
@@ -570,10 +570,10 @@ const config: ControlPanelConfig = {
|
||||
mapStateToProps(explore, _, chart) {
|
||||
const timeComparisonValue =
|
||||
explore?.controls?.time_compare?.value;
|
||||
const { colnames: _colnames, coltypes: _coltypes } =
|
||||
const { colnames: queryColnames, coltypes: queryColtypes } =
|
||||
chart?.queriesResponse?.[0] ?? {};
|
||||
let colnames: string[] = _colnames || [];
|
||||
let coltypes: GenericDataType[] = _coltypes || [];
|
||||
let colnames: string[] = queryColnames || [];
|
||||
let coltypes: GenericDataType[] = queryColtypes || [];
|
||||
const childColumnMap: Record<string, boolean> = {};
|
||||
const timeComparisonColumnMap: Record<string, boolean> = {};
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ const TreeNodeRenderer: React.FC<TreeNodeRendererProps> = ({
|
||||
}) => {
|
||||
const { data } = node;
|
||||
const parts = data.id.split(':');
|
||||
const [identifier, _dbId, schema, tableName] = parts;
|
||||
const [identifier, dbId, schema, tableName] = parts;
|
||||
|
||||
// Use manually tracked open state for icon display
|
||||
// This prevents search auto-expansion from affecting the icon
|
||||
@@ -205,7 +205,7 @@ const TreeNodeRenderer: React.FC<TreeNodeRendererProps> = ({
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
fetchLazyTables({
|
||||
dbId: _dbId,
|
||||
dbId,
|
||||
catalog,
|
||||
schema,
|
||||
forceRefresh: true,
|
||||
|
||||
@@ -71,7 +71,7 @@ export const ItemSeparator = styled.div<{
|
||||
export const TreeFolderContainer = styled(TreeItemContainer)<{
|
||||
isForbiddenDropTarget?: boolean;
|
||||
}>`
|
||||
${({ theme, depth, isForbiddenDropTarget, isOverlay }) => `
|
||||
${({ theme, depth, isForbiddenDropTarget, isOverlay: _isOverlay }) => `
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-top: ${theme.paddingSM}px;
|
||||
|
||||
@@ -288,14 +288,11 @@ interface CollectionTabTitleProps {
|
||||
|
||||
interface ColumnCollectionTableProps {
|
||||
columns: Column[];
|
||||
datasource: DatasourceObject;
|
||||
onColumnsChange: (columns: Column[]) => void;
|
||||
onDatasourceChange: (datasource: DatasourceObject) => void;
|
||||
editableColumnName?: boolean;
|
||||
showExpression?: boolean;
|
||||
allowAddItem?: boolean;
|
||||
allowEditDataType?: boolean;
|
||||
className?: string;
|
||||
itemGenerator?: () => Partial<Column>;
|
||||
columnLabelTooltips?: Record<string, string>;
|
||||
}
|
||||
@@ -472,9 +469,7 @@ function CollectionTabTitle({
|
||||
|
||||
function ColumnCollectionTable({
|
||||
columns,
|
||||
datasource,
|
||||
onColumnsChange,
|
||||
onDatasourceChange,
|
||||
editableColumnName = false,
|
||||
showExpression = false,
|
||||
allowAddItem = false,
|
||||
@@ -2320,13 +2315,10 @@ class DatasourceEditor extends PureComponent<
|
||||
</StyledButtonWrapper>
|
||||
</ColumnButtonWrapper>
|
||||
<ColumnCollectionTable
|
||||
className="columns-table"
|
||||
columns={this.state.databaseColumns}
|
||||
datasource={datasource}
|
||||
onColumnsChange={databaseColumns =>
|
||||
this.setColumns({ databaseColumns })
|
||||
}
|
||||
onDatasourceChange={this.onDatasourceChange}
|
||||
/>
|
||||
{this.state.metadataLoading && <Loading />}
|
||||
</StyledTableTabWrapper>
|
||||
@@ -2358,8 +2350,6 @@ class DatasourceEditor extends PureComponent<
|
||||
'as the alias in the SQL query.',
|
||||
),
|
||||
}}
|
||||
onDatasourceChange={this.onDatasourceChange}
|
||||
datasource={datasource}
|
||||
editableColumnName
|
||||
showExpression
|
||||
allowAddItem
|
||||
|
||||
@@ -23,7 +23,7 @@ import { ErrorAlert } from './ErrorAlert';
|
||||
|
||||
export function FrontendNetworkErrorMessage({
|
||||
error,
|
||||
subtitle,
|
||||
subtitle: _subtitle,
|
||||
compact,
|
||||
}: ErrorMessageComponentProps) {
|
||||
const { level, message } = error;
|
||||
|
||||
@@ -64,7 +64,6 @@ export const FilterableTable = ({
|
||||
filterText = '',
|
||||
expandedColumns = [],
|
||||
allowHTML = true,
|
||||
striped,
|
||||
}: FilterableTableProps) => {
|
||||
const getCellContent = useCellContentParser({
|
||||
columnKeys: orderedColumnKeys,
|
||||
@@ -128,7 +127,6 @@ export const FilterableTable = ({
|
||||
data={data}
|
||||
externalFilter={keywordFilter}
|
||||
showRowNumber
|
||||
striped={striped}
|
||||
enableActions
|
||||
columnReorderable
|
||||
/>
|
||||
|
||||
@@ -28,7 +28,6 @@ export interface FilterableTableProps {
|
||||
overscanColumnCount?: number;
|
||||
overscanRowCount?: number;
|
||||
rowHeight?: number;
|
||||
striped?: boolean;
|
||||
expandedColumns?: string[];
|
||||
allowHTML?: boolean;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ export function GridTable<RecordType extends object>({
|
||||
showRowNumber,
|
||||
enableActions,
|
||||
size = GridSize.Middle,
|
||||
striped,
|
||||
}: TableProps<RecordType>) {
|
||||
const theme = useTheme();
|
||||
const isExternalFilterPresent = useCallback(
|
||||
|
||||
@@ -57,6 +57,4 @@ export interface TableProps<RecordType> {
|
||||
showRowNumber?: boolean;
|
||||
|
||||
usePagination?: boolean;
|
||||
|
||||
striped?: boolean;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -32,12 +32,11 @@ interface StandardModalProps {
|
||||
saveDisabled?: boolean;
|
||||
saveLoading?: boolean;
|
||||
saveText?: string;
|
||||
cancelText?: string;
|
||||
errorTooltip?: ReactNode;
|
||||
children: ReactNode;
|
||||
isEditMode?: boolean;
|
||||
centered?: boolean;
|
||||
destroyOnClose?: boolean;
|
||||
destroyOnHidden?: boolean;
|
||||
maskClosable?: boolean;
|
||||
wrapProps?: object;
|
||||
contentLoading?: boolean;
|
||||
@@ -107,12 +106,11 @@ export function StandardModal({
|
||||
saveDisabled = false,
|
||||
saveLoading = false,
|
||||
saveText,
|
||||
cancelText,
|
||||
errorTooltip,
|
||||
children,
|
||||
isEditMode = false,
|
||||
centered = true,
|
||||
destroyOnClose = true,
|
||||
destroyOnHidden = true,
|
||||
maskClosable = false,
|
||||
wrapProps,
|
||||
contentLoading = false,
|
||||
@@ -129,6 +127,9 @@ export function StandardModal({
|
||||
primaryButtonName={primaryButtonName}
|
||||
show={show}
|
||||
width={`${width}px`}
|
||||
centered={centered}
|
||||
destroyOnHidden={destroyOnHidden}
|
||||
maskClosable={maskClosable}
|
||||
wrapProps={wrapProps}
|
||||
title={
|
||||
icon ? (
|
||||
|
||||
@@ -166,7 +166,7 @@ describe('loadTags', () => {
|
||||
const calls = fetchMock.callHistory.calls();
|
||||
|
||||
// Verify all calls include the custom tag filter
|
||||
calls.forEach(call => {
|
||||
calls.forEach(() => {
|
||||
const { url } = calls[0];
|
||||
const urlObj = new URL(url);
|
||||
const queryParam = urlObj.searchParams.get('q');
|
||||
|
||||
@@ -173,7 +173,11 @@ export class QueryResultContext
|
||||
requestedLimit?: number;
|
||||
} = {},
|
||||
) {
|
||||
const { appliedLimit, appliedLimitingFactor, ...opt } = options;
|
||||
const {
|
||||
appliedLimit,
|
||||
appliedLimitingFactor: _appliedLimitingFactor,
|
||||
...opt
|
||||
} = options;
|
||||
super(clientId, tab, runAsync, startDttm, opt);
|
||||
this.remoteId = remoteId;
|
||||
this.executedSql = executedSql;
|
||||
@@ -216,7 +220,7 @@ export class QueryErrorResultContext
|
||||
queryId?: number;
|
||||
} = {},
|
||||
) {
|
||||
const { queryId, executedSql, endDttm, ...opt } = options;
|
||||
const { queryId: _queryId, executedSql, endDttm, ...opt } = options;
|
||||
super(clientId, tab, runAsync, startDttm, opt);
|
||||
this.executedSql = executedSql ?? null;
|
||||
this.errorMessage = errorMessage;
|
||||
|
||||
@@ -230,20 +230,16 @@ export const useHeaderActionsMenu = ({
|
||||
createModalMenuItem(
|
||||
MenuKeys.SaveModal,
|
||||
<SaveModal
|
||||
addSuccessToast={addSuccessToast}
|
||||
addDangerToast={addDangerToast}
|
||||
dashboardId={dashboardId}
|
||||
dashboardTitle={dashboardTitle ?? ''}
|
||||
dashboardInfo={dashboardInfo}
|
||||
saveType={SAVE_TYPE_NEWDASHBOARD}
|
||||
layout={layout}
|
||||
expandedSlices={expandedSlices ?? {}}
|
||||
refreshFrequency={refreshFrequency}
|
||||
shouldPersistRefreshFrequency={shouldPersistRefreshFrequency}
|
||||
lastModifiedTime={lastModifiedTime}
|
||||
customCss={customCss ?? ''}
|
||||
colorNamespace={colorNamespace}
|
||||
colorScheme={colorScheme}
|
||||
onSave={onSave}
|
||||
triggerNode={
|
||||
<div data-test="save-as-menu-item">{t('Save as')}</div>
|
||||
|
||||
@@ -67,7 +67,6 @@ export const REFRESH_FREQUENCY_OPTIONS = [
|
||||
interface RefreshFrequencySelectProps {
|
||||
value: number;
|
||||
onChange: (value: number) => void;
|
||||
ariaLabel?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +76,6 @@ interface RefreshFrequencySelectProps {
|
||||
export const RefreshFrequencySelect = ({
|
||||
value,
|
||||
onChange,
|
||||
ariaLabel = t('Refresh frequency'),
|
||||
}: RefreshFrequencySelectProps) => {
|
||||
// Separate radio selection state from value state
|
||||
const [radioSelection, setRadioSelection] = useState(() =>
|
||||
|
||||
@@ -42,18 +42,14 @@ import {
|
||||
type SaveType = typeof SAVE_TYPE_OVERWRITE | typeof SAVE_TYPE_NEWDASHBOARD;
|
||||
|
||||
type SaveModalProps = {
|
||||
addSuccessToast: (arg: string) => void;
|
||||
addDangerToast: (arg: string) => void;
|
||||
dashboardId: number;
|
||||
dashboardTitle: string;
|
||||
dashboardInfo: Record<string, any>;
|
||||
expandedSlices: Record<string, any>;
|
||||
layout: Record<string, any>;
|
||||
saveType: SaveType;
|
||||
triggerNode: JSX.Element;
|
||||
customCss: string;
|
||||
colorNamespace?: string;
|
||||
colorScheme?: string;
|
||||
onSave: (data: any, id: number | string, saveType: SaveType) => void;
|
||||
canOverwrite: boolean;
|
||||
shouldPersistRefreshFrequency: boolean;
|
||||
@@ -65,18 +61,14 @@ type SaveModalProps = {
|
||||
|
||||
function SaveModal({
|
||||
saveType: initialSaveType = SAVE_TYPE_OVERWRITE,
|
||||
colorNamespace,
|
||||
colorScheme,
|
||||
shouldPersistRefreshFrequency = false,
|
||||
dashboardTitle,
|
||||
onSave,
|
||||
triggerNode,
|
||||
canOverwrite,
|
||||
addSuccessToast,
|
||||
addDangerToast,
|
||||
dashboardId,
|
||||
dashboardInfo,
|
||||
expandedSlices,
|
||||
layout,
|
||||
customCss,
|
||||
refreshFrequency,
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('Divider', () => {
|
||||
index: 0,
|
||||
editMode: false,
|
||||
handleComponentDrop: jest.fn(),
|
||||
deleteComponent: (id: string, parentId: string) => {},
|
||||
deleteComponent: () => {},
|
||||
};
|
||||
|
||||
const setup = (overrideProps: Partial<DividerProps> = {}) =>
|
||||
|
||||
@@ -543,7 +543,6 @@ const Tabs = (props: TabsProps): ReactElement => {
|
||||
tabBarPaddingLeft={tabBarPaddingLeft}
|
||||
onTabsReorder={handleTabsReorder}
|
||||
isEditingTabTitle={isEditingTabTitle}
|
||||
onTabTitleEditingChange={handleTabTitleEditingChange}
|
||||
/>
|
||||
),
|
||||
[
|
||||
@@ -559,7 +558,6 @@ const Tabs = (props: TabsProps): ReactElement => {
|
||||
tabBarPaddingLeft,
|
||||
handleTabsReorder,
|
||||
isEditingTabTitle,
|
||||
handleTabTitleEditingChange,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@@ -108,7 +108,6 @@ export interface TabsRendererProps {
|
||||
tabBarPaddingLeft?: number;
|
||||
onTabsReorder?: (oldIndex: number, newIndex: number) => void;
|
||||
isEditingTabTitle?: boolean;
|
||||
onTabTitleEditingChange?: (isEditing: boolean) => void;
|
||||
}
|
||||
|
||||
interface DraggableTabNodeProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
@@ -117,7 +116,7 @@ interface DraggableTabNodeProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
}
|
||||
|
||||
const DraggableTabNode: React.FC<Readonly<DraggableTabNodeProps>> = ({
|
||||
className,
|
||||
className: _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);
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ export default class WithPopoverMenu extends PureComponent<
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: WithPopoverMenuProps) {
|
||||
componentDidUpdate(_prevProps: WithPopoverMenuProps) {
|
||||
if (this.props.editMode && this.props.isFocused && !this.state.isFocused) {
|
||||
document.addEventListener('click', this.handleClick);
|
||||
document.addEventListener('drag', this.handleClick);
|
||||
|
||||
@@ -71,7 +71,7 @@ export const useFilterConfigModal = ({
|
||||
);
|
||||
}
|
||||
closeFilterConfigModal();
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Error toast already shown in action, prevent modal close
|
||||
}
|
||||
},
|
||||
|
||||
@@ -268,7 +268,7 @@ const FilterControls: FC<FilterControlsProps> = ({
|
||||
);
|
||||
|
||||
const customizationRenderer = useCallback(
|
||||
(item: ChartCustomization | ChartCustomizationDivider, index: number) => {
|
||||
(item: ChartCustomization | ChartCustomizationDivider, _index: number) => {
|
||||
if (isChartCustomizationDivider(item)) {
|
||||
return (
|
||||
<FilterDivider
|
||||
|
||||
@@ -139,8 +139,8 @@ const VerticalFilterBar: FC<VerticalBarProps> = ({
|
||||
onPendingCustomizationDataMaskChange,
|
||||
toggleFiltersBar,
|
||||
width,
|
||||
clearAllTriggers,
|
||||
onClearAllComplete,
|
||||
clearAllTriggers: _clearAllTriggers,
|
||||
onClearAllComplete: _onClearAllComplete,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const [isScrolling, setIsScrolling] = useState(false);
|
||||
|
||||
@@ -321,12 +321,11 @@ function FiltersConfigModal({
|
||||
(dragIndex: number, targetIndex: number, id: string) => {
|
||||
const isFilter = isFilterId(id);
|
||||
if (isFilter) {
|
||||
filterOperations.handleRearrangeFilters(dragIndex, targetIndex, id);
|
||||
filterOperations.handleRearrangeFilters(dragIndex, targetIndex);
|
||||
} else {
|
||||
customizationOperations.handleRearrangeCustomizations(
|
||||
dragIndex,
|
||||
targetIndex,
|
||||
id,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -35,7 +35,6 @@ export interface CustomizationOperations {
|
||||
handleRearrangeCustomizations: (
|
||||
dragIndex: number,
|
||||
targetIndex: number,
|
||||
id: string,
|
||||
) => void;
|
||||
}
|
||||
|
||||
@@ -105,7 +104,7 @@ export function useCustomizationOperations({
|
||||
);
|
||||
|
||||
const handleRearrangeCustomizations = useCallback(
|
||||
(dragIndex: number, targetIndex: number, id: string) => {
|
||||
(dragIndex: number, targetIndex: number) => {
|
||||
const newOrderedIds = [...customizationState.orderedIds];
|
||||
const [removed] = newOrderedIds.splice(dragIndex, 1);
|
||||
newOrderedIds.splice(targetIndex, 0, removed);
|
||||
|
||||
@@ -50,11 +50,7 @@ export interface FilterOperations {
|
||||
addFilter: (type: NativeFilterType) => void;
|
||||
handleRemoveFilter: (id: string) => void;
|
||||
restoreFilter: (id: string) => void;
|
||||
handleRearrangeFilters: (
|
||||
dragIndex: number,
|
||||
targetIndex: number,
|
||||
id: string,
|
||||
) => void;
|
||||
handleRearrangeFilters: (dragIndex: number, targetIndex: number) => void;
|
||||
canBeUsedAsDependency: (filterId: string) => boolean;
|
||||
buildDependencyMap: () => Map<string, string[]>;
|
||||
getAvailableFilters: (
|
||||
@@ -125,7 +121,7 @@ export function useFilterOperations({
|
||||
);
|
||||
|
||||
const handleRearrangeFilters = useCallback(
|
||||
(dragIndex: number, targetIndex: number, id: string) => {
|
||||
(dragIndex: number, targetIndex: number) => {
|
||||
const newOrderedIds = [...filterState.orderedIds];
|
||||
const [removed] = newOrderedIds.splice(dragIndex, 1);
|
||||
newOrderedIds.splice(targetIndex, 0, removed);
|
||||
|
||||
@@ -133,12 +133,12 @@ export default function DataSourcePanel({
|
||||
width,
|
||||
}: Props) {
|
||||
const [dropzones] = useContext(DropzoneContext);
|
||||
const { columns: _columns, metrics, folders: _folders } = datasource;
|
||||
const { columns, metrics, folders: rawFolders } = datasource;
|
||||
|
||||
const allowedColumns = useMemo(() => {
|
||||
const validators = Object.values(dropzones);
|
||||
if (!Array.isArray(_columns)) return [];
|
||||
return _columns.filter(column =>
|
||||
if (!Array.isArray(columns)) return [];
|
||||
return columns.filter(column =>
|
||||
validators.some(validator =>
|
||||
validator({
|
||||
value: column as DndItemValue,
|
||||
@@ -146,7 +146,7 @@ export default function DataSourcePanel({
|
||||
}),
|
||||
),
|
||||
);
|
||||
}, [dropzones, _columns]);
|
||||
}, [dropzones, columns]);
|
||||
|
||||
const allowedMetrics = useMemo(() => {
|
||||
const validators = Object.values(dropzones);
|
||||
@@ -229,11 +229,11 @@ export default function DataSourcePanel({
|
||||
transformDatasourceWithFolders(
|
||||
filteredMetrics,
|
||||
sortedColumns,
|
||||
_folders,
|
||||
rawFolders,
|
||||
allowedMetrics,
|
||||
allowedColumns,
|
||||
),
|
||||
[_folders, filteredMetrics, sortedColumns],
|
||||
[rawFolders, filteredMetrics, sortedColumns],
|
||||
);
|
||||
|
||||
const showInfoboxCheck = () => {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { forwardRef, RefObject, MouseEvent } from 'react';
|
||||
import { MouseEvent } from 'react';
|
||||
import { Button } from '@superset-ui/core/components';
|
||||
import { ErrorAlert } from 'src/components';
|
||||
import { styled } from '@apache-superset/core/ui';
|
||||
@@ -39,20 +39,17 @@ const ButtonContainer = styled.div`
|
||||
margin-top: ${({ theme }) => theme.sizeUnit * 4}px;
|
||||
`;
|
||||
|
||||
export const ExploreAlert = forwardRef(
|
||||
(
|
||||
{
|
||||
title,
|
||||
bodyText,
|
||||
primaryButtonAction,
|
||||
secondaryButtonAction,
|
||||
primaryButtonText,
|
||||
secondaryButtonText,
|
||||
type = 'info',
|
||||
className = '',
|
||||
}: ControlPanelAlertProps,
|
||||
ref: RefObject<HTMLDivElement>,
|
||||
) => (
|
||||
export function ExploreAlert({
|
||||
title,
|
||||
bodyText,
|
||||
primaryButtonAction,
|
||||
secondaryButtonAction,
|
||||
primaryButtonText,
|
||||
secondaryButtonText,
|
||||
type = 'info',
|
||||
className = '',
|
||||
}: ControlPanelAlertProps) {
|
||||
return (
|
||||
<ErrorAlert
|
||||
errorType={title}
|
||||
message={bodyText}
|
||||
@@ -74,5 +71,5 @@ export const ExploreAlert = forwardRef(
|
||||
</ButtonContainer>
|
||||
)}
|
||||
</ErrorAlert>
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -867,8 +867,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}
|
||||
|
||||
@@ -134,7 +134,7 @@ class CollectionControl extends Component<CollectionControlProps> {
|
||||
>
|
||||
{currentValue.map((o: CollectionItem, i: number) => {
|
||||
// label relevant only for header, not here
|
||||
const { label, theme, ...commonProps } = this.props;
|
||||
const { label: _label, theme: _theme, ...commonProps } = this.props;
|
||||
return (
|
||||
<SortableListItem
|
||||
selectable={false}
|
||||
|
||||
@@ -66,18 +66,19 @@ export default function ColumnConfigControl<T extends ColumnConfig>({
|
||||
height,
|
||||
...props
|
||||
}: ColumnConfigControlProps<T>) {
|
||||
const { colnames: _colnames, coltypes: _coltypes } = columnsPropsObject || {};
|
||||
const { colnames: queryColnames, coltypes: queryColtypes } =
|
||||
columnsPropsObject || {};
|
||||
let colnames: string[] = [];
|
||||
let coltypes: GenericDataType[] = [];
|
||||
if (appliedColumnNames.length === 0) {
|
||||
colnames = _colnames || [];
|
||||
coltypes = _coltypes || [];
|
||||
colnames = queryColnames || [];
|
||||
coltypes = queryColtypes || [];
|
||||
} else {
|
||||
const appliedCol = new Set(appliedColumnNames);
|
||||
_colnames?.forEach((col, idx) => {
|
||||
queryColnames?.forEach((col, idx) => {
|
||||
if (appliedCol.has(col)) {
|
||||
colnames.push(col);
|
||||
coltypes.push(_coltypes?.[idx] as GenericDataType);
|
||||
coltypes.push(queryColtypes?.[idx] as GenericDataType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ export default class AdhocFilterEditPopover extends Component<
|
||||
.filter((item: { sliceIndex: number }) => item.sliceIndex !== -1)
|
||||
.map(
|
||||
({
|
||||
sliceIndex,
|
||||
sliceIndex: _sliceIndex,
|
||||
...item
|
||||
}: {
|
||||
sliceIndex: number;
|
||||
@@ -358,12 +358,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
|
||||
|
||||
@@ -353,9 +353,9 @@ export default class AdhocMetricEditPopover extends PureComponent<
|
||||
savedMetric: propsSavedMetric,
|
||||
columns,
|
||||
savedMetricsOptions,
|
||||
onChange,
|
||||
onClose,
|
||||
onResize,
|
||||
onChange: _onChange,
|
||||
onClose: _onClose,
|
||||
onResize: _onResize,
|
||||
datasource,
|
||||
isNewMetric,
|
||||
isLabelModified,
|
||||
|
||||
@@ -1137,7 +1137,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
.catch(() => {
|
||||
addDangerToast(t('There was an error retrieving dashboard tabs.'));
|
||||
});
|
||||
}
|
||||
@@ -2596,7 +2596,6 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
|
||||
<TimezoneSelector
|
||||
onTimezoneChange={onTimezoneChange}
|
||||
timezone={currentAlert?.timezone}
|
||||
minWidth="100%"
|
||||
/>
|
||||
) : (
|
||||
<Loading size="s" muted position="normal" />
|
||||
|
||||
@@ -306,7 +306,7 @@ export const NotificationMethod: FunctionComponent<NotificationMethodProps> = ({
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
.catch(() => {
|
||||
// Fallback to slack v1 if slack v2 is not compatible
|
||||
setUseSlackV1(true);
|
||||
})
|
||||
|
||||
@@ -59,7 +59,7 @@ interface AllEntitiesTableProps {
|
||||
}
|
||||
|
||||
export default function AllEntitiesTable({
|
||||
search = '',
|
||||
search: _search = '',
|
||||
setShowTagModal,
|
||||
objects,
|
||||
canEditTag,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1634,7 +1634,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();
|
||||
};
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ const UploadDataModal: FunctionComponent<UploadDataModalProps> = ({
|
||||
|
||||
const loadDatabaseOptions = useMemo(
|
||||
() =>
|
||||
(input = '', page: number, pageSize: number) => {
|
||||
(_input = '', page: number, pageSize: number) => {
|
||||
const query = rison.encode_uri({
|
||||
filters: [
|
||||
{
|
||||
@@ -358,21 +358,20 @@ const UploadDataModal: FunctionComponent<UploadDataModalProps> = ({
|
||||
);
|
||||
|
||||
const loadSchemaOptions = useMemo(
|
||||
() =>
|
||||
(input = '', page: number, pageSize: number) => {
|
||||
if (!currentDatabaseId) {
|
||||
return Promise.resolve({ data: [], totalCount: 0 });
|
||||
}
|
||||
return SupersetClient.get({
|
||||
endpoint: `/api/v1/database/${currentDatabaseId}/schemas/?q=(upload_allowed:!t)`,
|
||||
}).then(response => {
|
||||
const list = response.json.result.map((item: string) => ({
|
||||
value: item,
|
||||
label: item,
|
||||
}));
|
||||
return { data: list, totalCount: response.json.count };
|
||||
});
|
||||
},
|
||||
() => () => {
|
||||
if (!currentDatabaseId) {
|
||||
return Promise.resolve({ data: [], totalCount: 0 });
|
||||
}
|
||||
return SupersetClient.get({
|
||||
endpoint: `/api/v1/database/${currentDatabaseId}/schemas/?q=(upload_allowed:!t)`,
|
||||
}).then(response => {
|
||||
const list = response.json.result.map((item: string) => ({
|
||||
value: item,
|
||||
label: item,
|
||||
}));
|
||||
return { data: list, totalCount: response.json.count };
|
||||
});
|
||||
},
|
||||
[currentDatabaseId],
|
||||
);
|
||||
|
||||
@@ -563,7 +562,7 @@ const UploadDataModal: FunctionComponent<UploadDataModalProps> = ({
|
||||
}
|
||||
}, [show]);
|
||||
|
||||
const validateUpload = (_: any, value: string) => {
|
||||
const validateUpload = () => {
|
||||
if (fileList.length === 0) {
|
||||
return Promise.reject(t('Uploading a file is required'));
|
||||
}
|
||||
@@ -578,7 +577,7 @@ const UploadDataModal: FunctionComponent<UploadDataModalProps> = ({
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
const validateDatabase = (_: any, value: string) => {
|
||||
const validateDatabase = () => {
|
||||
if (!currentDatabaseId) {
|
||||
return Promise.reject(t('Selecting a database is required'));
|
||||
}
|
||||
|
||||
@@ -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'));
|
||||
});
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ const TagModal: FC<TagModalProps> = ({
|
||||
setChartsToTag(resourceMap[TaggableResources.Chart]);
|
||||
setSavedQueriesToTag(resourceMap[TaggableResources.SavedQuery]);
|
||||
},
|
||||
(error: Response) => {
|
||||
() => {
|
||||
addDangerToast('Error Fetching Tagged Objects');
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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 =>
|
||||
|
||||
@@ -291,11 +291,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
Cell: ({
|
||||
row: {
|
||||
original: { kind },
|
||||
},
|
||||
}: any) => null,
|
||||
Cell: () => null,
|
||||
accessor: 'kind_icon',
|
||||
disableSortBy: true,
|
||||
size: 'xs',
|
||||
|
||||
@@ -146,7 +146,7 @@ function GroupsList({ user }: GroupsListProps) {
|
||||
.then(() => {
|
||||
deletedGroupsNames.push(group.name);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch(() => {
|
||||
addDangerToast(t('Error deleting %s', group.name));
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -168,7 +168,7 @@ function UsersList({ user }: UsersListProps) {
|
||||
.then(() => {
|
||||
deletedUserNames.push(user.username);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch(() => {
|
||||
addDangerToast(t('Error deleting %s', user.username));
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -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 = {},
|
||||
) {}
|
||||
|
||||
@@ -801,7 +801,7 @@ export class ThemeController {
|
||||
* @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(_newMode: ThemeMode): void {
|
||||
// Check if user can set a new theme mode (dark theme must exist)
|
||||
if (!this.canSetMode())
|
||||
throw new Error(
|
||||
|
||||
Reference in New Issue
Block a user