chore: replace Lodash usage with native JS implementation (#31907)
Signed-off-by: hainenber <dotronghai96@gmail.com>
This commit is contained in:
parent
eec374426f
commit
f8fe780f52
|
|
@ -18,7 +18,6 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { JsonObject } from '@superset-ui/core';
|
import { JsonObject } from '@superset-ui/core';
|
||||||
import { isString } from 'lodash';
|
|
||||||
|
|
||||||
export const getTimeOffset = (
|
export const getTimeOffset = (
|
||||||
series: JsonObject,
|
series: JsonObject,
|
||||||
|
|
@ -36,7 +35,9 @@ export const hasTimeOffset = (
|
||||||
series: JsonObject,
|
series: JsonObject,
|
||||||
timeCompare: string[],
|
timeCompare: string[],
|
||||||
): boolean =>
|
): boolean =>
|
||||||
isString(series.name) ? !!getTimeOffset(series, timeCompare) : false;
|
typeof series.name === 'string'
|
||||||
|
? !!getTimeOffset(series, timeCompare)
|
||||||
|
: false;
|
||||||
|
|
||||||
export const getOriginalSeries = (
|
export const getOriginalSeries = (
|
||||||
seriesName: string,
|
seriesName: string,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
||||||
import remarkGfm from 'remark-gfm';
|
import remarkGfm from 'remark-gfm';
|
||||||
import { mergeWith, isArray } from 'lodash';
|
import { mergeWith } from 'lodash';
|
||||||
import { FeatureFlag, isFeatureEnabled } from '../utils';
|
import { FeatureFlag, isFeatureEnabled } from '../utils';
|
||||||
|
|
||||||
interface SafeMarkdownProps {
|
interface SafeMarkdownProps {
|
||||||
|
|
@ -33,7 +33,7 @@ export function getOverrideHtmlSchema(
|
||||||
htmlSchemaOverrides: SafeMarkdownProps['htmlSchemaOverrides'],
|
htmlSchemaOverrides: SafeMarkdownProps['htmlSchemaOverrides'],
|
||||||
) {
|
) {
|
||||||
return mergeWith(originalSchema, htmlSchemaOverrides, (objValue, srcValue) =>
|
return mergeWith(originalSchema, htmlSchemaOverrides, (objValue, srcValue) =>
|
||||||
isArray(objValue) ? objValue.concat(srcValue) : undefined,
|
Array.isArray(objValue) ? objValue.concat(srcValue) : undefined,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { isEmpty, isBoolean } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
import { QueryObject } from './types';
|
import { QueryObject } from './types';
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ export default function normalizeOrderBy(
|
||||||
Array.isArray(orderbyClause) &&
|
Array.isArray(orderbyClause) &&
|
||||||
orderbyClause.length === 2 &&
|
orderbyClause.length === 2 &&
|
||||||
!isEmpty(orderbyClause[0]) &&
|
!isEmpty(orderbyClause[0]) &&
|
||||||
isBoolean(orderbyClause[1])
|
typeof orderbyClause[1] === 'boolean'
|
||||||
) {
|
) {
|
||||||
return queryObject;
|
return queryObject;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import {
|
||||||
QueryFormData,
|
QueryFormData,
|
||||||
SequentialScheme,
|
SequentialScheme,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { isNumber } from 'lodash';
|
|
||||||
import { hexToRGB } from './utils/colors';
|
import { hexToRGB } from './utils/colors';
|
||||||
|
|
||||||
const DEFAULT_NUM_BUCKETS = 10;
|
const DEFAULT_NUM_BUCKETS = 10;
|
||||||
|
|
@ -140,7 +139,7 @@ export function getBreakPointColorScaler(
|
||||||
} else {
|
} else {
|
||||||
// interpolate colors linearly
|
// interpolate colors linearly
|
||||||
const linearScaleDomain = extent(features, accessor);
|
const linearScaleDomain = extent(features, accessor);
|
||||||
if (!linearScaleDomain.some(isNumber)) {
|
if (!linearScaleDomain.some(i => typeof i === 'number')) {
|
||||||
scaler = colorScheme.createLinearScale();
|
scaler = colorScheme.createLinearScale();
|
||||||
} else {
|
} else {
|
||||||
scaler = colorScheme.createLinearScale(
|
scaler = colorScheme.createLinearScale(
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { isNumber } from 'lodash';
|
|
||||||
import { DataRecord, DTTM_ALIAS, ValueFormatter } from '@superset-ui/core';
|
import { DataRecord, DTTM_ALIAS, ValueFormatter } from '@superset-ui/core';
|
||||||
import type { OptionName } from 'echarts/types/src/util/types';
|
import type { OptionName } from 'echarts/types/src/util/types';
|
||||||
import type { TooltipMarker } from 'echarts/types/src/util/format';
|
import type { TooltipMarker } from 'echarts/types/src/util/format';
|
||||||
|
|
@ -64,7 +63,7 @@ export const extractForecastValuesFromTooltipParams = (
|
||||||
const { marker, seriesId, value } = param;
|
const { marker, seriesId, value } = param;
|
||||||
const context = extractForecastSeriesContext(seriesId);
|
const context = extractForecastSeriesContext(seriesId);
|
||||||
const numericValue = isHorizontal ? value[0] : value[1];
|
const numericValue = isHorizontal ? value[0] : value[1];
|
||||||
if (isNumber(numericValue)) {
|
if (typeof numericValue === 'number') {
|
||||||
if (!(context.name in values))
|
if (!(context.name in values))
|
||||||
values[context.name] = {
|
values[context.name] = {
|
||||||
marker: marker || '',
|
marker: marker || '',
|
||||||
|
|
@ -97,7 +96,7 @@ export const formatForecastTooltipSeries = ({
|
||||||
formatter: ValueFormatter;
|
formatter: ValueFormatter;
|
||||||
}): string[] => {
|
}): string[] => {
|
||||||
const name = `${marker}${sanitizeHtml(seriesName)}`;
|
const name = `${marker}${sanitizeHtml(seriesName)}`;
|
||||||
let value = isNumber(observation) ? formatter(observation) : '';
|
let value = typeof observation === 'number' ? formatter(observation) : '';
|
||||||
if (forecastTrend || forecastLower || forecastUpper) {
|
if (forecastTrend || forecastLower || forecastUpper) {
|
||||||
// forecast values take the form of "20, y = 30 (10, 40)"
|
// forecast values take the form of "20, y = 30 (10, 40)"
|
||||||
// where the first part is the observation, the second part is the forecast trend
|
// where the first part is the observation, the second part is the forecast trend
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { DataRecord, DataRecordValue } from '@superset-ui/core';
|
import { DataRecord, DataRecordValue } from '@superset-ui/core';
|
||||||
import { groupBy as _groupBy, isNumber, transform } from 'lodash';
|
import { groupBy as _groupBy, transform } from 'lodash';
|
||||||
|
|
||||||
export type TreeNode = {
|
export type TreeNode = {
|
||||||
name: DataRecordValue;
|
name: DataRecordValue;
|
||||||
|
|
@ -28,7 +28,7 @@ export type TreeNode = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function getMetricValue(datum: DataRecord, metric: string) {
|
function getMetricValue(datum: DataRecord, metric: string) {
|
||||||
return isNumber(datum[metric]) ? (datum[metric] as number) : 0;
|
return typeof datum[metric] === 'number' ? (datum[metric] as number) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function treeBuilder(
|
export function treeBuilder(
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ import {
|
||||||
PlusCircleOutlined,
|
PlusCircleOutlined,
|
||||||
TableOutlined,
|
TableOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { isEmpty, isNumber } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import {
|
import {
|
||||||
ColorSchemeEnum,
|
ColorSchemeEnum,
|
||||||
DataColumnMeta,
|
DataColumnMeta,
|
||||||
|
|
@ -899,7 +899,9 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||||
/* The following classes are added to support custom CSS styling */
|
/* The following classes are added to support custom CSS styling */
|
||||||
className={cx(
|
className={cx(
|
||||||
'cell-bar',
|
'cell-bar',
|
||||||
isNumber(value) && value < 0 ? 'negative' : 'positive',
|
typeof value === 'number' && value < 0
|
||||||
|
? 'negative'
|
||||||
|
: 'positive',
|
||||||
)}
|
)}
|
||||||
css={cellBarStyles}
|
css={cellBarStyles}
|
||||||
role="presentation"
|
role="presentation"
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ import { mountExploreUrl } from 'src/explore/exploreUtils';
|
||||||
import { postFormData } from 'src/explore/exploreUtils/formData';
|
import { postFormData } from 'src/explore/exploreUtils/formData';
|
||||||
import { URL_PARAMS } from 'src/constants';
|
import { URL_PARAMS } from 'src/constants';
|
||||||
import { SelectValue } from 'antd/lib/select';
|
import { SelectValue } from 'antd/lib/select';
|
||||||
import { isEmpty, isString } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
interface QueryDatabase {
|
interface QueryDatabase {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
|
@ -280,7 +280,7 @@ export const SaveDatasetModal = ({
|
||||||
// Remove the special filters entry from the templateParams
|
// Remove the special filters entry from the templateParams
|
||||||
// before saving the dataset.
|
// before saving the dataset.
|
||||||
let templateParams;
|
let templateParams;
|
||||||
if (isString(datasource?.templateParams)) {
|
if (typeof datasource?.templateParams === 'string') {
|
||||||
const p = JSON.parse(datasource.templateParams);
|
const p = JSON.parse(datasource.templateParams);
|
||||||
/* eslint-disable-next-line no-underscore-dangle */
|
/* eslint-disable-next-line no-underscore-dangle */
|
||||||
if (p._filters) {
|
if (p._filters) {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ import type {
|
||||||
CursorPosition,
|
CursorPosition,
|
||||||
} from 'src/SqlLab/types';
|
} from 'src/SqlLab/types';
|
||||||
import type { DatabaseObject } from 'src/features/databases/types';
|
import type { DatabaseObject } from 'src/features/databases/types';
|
||||||
import { debounce, throttle, isBoolean, isEmpty } from 'lodash';
|
import { debounce, throttle, isEmpty } from 'lodash';
|
||||||
import Modal from 'src/components/Modal';
|
import Modal from 'src/components/Modal';
|
||||||
import Mousetrap from 'mousetrap';
|
import Mousetrap from 'mousetrap';
|
||||||
import Button from 'src/components/Button';
|
import Button from 'src/components/Button';
|
||||||
|
|
@ -281,9 +281,10 @@ const SqlEditor: FC<Props> = ({
|
||||||
if (unsavedQueryEditor?.id === queryEditor.id) {
|
if (unsavedQueryEditor?.id === queryEditor.id) {
|
||||||
dbId = unsavedQueryEditor.dbId || dbId;
|
dbId = unsavedQueryEditor.dbId || dbId;
|
||||||
latestQueryId = unsavedQueryEditor.latestQueryId || latestQueryId;
|
latestQueryId = unsavedQueryEditor.latestQueryId || latestQueryId;
|
||||||
hideLeftBar = isBoolean(unsavedQueryEditor.hideLeftBar)
|
hideLeftBar =
|
||||||
? unsavedQueryEditor.hideLeftBar
|
typeof unsavedQueryEditor.hideLeftBar === 'boolean'
|
||||||
: hideLeftBar;
|
? unsavedQueryEditor.hideLeftBar
|
||||||
|
: hideLeftBar;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
hasSqlStatement: Boolean(queryEditor.sql?.trim().length > 0),
|
hasSqlStatement: Boolean(queryEditor.sql?.trim().length > 0),
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import fetchMock from 'fetch-mock';
|
import fetchMock from 'fetch-mock';
|
||||||
import { omit, isUndefined, omitBy } from 'lodash';
|
import { omit, omitBy } from 'lodash';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { waitFor, within } from '@testing-library/react';
|
import { waitFor, within } from '@testing-library/react';
|
||||||
import { render, screen } from 'spec/helpers/testing-library';
|
import { render, screen } from 'spec/helpers/testing-library';
|
||||||
|
|
@ -166,7 +166,7 @@ test('should generate Explore url', async () => {
|
||||||
form_data: {
|
form_data: {
|
||||||
...omitBy(
|
...omitBy(
|
||||||
omit(formData, ['slice_id', 'slice_name', 'dashboards']),
|
omit(formData, ['slice_id', 'slice_name', 'dashboards']),
|
||||||
isUndefined,
|
i => i === undefined,
|
||||||
),
|
),
|
||||||
groupby: ['name'],
|
groupby: ['name'],
|
||||||
adhoc_filters: [
|
adhoc_filters: [
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import { ControlConfig } from '@superset-ui/chart-controls';
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||||
import { FixedSizeList as List } from 'react-window';
|
import { FixedSizeList as List } from 'react-window';
|
||||||
|
|
||||||
import { isArray } from 'lodash';
|
|
||||||
import { matchSorter, rankings } from 'match-sorter';
|
import { matchSorter, rankings } from 'match-sorter';
|
||||||
import Alert from 'src/components/Alert';
|
import Alert from 'src/components/Alert';
|
||||||
import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
|
import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
|
||||||
|
|
@ -142,7 +141,7 @@ export default function DataSourcePanel({
|
||||||
|
|
||||||
const allowedColumns = useMemo(() => {
|
const allowedColumns = useMemo(() => {
|
||||||
const validators = Object.values(dropzones);
|
const validators = Object.values(dropzones);
|
||||||
if (!isArray(_columns)) return [];
|
if (!Array.isArray(_columns)) return [];
|
||||||
return _columns.filter(column =>
|
return _columns.filter(column =>
|
||||||
validators.some(validator =>
|
validators.some(validator =>
|
||||||
validator({
|
validator({
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { InputNumber } from 'src/components/Input';
|
import { InputNumber } from 'src/components/Input';
|
||||||
import { t, styled } from '@superset-ui/core';
|
import { t, styled } from '@superset-ui/core';
|
||||||
import { debounce, parseInt } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import ControlHeader from 'src/explore/components/ControlHeader';
|
import ControlHeader from 'src/explore/components/ControlHeader';
|
||||||
|
|
||||||
type ValueType = (number | null)[];
|
type ValueType = (number | null)[];
|
||||||
|
|
@ -47,7 +47,7 @@ const parseNumber = (value: undefined | number | string | null) => {
|
||||||
if (
|
if (
|
||||||
value === null ||
|
value === null ||
|
||||||
value === undefined ||
|
value === undefined ||
|
||||||
(typeof value === 'string' && Number.isNaN(parseInt(value)))
|
(typeof value === 'string' && Number.isNaN(Number.parseInt(value, 10)))
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import {
|
||||||
CategoricalColorNamespace,
|
CategoricalColorNamespace,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import AntdSelect from 'antd/lib/select';
|
import AntdSelect from 'antd/lib/select';
|
||||||
import { isFunction, sortBy } from 'lodash';
|
import { sortBy } from 'lodash';
|
||||||
import ControlHeader from 'src/explore/components/ControlHeader';
|
import ControlHeader from 'src/explore/components/ControlHeader';
|
||||||
import { Tooltip } from 'src/components/Tooltip';
|
import { Tooltip } from 'src/components/Tooltip';
|
||||||
import Icons from 'src/components/Icons';
|
import Icons from 'src/components/Icons';
|
||||||
|
|
@ -163,7 +163,7 @@ const ColorSchemeControl = ({
|
||||||
}
|
}
|
||||||
let result = value || defaultScheme;
|
let result = value || defaultScheme;
|
||||||
if (result === 'SUPERSET_DEFAULT') {
|
if (result === 'SUPERSET_DEFAULT') {
|
||||||
const schemesObject = isFunction(schemes) ? schemes() : schemes;
|
const schemesObject = typeof schemes === 'function' ? schemes() : schemes;
|
||||||
result = schemesObject?.SUPERSET_DEFAULT?.id;
|
result = schemesObject?.SUPERSET_DEFAULT?.id;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -179,8 +179,8 @@ const ColorSchemeControl = ({
|
||||||
</Option>,
|
</Option>,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
const schemesObject = isFunction(schemes) ? schemes() : schemes;
|
const schemesObject = typeof schemes === 'function' ? schemes() : schemes;
|
||||||
const controlChoices = isFunction(choices) ? choices() : choices;
|
const controlChoices = typeof choices === 'function' ? choices() : choices;
|
||||||
const allColorOptions: string[] = [];
|
const allColorOptions: string[] = [];
|
||||||
const filteredColorOptions = controlChoices.filter(o => {
|
const filteredColorOptions = controlChoices.filter(o => {
|
||||||
const option = o[0];
|
const option = o[0];
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ import ViewQueryModalFooter from 'src/explore/components/controls/ViewQueryModal
|
||||||
import ViewQuery from 'src/explore/components/controls/ViewQuery';
|
import ViewQuery from 'src/explore/components/controls/ViewQuery';
|
||||||
import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
|
import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
|
||||||
import { safeStringify } from 'src/utils/safeStringify';
|
import { safeStringify } from 'src/utils/safeStringify';
|
||||||
import { isString } from 'lodash';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
|
@ -383,7 +382,7 @@ class DatasourceControl extends PureComponent {
|
||||||
|
|
||||||
let extra;
|
let extra;
|
||||||
if (datasource?.extra) {
|
if (datasource?.extra) {
|
||||||
if (isString(datasource.extra)) {
|
if (typeof datasource.extra === 'string') {
|
||||||
try {
|
try {
|
||||||
extra = JSON.parse(datasource.extra);
|
extra = JSON.parse(datasource.extra);
|
||||||
} catch {} // eslint-disable-line no-empty
|
} catch {} // eslint-disable-line no-empty
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { isInteger } from 'lodash';
|
|
||||||
import { t, customTimeRangeDecode } from '@superset-ui/core';
|
import { t, customTimeRangeDecode } from '@superset-ui/core';
|
||||||
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
|
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
|
||||||
import { Col, Row } from 'src/components';
|
import { Col, Row } from 'src/components';
|
||||||
|
|
@ -76,7 +75,7 @@ export function CustomFrame(props: FrameComponentProps) {
|
||||||
value: string | number,
|
value: string | number,
|
||||||
) {
|
) {
|
||||||
// only positive values in grainValue controls
|
// only positive values in grainValue controls
|
||||||
if (isInteger(value) && value > 0) {
|
if (typeof value === 'number' && Number.isInteger(value) && value > 0) {
|
||||||
props.onChange(
|
props.onChange(
|
||||||
customTimeRangeEncode({
|
customTimeRangeEncode({
|
||||||
...customRange,
|
...customRange,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import { render, screen } from 'spec/helpers/testing-library';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { waitFor } from '@testing-library/react';
|
import { waitFor } from '@testing-library/react';
|
||||||
import { UploadFile } from 'antd/lib/upload/interface';
|
import { UploadFile } from 'antd/lib/upload/interface';
|
||||||
import { forEach } from 'lodash';
|
|
||||||
|
|
||||||
fetchMock.post('glob:*api/v1/database/1/csv_upload/', {});
|
fetchMock.post('glob:*api/v1/database/1/csv_upload/', {});
|
||||||
fetchMock.post('glob:*api/v1/database/1/excel_upload/', {});
|
fetchMock.post('glob:*api/v1/database/1/excel_upload/', {});
|
||||||
|
|
@ -782,7 +781,7 @@ test('Columnar, form post', async () => {
|
||||||
|
|
||||||
test('CSV, validate file extension returns false', () => {
|
test('CSV, validate file extension returns false', () => {
|
||||||
const invalidFileNames = ['out', 'out.exe', 'out.csv.exe', '.csv', 'out.xls'];
|
const invalidFileNames = ['out', 'out.exe', 'out.csv.exe', '.csv', 'out.xls'];
|
||||||
forEach(invalidFileNames, fileName => {
|
invalidFileNames.forEach(fileName => {
|
||||||
const file: UploadFile<any> = {
|
const file: UploadFile<any> = {
|
||||||
name: fileName,
|
name: fileName,
|
||||||
uid: 'xp',
|
uid: 'xp',
|
||||||
|
|
@ -795,7 +794,7 @@ test('CSV, validate file extension returns false', () => {
|
||||||
|
|
||||||
test('Excel, validate file extension returns false', () => {
|
test('Excel, validate file extension returns false', () => {
|
||||||
const invalidFileNames = ['out', 'out.exe', 'out.xls.exe', '.csv', 'out.csv'];
|
const invalidFileNames = ['out', 'out.exe', 'out.xls.exe', '.csv', 'out.csv'];
|
||||||
forEach(invalidFileNames, fileName => {
|
invalidFileNames.forEach(fileName => {
|
||||||
const file: UploadFile<any> = {
|
const file: UploadFile<any> = {
|
||||||
name: fileName,
|
name: fileName,
|
||||||
uid: 'xp',
|
uid: 'xp',
|
||||||
|
|
@ -814,7 +813,7 @@ test('Columnar, validate file extension returns false', () => {
|
||||||
'.parquet',
|
'.parquet',
|
||||||
'out.excel',
|
'out.excel',
|
||||||
];
|
];
|
||||||
forEach(invalidFileNames, fileName => {
|
invalidFileNames.forEach(fileName => {
|
||||||
const file: UploadFile<any> = {
|
const file: UploadFile<any> = {
|
||||||
name: fileName,
|
name: fileName,
|
||||||
uid: 'xp',
|
uid: 'xp',
|
||||||
|
|
@ -827,7 +826,7 @@ test('Columnar, validate file extension returns false', () => {
|
||||||
|
|
||||||
test('CSV, validate file extension returns true', () => {
|
test('CSV, validate file extension returns true', () => {
|
||||||
const invalidFileNames = ['out.csv', 'out.tsv', 'out.exe.csv', 'out a.csv'];
|
const invalidFileNames = ['out.csv', 'out.tsv', 'out.exe.csv', 'out a.csv'];
|
||||||
forEach(invalidFileNames, fileName => {
|
invalidFileNames.forEach(fileName => {
|
||||||
const file: UploadFile<any> = {
|
const file: UploadFile<any> = {
|
||||||
name: fileName,
|
name: fileName,
|
||||||
uid: 'xp',
|
uid: 'xp',
|
||||||
|
|
@ -840,7 +839,7 @@ test('CSV, validate file extension returns true', () => {
|
||||||
|
|
||||||
test('Excel, validate file extension returns true', () => {
|
test('Excel, validate file extension returns true', () => {
|
||||||
const invalidFileNames = ['out.xls', 'out.xlsx', 'out.exe.xls', 'out a.xls'];
|
const invalidFileNames = ['out.xls', 'out.xlsx', 'out.exe.xls', 'out a.xls'];
|
||||||
forEach(invalidFileNames, fileName => {
|
invalidFileNames.forEach(fileName => {
|
||||||
const file: UploadFile<any> = {
|
const file: UploadFile<any> = {
|
||||||
name: fileName,
|
name: fileName,
|
||||||
uid: 'xp',
|
uid: 'xp',
|
||||||
|
|
@ -858,7 +857,7 @@ test('Columnar, validate file extension returns true', () => {
|
||||||
'out.exe.zip',
|
'out.exe.zip',
|
||||||
'out a.parquet',
|
'out a.parquet',
|
||||||
];
|
];
|
||||||
forEach(invalidFileNames, fileName => {
|
invalidFileNames.forEach(fileName => {
|
||||||
const file: UploadFile<any> = {
|
const file: UploadFile<any> = {
|
||||||
name: fileName,
|
name: fileName,
|
||||||
uid: 'xp',
|
uid: 'xp',
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,7 @@
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { compose } from 'redux';
|
import { compose } from 'redux';
|
||||||
import persistState, { StorageAdapter } from 'redux-localstorage';
|
import persistState, { StorageAdapter } from 'redux-localstorage';
|
||||||
import {
|
import { isEqual, omitBy, omit, isEqualWith } from 'lodash';
|
||||||
isEqual,
|
|
||||||
omitBy,
|
|
||||||
omit,
|
|
||||||
isUndefined,
|
|
||||||
isNull,
|
|
||||||
isEqualWith,
|
|
||||||
} from 'lodash';
|
|
||||||
import { ensureIsArray } from '@superset-ui/core';
|
import { ensureIsArray } from '@superset-ui/core';
|
||||||
|
|
||||||
export function addToObject(
|
export function addToObject(
|
||||||
|
|
@ -195,12 +188,12 @@ export function areObjectsEqual(
|
||||||
let comp1 = obj1;
|
let comp1 = obj1;
|
||||||
let comp2 = obj2;
|
let comp2 = obj2;
|
||||||
if (opts.ignoreUndefined) {
|
if (opts.ignoreUndefined) {
|
||||||
comp1 = omitBy(comp1, isUndefined);
|
comp1 = omitBy(comp1, i => i === undefined);
|
||||||
comp2 = omitBy(comp2, isUndefined);
|
comp2 = omitBy(comp2, i => i === undefined);
|
||||||
}
|
}
|
||||||
if (opts.ignoreNull) {
|
if (opts.ignoreNull) {
|
||||||
comp1 = omitBy(comp1, isNull);
|
comp1 = omitBy(comp1, i => i === null);
|
||||||
comp2 = omitBy(comp2, isNull);
|
comp2 = omitBy(comp2, i => i === null);
|
||||||
}
|
}
|
||||||
if (opts.ignoreFields?.length) {
|
if (opts.ignoreFields?.length) {
|
||||||
const ignoreFields = ensureIsArray(opts.ignoreFields);
|
const ignoreFields = ensureIsArray(opts.ignoreFields);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue