diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef644cae77db0..6aa8b240eaea6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,6 +33,7 @@ repos: hooks: - id: check-docstring-first - id: check-added-large-files + exclude: \.(geojson)$ - id: check-yaml exclude: ^helm/superset/templates/ - id: debug-statements @@ -45,7 +46,7 @@ repos: - id: black language_version: python3 - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.2.1 # Use the sha or tag you want to point at + rev: v2.4.1 # Use the sha or tag you want to point at hooks: - id: prettier files: 'superset-frontend' diff --git a/.rat-excludes b/.rat-excludes index 85e9dd465e301..cb1048419e14d 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -48,3 +48,16 @@ vendor/* # github configuration .github/* .*mdx + +# skip license check in superset-ui +tmp/* +lib/* +esm/* +tsconfig.tsbuildinfo +.*ipynb +.*yml +.*iml +.esprintrc +.prettierignore +superset-frontend/packages/generator-superset +superset-frontend/temporary_superset_ui diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js index 98466ecc1ab28..35990a25a7f7a 100644 --- a/superset-frontend/.eslintrc.js +++ b/superset-frontend/.eslintrc.js @@ -16,6 +16,15 @@ * specific language governing permissions and limitations * under the License. */ + +const packageConfig = require('./package'); + +const importCoreModules = []; +Object.entries(packageConfig.dependencies).forEach(([pkg]) => { + if (/@superset-ui/.test(pkg)) { + importCoreModules.push(pkg); + } +}); module.exports = { extends: [ 'airbnb', @@ -33,7 +42,15 @@ module.exports = { browser: true, }, settings: { - 'import/resolver': 'webpack', + 'import/resolver': { + webpack: {}, + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], + }, + }, + // Allow only core/src and core/test, avoid import modules from lib + 'import/internal-regex': /^@superset-ui\/core\/(src|test)\/.*/, + 'import/core-modules': importCoreModules, react: { version: 'detect', }, @@ -76,11 +93,11 @@ module.exports = { '@typescript-eslint/no-empty-function': 0, '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/no-use-before-define': 1, // disabled temporarily + '@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily '@typescript-eslint/explicit-function-return-type': 0, '@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion camelcase: 0, 'class-methods-use-this': 0, - curly: 1, 'func-names': 0, 'guard-for-in': 0, 'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors @@ -170,11 +187,11 @@ module.exports = { }, { files: [ - 'src/**/*.test.ts', - 'src/**/*.test.tsx', - 'src/**/*.test.js', - 'src/**/*.test.jsx', - 'src/**/fixtures.*', + '*.test.ts', + '*.test.tsx', + '*.test.js', + '*.test.jsx', + 'fixtures.*', ], plugins: ['jest', 'jest-dom', 'no-only-tests', 'testing-library'], env: { @@ -195,9 +212,28 @@ module.exports = { 'error', { devDependencies: true }, ], - 'jest/consistent-test-it': 'error', 'no-only-tests/no-only-tests': 'error', + 'max-classes-per-file': 0, '@typescript-eslint/no-non-null-assertion': 0, + // TODO: disabled temporarily, re-enable after monorepo + 'jest/consistent-test-it': 'error', + 'jest/expect-expect': 0, + 'jest/no-test-prefixes': 0, + 'jest/valid-expect-in-promise': 0, + 'jest/valid-expect': 0, + 'jest/valid-title': 0, + 'jest-dom/prefer-to-have-attribute': 0, + 'jest-dom/prefer-to-have-text-content': 0, + 'jest-dom/prefer-to-have-style': 0, + }, + }, + { + files: './packages/generator-superset/**/*.test.*', + env: { + node: true, + }, + rules: { + 'jest/expect-expect': 0, }, }, ], @@ -210,7 +246,7 @@ module.exports = { }, ], 'class-methods-use-this': 0, - curly: 1, + curly: 2, 'func-names': 0, 'guard-for-in': 0, 'import/extensions': [ diff --git a/superset-frontend/babel.config.js b/superset-frontend/babel.config.js index 1d0cae25843d6..d58fd1644d715 100644 --- a/superset-frontend/babel.config.js +++ b/superset-frontend/babel.config.js @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -const packageConfig = require('./package.json'); +const packageConfig = require('./package'); module.exports = { sourceMaps: true, diff --git a/superset-frontend/cypress-base/cypress/utils/parsePostForm.ts b/superset-frontend/cypress-base/cypress/utils/parsePostForm.ts index 7bd0c018ceda4..0a818d18d557b 100644 --- a/superset-frontend/cypress-base/cypress/utils/parsePostForm.ts +++ b/superset-frontend/cypress-base/cypress/utils/parsePostForm.ts @@ -22,7 +22,7 @@ export default function parsePostForm(requestBody: ArrayBuffer) { type ParsedFields = Record; if (requestBody.constructor.name !== 'ArrayBuffer') { - return (requestBody as unknown) as ParsedFields; + return requestBody as unknown as ParsedFields; } const lines = new TextDecoder('utf-8').decode(requestBody).split('\n'); const fields: ParsedFields = {}; diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 42d71c7f2b7e4..a427a0104765c 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -126,12 +126,15 @@ "redux-thunk": "^2.1.0", "redux-undo": "^1.0.0-beta9-9-7", "regenerator-runtime": "^0.13.5", + "rimraf": "^3.0.2", "rison": "^0.1.1", "scroll-into-view-if-needed": "^2.2.28", "shortid": "^2.2.6", + "src": "file:./src", "urijs": "^1.19.6", "use-immer": "^0.6.0", - "use-query-params": "^1.1.9" + "use-query-params": "^1.1.9", + "yargs": "^15.4.1" }, "devDependencies": { "@babel/cli": "^7.15.7", @@ -206,7 +209,7 @@ "css-minimizer-webpack-plugin": "^3.0.2", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", - "eslint": "^7.17.0", + "eslint": "^7.32.0", "eslint-config-airbnb": "^18.2.1", "eslint-config-prettier": "^7.1.0", "eslint-import-resolver-typescript": "^2.5.0", @@ -239,7 +242,8 @@ "mini-css-extract-plugin": "^2.3.0", "mock-socket": "^9.0.3", "node-fetch": "^2.6.1", - "prettier": "^2.2.1", + "prettier": "^2.4.1", + "prettier-plugin-packagejson": "^2.2.15", "process": "^0.11.10", "react-resizable": "^3.0.4", "react-test-renderer": "^16.9.0", @@ -260,8 +264,7 @@ "webpack-cli": "^4.8.0", "webpack-dev-server": "^4.2.0", "webpack-manifest-plugin": "^4.0.2", - "webpack-sources": "^3.2.0", - "yargs": "^15.4.1" + "webpack-sources": "^3.2.0" }, "engines": { "node": "^16.9.1", @@ -4251,19 +4254,18 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", - "globals": "^12.1.0", + "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, @@ -4272,9 +4274,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -4289,12 +4291,12 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" @@ -4303,28 +4305,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@evocateur/libnpmaccess": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz", @@ -4419,6 +4417,18 @@ "which": "^1.3.1" } }, + "node_modules/@evocateur/pacote/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/@evocateur/pacote/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4479,6 +4489,49 @@ "object-assign": "^4.1.1" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -4812,21 +4865,6 @@ "node": ">=8" } }, - "node_modules/@jest/core/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@jest/core/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7261,6 +7299,18 @@ "node": ">= 6.9.0" } }, + "node_modules/@lerna/rimraf-dir/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/@lerna/run": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.21.0.tgz", @@ -8495,21 +8545,6 @@ "node": ">=10" } }, - "node_modules/@npmcli/move-file/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@octokit/auth-token": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", @@ -13283,6 +13318,18 @@ "postcss": "^7.0.6" } }, + "node_modules/@storybook/addon-essentials/node_modules/prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@storybook/addon-essentials/node_modules/pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", @@ -13323,21 +13370,6 @@ "node": ">=8" } }, - "node_modules/@storybook/addon-essentials/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@storybook/addon-essentials/node_modules/serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -15532,6 +15564,18 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@storybook/csf-tools/node_modules/prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@storybook/manager-webpack5": { "version": "6.3.12", "resolved": "https://registry.npmjs.org/@storybook/manager-webpack5/-/manager-webpack5-6.3.12.tgz", @@ -19508,21 +19552,6 @@ "node": ">=8" } }, - "node_modules/@storybook/react/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@storybook/react/node_modules/schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -24048,7 +24077,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -24063,7 +24091,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -24074,8 +24101,7 @@ "node_modules/ansi-styles/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/ansi-to-html": { "version": "0.6.15", @@ -26280,21 +26306,6 @@ "node": ">=8" } }, - "node_modules/c8/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/c8/node_modules/source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -26420,6 +26431,18 @@ "y18n": "^4.0.0" } }, + "node_modules/cacache/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -26528,7 +26551,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, "engines": { "node": ">=6" } @@ -27163,7 +27185,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -27174,7 +27195,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, "engines": { "node": ">=8" } @@ -27183,7 +27203,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -27192,7 +27211,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -27206,7 +27224,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.0" }, @@ -28110,6 +28127,18 @@ "run-queue": "^1.0.0" } }, + "node_modules/copy-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -30504,7 +30533,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -31450,8 +31478,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/emojis-list": { "version": "3.0.0", @@ -31980,29 +32007,32 @@ } }, "node_modules/eslint": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz", - "integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.2", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -32010,7 +32040,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -32019,7 +32049,7 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^6.0.4", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, @@ -32753,6 +32783,15 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, "node_modules/eslint/node_modules/ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -32793,6 +32832,18 @@ } } }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", @@ -32803,12 +32854,12 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" @@ -32817,22 +32868,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -32959,6 +32994,18 @@ "node": ">= 0.8.0" } }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -33036,9 +33083,9 @@ } }, "node_modules/esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -33048,9 +33095,9 @@ } }, "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -33844,9 +33891,9 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { "flat-cache": "^3.0.4" @@ -33961,6 +34008,18 @@ "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=", "dev": true }, + "node_modules/file-system-cache/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -34233,21 +34292,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatbuffers": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", @@ -34788,7 +34832,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -35122,6 +35165,15 @@ "assert-plus": "^1.0.0" } }, + "node_modules/git-hooks-list": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", + "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", + "dev": true, + "funding": { + "url": "https://github.com/fisker/git-hooks-list?sponsor=1" + } + }, "node_modules/git-raw-commits": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", @@ -41669,6 +41721,12 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -41717,6 +41775,12 @@ "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", "integrity": "sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=" }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -42972,6 +43036,18 @@ "run-queue": "^1.0.3" } }, + "node_modules/move-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -43341,6 +43417,18 @@ "nopt": "bin/nopt.js" } }, + "node_modules/node-gyp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/node-gyp/node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -44992,9 +45080,9 @@ } }, "node_modules/prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -45015,6 +45103,18 @@ "node": ">=6.0.0" } }, + "node_modules/prettier-plugin-packagejson": { + "version": "2.2.15", + "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.2.15.tgz", + "integrity": "sha512-r3WKxw0ALyD3gr3RlIFK3o7mUejCVkqwVKtUuPQaB3+aNiZYKxmad+GpZ6WFWTm6Zq2jX0wvSdlkGccQ2pEnCg==", + "dev": true, + "dependencies": { + "sort-package-json": "1.53.1" + }, + "peerDependencies": { + "prettier": ">= 1.16.0" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -49098,7 +49198,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -49115,8 +49214,7 @@ "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "node_modules/require-package-name": { "version": "2.0.1", @@ -49251,15 +49349,17 @@ } }, "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ripemd160": { @@ -49625,8 +49725,7 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "node_modules/set-value": { "version": "2.0.1", @@ -50121,6 +50220,84 @@ "node": ">=4" } }, + "node_modules/sort-object-keys": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", + "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", + "dev": true + }, + "node_modules/sort-package-json": { + "version": "1.53.1", + "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.53.1.tgz", + "integrity": "sha512-ltLORrQuuPMpy23YkWCA8fO7zBOxM4P1j9LcGxci4K2Fk8jmSyCA/ATU6CFyy8qR2HQRx4RBYWzoi78FU/Anuw==", + "dev": true, + "dependencies": { + "detect-indent": "^6.0.0", + "detect-newline": "3.1.0", + "git-hooks-list": "1.0.3", + "globby": "10.0.0", + "is-plain-obj": "2.1.0", + "sort-object-keys": "^1.1.3" + }, + "bin": { + "sort-package-json": "cli.js" + } + }, + "node_modules/sort-package-json/node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-package-json/node_modules/globby": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", + "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-package-json/node_modules/ignore": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/sort-package-json/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-package-json/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/sortablejs": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", @@ -50409,6 +50586,10 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "node_modules/src": { + "resolved": "src", + "link": true + }, "node_modules/sshpk": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", @@ -51212,15 +51393,16 @@ } }, "node_modules/table": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.3.tgz", + "integrity": "sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==", "dev": true, "dependencies": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=10.0.0" @@ -51257,9 +51439,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", - "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.0.tgz", + "integrity": "sha512-L+cJ/+pkdICMueKR6wIx3VP2fjIx3yAhuvadUv/osv9yFD7OVZy442xFF+Oeu3ZvmhBGQzoF6mTSt+LUWBmGQg==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -51273,9 +51455,9 @@ } }, "node_modules/table/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" @@ -51297,26 +51479,26 @@ "dev": true }, "node_modules/table/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/table/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -51693,22 +51875,6 @@ "node": ">=8.17.0" } }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -54013,21 +54179,6 @@ "node": ">= 0.8" } }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/webpack-dev-server/node_modules/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -54691,8 +54842,7 @@ "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, "node_modules/wide-align": { "version": "1.1.5", @@ -54836,7 +54986,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -54850,7 +54999,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, "engines": { "node": ">=8" } @@ -54859,7 +55007,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -54868,7 +55015,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -54882,7 +55028,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.0" }, @@ -55061,8 +55206,7 @@ "node_modules/y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "node_modules/yallist": { "version": "3.1.1", @@ -55082,7 +55226,6 @@ "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -55104,7 +55247,6 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -55117,7 +55259,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, "engines": { "node": ">=8" } @@ -55126,7 +55267,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -55139,7 +55279,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -55148,7 +55287,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -55160,7 +55298,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "dependencies": { "p-try": "^2.0.0" }, @@ -55175,7 +55312,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -55187,7 +55323,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, "engines": { "node": ">=6" } @@ -55196,7 +55331,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -55205,7 +55339,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -55219,7 +55352,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.0" }, @@ -55271,7 +55403,8 @@ "type": "github", "url": "https://github.com/sponsors/wooorm" } - } + }, + "src": {} }, "dependencies": { "@ant-design/colors": { @@ -58288,49 +58421,38 @@ "requires": {} }, "@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", - "globals": "^12.1.0", + "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" } }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", "dev": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "type-fest": "^0.20.2" } }, "ms": { @@ -58338,6 +58460,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, @@ -58439,6 +58567,15 @@ "which": "^1.3.1" }, "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -58483,6 +58620,40 @@ } } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -58737,15 +58908,6 @@ "picomatch": "^2.0.5" } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -60749,6 +60911,17 @@ "npmlog": "^4.1.2", "path-exists": "^3.0.0", "rimraf": "^2.6.2" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "@lerna/run": { @@ -61758,15 +61931,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } } } }, @@ -65329,6 +65493,12 @@ "postcss": "^7.0.6" } }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, "pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", @@ -65360,15 +65530,6 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -66997,6 +67158,14 @@ "lodash": "^4.17.20", "prettier": "~2.2.1", "regenerator-runtime": "^0.13.7" + }, + "dependencies": { + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + } } }, "@storybook/manager-webpack5": { @@ -69778,15 +69947,6 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -73645,7 +73805,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" }, @@ -73654,7 +73813,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -73662,8 +73820,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" } } }, @@ -75431,15 +75588,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -75538,6 +75686,17 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "cache-base": { @@ -75630,8 +75789,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "camelcase-css": { "version": "2.0.1", @@ -76128,7 +76286,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -76138,20 +76295,17 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -76162,7 +76316,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -76897,6 +77050,17 @@ "mkdirp": "^0.5.1", "rimraf": "^2.5.4", "run-queue": "^1.0.0" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "copy-descriptor": { @@ -78710,8 +78874,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decamelize-keys": { "version": "1.1.0", @@ -79522,8 +79685,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "emojis-list": { "version": "3.0.0", @@ -79975,29 +80137,32 @@ } }, "eslint": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz", - "integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.2", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -80005,7 +80170,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -80014,11 +80179,20 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^6.0.4", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -80045,6 +80219,12 @@ "ms": "2.1.2" } }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, "eslint-visitor-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", @@ -80052,22 +80232,12 @@ "dev": true }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", "dev": true, "requires": { - "type-fest": "^0.8.1" - } - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "type-fest": "^0.20.2" } }, "levn": { @@ -80163,6 +80333,12 @@ "prelude-ls": "^1.2.1" } }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -80736,18 +80912,18 @@ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -81401,9 +81577,9 @@ } }, "file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -81490,6 +81666,15 @@ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz", "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=", "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } } }, @@ -81717,17 +81902,6 @@ "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "flatbuffers": { @@ -82148,8 +82322,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { "version": "1.1.1", @@ -82401,6 +82574,12 @@ "assert-plus": "^1.0.0" } }, + "git-hooks-list": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", + "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", + "dev": true + }, "git-raw-commits": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", @@ -87490,6 +87669,12 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -87538,6 +87723,12 @@ "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", "integrity": "sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=" }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -88548,6 +88739,17 @@ "mkdirp": "^0.5.1", "rimraf": "^2.5.4", "run-queue": "^1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "ms": { @@ -88869,6 +89071,15 @@ "osenv": "^0.1.4" } }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -90182,9 +90393,9 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true }, "prettier-linter-helpers": { @@ -90196,6 +90407,15 @@ "fast-diff": "^1.1.2" } }, + "prettier-plugin-packagejson": { + "version": "2.2.15", + "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.2.15.tgz", + "integrity": "sha512-r3WKxw0ALyD3gr3RlIFK3o7mUejCVkqwVKtUuPQaB3+aNiZYKxmad+GpZ6WFWTm6Zq2jX0wvSdlkGccQ2pEnCg==", + "dev": true, + "requires": { + "sort-package-json": "1.53.1" + } + }, "pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -93412,8 +93632,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-from-string": { "version": "2.0.2", @@ -93424,8 +93643,7 @@ "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "require-package-name": { "version": "2.0.1", @@ -93533,10 +93751,9 @@ "dev": true }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } @@ -93858,8 +94075,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { "version": "2.0.1", @@ -94264,6 +94480,68 @@ "is-plain-obj": "^1.0.0" } }, + "sort-object-keys": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", + "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", + "dev": true + }, + "sort-package-json": { + "version": "1.53.1", + "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.53.1.tgz", + "integrity": "sha512-ltLORrQuuPMpy23YkWCA8fO7zBOxM4P1j9LcGxci4K2Fk8jmSyCA/ATU6CFyy8qR2HQRx4RBYWzoi78FU/Anuw==", + "dev": true, + "requires": { + "detect-indent": "^6.0.0", + "detect-newline": "3.1.0", + "git-hooks-list": "1.0.3", + "globby": "10.0.0", + "is-plain-obj": "2.1.0", + "sort-object-keys": "^1.1.3" + }, + "dependencies": { + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, + "globby": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", + "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, "sortablejs": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", @@ -94518,6 +94796,9 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "src": { + "version": "file:src" + }, "sshpk": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", @@ -95139,21 +95420,22 @@ } }, "table": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.3.tgz", + "integrity": "sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==", "dev": true, "requires": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "dependencies": { "ajv": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", - "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.0.tgz", + "integrity": "sha512-L+cJ/+pkdICMueKR6wIx3VP2fjIx3yAhuvadUv/osv9yFD7OVZy442xFF+Oeu3ZvmhBGQzoF6mTSt+LUWBmGQg==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -95163,9 +95445,9 @@ } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "is-fullwidth-code-point": { @@ -95181,23 +95463,23 @@ "dev": true }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } } } @@ -95511,18 +95793,6 @@ "peer": true, "requires": { "rimraf": "^3.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "peer": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "tmpl": { @@ -97495,15 +97765,6 @@ "unpipe": "1.0.0" } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -97805,8 +98066,7 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, "wide-align": { "version": "1.1.5", @@ -97924,7 +98184,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -97934,20 +98193,17 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -97958,7 +98214,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -98102,8 +98357,7 @@ "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { "version": "3.1.1", @@ -98120,7 +98374,6 @@ "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -98138,14 +98391,12 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -98154,14 +98405,12 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -98170,7 +98419,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -98179,7 +98427,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -98187,20 +98434,17 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -98211,7 +98455,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -98222,7 +98465,6 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" diff --git a/superset-frontend/package.json b/superset-frontend/package.json index cf9bff1d02aa3..ae1a02a732ebd 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -2,37 +2,6 @@ "name": "superset", "version": "0.0.0dev", "description": "Superset is a data exploration platform designed to be visual, intuitive, and interactive.", - "license": "Apache-2.0", - "directories": { - "doc": "docs", - "test": "spec" - }, - "scripts": { - "tdd": "cross-env NODE_ENV=test jest --watch", - "test": "cross-env NODE_ENV=test jest", - "type": "tsc --noEmit", - "cover": "cross-env NODE_ENV=test jest --coverage", - "dev": "webpack --mode=development --color --watch", - "dev-server": "cross-env NODE_ENV=development BABEL_ENV=development node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --mode=development", - "prod": "npm run build", - "build-dev": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=development webpack --mode=development --color", - "build-instrumented": "cross-env NODE_ENV=production BABEL_ENV=instrumented webpack --mode=production --color", - "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=production BABEL_ENV=\"${BABEL_ENV:=production}\" webpack --mode=production --color", - "lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx . && npm run type", - "prettier-check": "prettier --check 'src/**/*.{css,less,sass,scss}'", - "lint-fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx,.ts,tsx . && npm run clean-css && npm run type", - "clean-css": "prettier --write 'src/**/*.{css,less,sass,scss}'", - "format": "prettier --write './{src,spec,cypress-base}/**/*{.js,.jsx,.ts,.tsx,.css,.less,.scss,.sass}'", - "prettier": "npm run format", - "check-translation": "prettier --check ../superset/translations/**/LC_MESSAGES/*.json", - "clean-translation": "prettier --write ../superset/translations/**/LC_MESSAGES/*.json", - "storybook": "cross-env NODE_ENV=development BABEL_ENV=development start-storybook -s ./src/assets/images -p 6006", - "build-storybook": "build-storybook" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/apache/superset.git" - }, "keywords": [ "big", "data", @@ -45,21 +14,66 @@ "database", "flask" ], - "author": "Apache", + "homepage": "https://superset.apache.org/", "bugs": { "url": "https://github.com/apache/superset/issues" }, + "repository": { + "type": "git", + "url": "git+https://github.com/apache/superset.git" + }, + "license": "Apache-2.0", + "author": "Apache", + "directories": { + "doc": "docs", + "test": "spec" + }, + "scripts": { + "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=production BABEL_ENV=\"${BABEL_ENV:=production}\" webpack --mode=production --color", + "build-dev": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=development webpack --mode=development --color", + "build-instrumented": "cross-env NODE_ENV=production BABEL_ENV=instrumented webpack --mode=production --color", + "build-storybook": "build-storybook", + "check-translation": "prettier --check ../superset/translations/**/LC_MESSAGES/*.json", + "clean-css": "prettier --write 'src/**/*.{css,less,sass,scss}'", + "clean-translation": "prettier --write ../superset/translations/**/LC_MESSAGES/*.json", + "cover": "cross-env NODE_ENV=test jest --coverage", + "dev": "webpack --mode=development --color --watch", + "dev-server": "cross-env NODE_ENV=development BABEL_ENV=development node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --mode=development", + "format": "prettier --write './{src,spec,cypress-base,plugins,packages}/**/*{.js,.jsx,.ts,.tsx,.css,.less,.scss,.sass}'", + "lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx . && npm run type", + "lint-fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx,.ts,tsx . && npm run clean-css && npm run type", + "prettier": "npm run format", + "prettier-check": "prettier --check 'src/**/*.{css,less,sass,scss}'", + "prod": "npm run build", + "prune": "rm -rf ./{packages,plugins}/*/{lib,esm,tsconfig.tsbuildinfo,package-lock.json}", + "storybook": "cross-env NODE_ENV=development BABEL_ENV=development start-storybook -s ./src/assets/images -p 6006", + "tdd": "cross-env NODE_ENV=test jest --watch", + "test": "cross-env NODE_ENV=test jest", + "type": "tsc --noEmit" + }, "browserslist": [ "last 3 chrome versions", "last 3 firefox versions", "last 3 safari versions", "last 3 edge versions" ], - "engines": { - "node": "^16.9.1", - "npm": "^7.5.4" + "stylelint": { + "rules": { + "block-opening-brace-space-before": "always", + "no-missing-end-of-source-newline": "never", + "rule-empty-line-before": [ + "always", + { + "except": [ + "first-nested" + ], + "ignore": [ + "after-comment" + ] + } + ] + } }, - "homepage": "https://superset.apache.org/", "dependencies": { "@ant-design/icons": "^4.2.2", "@babel/runtime-corejs3": "^7.12.5", @@ -178,12 +192,15 @@ "redux-thunk": "^2.1.0", "redux-undo": "^1.0.0-beta9-9-7", "regenerator-runtime": "^0.13.5", + "rimraf": "^3.0.2", "rison": "^0.1.1", "scroll-into-view-if-needed": "^2.2.28", "shortid": "^2.2.6", + "src": "file:./src", "urijs": "^1.19.6", "use-immer": "^0.6.0", - "use-query-params": "^1.1.9" + "use-query-params": "^1.1.9", + "yargs": "^15.4.1" }, "devDependencies": { "@babel/cli": "^7.15.7", @@ -258,7 +275,7 @@ "css-minimizer-webpack-plugin": "^3.0.2", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", - "eslint": "^7.17.0", + "eslint": "^7.32.0", "eslint-config-airbnb": "^18.2.1", "eslint-config-prettier": "^7.1.0", "eslint-import-resolver-typescript": "^2.5.0", @@ -284,17 +301,18 @@ "jest-environment-enzyme": "^7.1.2", "jest-enzyme": "^7.1.2", "jest-websocket-mock": "^2.2.0", - "lerna": "^3.22.1", "jsdom": "^16.4.0", + "lerna": "^3.22.1", "less": "^3.12.2", "less-loader": "^5.0.0", "mini-css-extract-plugin": "^2.3.0", "mock-socket": "^9.0.3", "node-fetch": "^2.6.1", - "prettier": "^2.2.1", + "prettier": "^2.4.1", + "prettier-plugin-packagejson": "^2.2.15", "process": "^0.11.10", - "react-test-renderer": "^16.9.0", "react-resizable": "^3.0.4", + "react-test-renderer": "^16.9.0", "redux-mock-store": "^1.5.4", "sinon": "^9.0.2", "source-map-support": "^0.5.16", @@ -312,24 +330,10 @@ "webpack-cli": "^4.8.0", "webpack-dev-server": "^4.2.0", "webpack-manifest-plugin": "^4.0.2", - "webpack-sources": "^3.2.0", - "yargs": "^15.4.1" + "webpack-sources": "^3.2.0" }, - "stylelint": { - "rules": { - "block-opening-brace-space-before": "always", - "no-missing-end-of-source-newline": "never", - "rule-empty-line-before": [ - "always", - { - "except": [ - "first-nested" - ], - "ignore": [ - "after-comment" - ] - } - ] - } + "engines": { + "node": "^16.9.1", + "npm": "^7.5.4" } } diff --git a/superset-frontend/spec/fixtures/mockStore.js b/superset-frontend/spec/fixtures/mockStore.js index 9f8a065964db8..5fe8f54022eb7 100644 --- a/superset-frontend/spec/fixtures/mockStore.js +++ b/superset-frontend/spec/fixtures/mockStore.js @@ -65,7 +65,8 @@ export const getMockStoreWithChartsInTabsAndRoot = () => ); export const mockStoreWithTabs = getMockStoreWithTabs(); -export const mockStoreWithChartsInTabsAndRoot = getMockStoreWithChartsInTabsAndRoot(); +export const mockStoreWithChartsInTabsAndRoot = + getMockStoreWithChartsInTabsAndRoot(); export const sliceIdWithAppliedFilter = sliceId + 1; export const sliceIdWithRejectedFilter = sliceId + 2; diff --git a/superset-frontend/spec/javascripts/dashboard/actions/dashboardState_spec.js b/superset-frontend/spec/javascripts/dashboard/actions/dashboardState_spec.js index 00349fbfed428..295dc8cfc1189 100644 --- a/superset-frontend/spec/javascripts/dashboard/actions/dashboardState_spec.js +++ b/superset-frontend/spec/javascripts/dashboard/actions/dashboardState_spec.js @@ -93,9 +93,8 @@ describe('dashboardState actions', () => { // mock redux work: dispatch an event, cause modify redux state const mockParentsList = ['ROOT_ID']; dispatch.callsFake(() => { - mockState.dashboardLayout.present[ - DASHBOARD_GRID_ID - ].parents = mockParentsList; + mockState.dashboardLayout.present[DASHBOARD_GRID_ID].parents = + mockParentsList; }); // call saveDashboardRequest, it should post dashboard data with updated diff --git a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx index 79a2c9f97d619..1f65732dd197a 100644 --- a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx +++ b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx @@ -183,7 +183,8 @@ describe('Tabs', () => { expect(wrapper.state('tabIndex')).toBe(0); // display child in directPathToChild list - const directPathToChild = dashboardLayoutWithTabs.present.ROW_ID2.parents.slice(); + const directPathToChild = + dashboardLayoutWithTabs.present.ROW_ID2.parents.slice(); const directLinkProps = { ...props, directPathToChild, diff --git a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts index ddcb3cf55f481..2d385946afbef 100644 --- a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts +++ b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts @@ -65,13 +65,13 @@ describe('getFormDataWithExtraFilters', () => { nativeFilters: { filterSets: {}, filters: { - [filterId]: ({ + [filterId]: { id: filterId, scope: { rootPath: [DASHBOARD_ROOT_ID], excluded: [], }, - } as unknown) as Filter, + } as unknown as Filter, }, }, dataMask: { @@ -82,7 +82,7 @@ describe('getFormDataWithExtraFilters', () => { ownState: {}, }, }, - layout: (dashboardLayout.present as unknown) as { + layout: dashboardLayout.present as unknown as { [key: string]: LayoutItem; }, }; diff --git a/superset-frontend/spec/javascripts/dashboard/util/getLeafComponentIdFromPath_spec.js b/superset-frontend/spec/javascripts/dashboard/util/getLeafComponentIdFromPath_spec.js index 3d85d0ece3f01..9f3a65901716d 100644 --- a/superset-frontend/spec/javascripts/dashboard/util/getLeafComponentIdFromPath_spec.js +++ b/superset-frontend/spec/javascripts/dashboard/util/getLeafComponentIdFromPath_spec.js @@ -29,9 +29,8 @@ describe('getLeafComponentIdFromPath', () => { }); it('should not return label component', () => { - const updatedPath = dashboardFilters[filterId].directPathToFilter.concat( - 'LABEL-test123', - ); + const updatedPath = + dashboardFilters[filterId].directPathToFilter.concat('LABEL-test123'); expect(getLeafComponentIdFromPath(updatedPath)).toBe(leaf); }); }); diff --git a/superset-frontend/spec/javascripts/explore/controlUtils_spec.tsx b/superset-frontend/spec/javascripts/explore/controlUtils_spec.tsx index f50495602342f..db3e9717b8a32 100644 --- a/superset-frontend/spec/javascripts/explore/controlUtils_spec.tsx +++ b/superset-frontend/spec/javascripts/explore/controlUtils_spec.tsx @@ -43,10 +43,10 @@ const getKnownControlState = (...args: Parameters) => describe('controlUtils', () => { const state: ControlPanelState = { - datasource: ({ + datasource: { columns: [{ column_name: 'a' }], metrics: [{ metric_name: 'first' }, { metric_name: 'second' }], - } as unknown) as DatasourceMeta, + } as unknown as DatasourceMeta, controls: {}, form_data: { datasource: '1__table', viz_type: 'table' }, }; diff --git a/superset-frontend/spec/javascripts/explore/fixtures.tsx b/superset-frontend/spec/javascripts/explore/fixtures.tsx index e4327cccf48f2..afa615e9bfed3 100644 --- a/superset-frontend/spec/javascripts/explore/fixtures.tsx +++ b/superset-frontend/spec/javascripts/explore/fixtures.tsx @@ -68,39 +68,41 @@ export const controlPanelSectionsChartOptions: ControlPanelSectionConfig[] = [ }, ]; -export const controlPanelSectionsChartOptionsOnlyColorScheme: ControlPanelSectionConfig[] = [ - { - label: t('Chart Options'), - expanded: true, - controlSetRows: [['color_scheme']], - }, -]; +export const controlPanelSectionsChartOptionsOnlyColorScheme: ControlPanelSectionConfig[] = + [ + { + label: t('Chart Options'), + expanded: true, + controlSetRows: [['color_scheme']], + }, + ]; -export const controlPanelSectionsChartOptionsTable: ControlPanelSectionConfig[] = [ - { - label: t('Chart Options'), - expanded: true, - controlSetRows: [ - [ - 'metric', - 'metrics', - { - name: 'all_columns', - config: { - type: 'SelectControl', - multi: true, - label: t('Columns'), - default: [], - description: t('Columns to display'), - optionRenderer: c => , - valueKey: 'column_name', - mapStateToProps: stateRef => ({ - options: stateRef.datasource ? stateRef.datasource.columns : [], - }), - freeForm: true, - } as ControlConfig<'SelectControl', ColumnMeta>, - }, +export const controlPanelSectionsChartOptionsTable: ControlPanelSectionConfig[] = + [ + { + label: t('Chart Options'), + expanded: true, + controlSetRows: [ + [ + 'metric', + 'metrics', + { + name: 'all_columns', + config: { + type: 'SelectControl', + multi: true, + label: t('Columns'), + default: [], + description: t('Columns to display'), + optionRenderer: c => , + valueKey: 'column_name', + mapStateToProps: stateRef => ({ + options: stateRef.datasource ? stateRef.datasource.columns : [], + }), + freeForm: true, + } as ControlConfig<'SelectControl', ColumnMeta>, + }, + ], ], - ], - }, -]; + }, + ]; diff --git a/superset-frontend/src/CRUD/CollectionTable.tsx b/superset-frontend/src/CRUD/CollectionTable.tsx index 85380a553b681..17741bb31ecae 100644 --- a/superset-frontend/src/CRUD/CollectionTable.tsx +++ b/superset-frontend/src/CRUD/CollectionTable.tsx @@ -252,9 +252,9 @@ export default class CRUDCollection extends React.PureComponent< } // newly ordered collection - const sorted = [ - ...this.state.collectionArray, - ].sort((a: object, b: object) => compareSort(a[col], b[col])); + const sorted = [...this.state.collectionArray].sort( + (a: object, b: object) => compareSort(a[col], b[col]), + ); const newCollection = sort === SortOrder.asc ? sorted : sorted.reverse(); @@ -280,12 +280,8 @@ export default class CRUDCollection extends React.PureComponent< renderHeaderRow() { const cols = this.effectiveTableColumns(); - const { - allowDeletes, - expandFieldset, - extraButtons, - sortColumns, - } = this.props; + const { allowDeletes, expandFieldset, extraButtons, sortColumns } = + this.props; return ( @@ -322,12 +318,8 @@ export default class CRUDCollection extends React.PureComponent< } renderItem(record: any) { - const { - allowAddItem, - allowDeletes, - expandFieldset, - tableColumns, - } = this.props; + const { allowAddItem, allowDeletes, expandFieldset, tableColumns } = + this.props; /* eslint-disable no-underscore-dangle */ const isExpanded = !!this.state.expandedColumns[record.id] || record.__expanded; diff --git a/superset-frontend/src/SqlLab/components/ExploreResultsButton/index.jsx b/superset-frontend/src/SqlLab/components/ExploreResultsButton/index.jsx index 260fe3af0a9cf..969a7255a2340 100644 --- a/superset-frontend/src/SqlLab/components/ExploreResultsButton/index.jsx +++ b/superset-frontend/src/SqlLab/components/ExploreResultsButton/index.jsx @@ -44,9 +44,8 @@ class ExploreResultsButton extends React.PureComponent { constructor(props) { super(props); this.getInvalidColumns = this.getInvalidColumns.bind(this); - this.renderInvalidColumnMessage = this.renderInvalidColumnMessage.bind( - this, - ); + this.renderInvalidColumnMessage = + this.renderInvalidColumnMessage.bind(this); } getColumns() { diff --git a/superset-frontend/src/SqlLab/components/QuerySearch/index.tsx b/superset-frontend/src/SqlLab/components/QuerySearch/index.tsx index a5d624674eb1b..c5b1d47e16154 100644 --- a/superset-frontend/src/SqlLab/components/QuerySearch/index.tsx +++ b/superset-frontend/src/SqlLab/components/QuerySearch/index.tsx @@ -221,7 +221,7 @@ function QuerySearch({ actions, displayLimit }: QuerySearchProps) { value: xt, label: xt, }))} - value={(from as unknown) as undefined} + value={from as unknown as undefined} autosize={false} onChange={(selected: any) => setFrom(selected?.value)} /> @@ -230,7 +230,7 @@ function QuerySearch({ actions, displayLimit }: QuerySearchProps) { name="select-to" placeholder={t('[To]-')} options={TIME_OPTIONS.map(xt => ({ value: xt, label: xt }))} - value={(to as unknown) as undefined} + value={to as unknown as undefined} autosize={false} onChange={(selected: any) => setTo(selected?.value)} /> @@ -242,7 +242,7 @@ function QuerySearch({ actions, displayLimit }: QuerySearchProps) { value: s, label: s, }))} - value={(status as unknown) as undefined} + value={status as unknown as undefined} isLoading={false} autosize={false} onChange={(selected: any) => setStatus(selected?.value)} diff --git a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx index 16d1e014b49c6..987d87ea30071 100644 --- a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx +++ b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx @@ -203,30 +203,25 @@ export default class ResultSet extends React.PureComponent< this.fetchResults = this.fetchResults.bind(this); this.popSelectStar = this.popSelectStar.bind(this); this.reFetchQueryResults = this.reFetchQueryResults.bind(this); - this.toggleExploreResultsButton = this.toggleExploreResultsButton.bind( - this, - ); + this.toggleExploreResultsButton = + this.toggleExploreResultsButton.bind(this); this.handleSaveInDataset = this.handleSaveInDataset.bind(this); this.handleHideSaveModal = this.handleHideSaveModal.bind(this); this.handleDatasetNameChange = this.handleDatasetNameChange.bind(this); - this.handleSaveDatasetRadioBtnState = this.handleSaveDatasetRadioBtnState.bind( - this, - ); + this.handleSaveDatasetRadioBtnState = + this.handleSaveDatasetRadioBtnState.bind(this); this.handleOverwriteCancel = this.handleOverwriteCancel.bind(this); this.handleOverwriteDataset = this.handleOverwriteDataset.bind(this); - this.handleOverwriteDatasetOption = this.handleOverwriteDatasetOption.bind( - this, - ); + this.handleOverwriteDatasetOption = + this.handleOverwriteDatasetOption.bind(this); this.handleSaveDatasetModalSearch = debounce( this.handleSaveDatasetModalSearch.bind(this), 1000, ); - this.handleFilterAutocompleteOption = this.handleFilterAutocompleteOption.bind( - this, - ); - this.handleOnChangeAutoComplete = this.handleOnChangeAutoComplete.bind( - this, - ); + this.handleFilterAutocompleteOption = + this.handleFilterAutocompleteOption.bind(this); + this.handleOnChangeAutoComplete = + this.handleOnChangeAutoComplete.bind(this); this.handleExploreBtnClick = this.handleExploreBtnClick.bind(this); } diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx index 68d54e6e1bf8d..9263832502d93 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx @@ -184,9 +184,8 @@ class SqlEditor extends React.PureComponent { ); this.queryPane = this.queryPane.bind(this); this.renderQueryLimit = this.renderQueryLimit.bind(this); - this.getAceEditorAndSouthPaneHeights = this.getAceEditorAndSouthPaneHeights.bind( - this, - ); + this.getAceEditorAndSouthPaneHeights = + this.getAceEditorAndSouthPaneHeights.bind(this); this.getSqlEditorHeight = this.getSqlEditorHeight.bind(this); this.requestValidation = debounce( this.requestValidation.bind(this), @@ -456,14 +455,12 @@ class SqlEditor extends React.PureComponent { queryPane() { const hotkeys = this.getHotkeyConfig(); - const { - aceEditorHeight, - southPaneHeight, - } = this.getAceEditorAndSouthPaneHeights( - this.state.height, - this.state.northPercent, - this.state.southPercent, - ); + const { aceEditorHeight, southPaneHeight } = + this.getAceEditorAndSouthPaneHeights( + this.state.height, + this.state.northPercent, + this.state.southPercent, + ); return ( { const chart = (getState().charts || {})[chartKey]; - const timeout = getState().dashboardInfo.common.conf - .SUPERSET_WEBSERVER_TIMEOUT; + const timeout = + getState().dashboardInfo.common.conf.SUPERSET_WEBSERVER_TIMEOUT; if ( !chart.latestQueryFormData || diff --git a/superset-frontend/src/components/AnchorLink/index.jsx b/superset-frontend/src/components/AnchorLink/index.jsx index 16be622bdc039..743cb3a3c6493 100644 --- a/superset-frontend/src/components/AnchorLink/index.jsx +++ b/superset-frontend/src/components/AnchorLink/index.jsx @@ -70,12 +70,8 @@ class AnchorLink extends React.PureComponent { } render() { - const { - anchorLinkId, - filters, - showShortLinkButton, - placement, - } = this.props; + const { anchorLinkId, filters, showShortLinkButton, placement } = + this.props; return ( {showShortLinkButton && ( diff --git a/superset-frontend/src/components/AsyncEsmComponent/index.tsx b/superset-frontend/src/components/AsyncEsmComponent/index.tsx index c96368ca60bca..ebee09b1b3860 100644 --- a/superset-frontend/src/components/AsyncEsmComponent/index.tsx +++ b/superset-frontend/src/components/AsyncEsmComponent/index.tsx @@ -53,7 +53,7 @@ function DefaultPlaceholder({ */ export default function AsyncEsmComponent< P = PlaceholderProps, - M = React.ComponentType

| { default: React.ComponentType

} + M = React.ComponentType

| { default: React.ComponentType

}, >( /** * A promise generator that returns the React component to render. diff --git a/superset-frontend/src/components/Badge/index.tsx b/superset-frontend/src/components/Badge/index.tsx index 6dda874c948d6..f33d9808e4db4 100644 --- a/superset-frontend/src/components/Badge/index.tsx +++ b/superset-frontend/src/components/Badge/index.tsx @@ -25,10 +25,12 @@ export interface BadgeProps extends AntdBadgeProps { textColor?: string; } -const Badge = styled(( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - { textColor, ...props }: BadgeProps, -) => )` +const Badge = styled( + ( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + { textColor, ...props }: BadgeProps, + ) => , +)` & > sup { padding: 0 ${({ theme }) => theme.gridUnit * 2}px; background: ${({ theme, color }) => color || theme.colors.primary.base}; diff --git a/superset-frontend/src/components/Collapse/Collapse.test.tsx b/superset-frontend/src/components/Collapse/Collapse.test.tsx index 2d9355956ebad..99cc62302779e 100644 --- a/superset-frontend/src/components/Collapse/Collapse.test.tsx +++ b/superset-frontend/src/components/Collapse/Collapse.test.tsx @@ -93,8 +93,8 @@ test('renders with custom properties', () => { }); const header = document.getElementsByClassName('ant-collapse-header')[0]; - const arrow = document.getElementsByClassName('ant-collapse-arrow')[0] - .children[0]; + const arrow = + document.getElementsByClassName('ant-collapse-arrow')[0].children[0]; const headerStyle = window.getComputedStyle(header); const arrowStyle = window.getComputedStyle(arrow); diff --git a/superset-frontend/src/components/DatabaseSelector/index.tsx b/superset-frontend/src/components/DatabaseSelector/index.tsx index 7569f6585569c..e744af9045988 100644 --- a/superset-frontend/src/components/DatabaseSelector/index.tsx +++ b/superset-frontend/src/components/DatabaseSelector/index.tsx @@ -146,61 +146,62 @@ export default function DatabaseSelector({ const [refresh, setRefresh] = useState(0); const loadDatabases = useMemo( - () => async ( - search: string, - page: number, - pageSize: number, - ): Promise<{ - data: DatabaseValue[]; - totalCount: number; - }> => { - const queryParams = rison.encode({ - order_columns: 'database_name', - order_direction: 'asc', - page, - page_size: pageSize, - ...(formMode || !sqlLabMode - ? { filters: [{ col: 'database_name', opr: 'ct', value: search }] } - : { - filters: [ - { col: 'database_name', opr: 'ct', value: search }, - { - col: 'expose_in_sqllab', - opr: 'eq', - value: true, - }, - ], - }), - }); - const endpoint = `/api/v1/database/?q=${queryParams}`; - return SupersetClient.get({ endpoint }).then(({ json }) => { - const { result } = json; - if (getDbList) { - getDbList(result); - } - if (result.length === 0) { - handleError(t("It seems you don't have access to any database")); - } - const options = result.map((row: DatabaseObject) => ({ - label: ( - - ), - value: row.id, - id: row.id, - database_name: row.database_name, - backend: row.backend, - allow_multi_schema_metadata_fetch: - row.allow_multi_schema_metadata_fetch, - })); - return { - data: options, - totalCount: options.length, - }; - }); - }, + () => + async ( + search: string, + page: number, + pageSize: number, + ): Promise<{ + data: DatabaseValue[]; + totalCount: number; + }> => { + const queryParams = rison.encode({ + order_columns: 'database_name', + order_direction: 'asc', + page, + page_size: pageSize, + ...(formMode || !sqlLabMode + ? { filters: [{ col: 'database_name', opr: 'ct', value: search }] } + : { + filters: [ + { col: 'database_name', opr: 'ct', value: search }, + { + col: 'expose_in_sqllab', + opr: 'eq', + value: true, + }, + ], + }), + }); + const endpoint = `/api/v1/database/?q=${queryParams}`; + return SupersetClient.get({ endpoint }).then(({ json }) => { + const { result } = json; + if (getDbList) { + getDbList(result); + } + if (result.length === 0) { + handleError(t("It seems you don't have access to any database")); + } + const options = result.map((row: DatabaseObject) => ({ + label: ( + + ), + value: row.id, + id: row.id, + database_name: row.database_name, + backend: row.backend, + allow_multi_schema_metadata_fetch: + row.allow_multi_schema_metadata_fetch, + })); + return { + data: options, + totalCount: options.length, + }; + }); + }, [formMode, getDbList, handleError, sqlLabMode], ); diff --git a/superset-frontend/src/components/Datasource/DatasourceEditor.jsx b/superset-frontend/src/components/Datasource/DatasourceEditor.jsx index 6c6ae9854cb62..e293856fb1a8a 100644 --- a/superset-frontend/src/components/Datasource/DatasourceEditor.jsx +++ b/superset-frontend/src/components/Datasource/DatasourceEditor.jsx @@ -452,9 +452,8 @@ class DatasourceEditor extends React.PureComponent { this.onChangeEditMode = this.onChangeEditMode.bind(this); this.onDatasourcePropChange = this.onDatasourcePropChange.bind(this); this.onDatasourceChange = this.onDatasourceChange.bind(this); - this.tableChangeAndSyncMetadata = this.tableChangeAndSyncMetadata.bind( - this, - ); + this.tableChangeAndSyncMetadata = + this.tableChangeAndSyncMetadata.bind(this); this.syncMetadata = this.syncMetadata.bind(this); this.setColumns = this.setColumns.bind(this); this.validateAndChange = this.validateAndChange.bind(this); diff --git a/superset-frontend/src/components/EditableTitle/index.tsx b/superset-frontend/src/components/EditableTitle/index.tsx index 86c0350615ff4..8cb41fdf81142 100644 --- a/superset-frontend/src/components/EditableTitle/index.tsx +++ b/superset-frontend/src/components/EditableTitle/index.tsx @@ -52,10 +52,8 @@ export default function EditableTitle({ const [isEditing, setIsEditing] = useState(editing); const [currentTitle, setCurrentTitle] = useState(title); const [lastTitle, setLastTitle] = useState(title); - const [ - contentBoundingRect, - setContentBoundingRect, - ] = useState(null); + const [contentBoundingRect, setContentBoundingRect] = + useState(null); // Used so we can access the DOM element if a user clicks on this component. const contentRef = useRef(); diff --git a/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx b/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx index 0e9d6630b99d9..cda557b2f8160 100644 --- a/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx +++ b/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx @@ -38,10 +38,9 @@ function TimeoutErrorMessage({ }: ErrorMessageComponentProps) { const { extra, level } = error; - const isVisualization = (['dashboard', 'explore'] as ( - | string - | undefined - )[]).includes(source); + const isVisualization = ( + ['dashboard', 'explore'] as (string | undefined)[] + ).includes(source); const subtitle = isVisualization ? tn( diff --git a/superset-frontend/src/components/ErrorMessage/types.ts b/superset-frontend/src/components/ErrorMessage/types.ts index 496a9b4cefe58..87ef4a1bc47eb 100644 --- a/superset-frontend/src/components/ErrorMessage/types.ts +++ b/superset-frontend/src/components/ErrorMessage/types.ts @@ -96,12 +96,12 @@ export type SupersetError | null> = { message: string; }; -export type ErrorMessageComponentProps< - ExtraType = Record | null -> = { - error: SupersetError; - source?: ErrorSource; - subtitle?: React.ReactNode; -}; +export type ErrorMessageComponentProps | null> = + { + error: SupersetError; + source?: ErrorSource; + subtitle?: React.ReactNode; + }; -export type ErrorMessageComponent = React.ComponentType; +export type ErrorMessageComponent = + React.ComponentType; diff --git a/superset-frontend/src/components/ImportModal/index.tsx b/superset-frontend/src/components/ImportModal/index.tsx index 58b6724778e97..17e6cb3b589bf 100644 --- a/superset-frontend/src/components/ImportModal/index.tsx +++ b/superset-frontend/src/components/ImportModal/index.tsx @@ -126,9 +126,8 @@ const ImportModelsModal: FunctionComponent = ({ }) => { const [isHidden, setIsHidden] = useState(true); const [passwords, setPasswords] = useState>({}); - const [needsOverwriteConfirm, setNeedsOverwriteConfirm] = useState( - false, - ); + const [needsOverwriteConfirm, setNeedsOverwriteConfirm] = + useState(false); const [confirmedOverwrite, setConfirmedOverwrite] = useState(false); const [fileList, setFileList] = useState([]); const [importingModel, setImportingModel] = useState(false); diff --git a/superset-frontend/src/components/Label/index.tsx b/superset-frontend/src/components/Label/index.tsx index 4e33ede84436c..0bf4f2a058bf1 100644 --- a/superset-frontend/src/components/Label/index.tsx +++ b/superset-frontend/src/components/Label/index.tsx @@ -45,15 +45,8 @@ export default function Label(props: LabelProps) { const theme = useTheme(); const { colors, transitionTiming } = theme; const { type, onClick, children, ...rest } = props; - const { - primary, - secondary, - grayscale, - success, - warning, - error, - info, - } = colors; + const { primary, secondary, grayscale, success, warning, error, info } = + colors; let backgroundColor = grayscale.light3; let backgroundColorHover = onClick ? primary.light2 : grayscale.light3; diff --git a/superset-frontend/src/components/PopoverDropdown/PopoverDropdown.stories.tsx b/superset-frontend/src/components/PopoverDropdown/PopoverDropdown.stories.tsx index fcdb8345b7148..4995a5f393888 100644 --- a/superset-frontend/src/components/PopoverDropdown/PopoverDropdown.stories.tsx +++ b/superset-frontend/src/components/PopoverDropdown/PopoverDropdown.stories.tsx @@ -41,19 +41,18 @@ export const InteractivePopoverDropdown = (props: Props) => { const { value, buttonType, optionType, ...rest } = props; const [currentValue, setCurrentValue] = useState(value); - const newElementHandler = (type: ElementType) => ({ - label, - value, - }: OptionProps) => { - if (type === 'button') { - return ( - - ); - } - return {label}; - }; + const newElementHandler = + (type: ElementType) => + ({ label, value }: OptionProps) => { + if (type === 'button') { + return ( + + ); + } + return {label}; + }; return ( (state => state.reports); const reportsIds = Object.keys(reports); const report = reports[reportsIds[0]]; - const [ - currentReportDeleting, - setCurrentReportDeleting, - ] = useState(null); + const [currentReportDeleting, setCurrentReportDeleting] = + useState(null); const theme = useTheme(); const toggleActiveKey = async (data: AlertObject, checked: boolean) => { diff --git a/superset-frontend/src/components/Select/DeprecatedSelect.tsx b/superset-frontend/src/components/Select/DeprecatedSelect.tsx index 5d8f4051c932c..473a5c9797b02 100644 --- a/superset-frontend/src/components/Select/DeprecatedSelect.tsx +++ b/superset-frontend/src/components/Select/DeprecatedSelect.tsx @@ -71,7 +71,7 @@ type AnyReactSelect = export type SupersetStyledSelectProps< OptionType extends OptionTypeBase, - T extends WindowedSelectProps = WindowedSelectProps + T extends WindowedSelectProps = WindowedSelectProps, > = T & { // additional props for easier usage or backward compatibility labelKey?: string; @@ -103,7 +103,7 @@ function styled< | WindowedSelectComponentType | ComponentType< SelectProps - > = WindowedSelectComponentType + > = WindowedSelectComponentType, >(SelectComponent: SelectComponentType) { type SelectProps = SupersetStyledSelectProps; type Components = SelectComponents; @@ -113,7 +113,8 @@ function styled< }); // default components for the given OptionType - const supersetDefaultComponents: SelectComponentsConfig = DEFAULT_COMPONENTS; + const supersetDefaultComponents: SelectComponentsConfig = + DEFAULT_COMPONENTS; const getSortableMultiValue = (MultiValue: Components['MultiValue']) => SortableElement((props: MultiValueProps) => { diff --git a/superset-frontend/src/components/Select/Select.tsx b/superset-frontend/src/components/Select/Select.tsx index ab278e39fe208..1afca4466336f 100644 --- a/superset-frontend/src/components/Select/Select.tsx +++ b/superset-frontend/src/components/Select/Select.tsx @@ -246,15 +246,13 @@ const defaultSortComparator = (a: AntdLabeledValue, b: AntdLabeledValue) => { * It creates a comparator to check for a specific property. * Can be used with string and number property values. * */ -export const propertyComparator = (property: string) => ( - a: AntdLabeledValue, - b: AntdLabeledValue, -) => { - if (typeof a[property] === 'string' && typeof b[property] === 'string') { - return a[property].localeCompare(b[property]); - } - return (a[property] as number) - (b[property] as number); -}; +export const propertyComparator = + (property: string) => (a: AntdLabeledValue, b: AntdLabeledValue) => { + if (typeof a[property] === 'string' && typeof b[property] === 'string') { + return a[property].localeCompare(b[property]); + } + return (a[property] as number) - (b[property] as number); + }; /** * This component is a customized version of the Antdesign 4.X Select component @@ -300,9 +298,8 @@ const Select = ({ const shouldShowSearch = isAsync || allowNewOptions ? true : showSearch; const initialOptions = options && Array.isArray(options) ? options : EMPTY_OPTIONS; - const [selectOptions, setSelectOptions] = useState( - initialOptions, - ); + const [selectOptions, setSelectOptions] = + useState(initialOptions); const shouldUseChildrenOptions = !!selectOptions.find( opt => opt?.customLabel, ); diff --git a/superset-frontend/src/components/Select/WindowedSelect/WindowedMenuList.tsx b/superset-frontend/src/components/Select/WindowedSelect/WindowedMenuList.tsx index 95066d5d605c4..8eb94b55d3927 100644 --- a/superset-frontend/src/components/Select/WindowedSelect/WindowedMenuList.tsx +++ b/superset-frontend/src/components/Select/WindowedSelect/WindowedMenuList.tsx @@ -59,15 +59,14 @@ type MenuListPropsChildren = | Component>[] | ReactElement[]; -export type MenuListProps< - OptionType extends OptionTypeBase -> = MenuListComponentProps & { - children: MenuListPropsChildren; - // theme is not present with built-in @types/react-select, but is actually - // available via CommonProps. - theme?: ThemeConfig; - className?: string; -} & WindowedMenuListProps; +export type MenuListProps = + MenuListComponentProps & { + children: MenuListPropsChildren; + // theme is not present with built-in @types/react-select, but is actually + // available via CommonProps. + theme?: ThemeConfig; + className?: string; + } & WindowedMenuListProps; const DEFAULT_OPTION_HEIGHT = 30; diff --git a/superset-frontend/src/components/Select/WindowedSelect/windowed.tsx b/superset-frontend/src/components/Select/WindowedSelect/windowed.tsx index 804ba2daf3b1f..257e2a88917c2 100644 --- a/superset-frontend/src/components/Select/WindowedSelect/windowed.tsx +++ b/superset-frontend/src/components/Select/WindowedSelect/windowed.tsx @@ -29,15 +29,13 @@ const { MenuList: DefaultMenuList } = defaultComponents; export const DEFAULT_WINDOW_THRESHOLD = 100; -export type WindowedSelectProps< - OptionType extends OptionTypeBase -> = SelectProps & { - windowThreshold?: number; -} & WindowedMenuListProps['selectProps']; +export type WindowedSelectProps = + SelectProps & { + windowThreshold?: number; + } & WindowedMenuListProps['selectProps']; -export type WindowedSelectComponentType< - OptionType extends OptionTypeBase -> = FunctionComponent>; +export type WindowedSelectComponentType = + FunctionComponent>; export function MenuList({ children, diff --git a/superset-frontend/src/components/Select/styles.tsx b/superset-frontend/src/components/Select/styles.tsx index 015c9bbc471f0..d84d8e4de170a 100644 --- a/superset-frontend/src/components/Select/styles.tsx +++ b/superset-frontend/src/components/Select/styles.tsx @@ -71,12 +71,11 @@ export type ThemeConfig = { colors: { // add known colors [key in keyof typeof reactSelectColors]: string; - } & - { - [key in keyof ReturnType]: string; - } & { - [key: string]: string; // any other colors - }; + } & { + [key in keyof ReturnType]: string; + } & { + [key: string]: string; // any other colors + }; spacing: Theme['spacing'] & { // line height and font size must be pixels for easier computation // of option item height in WindowedMenuList @@ -89,21 +88,20 @@ export type ThemeConfig = { export type PartialThemeConfig = RecursivePartial; -export const defaultTheme: ( - theme: SupersetTheme, -) => PartialThemeConfig = theme => ({ - borderRadius: theme.borderRadius, - zIndex: 11, - colors: colors(theme), - spacing: { - baseUnit: 3, - menuGutter: 0, - controlHeight: 34, - lineHeight: 19, - fontSize: 14, - minWidth: '6.5em', - }, -}); +export const defaultTheme: (theme: SupersetTheme) => PartialThemeConfig = + theme => ({ + borderRadius: theme.borderRadius, + zIndex: 11, + colors: colors(theme), + spacing: { + baseUnit: 3, + menuGutter: 0, + controlHeight: 34, + lineHeight: 19, + fontSize: 14, + minWidth: '6.5em', + }, + }); // let styles accept serialized CSS, too type CSSStyles = CSSProperties | SerializedStyles; @@ -314,13 +312,8 @@ export type InputProps = ReactSelectInputProps & { inputStyle?: object; }; -const { - ClearIndicator, - DropdownIndicator, - Option, - Input, - SelectContainer, -} = defaultComponents as Required>; +const { ClearIndicator, DropdownIndicator, Option, Input, SelectContainer } = + defaultComponents as Required>; export const DEFAULT_COMPONENTS: SelectComponentsType = { SelectContainer: ({ children, ...props }) => { diff --git a/superset-frontend/src/dashboard/actions/dashboardInfo.ts b/superset-frontend/src/dashboard/actions/dashboardInfo.ts index 4bc1c79843437..7b1b0017baa24 100644 --- a/superset-frontend/src/dashboard/actions/dashboardInfo.ts +++ b/superset-frontend/src/dashboard/actions/dashboardInfo.ts @@ -60,41 +60,41 @@ export interface SetChartConfigFail { type: typeof SET_CHART_CONFIG_FAIL; chartConfiguration: ChartConfiguration; } -export const setChartConfiguration = ( - chartConfiguration: ChartConfiguration, -) => async (dispatch: Dispatch, getState: () => any) => { - dispatch({ - type: SET_CHART_CONFIG_BEGIN, - chartConfiguration, - }); - const { id, metadata } = getState().dashboardInfo; - - // TODO extract this out when makeApi supports url parameters - const updateDashboard = makeApi< - Partial, - { result: DashboardInfo } - >({ - method: 'PUT', - endpoint: `/api/v1/dashboard/${id}`, - }); - - try { - const response = await updateDashboard({ - json_metadata: JSON.stringify({ - ...metadata, - chart_configuration: chartConfiguration, - }), - }); - dispatch( - dashboardInfoChanged({ - metadata: JSON.parse(response.result.json_metadata), - }), - ); +export const setChartConfiguration = + (chartConfiguration: ChartConfiguration) => + async (dispatch: Dispatch, getState: () => any) => { dispatch({ - type: SET_CHART_CONFIG_COMPLETE, + type: SET_CHART_CONFIG_BEGIN, chartConfiguration, }); - } catch (err) { - dispatch({ type: SET_CHART_CONFIG_FAIL, chartConfiguration }); - } -}; + const { id, metadata } = getState().dashboardInfo; + + // TODO extract this out when makeApi supports url parameters + const updateDashboard = makeApi< + Partial, + { result: DashboardInfo } + >({ + method: 'PUT', + endpoint: `/api/v1/dashboard/${id}`, + }); + + try { + const response = await updateDashboard({ + json_metadata: JSON.stringify({ + ...metadata, + chart_configuration: chartConfiguration, + }), + }); + dispatch( + dashboardInfoChanged({ + metadata: JSON.parse(response.result.json_metadata), + }), + ); + dispatch({ + type: SET_CHART_CONFIG_COMPLETE, + chartConfiguration, + }); + } catch (err) { + dispatch({ type: SET_CHART_CONFIG_FAIL, chartConfiguration }); + } + }; diff --git a/superset-frontend/src/dashboard/actions/dashboardLayout.js b/superset-frontend/src/dashboard/actions/dashboardLayout.js index fc64f8c6756ad..1fe988849d627 100644 --- a/superset-frontend/src/dashboard/actions/dashboardLayout.js +++ b/superset-frontend/src/dashboard/actions/dashboardLayout.js @@ -38,28 +38,29 @@ export const UPDATE_COMPONENTS = 'UPDATE_COMPONENTS'; // an additional setUnsavedChanges(true) action after the dispatch in the case // that dashboardState.hasUnsavedChanges is false. function setUnsavedChangesAfterAction(action) { - return (...args) => (dispatch, getState) => { - const result = action(...args); - if (typeof result === 'function') { - dispatch(result(dispatch, getState)); - } else { - dispatch(result); - } + return (...args) => + (dispatch, getState) => { + const result = action(...args); + if (typeof result === 'function') { + dispatch(result(dispatch, getState)); + } else { + dispatch(result); + } - const isComponentLevelEvent = - result.type === UPDATE_COMPONENTS && - result.payload && - result.payload.nextComponents; - // trigger dashboardFilters state update if dashboard layout is changed. - if (!isComponentLevelEvent) { - const components = getState().dashboardLayout.present; - dispatch(updateLayoutComponents(components)); - } + const isComponentLevelEvent = + result.type === UPDATE_COMPONENTS && + result.payload && + result.payload.nextComponents; + // trigger dashboardFilters state update if dashboard layout is changed. + if (!isComponentLevelEvent) { + const components = getState().dashboardLayout.present; + dispatch(updateLayoutComponents(components)); + } - if (!getState().dashboardState.hasUnsavedChanges) { - dispatch(setUnsavedChanges(true)); - } - }; + if (!getState().dashboardState.hasUnsavedChanges) { + dispatch(setUnsavedChanges(true)); + } + }; } export const updateComponents = setUnsavedChangesAfterAction( diff --git a/superset-frontend/src/dashboard/actions/hydrate.js b/superset-frontend/src/dashboard/actions/hydrate.js index 7c049228cf75c..80a5a47ce00eb 100644 --- a/superset-frontend/src/dashboard/actions/hydrate.js +++ b/superset-frontend/src/dashboard/actions/hydrate.js @@ -62,347 +62,352 @@ import getNativeFilterConfig from '../util/filterboxMigrationHelper'; export const HYDRATE_DASHBOARD = 'HYDRATE_DASHBOARD'; -export const hydrateDashboard = ( - dashboardData, - chartData, - filterboxMigrationState = FILTER_BOX_MIGRATION_STATES.NOOP, -) => (dispatch, getState) => { - const { user, common } = getState(); +export const hydrateDashboard = + ( + dashboardData, + chartData, + filterboxMigrationState = FILTER_BOX_MIGRATION_STATES.NOOP, + ) => + (dispatch, getState) => { + const { user, common } = getState(); - const { metadata } = dashboardData; - const regularUrlParams = extractUrlParams('regular'); - const reservedUrlParams = extractUrlParams('reserved'); - const editMode = reservedUrlParams.edit === 'true'; + const { metadata } = dashboardData; + const regularUrlParams = extractUrlParams('regular'); + const reservedUrlParams = extractUrlParams('reserved'); + const editMode = reservedUrlParams.edit === 'true'; - let preselectFilters = {}; + let preselectFilters = {}; - chartData.forEach(chart => { - // eslint-disable-next-line no-param-reassign - chart.slice_id = chart.form_data.slice_id; - }); - try { - // allow request parameter overwrite dashboard metadata - preselectFilters = - getUrlParam(URL_PARAMS.preselectFilters) || - JSON.parse(metadata.default_filters); - } catch (e) { - // - } - - // Priming the color palette with user's label-color mapping provided in - // the dashboard's JSON metadata - if (metadata?.label_colors) { - const namespace = metadata.color_namespace; - const colorMap = isString(metadata.label_colors) - ? JSON.parse(metadata.label_colors) - : metadata.label_colors; - const categoricalNamespace = CategoricalColorNamespace.getNamespace( - namespace, - ); - - Object.keys(colorMap).forEach(label => { - categoricalNamespace.setColor(label, colorMap[label]); + chartData.forEach(chart => { + // eslint-disable-next-line no-param-reassign + chart.slice_id = chart.form_data.slice_id; }); - } + try { + // allow request parameter overwrite dashboard metadata + preselectFilters = + getUrlParam(URL_PARAMS.preselectFilters) || + JSON.parse(metadata.default_filters); + } catch (e) { + // + } - // dashboard layout - const { position_data } = dashboardData; - // new dash: position_json could be {} or null - const layout = - position_data && Object.keys(position_data).length > 0 - ? position_data - : getEmptyLayout(); + // Priming the color palette with user's label-color mapping provided in + // the dashboard's JSON metadata + if (metadata?.label_colors) { + const namespace = metadata.color_namespace; + const colorMap = isString(metadata.label_colors) + ? JSON.parse(metadata.label_colors) + : metadata.label_colors; + const categoricalNamespace = + CategoricalColorNamespace.getNamespace(namespace); - // create a lookup to sync layout names with slice names - const chartIdToLayoutId = {}; - Object.values(layout).forEach(layoutComponent => { - if (layoutComponent.type === CHART_TYPE) { - chartIdToLayoutId[layoutComponent.meta.chartId] = layoutComponent.id; + Object.keys(colorMap).forEach(label => { + categoricalNamespace.setColor(label, colorMap[label]); + }); } - }); - // find root level chart container node for newly-added slices - const parentId = findFirstParentContainerId(layout); - const parent = layout[parentId]; - let newSlicesContainer; - let newSlicesContainerWidth = 0; + // dashboard layout + const { position_data } = dashboardData; + // new dash: position_json could be {} or null + const layout = + position_data && Object.keys(position_data).length > 0 + ? position_data + : getEmptyLayout(); - const filterScopes = metadata?.filter_scopes || {}; + // create a lookup to sync layout names with slice names + const chartIdToLayoutId = {}; + Object.values(layout).forEach(layoutComponent => { + if (layoutComponent.type === CHART_TYPE) { + chartIdToLayoutId[layoutComponent.meta.chartId] = layoutComponent.id; + } + }); - const chartQueries = {}; - const dashboardFilters = {}; - const slices = {}; - const sliceIds = new Set(); - chartData.forEach(slice => { - const key = slice.slice_id; - const form_data = { - ...slice.form_data, - url_params: { - ...slice.form_data.url_params, - ...regularUrlParams, - }, - }; - chartQueries[key] = { - ...chart, - id: key, - form_data, - formData: applyDefaultFormData(form_data), - }; + // find root level chart container node for newly-added slices + const parentId = findFirstParentContainerId(layout); + const parent = layout[parentId]; + let newSlicesContainer; + let newSlicesContainerWidth = 0; - slices[key] = { - slice_id: key, - slice_url: slice.slice_url, - slice_name: slice.slice_name, - form_data: slice.form_data, - viz_type: slice.form_data.viz_type, - datasource: slice.form_data.datasource, - description: slice.description, - description_markeddown: slice.description_markeddown, - owners: slice.owners, - modified: slice.modified, - changed_on: new Date(slice.changed_on).getTime(), - }; + const filterScopes = metadata?.filter_scopes || {}; - sliceIds.add(key); + const chartQueries = {}; + const dashboardFilters = {}; + const slices = {}; + const sliceIds = new Set(); + chartData.forEach(slice => { + const key = slice.slice_id; + const form_data = { + ...slice.form_data, + url_params: { + ...slice.form_data.url_params, + ...regularUrlParams, + }, + }; + chartQueries[key] = { + ...chart, + id: key, + form_data, + formData: applyDefaultFormData(form_data), + }; - // if there are newly added slices from explore view, fill slices into 1 or more rows - if (!chartIdToLayoutId[key] && layout[parentId]) { - if ( - newSlicesContainerWidth === 0 || - newSlicesContainerWidth + GRID_DEFAULT_CHART_WIDTH > GRID_COLUMN_COUNT - ) { - newSlicesContainer = newComponentFactory( - ROW_TYPE, - (parent.parents || []).slice(), - ); - layout[newSlicesContainer.id] = newSlicesContainer; - parent.children.push(newSlicesContainer.id); - newSlicesContainerWidth = 0; - } + slices[key] = { + slice_id: key, + slice_url: slice.slice_url, + slice_name: slice.slice_name, + form_data: slice.form_data, + viz_type: slice.form_data.viz_type, + datasource: slice.form_data.datasource, + description: slice.description, + description_markeddown: slice.description_markeddown, + owners: slice.owners, + modified: slice.modified, + changed_on: new Date(slice.changed_on).getTime(), + }; - const chartHolder = newComponentFactory( - CHART_TYPE, - { - chartId: slice.slice_id, - }, - (newSlicesContainer.parents || []).slice(), - ); + sliceIds.add(key); - layout[chartHolder.id] = chartHolder; - newSlicesContainer.children.push(chartHolder.id); - chartIdToLayoutId[chartHolder.meta.chartId] = chartHolder.id; - newSlicesContainerWidth += GRID_DEFAULT_CHART_WIDTH; - } + // if there are newly added slices from explore view, fill slices into 1 or more rows + if (!chartIdToLayoutId[key] && layout[parentId]) { + if ( + newSlicesContainerWidth === 0 || + newSlicesContainerWidth + GRID_DEFAULT_CHART_WIDTH > GRID_COLUMN_COUNT + ) { + newSlicesContainer = newComponentFactory( + ROW_TYPE, + (parent.parents || []).slice(), + ); + layout[newSlicesContainer.id] = newSlicesContainer; + parent.children.push(newSlicesContainer.id); + newSlicesContainerWidth = 0; + } - // build DashboardFilters for interactive filter features - if (slice.form_data.viz_type === 'filter_box') { - const configs = getFilterConfigsFromFormdata(slice.form_data); - let { columns } = configs; - const { labels } = configs; - if (preselectFilters[key]) { - Object.keys(columns).forEach(col => { - if (preselectFilters[key][col]) { - columns = { - ...columns, - [col]: preselectFilters[key][col], - }; - } - }); + const chartHolder = newComponentFactory( + CHART_TYPE, + { + chartId: slice.slice_id, + }, + (newSlicesContainer.parents || []).slice(), + ); + + layout[chartHolder.id] = chartHolder; + newSlicesContainer.children.push(chartHolder.id); + chartIdToLayoutId[chartHolder.meta.chartId] = chartHolder.id; + newSlicesContainerWidth += GRID_DEFAULT_CHART_WIDTH; } - const scopesByChartId = Object.keys(columns).reduce((map, column) => { - const scopeSettings = { - ...filterScopes[key], - }; - const { scope, immune } = { - ...DASHBOARD_FILTER_SCOPE_GLOBAL, - ...scopeSettings[column], - }; + // build DashboardFilters for interactive filter features + if (slice.form_data.viz_type === 'filter_box') { + const configs = getFilterConfigsFromFormdata(slice.form_data); + let { columns } = configs; + const { labels } = configs; + if (preselectFilters[key]) { + Object.keys(columns).forEach(col => { + if (preselectFilters[key][col]) { + columns = { + ...columns, + [col]: preselectFilters[key][col], + }; + } + }); + } - return { - ...map, - [column]: { - scope, - immune, - }, - }; - }, {}); + const scopesByChartId = Object.keys(columns).reduce((map, column) => { + const scopeSettings = { + ...filterScopes[key], + }; + const { scope, immune } = { + ...DASHBOARD_FILTER_SCOPE_GLOBAL, + ...scopeSettings[column], + }; - const componentId = chartIdToLayoutId[key]; - const directPathToFilter = (layout[componentId].parents || []).slice(); - directPathToFilter.push(componentId); - if ( - [ - FILTER_BOX_MIGRATION_STATES.NOOP, - FILTER_BOX_MIGRATION_STATES.SNOOZED, - ].includes(filterboxMigrationState) - ) { - dashboardFilters[key] = { - ...dashboardFilter, - chartId: key, - componentId, - datasourceId: slice.form_data.datasource, - filterName: slice.slice_name, - directPathToFilter, - columns, - labels, - scopes: scopesByChartId, - isDateFilter: Object.keys(columns).includes(TIME_RANGE), - }; + return { + ...map, + [column]: { + scope, + immune, + }, + }; + }, {}); + + const componentId = chartIdToLayoutId[key]; + const directPathToFilter = (layout[componentId].parents || []).slice(); + directPathToFilter.push(componentId); + if ( + [ + FILTER_BOX_MIGRATION_STATES.NOOP, + FILTER_BOX_MIGRATION_STATES.SNOOZED, + ].includes(filterboxMigrationState) + ) { + dashboardFilters[key] = { + ...dashboardFilter, + chartId: key, + componentId, + datasourceId: slice.form_data.datasource, + filterName: slice.slice_name, + directPathToFilter, + columns, + labels, + scopes: scopesByChartId, + isDateFilter: Object.keys(columns).includes(TIME_RANGE), + }; + } } - } - // sync layout names with current slice names in case a slice was edited - // in explore since the layout was updated. name updates go through layout for undo/redo - // functionality and python updates slice names based on layout upon dashboard save - const layoutId = chartIdToLayoutId[key]; - if (layoutId && layout[layoutId]) { - layout[layoutId].meta.sliceName = slice.slice_name; - } - }); - buildActiveFilters({ - dashboardFilters, - components: layout, - }); + // sync layout names with current slice names in case a slice was edited + // in explore since the layout was updated. name updates go through layout for undo/redo + // functionality and python updates slice names based on layout upon dashboard save + const layoutId = chartIdToLayoutId[key]; + if (layoutId && layout[layoutId]) { + layout[layoutId].meta.sliceName = slice.slice_name; + } + }); + buildActiveFilters({ + dashboardFilters, + components: layout, + }); - // store the header as a layout component so we can undo/redo changes - layout[DASHBOARD_HEADER_ID] = { - id: DASHBOARD_HEADER_ID, - type: DASHBOARD_HEADER_TYPE, - meta: { - text: dashboardData.dashboard_title, - }, - }; + // store the header as a layout component so we can undo/redo changes + layout[DASHBOARD_HEADER_ID] = { + id: DASHBOARD_HEADER_ID, + type: DASHBOARD_HEADER_TYPE, + meta: { + text: dashboardData.dashboard_title, + }, + }; - const dashboardLayout = { - past: [], - present: layout, - future: [], - }; + const dashboardLayout = { + past: [], + present: layout, + future: [], + }; - // find direct link component and path from root - const directLinkComponentId = getLocationHash(); - let directPathToChild = []; - if (layout[directLinkComponentId]) { - directPathToChild = (layout[directLinkComponentId].parents || []).slice(); - directPathToChild.push(directLinkComponentId); - } + // find direct link component and path from root + const directLinkComponentId = getLocationHash(); + let directPathToChild = []; + if (layout[directLinkComponentId]) { + directPathToChild = (layout[directLinkComponentId].parents || []).slice(); + directPathToChild.push(directLinkComponentId); + } - // should convert filter_box to filter component? - let filterConfig = metadata?.native_filter_configuration || []; - if (filterboxMigrationState === FILTER_BOX_MIGRATION_STATES.REVIEWING) { - filterConfig = getNativeFilterConfig( - chartData, - filterScopes, - preselectFilters, - ); - metadata.native_filter_configuration = filterConfig; - metadata.show_native_filters = true; - } - const nativeFilters = getInitialNativeFilterState({ - filterConfig, - }); - metadata.show_native_filters = - dashboardData?.metadata?.show_native_filters ?? - (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) && - [ - FILTER_BOX_MIGRATION_STATES.CONVERTED, - FILTER_BOX_MIGRATION_STATES.REVIEWING, - FILTER_BOX_MIGRATION_STATES.NOOP, - ].includes(filterboxMigrationState)); + // should convert filter_box to filter component? + let filterConfig = metadata?.native_filter_configuration || []; + if (filterboxMigrationState === FILTER_BOX_MIGRATION_STATES.REVIEWING) { + filterConfig = getNativeFilterConfig( + chartData, + filterScopes, + preselectFilters, + ); + metadata.native_filter_configuration = filterConfig; + metadata.show_native_filters = true; + } + const nativeFilters = getInitialNativeFilterState({ + filterConfig, + }); + metadata.show_native_filters = + dashboardData?.metadata?.show_native_filters ?? + (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) && + [ + FILTER_BOX_MIGRATION_STATES.CONVERTED, + FILTER_BOX_MIGRATION_STATES.REVIEWING, + FILTER_BOX_MIGRATION_STATES.NOOP, + ].includes(filterboxMigrationState)); - if (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS)) { - // If user just added cross filter to dashboard it's not saving it scope on server, - // so we tweak it until user will update scope and will save it in server - Object.values(dashboardLayout.present).forEach(layoutItem => { - const chartId = layoutItem.meta?.chartId; - const behaviors = - ( - getChartMetadataRegistry().get( - chartQueries[chartId]?.formData?.viz_type, - ) ?? {} - )?.behaviors ?? []; + if (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS)) { + // If user just added cross filter to dashboard it's not saving it scope on server, + // so we tweak it until user will update scope and will save it in server + Object.values(dashboardLayout.present).forEach(layoutItem => { + const chartId = layoutItem.meta?.chartId; + const behaviors = + ( + getChartMetadataRegistry().get( + chartQueries[chartId]?.formData?.viz_type, + ) ?? {} + )?.behaviors ?? []; - if (!metadata.chart_configuration) { - metadata.chart_configuration = {}; - } - if ( - behaviors.includes(Behavior.INTERACTIVE_CHART) && - !metadata.chart_configuration[chartId] - ) { - metadata.chart_configuration[chartId] = { - id: chartId, - crossFilters: { - scope: { - rootPath: [DASHBOARD_ROOT_ID], - excluded: [chartId], // By default it doesn't affects itself + if (!metadata.chart_configuration) { + metadata.chart_configuration = {}; + } + if ( + behaviors.includes(Behavior.INTERACTIVE_CHART) && + !metadata.chart_configuration[chartId] + ) { + metadata.chart_configuration[chartId] = { + id: chartId, + crossFilters: { + scope: { + rootPath: [DASHBOARD_ROOT_ID], + excluded: [chartId], // By default it doesn't affects itself + }, }, - }, - }; - } - }); - } + }; + } + }); + } - const { roles } = user; - const canEdit = canUserEditDashboard(dashboardData, user); + const { roles } = user; + const canEdit = canUserEditDashboard(dashboardData, user); - return dispatch({ - type: HYDRATE_DASHBOARD, - data: { - sliceEntities: { ...initSliceEntities, slices, isLoading: false }, - charts: chartQueries, - // read-only data - dashboardInfo: { - ...dashboardData, - metadata, - userId: user.userId ? String(user.userId) : null, // legacy, please use state.user instead - dash_edit_perm: canEdit, - dash_save_perm: findPermission('can_save_dash', 'Superset', roles), - dash_share_perm: findPermission( - 'can_share_dashboard', - 'Superset', - roles, - ), - superset_can_explore: findPermission('can_explore', 'Superset', roles), - superset_can_share: findPermission( - 'can_share_chart', - 'Superset', - roles, - ), - superset_can_csv: findPermission('can_csv', 'Superset', roles), - slice_can_edit: findPermission('can_slice', 'Superset', roles), - common: { - // legacy, please use state.common instead - flash_messages: common.flash_messages, - conf: common.conf, + return dispatch({ + type: HYDRATE_DASHBOARD, + data: { + sliceEntities: { ...initSliceEntities, slices, isLoading: false }, + charts: chartQueries, + // read-only data + dashboardInfo: { + ...dashboardData, + metadata, + userId: user.userId ? String(user.userId) : null, // legacy, please use state.user instead + dash_edit_perm: canEdit, + dash_save_perm: findPermission('can_save_dash', 'Superset', roles), + dash_share_perm: findPermission( + 'can_share_dashboard', + 'Superset', + roles, + ), + superset_can_explore: findPermission( + 'can_explore', + 'Superset', + roles, + ), + superset_can_share: findPermission( + 'can_share_chart', + 'Superset', + roles, + ), + superset_can_csv: findPermission('can_csv', 'Superset', roles), + slice_can_edit: findPermission('can_slice', 'Superset', roles), + common: { + // legacy, please use state.common instead + flash_messages: common.flash_messages, + conf: common.conf, + }, }, + dashboardFilters, + nativeFilters, + dashboardState: { + preselectNativeFilters: getUrlParam(URL_PARAMS.nativeFilters), + sliceIds: Array.from(sliceIds), + directPathToChild, + directPathLastUpdated: Date.now(), + focusedFilterField: null, + expandedSlices: metadata?.expanded_slices || {}, + refreshFrequency: metadata?.refresh_frequency || 0, + // dashboard viewers can set refresh frequency for the current visit, + // only persistent refreshFrequency will be saved to backend + shouldPersistRefreshFrequency: false, + css: dashboardData.css || '', + colorNamespace: metadata?.color_namespace || null, + colorScheme: metadata?.color_scheme || null, + editMode: canEdit && editMode, + isPublished: dashboardData.published, + hasUnsavedChanges: false, + maxUndoHistoryExceeded: false, + lastModifiedTime: dashboardData.changed_on, + isRefreshing: false, + activeTabs: [], + filterboxMigrationState, + }, + dashboardLayout, }, - dashboardFilters, - nativeFilters, - dashboardState: { - preselectNativeFilters: getUrlParam(URL_PARAMS.nativeFilters), - sliceIds: Array.from(sliceIds), - directPathToChild, - directPathLastUpdated: Date.now(), - focusedFilterField: null, - expandedSlices: metadata?.expanded_slices || {}, - refreshFrequency: metadata?.refresh_frequency || 0, - // dashboard viewers can set refresh frequency for the current visit, - // only persistent refreshFrequency will be saved to backend - shouldPersistRefreshFrequency: false, - css: dashboardData.css || '', - colorNamespace: metadata?.color_namespace || null, - colorScheme: metadata?.color_scheme || null, - editMode: canEdit && editMode, - isPublished: dashboardData.published, - hasUnsavedChanges: false, - maxUndoHistoryExceeded: false, - lastModifiedTime: dashboardData.changed_on, - isRefreshing: false, - activeTabs: [], - filterboxMigrationState, - }, - dashboardLayout, - }, - }); -}; + }); + }; diff --git a/superset-frontend/src/dashboard/actions/nativeFilters.ts b/superset-frontend/src/dashboard/actions/nativeFilters.ts index aee5ca14165ad..65d655db6db49 100644 --- a/superset-frontend/src/dashboard/actions/nativeFilters.ts +++ b/superset-frontend/src/dashboard/actions/nativeFilters.ts @@ -111,82 +111,84 @@ export interface UpdateFilterSetFail { type: typeof UPDATE_FILTER_SET_FAIL; } -export const setFilterConfiguration = ( - filterConfig: FilterConfiguration, -) => async (dispatch: Dispatch, getState: () => any) => { - dispatch({ - type: SET_FILTER_CONFIG_BEGIN, - filterConfig, - }); - const { id, metadata } = getState().dashboardInfo; - const oldFilters = getState().nativeFilters?.filters; - - // TODO extract this out when makeApi supports url parameters - const updateDashboard = makeApi< - Partial, - { result: DashboardInfo } - >({ - method: 'PUT', - endpoint: `/api/v1/dashboard/${id}`, - }); - - const mergedFilterConfig = filterConfig.map(filter => { - const oldFilter = oldFilters[filter.id]; - if (!oldFilter) { - return filter; - } - return { ...oldFilter, ...filter }; - }); - - try { - const response = await updateDashboard({ - json_metadata: JSON.stringify({ - ...metadata, - native_filter_configuration: mergedFilterConfig, - }), - }); - dispatch( - dashboardInfoChanged({ - metadata: JSON.parse(response.result.json_metadata), - }), - ); +export const setFilterConfiguration = + (filterConfig: FilterConfiguration) => + async (dispatch: Dispatch, getState: () => any) => { dispatch({ - type: SET_FILTER_CONFIG_COMPLETE, - filterConfig: mergedFilterConfig, + type: SET_FILTER_CONFIG_BEGIN, + filterConfig, }); - dispatch( - setDataMaskForFilterConfigComplete(mergedFilterConfig, oldFilters), - ); - } catch (err) { - dispatch({ - type: SET_FILTER_CONFIG_FAIL, - filterConfig: mergedFilterConfig, + const { id, metadata } = getState().dashboardInfo; + const oldFilters = getState().nativeFilters?.filters; + + // TODO extract this out when makeApi supports url parameters + const updateDashboard = makeApi< + Partial, + { result: DashboardInfo } + >({ + method: 'PUT', + endpoint: `/api/v1/dashboard/${id}`, }); - dispatch({ - type: SET_DATA_MASK_FOR_FILTER_CONFIG_FAIL, - filterConfig: mergedFilterConfig, + + const mergedFilterConfig = filterConfig.map(filter => { + const oldFilter = oldFilters[filter.id]; + if (!oldFilter) { + return filter; + } + return { ...oldFilter, ...filter }; }); - } -}; -export const setInScopeStatusOfFilters = ( - filterScopes: { - filterId: string; - chartsInScope: number[]; - tabsInScope: string[]; - }[], -) => async (dispatch: Dispatch, getState: () => any) => { - const filters = getState().nativeFilters?.filters; - const filtersWithScopes = filterScopes.map(scope => ({ - ...filters[scope.filterId], - chartsInScope: scope.chartsInScope, - tabsInScope: scope.tabsInScope, - })); - dispatch({ - type: SET_IN_SCOPE_STATUS_OF_FILTERS, - filterConfig: filtersWithScopes, - }); -}; + try { + const response = await updateDashboard({ + json_metadata: JSON.stringify({ + ...metadata, + native_filter_configuration: mergedFilterConfig, + }), + }); + dispatch( + dashboardInfoChanged({ + metadata: JSON.parse(response.result.json_metadata), + }), + ); + dispatch({ + type: SET_FILTER_CONFIG_COMPLETE, + filterConfig: mergedFilterConfig, + }); + dispatch( + setDataMaskForFilterConfigComplete(mergedFilterConfig, oldFilters), + ); + } catch (err) { + dispatch({ + type: SET_FILTER_CONFIG_FAIL, + filterConfig: mergedFilterConfig, + }); + dispatch({ + type: SET_DATA_MASK_FOR_FILTER_CONFIG_FAIL, + filterConfig: mergedFilterConfig, + }); + } + }; + +export const setInScopeStatusOfFilters = + ( + filterScopes: { + filterId: string; + chartsInScope: number[]; + tabsInScope: string[]; + }[], + ) => + async (dispatch: Dispatch, getState: () => any) => { + const filters = getState().nativeFilters?.filters; + const filtersWithScopes = filterScopes.map(scope => ({ + ...filters[scope.filterId], + chartsInScope: scope.chartsInScope, + tabsInScope: scope.tabsInScope, + })); + dispatch({ + type: SET_IN_SCOPE_STATUS_OF_FILTERS, + filterConfig: filtersWithScopes, + }); + }; type BootstrapData = { nativeFilters: { @@ -201,138 +203,134 @@ export interface SetBootstrapData { data: BootstrapData; } -export const getFilterSets = () => async ( - dispatch: Dispatch, - getState: () => RootState, -) => { - const dashboardId = getState().dashboardInfo.id; - const fetchFilterSets = makeApi< - null, - { - count: number; - ids: number[]; - result: FilterSetFullData[]; - } - >({ - method: 'GET', - endpoint: `/api/v1/dashboard/${dashboardId}/filtersets`, - }); - - dispatch({ - type: SET_FILTER_SETS_BEGIN, - }); - - const response = await fetchFilterSets(null); - - dispatch({ - type: SET_FILTER_SETS_COMPLETE, - filterSets: response.ids.map((id, i) => ({ - ...response.result[i].params, - id, - name: response.result[i].name, - })), - }); -}; +export const getFilterSets = + () => async (dispatch: Dispatch, getState: () => RootState) => { + const dashboardId = getState().dashboardInfo.id; + const fetchFilterSets = makeApi< + null, + { + count: number; + ids: number[]; + result: FilterSetFullData[]; + } + >({ + method: 'GET', + endpoint: `/api/v1/dashboard/${dashboardId}/filtersets`, + }); -export const createFilterSet = (filterSet: Omit) => async ( - dispatch: Function, - getState: () => RootState, -) => { - const dashboardId = getState().dashboardInfo.id; - const postFilterSets = makeApi< - Partial, - { - count: number; - ids: number[]; - result: FilterSetFullData[]; - } - >({ - method: 'POST', - endpoint: `/api/v1/dashboard/${dashboardId}/filtersets`, - }); + dispatch({ + type: SET_FILTER_SETS_BEGIN, + }); - dispatch({ - type: CREATE_FILTER_SET_BEGIN, - }); + const response = await fetchFilterSets(null); - const serverFilterSet: Omit & { name?: string } = { - ...filterSet, + dispatch({ + type: SET_FILTER_SETS_COMPLETE, + filterSets: response.ids.map((id, i) => ({ + ...response.result[i].params, + id, + name: response.result[i].name, + })), + }); }; - delete serverFilterSet.name; +export const createFilterSet = + (filterSet: Omit) => + async (dispatch: Function, getState: () => RootState) => { + const dashboardId = getState().dashboardInfo.id; + const postFilterSets = makeApi< + Partial, + { + count: number; + ids: number[]; + result: FilterSetFullData[]; + } + >({ + method: 'POST', + endpoint: `/api/v1/dashboard/${dashboardId}/filtersets`, + }); + + dispatch({ + type: CREATE_FILTER_SET_BEGIN, + }); - await postFilterSets({ - name: filterSet.name, - owner_type: 'Dashboard', - owner_id: dashboardId, - json_metadata: JSON.stringify(serverFilterSet), - }); + const serverFilterSet: Omit & { name?: string } = + { + ...filterSet, + }; - dispatch({ - type: CREATE_FILTER_SET_COMPLETE, - }); - dispatch(getFilterSets()); -}; + delete serverFilterSet.name; -export const updateFilterSet = (filterSet: FilterSet) => async ( - dispatch: Function, - getState: () => RootState, -) => { - const dashboardId = getState().dashboardInfo.id; - const postFilterSets = makeApi< - Partial, - {} - >({ - method: 'PUT', - endpoint: `/api/v1/dashboard/${dashboardId}/filtersets/${filterSet.id}`, - }); - - dispatch({ - type: UPDATE_FILTER_SET_BEGIN, - }); - - const serverFilterSet: Omit & { - name?: string; - id?: number; - } = { - ...filterSet, + await postFilterSets({ + name: filterSet.name, + owner_type: 'Dashboard', + owner_id: dashboardId, + json_metadata: JSON.stringify(serverFilterSet), + }); + + dispatch({ + type: CREATE_FILTER_SET_COMPLETE, + }); + dispatch(getFilterSets()); }; - delete serverFilterSet.id; - delete serverFilterSet.name; +export const updateFilterSet = + (filterSet: FilterSet) => + async (dispatch: Function, getState: () => RootState) => { + const dashboardId = getState().dashboardInfo.id; + const postFilterSets = makeApi< + Partial, + {} + >({ + method: 'PUT', + endpoint: `/api/v1/dashboard/${dashboardId}/filtersets/${filterSet.id}`, + }); - await postFilterSets({ - name: filterSet.name, - json_metadata: JSON.stringify(serverFilterSet), - }); + dispatch({ + type: UPDATE_FILTER_SET_BEGIN, + }); - dispatch({ - type: UPDATE_FILTER_SET_COMPLETE, - }); - dispatch(getFilterSets()); -}; + const serverFilterSet: Omit & { + name?: string; + id?: number; + } = { + ...filterSet, + }; -export const deleteFilterSet = (filterSetId: number) => async ( - dispatch: Function, - getState: () => RootState, -) => { - const dashboardId = getState().dashboardInfo.id; - const deleteFilterSets = makeApi<{}, {}>({ - method: 'DELETE', - endpoint: `/api/v1/dashboard/${dashboardId}/filtersets/${filterSetId}`, - }); - - dispatch({ - type: DELETE_FILTER_SET_BEGIN, - }); - - await deleteFilterSets({}); - - dispatch({ - type: DELETE_FILTER_SET_COMPLETE, - }); - dispatch(getFilterSets()); -}; + delete serverFilterSet.id; + delete serverFilterSet.name; + + await postFilterSets({ + name: filterSet.name, + json_metadata: JSON.stringify(serverFilterSet), + }); + + dispatch({ + type: UPDATE_FILTER_SET_COMPLETE, + }); + dispatch(getFilterSets()); + }; + +export const deleteFilterSet = + (filterSetId: number) => + async (dispatch: Function, getState: () => RootState) => { + const dashboardId = getState().dashboardInfo.id; + const deleteFilterSets = makeApi<{}, {}>({ + method: 'DELETE', + endpoint: `/api/v1/dashboard/${dashboardId}/filtersets/${filterSetId}`, + }); + + dispatch({ + type: DELETE_FILTER_SET_BEGIN, + }); + + await deleteFilterSets({}); + + dispatch({ + type: DELETE_FILTER_SET_COMPLETE, + }); + dispatch(getFilterSets()); + }; export const SET_FOCUSED_NATIVE_FILTER = 'SET_FOCUSED_NATIVE_FILTER'; export interface SetFocusedNativeFilter { diff --git a/superset-frontend/src/dashboard/components/FilterBoxMigrationModal.tsx b/superset-frontend/src/dashboard/components/FilterBoxMigrationModal.tsx index dc73d34006c15..d42b3254bec79 100644 --- a/superset-frontend/src/dashboard/components/FilterBoxMigrationModal.tsx +++ b/superset-frontend/src/dashboard/components/FilterBoxMigrationModal.tsx @@ -56,45 +56,40 @@ interface FilterBoxMigrationModalProps { hideFooter: boolean; } -const FilterBoxMigrationModal: FunctionComponent = ({ - onClickReview, - onClickSnooze, - onHide, - show, - hideFooter = false, -}) => ( - - - - - - } - responsive - > -

- {t( - 'filter_box will be deprecated ' + - 'in a future version of Superset. ' + - 'Please replace filter_box by dashboard filter components.', - )} -
- -); +const FilterBoxMigrationModal: FunctionComponent = + ({ onClickReview, onClickSnooze, onHide, show, hideFooter = false }) => ( + + + + + + } + responsive + > +
+ {t( + 'filter_box will be deprecated ' + + 'in a future version of Superset. ' + + 'Please replace filter_box by dashboard filter components.', + )} +
+
+ ); export default FilterBoxMigrationModal; diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx index 4dff0e40c649f..845a1ada8089c 100644 --- a/superset-frontend/src/dashboard/components/Header/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/index.jsx @@ -611,10 +611,8 @@ class Header extends React.PureComponent { onHide={this.hidePropertiesModal} colorScheme={this.props.colorScheme} onSubmit={updates => { - const { - dashboardInfoChanged, - dashboardTitleChanged, - } = this.props; + const { dashboardInfoChanged, dashboardTitleChanged } = + this.props; dashboardInfoChanged({ slug: updates.slug, metadata: JSON.parse(updates.jsonMetadata), diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/index.jsx b/superset-frontend/src/dashboard/components/PropertiesModal/index.jsx index 8acff9867dd2c..73483c18b9687 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/index.jsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/index.jsx @@ -85,24 +85,26 @@ const handleErrorResponse = async response => { }); }; -const loadAccessOptions = accessType => (input = '') => { - const query = rison.encode({ filter: input }); - return SupersetClient.get({ - endpoint: `/api/v1/dashboard/related/${accessType}?q=${query}`, - }).then( - response => ({ - data: response.json.result.map(item => ({ - value: item.value, - label: item.text, - })), - totalCount: response.json.count, - }), - badResponse => { - handleErrorResponse(badResponse); - return []; - }, - ); -}; +const loadAccessOptions = + accessType => + (input = '') => { + const query = rison.encode({ filter: input }); + return SupersetClient.get({ + endpoint: `/api/v1/dashboard/related/${accessType}?q=${query}`, + }).then( + response => ({ + data: response.json.result.map(item => ({ + value: item.value, + label: item.text, + })), + totalCount: response.json.count, + }), + badResponse => { + handleErrorResponse(badResponse); + return []; + }, + ); + }; const loadOwners = loadAccessOptions('owners'); const loadRoles = loadAccessOptions('roles'); diff --git a/superset-frontend/src/dashboard/components/PublishedStatus/PublishedStatus.test.tsx b/superset-frontend/src/dashboard/components/PublishedStatus/PublishedStatus.test.tsx index a15d9d1b3813e..5d37e9fba4efb 100644 --- a/superset-frontend/src/dashboard/components/PublishedStatus/PublishedStatus.test.tsx +++ b/superset-frontend/src/dashboard/components/PublishedStatus/PublishedStatus.test.tsx @@ -30,7 +30,8 @@ const defaultProps = { }; test('renders with unpublished status and readonly permissions', async () => { - const tooltip = /This dashboard is not published which means it will not show up in the list of dashboards/; + const tooltip = + /This dashboard is not published which means it will not show up in the list of dashboards/; render(); expect(screen.getByText('Draft')).toBeInTheDocument(); userEvent.hover(screen.getByText('Draft')); @@ -38,7 +39,8 @@ test('renders with unpublished status and readonly permissions', async () => { }); test('renders with unpublished status and write permissions', async () => { - const tooltip = /This dashboard is not published, it will not show up in the list of dashboards/; + const tooltip = + /This dashboard is not published, it will not show up in the list of dashboards/; const savePublished = jest.fn(); render( { - const { - activeFilterField, - checkedFilterFields, - filterScopeMap, - } = prevState; + const { activeFilterField, checkedFilterFields, filterScopeMap } = + prevState; const key = getKeyForFilterScopeTree({ activeFilterField, checkedFilterFields, @@ -370,11 +361,8 @@ export default class FilterScopeSelector extends React.PureComponent { }); } else { const updater = prevState => { - const { - activeFilterField, - checkedFilterFields, - filterScopeMap, - } = prevState; + const { activeFilterField, checkedFilterFields, filterScopeMap } = + prevState; const key = getKeyForFilterScopeTree({ activeFilterField, checkedFilterFields, diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx index 9d447674d1a1a..6a0569cc4258d 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx @@ -167,10 +167,8 @@ class ChartHolder extends React.Component { static getDerivedStateFromProps(props, state) { const { component, directPathToChild, directPathLastUpdated } = props; - const { - label: columnName, - chart: chartComponentId, - } = getChartAndLabelComponentIdFromPath(directPathToChild); + const { label: columnName, chart: chartComponentId } = + getChartAndLabelComponentIdFromPath(directPathToChild); if ( directPathLastUpdated !== state.directPathLastUpdated && diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx index cf240d9eb5102..3db54d6381421 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx +++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx @@ -83,8 +83,9 @@ describe('ChartHolder', () => { it('should render full size', async () => { renderWrapper(); - const chart = (screen.getByTestId('slice-container') - .firstChild as HTMLElement).style; + const chart = ( + screen.getByTestId('slice-container').firstChild as HTMLElement + ).style; await waitFor(() => expect(chart?.width).toBe('992px')); expect(chart?.height).toBe('714px'); diff --git a/superset-frontend/src/dashboard/components/gridComponents/Markdown.jsx b/superset-frontend/src/dashboard/components/gridComponents/Markdown.jsx index dcc855449f716..31fae65c462af 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Markdown.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Markdown.jsx @@ -110,13 +110,8 @@ class Markdown extends React.PureComponent { } static getDerivedStateFromProps(nextProps, state) { - const { - hasError, - editorMode, - markdownSource, - undoLength, - redoLength, - } = state; + const { hasError, editorMode, markdownSource, undoLength, redoLength } = + state; const { component: nextComponent, undoLength: nextUndoLength, diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx index 60cc4d60054bf..b164e5a7341be 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx @@ -135,10 +135,10 @@ const CascadePopover: React.FC = ({ }; const allFilters = getAllFilters(filter); - const activeFilters = useMemo(() => getActiveChildren(filter) || [filter], [ - filter, - getActiveChildren, - ]); + const activeFilters = useMemo( + () => getActiveChildren(filter) || [filter], + [filter, getActiveChildren], + ); useEffect(() => { const focusedFilterId = currentPathToChild?.[0]; diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControls.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControls.tsx index ab7855f591ab0..99331f97c5c14 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControls.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControls.tsx @@ -73,9 +73,8 @@ const FilterControls: FC = ({ }, [filterValues, dataMaskSelected]); const cascadeFilterIds = new Set(cascadeFilters.map(item => item.id)); - const [filtersInScope, filtersOutOfScope] = useSelectFiltersInScope( - cascadeFilters, - ); + const [filtersInScope, filtersOutOfScope] = + useSelectFiltersInScope(cascadeFilters); const dashboardHasTabs = useDashboardHasTabs(); const showCollapsePanel = dashboardHasTabs && cascadeFilters.length > 0; diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx index 60cf35bcd7e6e..4d6bdc23f022f 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx @@ -213,9 +213,10 @@ const FilterValue: React.FC = ({ () => dispatchFocusAction(dispatch, id), [dispatch, id], ); - const unsetFocusedFilter = useCallback(() => dispatchFocusAction(dispatch), [ - dispatch, - ]); + const unsetFocusedFilter = useCallback( + () => dispatchFocusAction(dispatch), + [dispatch], + ); const hooks = useMemo( () => ({ setDataMask, setFocusedFilter, unsetFocusedFilter }), diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx index 7c3d92731208e..703f47ec7aff8 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx @@ -151,9 +151,8 @@ const FilterBar: React.FC = ({ const history = useHistory(); const dataMaskApplied: DataMaskStateWithId = useNativeFiltersDataMask(); const [editFilterSetId, setEditFilterSetId] = useState(null); - const [dataMaskSelected, setDataMaskSelected] = useImmer( - dataMaskApplied, - ); + const [dataMaskSelected, setDataMaskSelected] = + useImmer(dataMaskApplied); const dispatch = useDispatch(); const filterSets = useFilterSets(); const filterSetFilterValues = Object.values(filterSets); @@ -267,9 +266,10 @@ const FilterBar: React.FC = ({ }); }, [dataMaskSelected, dispatch]); - const openFiltersBar = useCallback(() => toggleFiltersBar(true), [ - toggleFiltersBar, - ]); + const openFiltersBar = useCallback( + () => toggleFiltersBar(true), + [toggleFiltersBar], + ); useFilterUpdates(dataMaskSelected, setDataMaskSelected); const isApplyDisabled = checkIsApplyDisabled( diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts index af358a09fe214..f1cfbb23b4e95 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts @@ -27,9 +27,9 @@ export enum TabIds { FilterSets = 'filterSets', } -export function mapParentFiltersToChildren( - filters: Filter[], -): { [id: string]: Filter[] } { +export function mapParentFiltersToChildren(filters: Filter[]): { + [id: string]: Filter[]; +} { const cascadeChildren = {}; filters.forEach(filter => { const [parentId] = filter.cascadeParentIds || []; diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTitlePane.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTitlePane.tsx index 5da0b1031a9a5..8f4e67b6afb16 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTitlePane.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTitlePane.tsx @@ -104,9 +104,8 @@ const FilterTitlePane: React.FC = ({ setTimeout(() => { const element = document.getElementById('native-filters-tabs'); if (element) { - const navList = element.getElementsByClassName( - 'ant-tabs-nav-list', - )[0]; + const navList = + element.getElementsByClassName('ant-tabs-nav-list')[0]; navList.scrollTop = navList.scrollHeight; } }, 0); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx index 92d98bbe4c337..b04cee63d6f22 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx @@ -77,8 +77,8 @@ export function ColumnSelect({ [columns, filterValues], ); - const currentFilterType = form.getFieldValue('filters')?.[filterId] - .filterType; + const currentFilterType = + form.getFieldValue('filters')?.[filterId].filterType; const currentColumn = useMemo( () => columns?.find(column => column.column_name === value), [columns, value], diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx index d1e905407d7da..ffd64d3746950 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx @@ -390,9 +390,9 @@ const FiltersConfigForm = ( return currentDataset ? hasTemporalColumns(currentDataset) : true; }, [formFilter?.dataset?.value, loadedDatasets]); - // @ts-ignore - const hasDataset = !!nativeFilterItems[formFilter?.filterType]?.value - ?.datasourceCount; + const hasDataset = + // @ts-ignore + !!nativeFilterItems[formFilter?.filterType]?.value?.datasourceCount; const datasetId = formFilter?.dataset?.value ?? @@ -514,12 +514,8 @@ const FiltersConfigForm = ( ...formFilter, }); - const [ - hasDefaultValue, - isRequired, - defaultValueTooltip, - setHasDefaultValue, - ] = useDefaultValue(formFilter, filterToEdit); + const [hasDefaultValue, isRequired, defaultValueTooltip, setHasDefaultValue] = + useDefaultValue(formFilter, filterToEdit); const showDataset = !datasetId || datasetDetails || formFilter?.dataset?.label; diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts index 84b224b118edb..b49be4f67045e 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts @@ -118,53 +118,55 @@ export const validateForm = async ( } }; -export const createHandleSave = ( - filterConfigMap: Record, - filterIds: string[], - removedFilters: Record, - saveForm: Function, - values: NativeFiltersForm, -) => async () => { - const newFilterConfig: FilterConfiguration = filterIds - .filter(id => !removedFilters[id]) - .map(id => { - // create a filter config object from the form inputs - const formInputs = values.filters?.[id]; - // if user didn't open a filter, return the original config - if (!formInputs) return filterConfigMap[id]; - const target: Partial = {}; - if (formInputs.dataset) { - target.datasetId = formInputs.dataset.value; - } - if (formInputs.dataset && formInputs.column) { - target.column = { name: formInputs.column }; - } - return { - id, - adhoc_filters: formInputs.adhoc_filters, - time_range: formInputs.time_range, - controlValues: formInputs.controlValues ?? {}, - granularity_sqla: formInputs.granularity_sqla, - requiredFirst: Object.values(formInputs.requiredFirst ?? {}).find( - rf => rf, - ), - name: formInputs.name, - filterType: formInputs.filterType, - // for now there will only ever be one target - targets: [target], - defaultDataMask: formInputs.defaultDataMask ?? getInitialDataMask(), - cascadeParentIds: formInputs.parentFilter - ? [formInputs.parentFilter.value] - : [], - scope: formInputs.scope, - sortMetric: formInputs.sortMetric, - type: formInputs.type, - description: (formInputs.description || '').trim(), - }; - }); +export const createHandleSave = + ( + filterConfigMap: Record, + filterIds: string[], + removedFilters: Record, + saveForm: Function, + values: NativeFiltersForm, + ) => + async () => { + const newFilterConfig: FilterConfiguration = filterIds + .filter(id => !removedFilters[id]) + .map(id => { + // create a filter config object from the form inputs + const formInputs = values.filters?.[id]; + // if user didn't open a filter, return the original config + if (!formInputs) return filterConfigMap[id]; + const target: Partial = {}; + if (formInputs.dataset) { + target.datasetId = formInputs.dataset.value; + } + if (formInputs.dataset && formInputs.column) { + target.column = { name: formInputs.column }; + } + return { + id, + adhoc_filters: formInputs.adhoc_filters, + time_range: formInputs.time_range, + controlValues: formInputs.controlValues ?? {}, + granularity_sqla: formInputs.granularity_sqla, + requiredFirst: Object.values(formInputs.requiredFirst ?? {}).find( + rf => rf, + ), + name: formInputs.name, + filterType: formInputs.filterType, + // for now there will only ever be one target + targets: [target], + defaultDataMask: formInputs.defaultDataMask ?? getInitialDataMask(), + cascadeParentIds: formInputs.parentFilter + ? [formInputs.parentFilter.value] + : [], + scope: formInputs.scope, + sortMetric: formInputs.sortMetric, + type: formInputs.type, + description: (formInputs.description || '').trim(), + }; + }); - await saveForm(newFilterConfig); -}; + await saveForm(newFilterConfig); + }; export function buildFilterGroup(nodes: FilterHierarchyNode[]) { const buildGroup = ( elementId: string, @@ -208,84 +210,88 @@ export function buildFilterGroup(nodes: FilterHierarchyNode[]) { } return group; } -export const createHandleTabEdit = ( - setRemovedFilters: ( - value: - | (( - prevState: Record, - ) => Record) - | Record, - ) => void, - setSaveAlertVisible: Function, - setOrderedFilters: ( - val: string[][] | ((prevState: string[][]) => string[][]), - ) => void, - setFilterHierarchy: ( - state: FilterHierarchy | ((prevState: FilterHierarchy) => FilterHierarchy), - ) => void, - addFilter: Function, - filterHierarchy: FilterHierarchy, -) => (filterId: string, action: 'add' | 'remove') => { - const completeFilterRemoval = (filterId: string) => { - const buildNewFilterHierarchy = (hierarchy: FilterHierarchy) => - hierarchy - .filter(nativeFilter => nativeFilter.id !== filterId) - .map(nativeFilter => { - const didRemoveParent = nativeFilter.parentId === filterId; - return didRemoveParent - ? { ...nativeFilter, parentId: null } - : nativeFilter; - }); - // the filter state will actually stick around in the form, - // and the filterConfig/newFilterIds, but we use removedFilters - // to mark it as removed. - setRemovedFilters(removedFilters => ({ - ...removedFilters, - [filterId]: { isPending: false }, - })); - // Remove the filter from the side tab and de-associate children - // in case we removed a parent. - setFilterHierarchy(prevFilterHierarchy => - buildNewFilterHierarchy(prevFilterHierarchy), - ); - setOrderedFilters((orderedFilters: string[][]) => { - const newOrder = []; - for (let index = 0; index < orderedFilters.length; index += 1) { - const doesGroupContainDeletedFilter = - orderedFilters[index].findIndex(id => id === filterId) >= 0; - // Rebuild just the group that contains deleted filter ID. - if (doesGroupContainDeletedFilter) { - const newGroups = buildFilterGroup( - buildNewFilterHierarchy( - filterHierarchy.filter(filter => - orderedFilters[index].includes(filter.id), +export const createHandleTabEdit = + ( + setRemovedFilters: ( + value: + | (( + prevState: Record, + ) => Record) + | Record, + ) => void, + setSaveAlertVisible: Function, + setOrderedFilters: ( + val: string[][] | ((prevState: string[][]) => string[][]), + ) => void, + setFilterHierarchy: ( + state: + | FilterHierarchy + | ((prevState: FilterHierarchy) => FilterHierarchy), + ) => void, + addFilter: Function, + filterHierarchy: FilterHierarchy, + ) => + (filterId: string, action: 'add' | 'remove') => { + const completeFilterRemoval = (filterId: string) => { + const buildNewFilterHierarchy = (hierarchy: FilterHierarchy) => + hierarchy + .filter(nativeFilter => nativeFilter.id !== filterId) + .map(nativeFilter => { + const didRemoveParent = nativeFilter.parentId === filterId; + return didRemoveParent + ? { ...nativeFilter, parentId: null } + : nativeFilter; + }); + // the filter state will actually stick around in the form, + // and the filterConfig/newFilterIds, but we use removedFilters + // to mark it as removed. + setRemovedFilters(removedFilters => ({ + ...removedFilters, + [filterId]: { isPending: false }, + })); + // Remove the filter from the side tab and de-associate children + // in case we removed a parent. + setFilterHierarchy(prevFilterHierarchy => + buildNewFilterHierarchy(prevFilterHierarchy), + ); + setOrderedFilters((orderedFilters: string[][]) => { + const newOrder = []; + for (let index = 0; index < orderedFilters.length; index += 1) { + const doesGroupContainDeletedFilter = + orderedFilters[index].findIndex(id => id === filterId) >= 0; + // Rebuild just the group that contains deleted filter ID. + if (doesGroupContainDeletedFilter) { + const newGroups = buildFilterGroup( + buildNewFilterHierarchy( + filterHierarchy.filter(filter => + orderedFilters[index].includes(filter.id), + ), ), - ), - ); - newGroups.forEach(group => newOrder.push(group)); - } else { - newOrder.push(orderedFilters[index]); + ); + newGroups.forEach(group => newOrder.push(group)); + } else { + newOrder.push(orderedFilters[index]); + } } - } - return newOrder; - }); - }; + return newOrder; + }); + }; - if (action === 'remove') { - // first set up the timer to completely remove it - const timerId = window.setTimeout(() => { - completeFilterRemoval(filterId); - }, REMOVAL_DELAY_SECS * 1000); - // mark the filter state as "removal in progress" - setRemovedFilters(removedFilters => ({ - ...removedFilters, - [filterId]: { isPending: true, timerId }, - })); - setSaveAlertVisible(false); - } else if (action === 'add') { - addFilter(); - } -}; + if (action === 'remove') { + // first set up the timer to completely remove it + const timerId = window.setTimeout(() => { + completeFilterRemoval(filterId); + }, REMOVAL_DELAY_SECS * 1000); + // mark the filter state as "removal in progress" + setRemovedFilters(removedFilters => ({ + ...removedFilters, + [filterId]: { isPending: true, timerId }, + })); + setSaveAlertVisible(false); + } else if (action === 'add') { + addFilter(); + } + }; export const NATIVE_FILTER_PREFIX = 'NATIVE_FILTER-'; export const generateFilterId = () => diff --git a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx index 2605f75f754f9..0605237cc55ff 100644 --- a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx +++ b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx @@ -81,7 +81,8 @@ function mapStateToProps({ ).text, expandedSlices: dashboardState.expandedSlices, refreshFrequency: dashboardState.refreshFrequency, - shouldPersistRefreshFrequency: !!dashboardState.shouldPersistRefreshFrequency, + shouldPersistRefreshFrequency: + !!dashboardState.shouldPersistRefreshFrequency, customCss: dashboardState.css, colorNamespace: dashboardState.colorNamespace, colorScheme: dashboardState.colorScheme, diff --git a/superset-frontend/src/dashboard/containers/DashboardPage.tsx b/superset-frontend/src/dashboard/containers/DashboardPage.tsx index 0622fac505a5f..35968886b8453 100644 --- a/superset-frontend/src/dashboard/containers/DashboardPage.tsx +++ b/superset-frontend/src/dashboard/containers/DashboardPage.tsx @@ -72,15 +72,12 @@ const DashboardPage: FC = () => { ); const { addDangerToast } = useToasts(); const { idOrSlug } = useParams<{ idOrSlug: string }>(); - const { result: dashboard, error: dashboardApiError } = useDashboard( - idOrSlug, - ); - const { result: charts, error: chartsApiError } = useDashboardCharts( - idOrSlug, - ); - const { result: datasets, error: datasetsApiError } = useDashboardDatasets( - idOrSlug, - ); + const { result: dashboard, error: dashboardApiError } = + useDashboard(idOrSlug); + const { result: charts, error: chartsApiError } = + useDashboardCharts(idOrSlug); + const { result: datasets, error: datasetsApiError } = + useDashboardDatasets(idOrSlug); const isDashboardHydrated = useRef(false); const error = dashboardApiError || chartsApiError; diff --git a/superset-frontend/src/dashboard/util/activeDashboardFilters.js b/superset-frontend/src/dashboard/util/activeDashboardFilters.js index e0a00db9ce04c..20e420d8de2a2 100644 --- a/superset-frontend/src/dashboard/util/activeDashboardFilters.js +++ b/superset-frontend/src/dashboard/util/activeDashboardFilters.js @@ -49,9 +49,9 @@ export function isFilterBox(chartId) { export function getAppliedFilterValues(chartId) { // use cached data if possible if (!(chartId in appliedFilterValuesByChart)) { - const applicableFilters = Object.entries( - activeFilters, - ).filter(([, { scope: chartIds }]) => chartIds.includes(chartId)); + const applicableFilters = Object.entries(activeFilters).filter( + ([, { scope: chartIds }]) => chartIds.includes(chartId), + ); appliedFilterValuesByChart[chartId] = flow( keyBy( ([filterKey]) => getChartIdAndColumnFromFilterKey(filterKey).column, diff --git a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts b/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts index 78c03944e067b..87b3ab5e52b67 100644 --- a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts +++ b/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts @@ -103,15 +103,18 @@ enum FILTER_COMPONENT_FILTER_TYPES { FILTER_RANGE = 'filter_range', } -const getPreselectedValuesFromDashboard = ( - preselectedFilters: PreselectedFiltersMeatadata, -) => (filterKey: string, column: string) => { - if (preselectedFilters[filterKey] && preselectedFilters[filterKey][column]) { - // overwrite default values by dashboard default_filters - return preselectedFilters[filterKey][column]; - } - return null; -}; +const getPreselectedValuesFromDashboard = + (preselectedFilters: PreselectedFiltersMeatadata) => + (filterKey: string, column: string) => { + if ( + preselectedFilters[filterKey] && + preselectedFilters[filterKey][column] + ) { + // overwrite default values by dashboard default_filters + return preselectedFilters[filterKey][column]; + } + return null; + }; const getFilterBoxDefaultValues = (config: FilterConfig) => { let defaultValues = config[FILTER_CONFIG_ATTRIBUTES.DEFAULT_VALUE]; @@ -218,9 +221,8 @@ export default function getNativeFilterConfig( time_range, } = slice.form_data; - const getDashboardDefaultValues = getPreselectedValuesFromDashboard( - preselectFilters, - ); + const getDashboardDefaultValues = + getPreselectedValuesFromDashboard(preselectFilters); if (date_filter) { const { scope, immune }: FilterScopeType = @@ -488,9 +490,8 @@ export default function getNativeFilterConfig( } }); - const dependencies: FilterBoxDependencyMap = getFilterboxDependencies( - filterScopes, - ); + const dependencies: FilterBoxDependencyMap = + getFilterboxDependencies(filterScopes); Object.entries(dependencies).forEach(([key, filterFields]) => { Object.entries(filterFields).forEach(([field, childrenChartIds]) => { const parentComponentId = filterBoxToFilterComponentMap[key][field]; diff --git a/superset-frontend/src/dashboard/util/getComponentWidthFromDrop.js b/superset-frontend/src/dashboard/util/getComponentWidthFromDrop.js index 766df531bf1a8..35f1c99946d17 100644 --- a/superset-frontend/src/dashboard/util/getComponentWidthFromDrop.js +++ b/superset-frontend/src/dashboard/util/getComponentWidthFromDrop.js @@ -37,35 +37,29 @@ export default function getComponentWidthFromDrop({ return component.meta.width; } - const { - width: draggingWidth, - minimumWidth: minDraggingWidth, - } = getDetailedComponentWidth({ - component, - components, - }); + const { width: draggingWidth, minimumWidth: minDraggingWidth } = + getDetailedComponentWidth({ + component, + components, + }); - const { - width: destinationWidth, - occupiedWidth: draggingOccupiedWidth, - } = getDetailedComponentWidth({ - id: destination.id, - components, - }); + const { width: destinationWidth, occupiedWidth: draggingOccupiedWidth } = + getDetailedComponentWidth({ + id: destination.id, + components, + }); let destinationCapacity = Number(destinationWidth - draggingOccupiedWidth); if (Number.isNaN(destinationCapacity)) { - const { - width: grandparentWidth, - occupiedWidth: grandparentOccupiedWidth, - } = getDetailedComponentWidth({ - id: findParentId({ - childId: destination.id, - layout: components, - }), - components, - }); + const { width: grandparentWidth, occupiedWidth: grandparentOccupiedWidth } = + getDetailedComponentWidth({ + id: findParentId({ + childId: destination.id, + layout: components, + }), + components, + }); destinationCapacity = Number(grandparentWidth - grandparentOccupiedWidth); } diff --git a/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js b/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js index e22f50573a44c..1ecaa2b9baaa1 100644 --- a/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js +++ b/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js @@ -57,12 +57,11 @@ function getTabChildrenScope({ )) ) { // get all charts from tabChildren that is not in scope - const immuneChartIdsFromTabsNotInScope = getImmuneChartIdsFromTabsNotInScope( - { + const immuneChartIdsFromTabsNotInScope = + getImmuneChartIdsFromTabsNotInScope({ tabs: tabChildren, tabsInScope: flatMap(tabScopes, ({ scope }) => scope), - }, - ); + }); const immuneChartIdsFromTabsInScope = flatMap( Object.values(tabScopes), ({ immune }) => immune, diff --git a/superset-frontend/src/dashboard/util/injectCustomCss.ts b/superset-frontend/src/dashboard/util/injectCustomCss.ts index a686503725211..36b3f4d7621e0 100644 --- a/superset-frontend/src/dashboard/util/injectCustomCss.ts +++ b/superset-frontend/src/dashboard/util/injectCustomCss.ts @@ -40,7 +40,7 @@ export default function injectCustomCss(css: string) { document.querySelector(`.${className}`) || createStyleElement(className); if ('styleSheet' in style) { - ((style as unknown) as MysteryStyleElement).styleSheet.cssText = css; + (style as unknown as MysteryStyleElement).styleSheet.cssText = css; } else { style.innerHTML = css; } diff --git a/superset-frontend/src/explore/components/Control.tsx b/superset-frontend/src/explore/components/Control.tsx index 6e2fa78cd5920..0f4820f4a2b5c 100644 --- a/superset-frontend/src/explore/components/Control.tsx +++ b/superset-frontend/src/explore/components/Control.tsx @@ -49,9 +49,8 @@ export type ControlProps = { /** * */ -export type ControlComponentProps< - ValueType extends JsonValue = JsonValue -> = Omit & BaseControlComponentProps; +export type ControlComponentProps = + Omit & BaseControlComponentProps; export default function Control(props: ControlProps) { const { diff --git a/superset-frontend/src/explore/components/ExploreActionButtons.tsx b/superset-frontend/src/explore/components/ExploreActionButtons.tsx index fa933a8abd882..c16d1242456a5 100644 --- a/superset-frontend/src/explore/components/ExploreActionButtons.tsx +++ b/superset-frontend/src/explore/components/ExploreActionButtons.tsx @@ -49,14 +49,8 @@ type ExploreActionButtonsProps = { }; const ActionButton = (props: ActionButtonProps) => { - const { - icon, - text, - tooltip, - className, - onTooltipVisibilityChange, - ...rest - } = props; + const { icon, text, tooltip, className, onTooltipVisibilityChange, ...rest } = + props; return ( ({ }, chartStatus: 'rendered', }, - slice: ({ + slice: { cache_timeout: null, changed_on: '2021-03-19T16:30:56.750230', changed_on_humanized: '7 days ago', @@ -85,7 +85,7 @@ const createProps = () => ({ slice_id: 318, slice_name: 'Age distribution of respondents', slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20318%7D', - } as unknown) as Slice, + } as unknown as Slice, slice_name: 'Age distribution of respondents', actions: { postChartFormData: () => null, diff --git a/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx b/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx index c1a3ab94b8f61..f0d77a8b7d445 100644 --- a/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx +++ b/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx @@ -25,7 +25,7 @@ import userEvent from '@testing-library/user-event'; import PropertiesModal from '.'; const createProps = () => ({ - slice: ({ + slice: { cache_timeout: null, changed_on: '2021-03-19T16:30:56.750230', changed_on_humanized: '7 days ago', @@ -62,7 +62,7 @@ const createProps = () => ({ slice_id: 318, slice_name: 'Age distribution of respondents', slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20318%7D', - } as unknown) as Slice, + } as unknown as Slice, show: true, onHide: jest.fn(), onSave: jest.fn(), diff --git a/superset-frontend/src/explore/components/PropertiesModal/index.tsx b/superset-frontend/src/explore/components/PropertiesModal/index.tsx index 76773f1f00db3..928589856390c 100644 --- a/superset-frontend/src/explore/components/PropertiesModal/index.tsx +++ b/superset-frontend/src/explore/components/PropertiesModal/index.tsx @@ -88,20 +88,25 @@ export default function PropertiesModal({ ); const loadOptions = useMemo( - () => (input = '', page: number, pageSize: number) => { - const query = rison.encode({ filter: input, page, page_size: pageSize }); - return SupersetClient.get({ - endpoint: `/api/v1/chart/related/owners?q=${query}`, - }).then(response => ({ - data: response.json.result.map( - (item: { value: number; text: string }) => ({ - value: item.value, - label: item.text, - }), - ), - totalCount: response.json.count, - })); - }, + () => + (input = '', page: number, pageSize: number) => { + const query = rison.encode({ + filter: input, + page, + page_size: pageSize, + }); + return SupersetClient.get({ + endpoint: `/api/v1/chart/related/owners?q=${query}`, + }).then(response => ({ + data: response.json.result.map( + (item: { value: number; text: string }) => ({ + value: item.value, + label: item.text, + }), + ), + totalCount: response.json.count, + })); + }, [], ); @@ -115,10 +120,12 @@ export default function PropertiesModal({ cache_timeout: cacheTimeout || null, }; if (selectedOwners) { - payload.owners = (selectedOwners as { - value: number; - label: string; - }[]).map(o => o.value); + payload.owners = ( + selectedOwners as { + value: number; + label: string; + }[] + ).map(o => o.value); } try { const res = await SupersetClient.put({ diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx index 355b38df1980b..e6d5fbe96803a 100644 --- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx +++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx @@ -164,9 +164,8 @@ export default class AnnotationLayer extends React.PureComponent { this.applyAnnotation = this.applyAnnotation.bind(this); this.fetchOptions = this.fetchOptions.bind(this); this.handleAnnotationType = this.handleAnnotationType.bind(this); - this.handleAnnotationSourceType = this.handleAnnotationSourceType.bind( - this, - ); + this.handleAnnotationSourceType = + this.handleAnnotationSourceType.bind(this); this.handleValue = this.handleValue.bind(this); this.isValidForm = this.isValidForm.bind(this); } diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx index 401364e0dfc0d..d03b2370317ef 100644 --- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx +++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx @@ -74,10 +74,8 @@ const ConditionalFormattingControl = ({ ...props }: ConditionalFormattingControlProps) => { const theme = useTheme(); - const [ - conditionalFormattingConfigs, - setConditionalFormattingConfigs, - ] = useState(value ?? []); + const [conditionalFormattingConfigs, setConditionalFormattingConfigs] = + useState(value ?? []); useEffect(() => { if (onChange) { diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx index 252feff4ee314..ee862b2b69732 100644 --- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx +++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx @@ -57,22 +57,22 @@ const operatorOptions = [ { value: COMPARATOR.BETWEEN_OR_RIGHT_EQUAL, label: '< x ≤', order: 10 }, ]; -const targetValueValidator = ( - compare: (targetValue: number, compareValue: number) => boolean, - rejectMessage: string, -) => (targetValue: number | string) => ( - _: any, - compareValue: number | string, -) => { - if ( - !targetValue || - !compareValue || - compare(Number(targetValue), Number(compareValue)) - ) { - return Promise.resolve(); - } - return Promise.reject(new Error(rejectMessage)); -}; +const targetValueValidator = + ( + compare: (targetValue: number, compareValue: number) => boolean, + rejectMessage: string, + ) => + (targetValue: number | string) => + (_: any, compareValue: number | string) => { + if ( + !targetValue || + !compareValue || + compare(Number(targetValue), Number(compareValue)) + ) { + return Promise.resolve(); + } + return Promise.reject(new Error(rejectMessage)); + }; const targetValueLeftValidator = targetValueValidator( (target: number, val: number) => target > val, diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx b/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx index 913311de4e47d..c78683b9980d9 100644 --- a/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx +++ b/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx @@ -116,9 +116,8 @@ class DatasourceControl extends React.PureComponent { showChangeDatasourceModal: false, }; this.onDatasourceSave = this.onDatasourceSave.bind(this); - this.toggleChangeDatasourceModal = this.toggleChangeDatasourceModal.bind( - this, - ); + this.toggleChangeDatasourceModal = + this.toggleChangeDatasourceModal.bind(this); this.toggleEditDatasourceModal = this.toggleEditDatasourceModal.bind(this); this.toggleShowDatasource = this.toggleShowDatasource.bind(this); this.handleMenuItemClick = this.handleMenuItemClick.bind(this); diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts index 613179d3d55aa..7e2f34e141356 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts @@ -93,7 +93,8 @@ export const SINCE_MODE_OPTIONS: SelectOptionType[] = [ { value: 'today', label: t('Midnight'), order: 3 }, ]; -export const UNTIL_MODE_OPTIONS: SelectOptionType[] = SINCE_MODE_OPTIONS.slice(); +export const UNTIL_MODE_OPTIONS: SelectOptionType[] = + SINCE_MODE_OPTIONS.slice(); export const COMMON_RANGE_SET: Set = new Set([ 'Last day', diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts index 9aae21a4039b8..8ad5f1d8d83cb 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts @@ -32,9 +32,9 @@ export const formatTimeRange = ( ) => { const splitDateRange = timeRange.split(SEPARATOR); if (splitDateRange.length === 1) return timeRange; - const formattedEndpoints = ( - endpoints || ['unknown', 'unknown'] - ).map((endpoint: string) => (endpoint === 'inclusive' ? '≤' : '<')); + const formattedEndpoints = (endpoints || ['unknown', 'unknown']).map( + (endpoint: string) => (endpoint === 'inclusive' ? '≤' : '<'), + ); return `${formatDateEndpoint(splitDateRange[0], true)} ${ formattedEndpoints[0] diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateParser.ts b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateParser.ts index d1be0def7e3b0..0d259f8c80d02 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateParser.ts +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateParser.ts @@ -84,12 +84,12 @@ export const customTimeRangeDecode = ( // specific : specific if (ISO8601_AND_CONSTANT.test(since) && ISO8601_AND_CONSTANT.test(until)) { - const sinceMode = (DATETIME_CONSTANT.includes(since) - ? since - : 'specific') as DateTimeModeType; - const untilMode = (DATETIME_CONSTANT.includes(until) - ? until - : 'specific') as DateTimeModeType; + const sinceMode = ( + DATETIME_CONSTANT.includes(since) ? since : 'specific' + ) as DateTimeModeType; + const untilMode = ( + DATETIME_CONSTANT.includes(until) ? until : 'specific' + ) as DateTimeModeType; return { customRange: { ...defaultCustomRange, @@ -110,9 +110,9 @@ export const customTimeRangeDecode = ( since.includes(until) ) { const [dttm, grainValue, grain] = sinceCapturedGroup.slice(1); - const untilMode = (DATETIME_CONSTANT.includes(until) - ? until - : 'specific') as DateTimeModeType; + const untilMode = ( + DATETIME_CONSTANT.includes(until) ? until : 'specific' + ) as DateTimeModeType; return { customRange: { ...defaultCustomRange, @@ -135,9 +135,9 @@ export const customTimeRangeDecode = ( until.includes(since) ) { const [dttm, grainValue, grain] = [...untilCapturedGroup.slice(1)]; - const sinceMode = (DATETIME_CONSTANT.includes(since) - ? since - : 'specific') as DateTimeModeType; + const sinceMode = ( + DATETIME_CONSTANT.includes(since) ? since : 'specific' + ) as DateTimeModeType; return { customRange: { ...defaultCustomRange, diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx index 597b9964e68ad..8b2d3b9bc39c7 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx @@ -88,11 +88,8 @@ const ColumnSelectPopover = ({ isAdhocColumnsEnabled, }: ColumnSelectPopoverProps) => { const [initialLabel] = useState(label); - const [ - initialAdhocColumn, - initialCalculatedColumn, - initialSimpleColumn, - ] = getInitialColumnValues(editedColumn); + const [initialAdhocColumn, initialCalculatedColumn, initialSimpleColumn] = + getInitialColumnValues(editedColumn); const [adhocColumn, setAdhocColumn] = useState( initialAdhocColumn, diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx index a7b1f3895cac7..4298d2289018b 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx @@ -81,21 +81,18 @@ const ColumnSelectPopoverTrigger = ({ setPopoverVisible(false); }, []); - const { - visible, - handleTogglePopover, - handleClosePopover, - } = isControlledComponent - ? { - visible: props.visible, - handleTogglePopover: props.togglePopover!, - handleClosePopover: props.closePopover!, - } - : { - visible: popoverVisible, - handleTogglePopover: togglePopover, - handleClosePopover: closePopover, - }; + const { visible, handleTogglePopover, handleClosePopover } = + isControlledComponent + ? { + visible: props.visible, + handleTogglePopover: props.togglePopover!, + handleClosePopover: props.closePopover!, + } + : { + visible: popoverVisible, + handleTogglePopover: togglePopover, + handleClosePopover: closePopover, + }; const getCurrentTab = useCallback((tab: string) => { setIsTitleEditDisabled(tab !== editableTitleTab); diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx index 9d9fb83acede5..7371d7bb488a1 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx @@ -28,7 +28,7 @@ import { DndFilterSelectProps, } from 'src/explore/components/controls/DndColumnSelectControl/DndFilterSelect'; import { PLACEHOLDER_DATASOURCE } from 'src/dashboard/constants'; -import { DEFAULT_FORM_DATA } from '@superset-ui/plugin-chart-echarts/lib/Timeseries/types'; +import { TimeseriesDefaultFormData } from '@superset-ui/plugin-chart-echarts'; const defaultProps: DndFilterSelectProps = { type: 'DndFilterSelect', @@ -70,7 +70,7 @@ test('renders options with saved metric', () => { {...defaultProps} formData={{ ...baseFormData, - ...DEFAULT_FORM_DATA, + ...TimeseriesDefaultFormData, metrics: ['saved_metric'], }} />, @@ -111,7 +111,7 @@ test('renders options with adhoc metric', () => { {...defaultProps} formData={{ ...baseFormData, - ...DEFAULT_FORM_DATA, + ...TimeseriesDefaultFormData, metrics: [adhocMetric], }} />, diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts index e0e4693197cab..b2c9bd953b981 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts @@ -41,13 +41,12 @@ export interface OptionItemInterface { /** * Shared control props for all DnD control. */ -export type DndControlProps< - ValueType extends JsonValue -> = ControlComponentProps & { - multi?: boolean; - canDelete?: boolean; - ghostButtonText?: string; - onChange: (value: ValueType | ValueType[] | null | undefined) => void; -}; +export type DndControlProps = + ControlComponentProps & { + multi?: boolean; + canDelete?: boolean; + ghostButtonText?: string; + onChange: (value: ValueType | ValueType[] | null | undefined) => void; + }; export type OptionValueType = Record; diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilter/index.js b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilter/index.js index f6f00271ace61..5b6278bde2679 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilter/index.js +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilter/index.js @@ -121,9 +121,9 @@ export default class AdhocFilter { this.filterOptionName = adhocFilter.filterOptionName || - `filter_${Math.random() + `filter_${Math.random().toString(36).substring(2, 15)}_${Math.random() .toString(36) - .substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`; + .substring(2, 15)}`; } duplicateWith(nextFields) { diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx index c5768634134e3..c9fe9c5ba9ee1 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx @@ -227,10 +227,8 @@ const AdhocFilterEditPopoverSimpleTabContent: React.FC = props => { } = useSimpleTabFilterProps(props); const [suggestions, setSuggestions] = useState>([]); const [comparator, setComparator] = useState(props.adhocFilter.comparator); - const [ - loadingComparatorSuggestions, - setLoadingComparatorSuggestions, - ] = useState(false); + const [loadingComparatorSuggestions, setLoadingComparatorSuggestions] = + useState(false); const onInputComparatorChange = ( event: React.ChangeEvent, diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx index 93e73d6563f6b..2c897c0994a28 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx @@ -55,9 +55,8 @@ export default class AdhocFilterEditPopoverSqlTabContent extends React.Component constructor(props) { super(props); this.onSqlExpressionChange = this.onSqlExpressionChange.bind(this); - this.onSqlExpressionClauseChange = this.onSqlExpressionClauseChange.bind( - this, - ); + this.onSqlExpressionClauseChange = + this.onSqlExpressionClauseChange.bind(this); this.handleAceEditorRef = this.handleAceEditorRef.bind(this); this.selectProps = { diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js index 497de79f03eff..01fea2dab69f7 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js +++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js @@ -80,9 +80,9 @@ export default class AdhocMetric { this.optionName = adhocMetric.optionName || - `metric_${Math.random() + `metric_${Math.random().toString(36).substring(2, 15)}_${Math.random() .toString(36) - .substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`; + .substring(2, 15)}`; } getDefaultLabel() { diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx index cafebd602add9..25d1b5ac9e01a 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx @@ -207,19 +207,20 @@ const MetricsControl = ({ [value], ); - const isAddNewMetricDisabled = useCallback(() => !multi && value.length > 0, [ - multi, - value.length, - ]); + const isAddNewMetricDisabled = useCallback( + () => !multi && value.length > 0, + [multi, value.length], + ); const savedMetricOptions = useMemo( () => getOptionsForSavedMetrics(savedMetrics, propsValue, null), [propsValue, savedMetrics], ); - const newAdhocMetric = useMemo(() => new AdhocMetric({ isNew: true }), [ - value, - ]); + const newAdhocMetric = useMemo( + () => new AdhocMetric({ isNew: true }), + [value], + ); const addNewMetricPopoverTrigger = useCallback( trigger => { if (isAddNewMetricDisabled()) { @@ -271,10 +272,10 @@ const MetricsControl = ({ setValue(coerceAdhocMetrics(propsValue)); }, [propsValue]); - const onDropLabel = useCallback(() => handleChange(value), [ - handleChange, - value, - ]); + const onDropLabel = useCallback( + () => handleChange(value), + [handleChange, value], + ); const valueRenderer = useCallback( (option, index) => ( diff --git a/superset-frontend/src/explore/components/controls/TextControl/index.tsx b/superset-frontend/src/explore/components/controls/TextControl/index.tsx index e5795ce4df563..d5dc8e2427868 100644 --- a/superset-frontend/src/explore/components/controls/TextControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/TextControl/index.tsx @@ -46,7 +46,7 @@ const safeStringify = (value?: InputValueType | null) => value == null ? '' : String(value); export default class TextControl< - T extends InputValueType = InputValueType + T extends InputValueType = InputValueType, > extends React.Component, TextControlState> { initialValue?: TextControlProps['value']; diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx index aced5e6185f6d..9474d24b4b43a 100644 --- a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx @@ -31,8 +31,8 @@ import { testWithId } from 'src/utils/testUtils'; import { EchartsMixedTimeseriesChartPlugin, EchartsTimeseriesChartPlugin, -} from '@superset-ui/plugin-chart-echarts/lib'; -import { LineChartPlugin } from '@superset-ui/preset-chart-xy/lib'; +} from '@superset-ui/plugin-chart-echarts'; +import { LineChartPlugin } from '@superset-ui/preset-chart-xy'; import TimeTableChartPlugin from '../../../../visualizations/TimeTable/TimeTableChartPlugin'; import VizTypeControl, { VIZ_TYPE_CONTROL_TEST_ID } from './index'; diff --git a/superset-frontend/src/explore/constants.ts b/superset-frontend/src/explore/constants.ts index 417dda75a9019..28668389fe557 100644 --- a/superset-frontend/src/explore/constants.ts +++ b/superset-frontend/src/explore/constants.ts @@ -102,9 +102,12 @@ export const DISABLE_INPUT_OPERATORS = [ Operators.IS_FALSE, ]; -export const sqlaAutoGeneratedMetricNameRegex = /^(sum|min|max|avg|count|count_distinct)__.*$/i; -export const sqlaAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|AVG|MAX|MIN|COUNT)\([A-Z0-9_."]*\)$/i; -export const druidAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|MAX|MIN|COUNT)\([A-Z0-9_."]*\)$/i; +export const sqlaAutoGeneratedMetricNameRegex = + /^(sum|min|max|avg|count|count_distinct)__.*$/i; +export const sqlaAutoGeneratedMetricRegex = + /^(LONG|DOUBLE|FLOAT)?(SUM|AVG|MAX|MIN|COUNT)\([A-Z0-9_."]*\)$/i; +export const druidAutoGeneratedMetricRegex = + /^(LONG|DOUBLE|FLOAT)?(SUM|MAX|MIN|COUNT)\([A-Z0-9_."]*\)$/i; export const TIME_FILTER_LABELS = { time_range: t('Time range'), diff --git a/superset-frontend/src/explore/controlUtils/getControlConfig.ts b/superset-frontend/src/explore/controlUtils/getControlConfig.ts index fb36e3f4338ac..c0b2363275597 100644 --- a/superset-frontend/src/explore/controlUtils/getControlConfig.ts +++ b/superset-frontend/src/explore/controlUtils/getControlConfig.ts @@ -47,10 +47,8 @@ export function findControlItem( const getMemoizedControlConfig = memoizeOne( (controlKey, controlPanelConfig) => { - const { - controlOverrides = {}, - controlPanelSections = [], - } = controlPanelConfig; + const { controlOverrides = {}, controlPanelSections = [] } = + controlPanelConfig; const control = expandControlConfig( findControlItem(controlPanelSections, controlKey), controlOverrides, diff --git a/superset-frontend/src/filters/components/TimeGrain/transformProps.ts b/superset-frontend/src/filters/components/TimeGrain/transformProps.ts index 526a27754cd2b..c49d5e0edd6c3 100644 --- a/superset-frontend/src/filters/components/TimeGrain/transformProps.ts +++ b/superset-frontend/src/filters/components/TimeGrain/transformProps.ts @@ -20,14 +20,8 @@ import { ChartProps } from '@superset-ui/core'; import { DEFAULT_FORM_DATA } from './types'; export default function transformProps(chartProps: ChartProps) { - const { - formData, - height, - hooks, - queriesData, - width, - filterState, - } = chartProps; + const { formData, height, hooks, queriesData, width, filterState } = + chartProps; const { setDataMask = () => {}, setFocusedFilter = () => {}, diff --git a/superset-frontend/src/middleware/loggerMiddleware.js b/superset-frontend/src/middleware/loggerMiddleware.js index 27e41bba8cb27..b88d555428514 100644 --- a/superset-frontend/src/middleware/loggerMiddleware.js +++ b/superset-frontend/src/middleware/loggerMiddleware.js @@ -68,12 +68,8 @@ const loggerMiddleware = store => next => action => { return next(action); } - const { - dashboardInfo, - explore, - impressionId, - dashboardLayout, - } = store.getState(); + const { dashboardInfo, explore, impressionId, dashboardLayout } = + store.getState(); let logMetadata = { impression_id: impressionId, version: 'v2', diff --git a/superset-frontend/src/utils/cacheWrapper.ts b/superset-frontend/src/utils/cacheWrapper.ts index 221845c18fde5..7d7de57ee974c 100644 --- a/superset-frontend/src/utils/cacheWrapper.ts +++ b/superset-frontend/src/utils/cacheWrapper.ts @@ -17,16 +17,18 @@ * under the License. */ -export const cacheWrapper = , U>( - fn: (...args: T) => U, - cache: Map, - keyFn: (...args: T) => string = (...args: T) => JSON.stringify([...args]), -) => (...args: T): U => { - const key = keyFn(...args); - if (cache.has(key)) { - return cache.get(key); - } - const result = fn(...args); - cache.set(key, result); - return result; -}; +export const cacheWrapper = + , U>( + fn: (...args: T) => U, + cache: Map, + keyFn: (...args: T) => string = (...args: T) => JSON.stringify([...args]), + ) => + (...args: T): U => { + const key = keyFn(...args); + if (cache.has(key)) { + return cache.get(key); + } + const result = fn(...args); + cache.set(key, result); + return result; + }; diff --git a/superset-frontend/src/utils/testUtils.ts b/superset-frontend/src/utils/testUtils.ts index 3c1957e30f653..c62ce741a2889 100644 --- a/superset-frontend/src/utils/testUtils.ts +++ b/superset-frontend/src/utils/testUtils.ts @@ -21,23 +21,25 @@ import { JsonObject } from '@superset-ui/core'; type TestWithIdType = T extends string ? string : { 'data-test': string }; // Using bem standard -export const testWithId = ( - prefix?: string, - idOnly = false, -) => (id?: string, localIdOnly = false): TestWithIdType => { - const resultIdOnly = localIdOnly || idOnly; - if (!id && prefix) { - return (resultIdOnly - ? prefix - : { 'data-test': prefix }) as TestWithIdType; - } - if (id && !prefix) { - return (resultIdOnly ? id : { 'data-test': id }) as TestWithIdType; - } - if (!id && !prefix) { - console.warn('testWithId function has missed "prefix" and "id" params'); - return (resultIdOnly ? '' : { 'data-test': '' }) as TestWithIdType; - } - const newId = `${prefix}__${id}`; - return (resultIdOnly ? newId : { 'data-test': newId }) as TestWithIdType; -}; +export const testWithId = + ( + prefix?: string, + idOnly = false, + ) => + (id?: string, localIdOnly = false): TestWithIdType => { + const resultIdOnly = localIdOnly || idOnly; + if (!id && prefix) { + return ( + resultIdOnly ? prefix : { 'data-test': prefix } + ) as TestWithIdType; + } + if (id && !prefix) { + return (resultIdOnly ? id : { 'data-test': id }) as TestWithIdType; + } + if (!id && !prefix) { + console.warn('testWithId function has missed "prefix" and "id" params'); + return (resultIdOnly ? '' : { 'data-test': '' }) as TestWithIdType; + } + const newId = `${prefix}__${id}`; + return (resultIdOnly ? newId : { 'data-test': newId }) as TestWithIdType; + }; diff --git a/superset-frontend/src/views/CRUD/alert/AlertList.tsx b/superset-frontend/src/views/CRUD/alert/AlertList.tsx index d9c69d7ada752..c9d8d63461934 100644 --- a/superset-frontend/src/views/CRUD/alert/AlertList.tsx +++ b/superset-frontend/src/views/CRUD/alert/AlertList.tsx @@ -123,10 +123,8 @@ function AlertList({ const [currentAlert, setCurrentAlert] = useState | null>( null, ); - const [ - currentAlertDeleting, - setCurrentAlertDeleting, - ] = useState(null); + const [currentAlertDeleting, setCurrentAlertDeleting] = + useState(null); // Actions function handleAlertEdit(alert: AlertObject | null) { diff --git a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx index 8ad693ebdf590..775423ad76d57 100644 --- a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx +++ b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx @@ -408,10 +408,8 @@ const AlertReportModal: FunctionComponent = ({ conf?.ALERT_REPORTS_NOTIFICATION_METHODS || DEFAULT_NOTIFICATION_METHODS; const [disableSave, setDisableSave] = useState(true); - const [ - currentAlert, - setCurrentAlert, - ] = useState | null>(); + const [currentAlert, setCurrentAlert] = + useState | null>(); const [isHidden, setIsHidden] = useState(true); const [contentType, setContentType] = useState('dashboard'); const [reportFormat, setReportFormat] = useState( @@ -432,10 +430,8 @@ const AlertReportModal: FunctionComponent = ({ contentType === 'chart' && (isFeatureEnabled(FeatureFlag.ALERTS_ATTACH_REPORTS) || isReport); - const [ - notificationAddState, - setNotificationAddState, - ] = useState('active'); + const [notificationAddState, setNotificationAddState] = + useState('active'); const [notificationSettings, setNotificationSettings] = useState< NotificationSetting[] >([]); @@ -581,20 +577,25 @@ const AlertReportModal: FunctionComponent = ({ // Fetch data to populate form dropdowns const loadOwnerOptions = useMemo( - () => (input = '', page: number, pageSize: number) => { - const query = rison.encode({ filter: input, page, page_size: pageSize }); - return SupersetClient.get({ - endpoint: `/api/v1/report/related/owners?q=${query}`, - }).then(response => ({ - data: response.json.result.map( - (item: { value: number; text: string }) => ({ - value: item.value, - label: item.text, - }), - ), - totalCount: response.json.count, - })); - }, + () => + (input = '', page: number, pageSize: number) => { + const query = rison.encode({ + filter: input, + page, + page_size: pageSize, + }); + return SupersetClient.get({ + endpoint: `/api/v1/report/related/owners?q=${query}`, + }).then(response => ({ + data: response.json.result.map( + (item: { value: number; text: string }) => ({ + value: item.value, + label: item.text, + }), + ), + totalCount: response.json.count, + })); + }, [], ); @@ -629,21 +630,26 @@ const AlertReportModal: FunctionComponent = ({ }; const loadSourceOptions = useMemo( - () => (input = '', page: number, pageSize: number) => { - const query = rison.encode({ filter: input, page, page_size: pageSize }); - return SupersetClient.get({ - endpoint: `/api/v1/report/related/database?q=${query}`, - }).then(response => { - const list = response.json.result.map( - (item: { value: number; text: string }) => ({ - value: item.value, - label: item.text, - }), - ); - setSourceOptions(list); - return { data: list, totalCount: response.json.count }; - }); - }, + () => + (input = '', page: number, pageSize: number) => { + const query = rison.encode({ + filter: input, + page, + page_size: pageSize, + }); + return SupersetClient.get({ + endpoint: `/api/v1/report/related/database?q=${query}`, + }).then(response => { + const list = response.json.result.map( + (item: { value: number; text: string }) => ({ + value: item.value, + label: item.text, + }), + ); + setSourceOptions(list); + return { data: list, totalCount: response.json.count }; + }); + }, [], ); @@ -657,21 +663,26 @@ const AlertReportModal: FunctionComponent = ({ }, [databaseLabel, getSourceData]); const loadDashboardOptions = useMemo( - () => (input = '', page: number, pageSize: number) => { - const query = rison.encode({ filter: input, page, page_size: pageSize }); - return SupersetClient.get({ - endpoint: `/api/v1/report/related/dashboard?q=${query}`, - }).then(response => { - const list = response.json.result.map( - (item: { value: number; text: string }) => ({ - value: item.value, - label: item.text, - }), - ); - setDashboardOptions(list); - return { data: list, totalCount: response.json.count }; - }); - }, + () => + (input = '', page: number, pageSize: number) => { + const query = rison.encode({ + filter: input, + page, + page_size: pageSize, + }); + return SupersetClient.get({ + endpoint: `/api/v1/report/related/dashboard?q=${query}`, + }).then(response => { + const list = response.json.result.map( + (item: { value: number; text: string }) => ({ + value: item.value, + label: item.text, + }), + ); + setDashboardOptions(list); + return { data: list, totalCount: response.json.count }; + }); + }, [], ); @@ -726,22 +737,27 @@ const AlertReportModal: FunctionComponent = ({ }, [getChartData, noChartLabel]); const loadChartOptions = useMemo( - () => (input = '', page: number, pageSize: number) => { - const query = rison.encode({ filter: input, page, page_size: pageSize }); - return SupersetClient.get({ - endpoint: `/api/v1/report/related/chart?q=${query}`, - }).then(response => { - const list = response.json.result.map( - (item: { value: number; text: string }) => ({ - value: item.value, - label: item.text, - }), - ); - - setChartOptions(list); - return { data: list, totalCount: response.json.count }; - }); - }, + () => + (input = '', page: number, pageSize: number) => { + const query = rison.encode({ + filter: input, + page, + page_size: pageSize, + }); + return SupersetClient.get({ + endpoint: `/api/v1/report/related/chart?q=${query}`, + }).then(response => { + const list = response.json.result.map( + (item: { value: number; text: string }) => ({ + value: item.value, + label: item.text, + }), + ); + + setChartOptions(list); + return { data: list, totalCount: response.json.count }; + }); + }, [], ); diff --git a/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx b/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx index 9f34fc1665f8d..d7e6af521dd69 100644 --- a/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx +++ b/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx @@ -29,64 +29,62 @@ interface AlertReportCronSchedulerProps { onChange: (change: string) => any; } -export const AlertReportCronScheduler: FunctionComponent = ({ - value, - onChange, -}) => { - const theme = useTheme(); - const inputRef = useRef(null); - const [scheduleFormat, setScheduleFormat] = useState<'picker' | 'input'>( - 'picker', - ); - const customSetValue = useCallback( - (newValue: string) => { - onChange(newValue); - inputRef.current?.setValue(newValue); - }, - [inputRef, onChange], - ); - const [error, onError] = useState(); +export const AlertReportCronScheduler: FunctionComponent = + ({ value, onChange }) => { + const theme = useTheme(); + const inputRef = useRef(null); + const [scheduleFormat, setScheduleFormat] = useState<'picker' | 'input'>( + 'picker', + ); + const customSetValue = useCallback( + (newValue: string) => { + onChange(newValue); + inputRef.current?.setValue(newValue); + }, + [inputRef, onChange], + ); + const [error, onError] = useState(); - return ( - <> - setScheduleFormat(e.target.value)} - value={scheduleFormat} - > -
- - -
-
- - CRON Schedule - -
- { - onChange(event.target.value); - }} - onPressEnter={() => { - onChange(inputRef.current?.input.value || ''); - }} - /> -
-
-
-
- - ); -}; + return ( + <> + setScheduleFormat(e.target.value)} + value={scheduleFormat} + > +
+ + +
+
+ + CRON Schedule + +
+ { + onChange(event.target.value); + }} + onPressEnter={() => { + onChange(inputRef.current?.input.value || ''); + }} + /> +
+
+
+
+ + ); + }; diff --git a/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx b/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx index aeebb2bf24205..1153865fb8f25 100644 --- a/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx +++ b/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx @@ -65,18 +65,13 @@ function AnnotationList({ addDangerToast, false, ); - const [annotationModalOpen, setAnnotationModalOpen] = useState( - false, - ); + const [annotationModalOpen, setAnnotationModalOpen] = + useState(false); const [annotationLayerName, setAnnotationLayerName] = useState(''); - const [ - currentAnnotation, - setCurrentAnnotation, - ] = useState(null); - const [ - annotationCurrentlyDeleting, - setAnnotationCurrentlyDeleting, - ] = useState(null); + const [currentAnnotation, setCurrentAnnotation] = + useState(null); + const [annotationCurrentlyDeleting, setAnnotationCurrentlyDeleting] = + useState(null); const handleAnnotationEdit = (annotation: AnnotationObject | null) => { setCurrentAnnotation(annotation); setAnnotationModalOpen(true); diff --git a/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx b/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx index 4d8fedceca788..22af06241f77b 100644 --- a/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx +++ b/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx @@ -91,10 +91,8 @@ const AnnotationModal: FunctionComponent = ({ show, }) => { const [disableSave, setDisableSave] = useState(true); - const [ - currentAnnotation, - setCurrentAnnotation, - ] = useState(null); + const [currentAnnotation, setCurrentAnnotation] = + useState(null); const isEditMode = annotation !== null; // annotation fetch logic diff --git a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx index e3ea229482216..75ba970874e34 100644 --- a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx +++ b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx @@ -86,10 +86,8 @@ const AnnotationLayerModal: FunctionComponent = ({ layer = null, }) => { const [disableSave, setDisableSave] = useState(true); - const [ - currentLayer, - setCurrentLayer, - ] = useState(); + const [currentLayer, setCurrentLayer] = + useState(); const [isHidden, setIsHidden] = useState(true); const isEditMode = layer !== null; diff --git a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx index 56c5884f81312..4fc77576458e4 100644 --- a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx +++ b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx @@ -73,19 +73,13 @@ function AnnotationLayersList({ addDangerToast, ); - const [ - annotationLayerModalOpen, - setAnnotationLayerModalOpen, - ] = useState(false); - const [ - currentAnnotationLayer, - setCurrentAnnotationLayer, - ] = useState(null); + const [annotationLayerModalOpen, setAnnotationLayerModalOpen] = + useState(false); + const [currentAnnotationLayer, setCurrentAnnotationLayer] = + useState(null); - const [ - layerCurrentlyDeleting, - setLayerCurrentlyDeleting, - ] = useState(null); + const [layerCurrentlyDeleting, setLayerCurrentlyDeleting] = + useState(null); const handleLayerDelete = ({ id, name }: AnnotationLayerObject) => { SupersetClient.delete({ diff --git a/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx b/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx index c1d15a766ba45..3248babb63cfb 100644 --- a/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx +++ b/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx @@ -75,10 +75,8 @@ const CssTemplateModal: FunctionComponent = ({ cssTemplate = null, }) => { const [disableSave, setDisableSave] = useState(true); - const [ - currentCssTemplate, - setCurrentCssTemplate, - ] = useState(null); + const [currentCssTemplate, setCurrentCssTemplate] = + useState(null); const [isHidden, setIsHidden] = useState(true); const isEditMode = cssTemplate !== null; diff --git a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx index b1b53f2f487c6..9c943980540e9 100644 --- a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx +++ b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx @@ -71,22 +71,17 @@ function CssTemplatesList({ t('CSS templates'), addDangerToast, ); - const [cssTemplateModalOpen, setCssTemplateModalOpen] = useState( - false, - ); - const [ - currentCssTemplate, - setCurrentCssTemplate, - ] = useState(null); + const [cssTemplateModalOpen, setCssTemplateModalOpen] = + useState(false); + const [currentCssTemplate, setCurrentCssTemplate] = + useState(null); const canCreate = hasPerm('can_write'); const canEdit = hasPerm('can_write'); const canDelete = hasPerm('can_write'); - const [ - templateCurrentlyDeleting, - setTemplateCurrentlyDeleting, - ] = useState(null); + const [templateCurrentlyDeleting, setTemplateCurrentlyDeleting] = + useState(null); const handleTemplateDelete = ({ id, template_name }: TemplateObject) => { SupersetClient.delete({ diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx index ab2ecdeb89b8f..a489240b0f9c2 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx @@ -90,10 +90,8 @@ function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) { addDangerToast, ); const [databaseModalOpen, setDatabaseModalOpen] = useState(false); - const [ - databaseCurrentlyDeleting, - setDatabaseCurrentlyDeleting, - ] = useState(null); + const [databaseCurrentlyDeleting, setDatabaseCurrentlyDeleting] = + useState(null); const [currentDatabase, setCurrentDatabase] = useState( null, ); diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx index 9403762ce2008..f34e5fdd58aa5 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx @@ -185,9 +185,9 @@ export const EncryptedField = ({ checked: false, }, }); - (document.getElementById( - 'selectedFile', - ) as HTMLInputElement).value = null as any; + ( + document.getElementById('selectedFile') as HTMLInputElement + ).value = null as any; }} /> diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx index 5f0b810f4b2bf..ccc70e14ce8c0 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx @@ -410,7 +410,7 @@ const serializeExtra = (extraJson: DatabaseObject['extra_json']) => ...extraJson, metadata_params: JSON.parse((extraJson?.metadata_params as string) || '{}'), engine_params: JSON.parse( - ((extraJson?.engine_params as unknown) as string) || '{}', + (extraJson?.engine_params as unknown as string) || '{}', ), schemas_allowed_for_file_upload: ( extraJson?.schemas_allowed_for_file_upload || [] @@ -430,11 +430,8 @@ const DatabaseModal: FunctionComponent = ({ >(dbReducer, null); const [tabKey, setTabKey] = useState(DEFAULT_TAB_KEY); const [availableDbs, getAvailableDbs] = useAvailableDatabases(); - const [ - validationErrors, - getValidation, - setValidationErrors, - ] = useDatabaseValidation(); + const [validationErrors, getValidation, setValidationErrors] = + useDatabaseValidation(); const [hasConnectedDb, setHasConnectedDb] = useState(false); const [dbName, setDbName] = useState(''); const [editNewDb, setEditNewDb] = useState(false); diff --git a/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx index 4eb77247217ec..2ef09249fed7e 100644 --- a/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx +++ b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx @@ -122,18 +122,15 @@ const DatasetList: FunctionComponent = ({ refreshData, } = useListViewResource('dataset', t('dataset'), addDangerToast); - const [datasetAddModalOpen, setDatasetAddModalOpen] = useState( - false, - ); + const [datasetAddModalOpen, setDatasetAddModalOpen] = + useState(false); const [datasetCurrentlyDeleting, setDatasetCurrentlyDeleting] = useState< (Dataset & { chart_count: number; dashboard_count: number }) | null >(null); - const [ - datasetCurrentlyEditing, - setDatasetCurrentlyEditing, - ] = useState(null); + const [datasetCurrentlyEditing, setDatasetCurrentlyEditing] = + useState(null); const [importingDataset, showImportModal] = useState(false); const [passwordFields, setPasswordFields] = useState([]); diff --git a/superset-frontend/src/views/CRUD/data/query/QueryList.tsx b/superset-frontend/src/views/CRUD/data/query/QueryList.tsx index aa56d5c1a755f..ded828309e214 100644 --- a/superset-frontend/src/views/CRUD/data/query/QueryList.tsx +++ b/superset-frontend/src/views/CRUD/data/query/QueryList.tsx @@ -91,10 +91,8 @@ function QueryList({ addDangerToast, addSuccessToast }: QueryListProps) { false, ); - const [ - queryCurrentlyPreviewing, - setQueryCurrentlyPreviewing, - ] = useState(); + const [queryCurrentlyPreviewing, setQueryCurrentlyPreviewing] = + useState(); const theme = useTheme(); diff --git a/superset-frontend/src/views/CRUD/data/query/QueryPreviewModal.tsx b/superset-frontend/src/views/CRUD/data/query/QueryPreviewModal.tsx index 458b8c1fbb1a2..397970e1b2941 100644 --- a/superset-frontend/src/views/CRUD/data/query/QueryPreviewModal.tsx +++ b/superset-frontend/src/views/CRUD/data/query/QueryPreviewModal.tsx @@ -99,16 +99,12 @@ function QueryPreviewModal({ addDangerToast, addSuccessToast, }: QueryPreviewModalProps) { - const { - handleKeyPress, - handleDataChange, - disablePrevious, - disableNext, - } = useQueryPreviewState({ - queries, - currentQueryId: query.id, - fetchData, - }); + const { handleKeyPress, handleDataChange, disablePrevious, disableNext } = + useQueryPreviewState({ + queries, + currentQueryId: query.id, + fetchData, + }); const [currentTab, setCurrentTab] = useState<'user' | 'executed'>('user'); diff --git a/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx b/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx index 0f6fd5f16b9a9..d6df355e020bb 100644 --- a/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx +++ b/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx @@ -108,14 +108,10 @@ function SavedQueryList({ t('Saved queries'), addDangerToast, ); - const [ - queryCurrentlyDeleting, - setQueryCurrentlyDeleting, - ] = useState(null); - const [ - savedQueryCurrentlyPreviewing, - setSavedQueryCurrentlyPreviewing, - ] = useState(null); + const [queryCurrentlyDeleting, setQueryCurrentlyDeleting] = + useState(null); + const [savedQueryCurrentlyPreviewing, setSavedQueryCurrentlyPreviewing] = + useState(null); const [importingSavedQuery, showImportModal] = useState(false); const [passwordFields, setPasswordFields] = useState([]); const [preparingExport, setPreparingExport] = useState(false); diff --git a/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryPreviewModal.tsx b/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryPreviewModal.tsx index d14b32166230a..883ce3b695005 100644 --- a/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryPreviewModal.tsx +++ b/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryPreviewModal.tsx @@ -71,72 +71,69 @@ interface SavedQueryPreviewModalProps extends ToastProps { show: boolean; } -const SavedQueryPreviewModal: FunctionComponent = ({ - fetchData, - onHide, - openInSqlLab, - queries, - savedQuery, - show, - addDangerToast, - addSuccessToast, -}) => { - const { - handleKeyPress, - handleDataChange, - disablePrevious, - disableNext, - } = useQueryPreviewState({ - queries, - currentQueryId: savedQuery.id, +const SavedQueryPreviewModal: FunctionComponent = + ({ fetchData, - }); + onHide, + openInSqlLab, + queries, + savedQuery, + show, + addDangerToast, + addSuccessToast, + }) => { + const { handleKeyPress, handleDataChange, disablePrevious, disableNext } = + useQueryPreviewState({ + queries, + currentQueryId: savedQuery.id, + fetchData, + }); - return ( -
- handleDataChange(true)} - > - {t('Previous')} - , - , - , - ]} - > - {t('Query name')} - {savedQuery.label} - + handleDataChange(true)} + > + {t('Previous')} + , + , + , + ]} > - {savedQuery.sql || ''} - - -
- ); -}; + {t('Query name')} + {savedQuery.label} + + {savedQuery.sql || ''} + + + + ); + }; export default withToasts(SavedQueryPreviewModal); diff --git a/superset-frontend/src/views/CRUD/hooks.ts b/superset-frontend/src/views/CRUD/hooks.ts index 7a546baa8cca1..057e4799aea40 100644 --- a/superset-frontend/src/views/CRUD/hooks.ts +++ b/superset-frontend/src/views/CRUD/hooks.ts @@ -555,10 +555,8 @@ export const useChartEditModal = ( setCharts: (charts: Array) => void, charts: Array, ) => { - const [ - sliceCurrentlyEditing, - setSliceCurrentlyEditing, - ] = useState(null); + const [sliceCurrentlyEditing, setSliceCurrentlyEditing] = + useState(null); function openChartEditModal(chart: Chart) { setSliceCurrentlyEditing({ diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx index de1909473d26f..f261e1cd69c6b 100644 --- a/superset-frontend/src/views/CRUD/utils.tsx +++ b/superset-frontend/src/views/CRUD/utils.tsx @@ -33,57 +33,60 @@ import { FetchDataConfig } from 'src/components/ListView'; import SupersetText from 'src/utils/textUtils'; import { Dashboard, Filters } from './types'; -const createFetchResourceMethod = (method: string) => ( - resource: string, - relation: string, - handleError: (error: Response) => void, - user?: { userId: string | number; firstName: string; lastName: string }, -) => async (filterValue = '', page: number, pageSize: number) => { - const resourceEndpoint = `/api/v1/${resource}/${method}/${relation}`; - const queryParams = rison.encode({ - filter: filterValue, - page, - page_size: pageSize, - }); - const { json = {} } = await SupersetClient.get({ - endpoint: `${resourceEndpoint}?q=${queryParams}`, - }); +const createFetchResourceMethod = + (method: string) => + ( + resource: string, + relation: string, + handleError: (error: Response) => void, + user?: { userId: string | number; firstName: string; lastName: string }, + ) => + async (filterValue = '', page: number, pageSize: number) => { + const resourceEndpoint = `/api/v1/${resource}/${method}/${relation}`; + const queryParams = rison.encode({ + filter: filterValue, + page, + page_size: pageSize, + }); + const { json = {} } = await SupersetClient.get({ + endpoint: `${resourceEndpoint}?q=${queryParams}`, + }); - let fetchedLoggedUser = false; - const loggedUser = user - ? { - label: `${user.firstName} ${user.lastName}`, - value: user.userId, - } - : undefined; + let fetchedLoggedUser = false; + const loggedUser = user + ? { + label: `${user.firstName} ${user.lastName}`, + value: user.userId, + } + : undefined; - const data: { label: string; value: string | number }[] = []; - json?.result?.forEach( - ({ text, value }: { text: string; value: string | number }) => { - if ( - loggedUser && - value === loggedUser.value && - text === loggedUser.label - ) { - fetchedLoggedUser = true; - } else { - data.push({ - label: text, - value, - }); - } - }, - ); + const data: { label: string; value: string | number }[] = []; + json?.result?.forEach( + ({ text, value }: { text: string; value: string | number }) => { + if ( + loggedUser && + value === loggedUser.value && + text === loggedUser.label + ) { + fetchedLoggedUser = true; + } else { + data.push({ + label: text, + value, + }); + } + }, + ); - if (loggedUser && (!filterValue || fetchedLoggedUser)) { - data.unshift(loggedUser); - } + if (loggedUser && (!filterValue || fetchedLoggedUser)) { + data.unshift(loggedUser); + } - return { - data, - totalCount: json?.count, + return { + data, + totalCount: json?.count, + }; }; -}; export const PAGE_SIZE = 5; const getParams = (filters?: Array) => { diff --git a/superset-frontend/src/views/store.ts b/superset-frontend/src/views/store.ts index 651b50fa640b2..e9be565131082 100644 --- a/superset-frontend/src/views/store.ts +++ b/superset-frontend/src/views/store.ts @@ -35,9 +35,10 @@ import shortid from 'shortid'; // Some reducers don't do anything, and redux is just used to reference the initial "state". // This may change later, as the client application takes on more responsibilities. -const noopReducer = (initialState: STATE) => ( - state: STATE = initialState, -) => state; +const noopReducer = + (initialState: STATE) => + (state: STATE = initialState) => + state; const container = document.getElementById('app'); const bootstrap = JSON.parse(container?.getAttribute('data-bootstrap') ?? '{}'); diff --git a/superset-frontend/src/visualizations/FilterBox/FilterBoxChartPlugin.js b/superset-frontend/src/visualizations/FilterBox/FilterBoxChartPlugin.js index 861624783d0a5..e1f871fa4cf4f 100644 --- a/superset-frontend/src/visualizations/FilterBox/FilterBoxChartPlugin.js +++ b/superset-frontend/src/visualizations/FilterBox/FilterBoxChartPlugin.js @@ -24,7 +24,8 @@ import controlPanel from './controlPanel'; const metadata = new ChartMetadata({ category: t('Tools'), name: t('Filter box'), - description: t(`Chart component that lets you add a custom filter UI in your dashboard. When added to dashboard, a filter box lets users specify specific values or ranges to filter charts by. The charts that each filter box is applied to can be fine tuned as well in the dashboard view. + description: + t(`Chart component that lets you add a custom filter UI in your dashboard. When added to dashboard, a filter box lets users specify specific values or ranges to filter charts by. The charts that each filter box is applied to can be fine tuned as well in the dashboard view. Note that this plugin is being replaced with the new Filters feature that lives in the dashboard view itself. It's easier to use and has more capabilities!`), thumbnail,