chore(build): uplift several outdated frontend packages (#29652)

Signed-off-by: hainenber <dotronghai96@gmail.com>
This commit is contained in:
Đỗ Trọng Hải 2024-08-06 22:02:01 +07:00 committed by GitHub
parent 9fed576cb4
commit 1c3ef01209
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 10005 additions and 32451 deletions

View File

@ -58,6 +58,8 @@ repos:
rev: v3.1.0 # Use the sha or tag you want to point at
hooks:
- id: prettier
additional_dependencies:
- prettier@3.3.3
args: ["--ignore-path=./superset-frontend/.prettierignore"]
files: "superset-frontend"
# blacklist unsafe functions like make_url (see #19526)

View File

@ -56,7 +56,7 @@ module.exports = {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
snapshotSerializers: ['@emotion/jest/enzyme-serializer'],
transformIgnorePatterns: [
'node_modules/(?!d3-(interpolate|color)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid)',
'node_modules/(?!d3-(interpolate|color)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|@rjsf/*.|sinon)',
],
globals: {
__DEV__: true,

File diff suppressed because it is too large Load Diff

View File

@ -86,6 +86,9 @@
"@fontsource/fira-code": "^5.0.18",
"@fontsource/inter": "^5.0.20",
"@reduxjs/toolkit": "^1.9.3",
"@rjsf/core": "^5.19.3",
"@rjsf/utils": "^5.19.3",
"@rjsf/validator-ajv8": "^5.19.3",
"@scarf/scarf": "^1.3.0",
"@superset-ui/chart-controls": "file:./packages/superset-ui-chart-controls",
"@superset-ui/core": "file:./packages/superset-ui-core",
@ -141,7 +144,7 @@
"html-webpack-plugin": "^5.3.2",
"immer": "^9.0.6",
"interweave": "^13.1.0",
"jquery": "^3.5.1",
"jquery": "^3.7.1",
"js-levenshtein": "^1.1.6",
"js-yaml-loader": "^1.2.2",
"json-bigint": "^1.0.0",
@ -174,7 +177,6 @@
"react-intersection-observer": "^9.10.2",
"react-js-cron": "^2.1.2",
"react-json-tree": "^0.17.0",
"react-jsonschema-form": "^1.8.1",
"react-lines-ellipsis": "^0.15.4",
"react-loadable": "^5.5.0",
"react-redux": "^7.2.9",
@ -221,6 +223,7 @@
"@babel/preset-env": "^7.22.7",
"@babel/preset-react": "^7.22.5",
"@babel/register": "^7.23.7",
"@babel/types": "^7.24.9",
"@cypress/react": "^5.10.0",
"@emotion/babel-plugin": "^11.11.0",
"@emotion/jest": "^11.11.0",
@ -256,7 +259,6 @@
"@types/react-dom": "^16.9.8",
"@types/react-gravatar": "^2.6.14",
"@types/react-json-tree": "^0.6.11",
"@types/react-jsonschema-form": "^1.7.4",
"@types/react-loadable": "^5.5.6",
"@types/react-redux": "^7.1.10",
"@types/react-router-dom": "^5.3.3",
@ -269,13 +271,12 @@
"@types/redux-localstorage": "^1.0.8",
"@types/redux-mock-store": "^1.0.6",
"@types/rison": "0.0.9",
"@types/shortid": "^0.0.29",
"@types/sinon": "^9.0.5",
"@types/sinon": "^17.0.3",
"@types/tinycolor2": "^1.4.3",
"@types/yargs": "12 - 18",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"babel-jest": "^26.6.3",
"babel-jest": "^29.7.0",
"babel-loader": "^9.1.3",
"babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-jsx-remove-data-test-id": "^3.0.0",
@ -320,29 +321,28 @@
"jest-enzyme": "^7.1.2",
"jest-html-reporter": "^3.10.2",
"jest-websocket-mock": "^2.5.0",
"jsdom": "^24.0.0",
"lerna": "^8.1.5",
"jsdom": "^24.1.1",
"lerna": "^8.1.7",
"less": "^4.2.0",
"less-loader": "^10.2.0",
"less-loader": "^12.2.0",
"mini-css-extract-plugin": "^2.9.0",
"mock-socket": "^9.3.1",
"moment-locales-webpack-plugin": "^1.2.0",
"node-fetch": "^2.6.7",
"po2json": "^0.4.5",
"prettier": "3.1.0",
"prettier": "3.3.3",
"prettier-plugin-packagejson": "^2.4.10",
"process": "^0.11.10",
"react-resizable": "^3.0.5",
"react-test-renderer": "^16.14.0",
"redux-mock-store": "^1.5.4",
"sinon": "^9.0.2",
"sinon": "^18.0.0",
"source-map": "^0.7.4",
"source-map-support": "^0.5.21",
"speed-measure-webpack-plugin": "^1.5.0",
"storybook": "^8.1.11",
"storybook": "8.1.11",
"style-loader": "^4.0.0",
"thread-loader": "^4.0.2",
"transform-loader": "^0.2.4",
"ts-loader": "^9.5.1",
"typescript": "^4.8.4",
"vm-browserify": "^1.1.2",

View File

@ -105,7 +105,7 @@ export default {
'verbose_map',
)
? (explore?.datasource as Dataset)?.verbose_map
: explore?.datasource?.columns ?? {};
: (explore?.datasource?.columns ?? {});
const { colnames, coltypes } =
chart?.queriesResponse?.[0] ?? {};
const numericColumns =

View File

@ -312,11 +312,11 @@ export default function transformProps(
stack,
formatter: forcePercentFormatter
? percentFormatter
: getCustomFormatter(
: (getCustomFormatter(
customFormatters,
metrics,
labelMap?.[seriesName]?.[0],
) ?? defaultFormatter,
) ?? defaultFormatter),
showValue,
onlyTotal,
totalStackedValues: sortedTotalValues,
@ -553,7 +553,7 @@ export default function transformProps(
const formatter = forcePercentFormatter
? percentFormatter
: getCustomFormatter(customFormatters, metrics) ?? defaultFormatter;
: (getCustomFormatter(customFormatters, metrics) ?? defaultFormatter);
const rows: string[][] = [];
const total = Object.values(forecastValues).reduce(

View File

@ -411,7 +411,7 @@ const config: ControlPanelConfig = {
'verbose_map',
)
? (explore?.datasource as Dataset)?.verbose_map
: explore?.datasource?.columns ?? {};
: (explore?.datasource?.columns ?? {});
const chartStatus = chart?.chartStatus;
const metricColumn = values.map(value => {
if (typeof value === 'string') {

View File

@ -636,7 +636,7 @@ const config: ControlPanelConfig = {
'verbose_map',
)
? (explore?.datasource as Dataset)?.verbose_map
: explore?.datasource?.columns ?? {};
: (explore?.datasource?.columns ?? {});
const chartStatus = chart?.chartStatus;
const { colnames, coltypes } =
chart?.queriesResponse?.[0] ?? {};

View File

@ -25,7 +25,7 @@
*/
process.env.PATH = `./node_modules/.bin:${process.env.PATH}`;
const rimraf = require('rimraf');
const { sync } = require('rimraf');
const { spawnSync } = require('child_process');
const fastGlob = require('fast-glob');
const { argv } = require('yargs')
@ -114,7 +114,7 @@ if (shouldCleanup) {
const dirtyModules = 'node_modules/@types/react,node_modules/@superset-ui';
const cachePath = `./node_modules/${scope}/{lib,esm,tsconfig.tsbuildinfo,${dirtyModules}}`;
console.log(`\n>> Cleaning up ${cachePath}`);
rimraf.sync(cachePath);
sync(cachePath);
}
if (shouldRunBabel) {

View File

@ -115,8 +115,8 @@ describe('QueryLimitSelect', () => {
const expectedLabels = [10, 100, 1000, 10000, 50000].map(i =>
convertToNumWithSpaces(i),
);
const actualLabels = getAllByRole('menuitem').map(
elem => elem.textContent?.trim(),
const actualLabels = getAllByRole('menuitem').map(elem =>
elem.textContent?.trim(),
);
expect(actualLabels).toEqual(expectedLabels);
@ -135,8 +135,8 @@ describe('QueryLimitSelect', () => {
await waitFor(() => expect(getByRole('menu')).toBeInTheDocument());
const expectedLabels = [5].map(i => convertToNumWithSpaces(i));
const actualLabels = getAllByRole('menuitem').map(
elem => elem.textContent?.trim(),
const actualLabels = getAllByRole('menuitem').map(elem =>
elem.textContent?.trim(),
);
expect(actualLabels).toEqual(expectedLabels);
@ -157,8 +157,8 @@ describe('QueryLimitSelect', () => {
const expectedLabels = [10, 100, 1000, 10000].map(i =>
convertToNumWithSpaces(i),
);
const actualLabels = getAllByRole('menuitem').map(
elem => elem.textContent?.trim(),
const actualLabels = getAllByRole('menuitem').map(elem =>
elem.textContent?.trim(),
);
expect(actualLabels).toEqual(expectedLabels);

View File

@ -18,7 +18,9 @@
*/
import { FunctionComponent, useState, useRef, ChangeEvent } from 'react';
import SchemaForm, { FormProps, FormValidation } from 'react-jsonschema-form';
import SchemaForm, { FormProps } from '@rjsf/core';
import { FormValidation } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';
import { Row, Col } from 'src/components';
import { Input, TextArea } from 'src/components/Input';
import { t, styled } from '@superset-ui/core';
@ -71,7 +73,7 @@ const getValidator = () => {
const args = rule.arguments.map((name: string) => formData[name]);
const container = rule.container || rule.arguments.slice(-1)[0];
if (!test(...args)) {
errors[container].addError(rule.message);
errors[container]?.addError(rule.message);
}
});
return errors;
@ -151,7 +153,7 @@ const ScheduleQueryButton: FunctionComponent<ScheduleQueryButtonProps> = ({
const onScheduleSubmit = ({
formData,
}: {
formData: Omit<FormProps<Record<string, any>>, 'schema'>;
formData?: Omit<FormProps<Record<string, any>>, 'schema'>;
}) => {
const query = {
label,
@ -202,7 +204,8 @@ const ScheduleQueryButton: FunctionComponent<ScheduleQueryButtonProps> = ({
schema={getJSONSchema()}
uiSchema={getUISchema()}
onSubmit={onScheduleSubmit}
validate={getValidator()}
customValidate={getValidator()}
validator={validator}
>
<Button
buttonStyle="primary"

View File

@ -30,8 +30,8 @@ export const newQueryTabName = (
const resultTitle = t(initialTitle);
if (queryEditors.length > 0) {
const mappedUntitled = queryEditors.filter(
qe => qe.name?.match(untitledQueryRegex),
const mappedUntitled = queryEditors.filter(qe =>
qe.name?.match(untitledQueryRegex),
);
const untitledQueryNumbers = mappedUntitled.map(
qe => +qe.name.replace(untitledQuery, ''),

View File

@ -189,8 +189,8 @@ export default function DrillByModal({
const initialGroupbyColumns = useMemo(
() =>
ensureIsArray(formData[groupbyFieldName])
.map(
colName => dataset.columns?.find(col => col.column_name === colName),
.map(colName =>
dataset.columns?.find(col => col.column_name === colName),
)
.filter(isDefined),
[dataset.columns, formData, groupbyFieldName],

View File

@ -169,14 +169,13 @@ export default function DrillDetailPane({
const data: DataType[] = useMemo(
() =>
resultsPage?.data.map(
(row, index) =>
resultsPage?.colNames.reduce(
(acc, curr) => ({ ...acc, [curr]: row[curr] }),
{
key: index,
},
),
resultsPage?.data.map((row, index) =>
resultsPage?.colNames.reduce(
(acc, curr) => ({ ...acc, [curr]: row[curr] }),
{
key: index,
},
),
) || [],
[resultsPage?.colNames, resultsPage?.data],
);

View File

@ -175,8 +175,8 @@ const FilterControls: FC<FilterControlsProps> = ({
const overflowedCrossFilters = useMemo(
() =>
selectedCrossFilters.filter(
({ emitterId, name }) => overflowedIds?.includes(`${name}${emitterId}`),
selectedCrossFilters.filter(({ emitterId, name }) =>
overflowedIds?.includes(`${name}${emitterId}`),
),
[overflowedIds, selectedCrossFilters],
);

View File

@ -102,11 +102,10 @@ export const useFilterScope = (filter: Filter) => {
);
// Exclude the tabs that contain excluded charts
filter.scope.excluded.forEach(chartId => {
const excludedIndex = topLevelTabsInFullScope.findIndex(
tabId =>
layoutChartElementsInTabsInScope
.find(chart => chart.meta.chartId === chartId)
?.parents.includes(tabId),
const excludedIndex = topLevelTabsInFullScope.findIndex(tabId =>
layoutChartElementsInTabsInScope
.find(chart => chart.meta.chartId === chartId)
?.parents.includes(tabId),
);
if (excludedIndex > -1) {
topLevelTabsInFullScope.splice(excludedIndex, 1);

View File

@ -105,8 +105,8 @@ export function ColumnSelect({
.then(
({ json: { result } }) => {
const lookupValue = Array.isArray(value) ? value : [value];
const valueExists = result.columns.some(
(column: Column) => lookupValue?.includes(column.column_name),
const valueExists = result.columns.some((column: Column) =>
lookupValue?.includes(column.column_name),
);
if (!valueExists) {
resetColumnField();

View File

@ -250,8 +250,8 @@ export const useFilteredTableData = (
return [];
}
return data.filter((_, index: number) =>
rowsAsStrings[index].some(
value => value?.includes(filterText.toLowerCase()),
rowsAsStrings[index].some(value =>
value?.includes(filterText.toLowerCase()),
),
);
}, [data, filterText, rowsAsStrings]);

View File

@ -302,7 +302,9 @@ export const getSimpleSQLExpression = (subject, operator, comparator) => {
.indexOf(operator) >= 0;
// If returned value is an object after changing dataset
let expression =
typeof subject === 'object' ? subject?.column_name ?? '' : subject ?? '';
typeof subject === 'object'
? (subject?.column_name ?? '')
: (subject ?? '');
if (subject && operator) {
expression += ` ${operator}`;
const firstValue =

View File

@ -43,6 +43,10 @@ describe('logger middleware', () => {
},
};
const timeSandbox = sinon.createSandbox({
useFakeTimers: true,
});
let postStub;
beforeEach(() => {
postStub = sinon.stub(SupersetClient, 'post');
@ -50,6 +54,7 @@ describe('logger middleware', () => {
afterEach(() => {
next.resetHistory();
postStub.restore();
timeSandbox.clock.reset();
});
it('should listen to LOG_EVENT action type', () => {
@ -64,11 +69,10 @@ describe('logger middleware', () => {
});
it('should POST an event to /superset/log/ when called', () => {
const clock = sinon.useFakeTimers();
logger(mockStore)(next)(action);
expect(next.callCount).toBe(0);
clock.tick(2000);
timeSandbox.clock.tick(2000);
expect(SupersetClient.post.callCount).toBe(1);
expect(SupersetClient.post.getCall(0).args[0].endpoint).toMatch(
'/superset/log/',
@ -76,9 +80,8 @@ describe('logger middleware', () => {
});
it('should include ts, start_offset, event_name, impression_id, source, and source_id in every event', () => {
const clock = sinon.useFakeTimers();
logger(mockStore)(next)(action);
clock.tick(2000);
timeSandbox.clock.tick(2000);
expect(SupersetClient.post.callCount).toBe(1);
const { events } = SupersetClient.post.getCall(0).args[0].postPayload;
@ -98,11 +101,10 @@ describe('logger middleware', () => {
});
it('should debounce a few log requests to one', () => {
const clock = sinon.useFakeTimers();
logger(mockStore)(next)(action);
logger(mockStore)(next)(action);
logger(mockStore)(next)(action);
clock.tick(2000);
timeSandbox.clock.tick(2000);
expect(SupersetClient.post.callCount).toBe(1);
expect(
@ -111,7 +113,6 @@ describe('logger middleware', () => {
});
it('should use navigator.sendBeacon if it exists', () => {
const clock = sinon.useFakeTimers();
const beaconMock = jest.fn();
Object.defineProperty(navigator, 'sendBeacon', {
writable: true,
@ -120,7 +121,7 @@ describe('logger middleware', () => {
logger(mockStore)(next)(action);
expect(beaconMock.mock.calls.length).toBe(0);
clock.tick(2000);
timeSandbox.clock.tick(2000);
expect(beaconMock.mock.calls.length).toBe(1);
const endpoint = beaconMock.mock.calls[0][0];
@ -128,7 +129,6 @@ describe('logger middleware', () => {
});
it('should pass a guest token to sendBeacon if present', () => {
const clock = sinon.useFakeTimers();
const beaconMock = jest.fn();
Object.defineProperty(navigator, 'sendBeacon', {
writable: true,
@ -138,7 +138,7 @@ describe('logger middleware', () => {
logger(mockStore)(next)(action);
expect(beaconMock.mock.calls.length).toBe(0);
clock.tick(2000);
timeSandbox.clock.tick(2000);
expect(beaconMock.mock.calls.length).toBe(1);
const formData = beaconMock.mock.calls[0][1];