Compare commits

...
Author SHA1 Message Date
Maxime Beauchemin bc01eba075 feat: add Claudette theme to examples 2025-08-03 20:38:52 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 96a1aa60e8 chore(deps): update gh-pages requirement from ^6.2.0 to ^6.3.0 in /superset-frontend/packages/superset-ui-demo (#34444)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-03 00:38:12 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 2ea0368c2d chore(deps-dev): bump @types/classnames from 2.3.0 to 2.3.4 in /superset-frontend (#34478)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-03 00:36:27 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 9e407e4e80 chore(deps): bump dom-to-image-more from 3.5.0 to 3.6.0 in /superset-frontend (#34482)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-03 00:11:29 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 360e58c181 chore(deps): bump @deck.gl/core from 9.1.13 to 9.1.14 in /superset-frontend (#34480)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-03 00:11:13 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 22d5eb7835 chore(deps-dev): bump tsx from 4.19.4 to 4.20.3 in /superset-frontend (#34484)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-03 00:10:12 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 7c4a77a909 chore(deps-dev): bump @babel/compat-data from 7.27.2 to 7.28.0 in /superset-frontend (#34485)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-03 00:09:55 -07:00
Evan RusackasandClaude 4e209e51d0 fix(sqllab): prevent strings with angle brackets from being hidden (#34512)
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-02 22:53:17 -07:00
Ville Brofeldt 7191ae55c8 fix: docs eslint command (#34520) 2025-08-02 16:49:23 -07:00
Ville Brofeldt 17725ebc83 chore: use logger on all migrations (#34521) 2025-08-02 12:19:50 -07:00
JUST.in DO IT 1a7a381bd5 fix(echart): initial chart animation (#34516) 2025-08-02 08:41:53 -03:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> daf207e5c2 chore(deps): bump less from 4.3.0 to 4.4.0 in /docs (#34494)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 17:10:59 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 72294c569f chore(deps): bump antd from 5.26.3 to 5.26.7 in /docs (#34495)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 17:10:39 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 792dd08d38 chore(deps-dev): bump @eslint/js from 9.31.0 to 9.32.0 in /docs (#34497)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 17:09:58 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 1e40e7d02b chore(deps): bump swagger-ui-react from 5.26.0 to 5.27.1 in /docs (#34498)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 17:09:29 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 7e98c75f01 chore(deps-dev): bump eslint-config-prettier from 10.1.5 to 10.1.8 in /docs (#34499)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 17:08:40 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> b18de05ea4 chore(deps-dev): bump webpack from 5.99.9 to 5.101.0 in /docs (#34500)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 17:08:09 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 9300652277 chore(deps): bump actions/first-interaction from 1 to 2 (#34459)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 14:02:25 -07:00
yousophandClaude 7c2ec4ca5f fix: Update table chart configuration labels to sentence case (#34438)
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-01 12:02:42 -07:00
Evan Rusackas 6a83b6fd87 fix(pie chart): Total now positioned correctly with all Legend positions, and respects theming (#34435) 2025-08-01 12:00:23 -07:00
Evan RusackasandClaude 659cd33749 fix(echarts): resolve bar chart X-axis time formatting stuck on adaptive (#34436)
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-01 09:55:20 -07:00
67 changed files with 1341 additions and 273 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Welcome Message
uses: actions/first-interaction@v1
uses: actions/first-interaction@v2
continue-on-error: true
with:
repo-token: ${{ github.token }}
+6 -3
View File
@@ -28,6 +28,9 @@ const globals = require('globals');
const { defineConfig, globalIgnores } = require('eslint/config');
module.exports = defineConfig([
{
files: ['**/*.{js,jsx,ts,tsx}'],
},
globalIgnores(['build/**/*', '.docusaurus/**/*', 'node_modules/**/*']),
js.configs.recommended,
...ts.configs.recommended,
@@ -36,7 +39,7 @@ module.exports = defineConfig([
files: ['eslint.config.js'],
rules: {
'@typescript-eslint/no-require-imports': 'off',
}
},
},
{
languageOptions: {
@@ -68,5 +71,5 @@ module.exports = defineConfig([
version: 'detect',
},
},
}
])
},
]);
+7 -7
View File
@@ -15,7 +15,7 @@
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc",
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx"
"eslint": "eslint ."
},
"dependencies": {
"@ant-design/icons": "^6.0.0",
@@ -26,33 +26,33 @@
"@emotion/styled": "^10.0.27",
"@saucelabs/theme-github-codeblock": "^0.3.0",
"@superset-ui/style": "^0.14.23",
"antd": "^5.26.3",
"antd": "^5.26.7",
"docusaurus-plugin-less": "^2.0.2",
"less": "^4.3.0",
"less": "^4.4.0",
"less-loader": "^12.3.0",
"prism-react-renderer": "^2.4.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-github-btn": "^1.4.0",
"react-svg-pan-zoom": "^3.13.1",
"swagger-ui-react": "^5.26.0"
"swagger-ui-react": "^5.27.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.8.1",
"@docusaurus/tsconfig": "^3.8.1",
"@eslint/js": "^9.31.0",
"@eslint/js": "^9.32.0",
"@types/react": "^19.1.8",
"@typescript-eslint/eslint-plugin": "^8.37.0",
"@typescript-eslint/parser": "^8.37.0",
"eslint": "^9.31.0",
"eslint-config-prettier": "^10.1.5",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.1",
"eslint-plugin-react": "^7.37.5",
"globals": "^16.3.0",
"prettier": "^3.6.2",
"typescript": "~5.8.3",
"typescript-eslint": "^8.37.0",
"webpack": "^5.99.9"
"webpack": "^5.101.0"
},
"browserslist": {
"production": [
+62 -71
View File
@@ -2205,11 +2205,16 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@9.31.0", "@eslint/js@^9.31.0":
"@eslint/js@9.31.0":
version "9.31.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.31.0.tgz#adb1f39953d8c475c4384b67b67541b0d7206ed8"
integrity sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==
"@eslint/js@^9.32.0":
version "9.32.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.32.0.tgz#a02916f58bd587ea276876cb051b579a3d75d091"
integrity sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==
"@eslint/object-schema@^2.1.6":
version "2.1.6"
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f"
@@ -2512,10 +2517,10 @@
classnames "^2.3.2"
rc-util "^5.24.4"
"@rc-component/trigger@^2.0.0", "@rc-component/trigger@^2.1.1", "@rc-component/trigger@^2.2.7":
version "2.2.7"
resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-2.2.7.tgz#a2b97ecbb93280a3c424e51fa415b371b355d76a"
integrity sha512-Qggj4Z0AA2i5dJhzlfFSmg1Qrziu8dsdHOihROL5Kl18seO2Eh/ZaTYt2c8a/CyGaTChnFry7BEYew1+/fhSbA==
"@rc-component/trigger@^2.0.0", "@rc-component/trigger@^2.1.1", "@rc-component/trigger@^2.3.0":
version "2.3.0"
resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-2.3.0.tgz#9499ada078daca9dd99d01f0f0743ee1ab9e398b"
integrity sha512-iwaxZyzOuK0D7lS+0AQEtW52zUWxoGqTGkke3dRyb8pYiShmRpCjB/8TzPI4R6YySCH7Vm9BZj/31VPiiQTLBg==
dependencies:
"@babel/runtime" "^7.23.2"
"@rc-component/portal" "^1.1.0"
@@ -3422,10 +3427,10 @@
dependencies:
"@types/estree" "*"
"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8"
integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==
"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@^1.0.8":
version "1.0.8"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0":
version "5.0.6"
@@ -3966,6 +3971,11 @@ accepts@~1.3.4, accepts@~1.3.8:
mime-types "~2.1.34"
negotiator "0.6.3"
acorn-import-phases@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7"
integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==
acorn-jsx@^5.0.0, acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -3978,12 +3988,7 @@ acorn-walk@^8.0.0:
dependencies:
acorn "^8.11.0"
acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.8.2:
version "8.14.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb"
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
acorn@^8.15.0:
acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0, acorn@^8.8.2:
version "8.15.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
@@ -4107,10 +4112,10 @@ ansi-styles@^6.1.0:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
antd@^5.26.3:
version "5.26.3"
resolved "https://registry.yarnpkg.com/antd/-/antd-5.26.3.tgz#cbbb7e1b48a972dc7b6ee8b6948f51cc91c263f8"
integrity sha512-M/s9Q39h/+G7AWnS6fbNxmAI9waTH4ti022GVEXBLq2j810V1wJ3UOQps13nEilzDNcyxnFN/EIbqIgS7wSYaA==
antd@^5.26.7:
version "5.26.7"
resolved "https://registry.yarnpkg.com/antd/-/antd-5.26.7.tgz#e2f7e37330b27eec0de7a7789767975373f61602"
integrity sha512-iCyXN6+i2CUVEOSzzJKfbKeg115qoJhGvSkCh5uzAf9hANwHUOJQhsMn+KtN+Lx/2NQ6wfM7nGZ+7NPNO5Pn1w==
dependencies:
"@ant-design/colors" "^7.2.1"
"@ant-design/cssinjs" "^1.23.0"
@@ -4123,7 +4128,7 @@ antd@^5.26.3:
"@rc-component/mutate-observer" "^1.1.0"
"@rc-component/qrcode" "~1.0.0"
"@rc-component/tour" "~1.15.1"
"@rc-component/trigger" "^2.2.7"
"@rc-component/trigger" "^2.3.0"
classnames "^2.5.1"
copy-to-clipboard "^3.3.3"
dayjs "^1.11.11"
@@ -4153,7 +4158,7 @@ antd@^5.26.3:
rc-switch "~4.1.0"
rc-table "~7.51.1"
rc-tabs "~15.6.1"
rc-textarea "~1.10.0"
rc-textarea "~1.10.1"
rc-tooltip "~6.4.0"
rc-tree "~5.13.1"
rc-tree-select "~5.27.0"
@@ -4508,17 +4513,7 @@ braces@^3.0.3, braces@~3.0.2:
dependencies:
fill-range "^7.1.1"
browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4:
version "4.24.4"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b"
integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==
dependencies:
caniuse-lite "^1.0.30001688"
electron-to-chromium "^1.5.73"
node-releases "^2.0.19"
update-browserslist-db "^1.1.1"
browserslist@^4.25.0:
browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.25.0:
version "4.25.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.0.tgz#986aa9c6d87916885da2b50d8eb577ac8d133b2c"
integrity sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==
@@ -4620,7 +4615,7 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001702:
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702:
version "1.0.30001714"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001714.tgz#cfd27ff07e6fa20a0f45c7a10d28a0ffeaba2122"
integrity sha512-mtgapdwDLSSBnCI3JokHM7oEQBLxiJKVRtg10AxM1AyeiKcM96f0Mkbqeq+1AbiCtvMcHRulAAEMu693JrSWqg==
@@ -5903,11 +5898,6 @@ electron-to-chromium@^1.5.160:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz#9f6697de4339e24da8b234e4492a9ecb91f5989c"
integrity sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==
electron-to-chromium@^1.5.73:
version "1.5.138"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.138.tgz#319e775179bd0889ed96a04d4390d355fb315a44"
integrity sha512-FWlQc52z1dXqm+9cCJ2uyFgJkESd+16j6dBEjsgDNuHjBpuIzL8/lRc0uvh1k8RNI6waGo6tcy2DvwkTBJOLDg==
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
@@ -5952,10 +5942,10 @@ encodeurl@~2.0.0:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58"
integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==
enhanced-resolve@^5.17.1:
version "5.18.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf"
integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==
enhanced-resolve@^5.17.2:
version "5.18.2"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz#7903c5b32ffd4b2143eeb4b92472bd68effd5464"
integrity sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
@@ -6161,10 +6151,10 @@ escape-string-regexp@^5.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
eslint-config-prettier@^10.1.5:
version "10.1.5"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz#00c18d7225043b6fbce6a665697377998d453782"
integrity sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==
eslint-config-prettier@^10.1.8:
version "10.1.8"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz#15734ce4af8c2778cc32f0b01b37b0b5cd1ecb97"
integrity sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==
eslint-plugin-prettier@^5.5.1:
version "5.5.1"
@@ -8063,10 +8053,10 @@ less-loader@^12.3.0:
resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-12.3.0.tgz#d4a00361568be86a97da3df4f16954b0d4c15340"
integrity sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==
less@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/less/-/less-4.3.0.tgz#ef0cfc260a9ca8079ed8d0e3512bda8a12c82f2a"
integrity sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==
less@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/less/-/less-4.4.0.tgz#deaf881f4880ee80691beae925b8fac699d3a76d"
integrity sha512-kdTwsyRuncDfjEs0DlRILWNvxhDG/Zij4YLO4TMJgDLW+8OzpfkdPnRgrsRuY1o+oaxJGWsps5f/RVBgGmmN0w==
dependencies:
copy-anything "^2.0.1"
parse-node-version "^1.0.1"
@@ -10714,10 +10704,10 @@ rc-tabs@~15.6.1:
rc-resize-observer "^1.0.0"
rc-util "^5.34.1"
rc-textarea@~1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-1.10.0.tgz#f8f962ef83be0b8e35db97cf03dbfb86ddd9c46c"
integrity sha512-ai9IkanNuyBS4x6sOL8qu/Ld40e6cEs6pgk93R+XLYg0mDSjNBGey6/ZpDs5+gNLD7urQ14po3V6Ck2dJLt9SA==
rc-textarea@~1.10.0, rc-textarea@~1.10.1:
version "1.10.2"
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-1.10.2.tgz#459e3574a95c32939c6793045a1e4db04cb514cc"
integrity sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.1"
@@ -12100,10 +12090,10 @@ swagger-client@^3.35.5:
ramda "^0.30.1"
ramda-adjunct "^5.1.0"
swagger-ui-react@^5.26.0:
version "5.26.0"
resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.26.0.tgz#b15a903d556cc0ec2a56a969beb9d5bc9ea52910"
integrity sha512-4e6bP9bdJyh+SqQW0lxulPn/SDno4+oWrKXsuon5Z9kjtV0zeoWEJ1c70Qxp8kN/c3caFwec8OyxDNhvo14pkw==
swagger-ui-react@^5.27.1:
version "5.27.1"
resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.27.1.tgz#315b59970c33933a5f62ca0f702789741dcedc7c"
integrity sha512-wwDoavIeJI/Pwiavn32FMJ5dfptz0BAOKjSrj7EdU22QdP3gdk9+MZHdzzjxWURmVj0kc0XoQfsFgjln0toJaw==
dependencies:
"@babel/runtime-corejs3" "^7.27.1"
"@scarf/scarf" "=1.4.0"
@@ -12525,7 +12515,7 @@ unraw@^3.0.0:
resolved "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz"
integrity sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==
update-browserslist-db@^1.1.1, update-browserslist-db@^1.1.3:
update-browserslist-db@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
@@ -12794,26 +12784,27 @@ webpack-merge@^6.0.1:
flat "^5.0.2"
wildcard "^2.0.1"
webpack-sources@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
webpack-sources@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723"
integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==
webpack@^5.88.1, webpack@^5.95.0, webpack@^5.99.9:
version "5.99.9"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.99.9.tgz#d7de799ec17d0cce3c83b70744b4aedb537d8247"
integrity sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==
webpack@^5.101.0, webpack@^5.88.1, webpack@^5.95.0:
version "5.101.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.101.0.tgz#4b81407ffad9857f81ff03f872e3369b9198cc9d"
integrity sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==
dependencies:
"@types/eslint-scope" "^3.7.7"
"@types/estree" "^1.0.6"
"@types/estree" "^1.0.8"
"@types/json-schema" "^7.0.15"
"@webassemblyjs/ast" "^1.14.1"
"@webassemblyjs/wasm-edit" "^1.14.1"
"@webassemblyjs/wasm-parser" "^1.14.1"
acorn "^8.14.0"
acorn "^8.15.0"
acorn-import-phases "^1.0.3"
browserslist "^4.24.0"
chrome-trace-event "^1.0.2"
enhanced-resolve "^5.17.1"
enhanced-resolve "^5.17.2"
es-module-lexer "^1.2.1"
eslint-scope "5.1.1"
events "^3.2.0"
@@ -12827,7 +12818,7 @@ webpack@^5.88.1, webpack@^5.95.0, webpack@^5.99.9:
tapable "^2.1.1"
terser-webpack-plugin "^5.3.11"
watchpack "^2.4.1"
webpack-sources "^3.2.3"
webpack-sources "^3.3.3"
webpackbar@^6.0.1:
version "6.0.1"
+27 -26
View File
@@ -61,7 +61,7 @@
"d3-color": "^3.1.0",
"d3-scale": "^2.1.2",
"dayjs": "^1.11.13",
"dom-to-image-more": "^3.2.0",
"dom-to-image-more": "^3.6.0",
"dom-to-pdf": "^0.3.2",
"echarts": "^5.6.0",
"emotion-rgba": "0.0.12",
@@ -140,7 +140,7 @@
"devDependencies": {
"@applitools/eyes-storybook": "^3.55.6",
"@babel/cli": "^7.27.2",
"@babel/compat-data": "^7.26.8",
"@babel/compat-data": "^7.28.0",
"@babel/core": "^7.26.0",
"@babel/eslint-parser": "^7.25.9",
"@babel/node": "^7.22.6",
@@ -175,7 +175,7 @@
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^12.8.3",
"@types/classnames": "^2.2.10",
"@types/classnames": "^2.3.4",
"@types/dom-to-image": "^2.6.7",
"@types/jest": "^29.5.14",
"@types/js-levenshtein": "^1.1.3",
@@ -263,7 +263,7 @@
"ts-jest": "^29.4.0",
"ts-loader": "^9.5.1",
"tscw-config": "^1.1.2",
"tsx": "^4.19.2",
"tsx": "^4.20.3",
"typescript": "5.4.5",
"vm-browserify": "^1.1.2",
"webpack": "^5.99.9",
@@ -1086,9 +1086,9 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.2.tgz",
"integrity": "sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==",
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
"integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3989,18 +3989,18 @@
}
},
"node_modules/@deck.gl/core": {
"version": "9.1.13",
"resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-9.1.13.tgz",
"integrity": "sha512-c15DpwUEvDjmt3+/azSjcfhVQ5L5HiIj6LJob1KAwQOnB5zgVdKWukN/21ELQ7ekppEkfT0x4byRv5k4QVocqQ==",
"version": "9.1.14",
"resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-9.1.14.tgz",
"integrity": "sha512-tXakSSvi5g+EvxSsnnjoRO8z3XxHxISTRzzIqcs3AZuWHnDptK28y9iD0Da21ILop1IYLaWE1QTUe6IAdp/Wag==",
"license": "MIT",
"dependencies": {
"@loaders.gl/core": "^4.2.0",
"@loaders.gl/images": "^4.2.0",
"@luma.gl/constants": "^9.1.5",
"@luma.gl/core": "^9.1.5",
"@luma.gl/engine": "^9.1.5",
"@luma.gl/shadertools": "^9.1.5",
"@luma.gl/webgl": "^9.1.5",
"@luma.gl/constants": "~9.1.9",
"@luma.gl/core": "~9.1.9",
"@luma.gl/engine": "~9.1.9",
"@luma.gl/shadertools": "~9.1.9",
"@luma.gl/webgl": "~9.1.9",
"@math.gl/core": "^4.1.0",
"@math.gl/sun": "^4.1.0",
"@math.gl/types": "^4.1.0",
@@ -15253,9 +15253,10 @@
"license": "MIT"
},
"node_modules/@types/classnames": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.3.0.tgz",
"integrity": "sha512-3GsbOoDYteFShlrBTKzI2Eii4vPg/jAf7LXRIn0WQePKlmhpkV0KoTMuawA7gZJkrbPrZGwv9IEAfIWaOaQK8w==",
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.3.4.tgz",
"integrity": "sha512-dwmfrMMQb9ujX1uYGvB5ERDlOzBNywnZAZBtOe107/hORWP05ESgU4QyaanZMWYYfd2BzrG78y13/Bju8IQcMQ==",
"deprecated": "This is a stub types definition. classnames provides its own type definitions, so you do not need this installed.",
"license": "MIT",
"dependencies": {
"classnames": "*"
@@ -24128,9 +24129,9 @@
"license": "MIT"
},
"node_modules/dom-to-image-more": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.5.0.tgz",
"integrity": "sha512-VF/vwfHsPNMHJb5W/5sAmco3UIlEWSEFLppInQwqwN4joUvBULDwE3CqVcUDkUWleke/nZ5KwIVSrrFlGw7WPA==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.6.0.tgz",
"integrity": "sha512-0BB0M9gRRP7znKBNLRAvNyWnkDIzSgMSDcS7WdPDzPnWhW2YJqxUR/dCHiJ2HdCV3K2rVky5Vba8UF31mvrCuQ==",
"license": "MIT"
},
"node_modules/dom-to-pdf": {
@@ -54976,9 +54977,9 @@
"license": "0BSD"
},
"node_modules/tsx": {
"version": "4.19.4",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz",
"integrity": "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==",
"version": "4.20.3",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz",
"integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -61643,7 +61644,7 @@
"@storybook/types": "8.4.7",
"@types/react-loadable": "^5.5.11",
"core-js": "3.40.0",
"gh-pages": "^6.2.0",
"gh-pages": "^6.3.0",
"jquery": "^3.7.1",
"memoize-one": "^5.2.1",
"react": "^17.0.2",
@@ -62584,7 +62585,7 @@
"license": "Apache-2.0",
"dependencies": {
"@deck.gl/aggregation-layers": "^9.1.13",
"@deck.gl/core": "^9.1.13",
"@deck.gl/core": "^9.1.14",
"@deck.gl/geo-layers": "^9.1.13",
"@deck.gl/layers": "^9.1.13",
"@deck.gl/react": "^9.1.13",
+4 -4
View File
@@ -129,7 +129,7 @@
"d3-color": "^3.1.0",
"d3-scale": "^2.1.2",
"dayjs": "^1.11.13",
"dom-to-image-more": "^3.2.0",
"dom-to-image-more": "^3.6.0",
"dom-to-pdf": "^0.3.2",
"echarts": "^5.6.0",
"emotion-rgba": "0.0.12",
@@ -208,7 +208,7 @@
"devDependencies": {
"@applitools/eyes-storybook": "^3.55.6",
"@babel/cli": "^7.27.2",
"@babel/compat-data": "^7.26.8",
"@babel/compat-data": "^7.28.0",
"@babel/core": "^7.26.0",
"@babel/eslint-parser": "^7.25.9",
"@babel/node": "^7.22.6",
@@ -243,7 +243,7 @@
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^12.8.3",
"@types/classnames": "^2.2.10",
"@types/classnames": "^2.3.4",
"@types/dom-to-image": "^2.6.7",
"@types/jest": "^29.5.14",
"@types/js-levenshtein": "^1.1.3",
@@ -331,7 +331,7 @@
"ts-jest": "^29.4.0",
"ts-loader": "^9.5.1",
"tscw-config": "^1.1.2",
"tsx": "^4.19.2",
"tsx": "^4.20.3",
"typescript": "5.4.5",
"vm-browserify": "^1.1.2",
"webpack": "^5.99.9",
@@ -57,5 +57,206 @@ const exampleThemes: Record<string, SerializableThemeConfig> = {
},
algorithm: ThemeAlgorithm.DARK,
},
claudette: {
algorithm: 'dark',
token: {
colorPrimary: '#C15F3C',
colorPrimaryHover: '#d16b48',
colorPrimaryActive: '#a84f30',
colorBgBase: '#1a1a1a',
colorBgContainer: '#2a2a2a',
colorBgElevated: '#323232',
colorBgLayout: '#0f0f0f',
colorBgSpotlight: '#323232',
colorText: '#F4F3EE',
colorTextSecondary: '#B1ADA1',
colorTextTertiary: '#8a8680',
colorTextQuaternary: '#6b6862',
colorTextPlaceholder: '#B1ADA1',
colorTextLightSolid: '#F4F3EE',
colorBorder: '#404040',
colorBorderSecondary: '#303030',
colorFill: '#404040',
colorFillSecondary: '#353535',
colorFillTertiary: '#2a2a2a',
colorFillQuaternary: '#1f1f1f',
colorFillAlter: '#323232',
colorIcon: '#B1ADA1',
colorIconHover: '#F4F3EE',
fontFamily:
"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu'",
fontFamilyCode:
"'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace",
fontSize: 14,
borderRadius: 6,
borderRadiusLG: 8,
wireframe: false,
},
},
figmate: {
algorithm: 'light',
token: {
colorPrimary: '#0d99ff',
colorPrimaryHover: '#3dadff',
colorPrimaryActive: '#0085e6',
colorInfo: '#4c74f4',
colorInfoHover: '#6b8af5',
colorInfoActive: '#2d5af2',
colorSuccess: '#00d2aa',
colorSuccessHover: '#1adbba',
colorSuccessActive: '#00c299',
colorWarning: '#ffad33',
colorWarningHover: '#ffbf5c',
colorWarningActive: '#ff9900',
colorError: '#ff5757',
colorErrorHover: '#ff7a7a',
colorErrorActive: '#ff3333',
colorBgBase: '#ffffff',
colorBgContainer: '#fafafa',
colorBgElevated: '#ffffff',
colorBgLayout: '#f5f5f5',
colorText: '#1a1a1a',
colorTextSecondary: '#666666',
colorTextTertiary: '#999999',
colorTextQuaternary: '#cccccc',
colorTextPlaceholder: '#999999',
colorBorder: '#e6e6e6',
colorBorderSecondary: '#f0f0f0',
colorFill: '#f0f0f0',
colorFillSecondary: '#f5f5f5',
colorFillTertiary: '#fafafa',
colorFillQuaternary: '#ffffff',
colorIcon: '#666666',
colorIconHover: '#333333',
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif',
fontFamilyCode:
'"SF Mono", Monaco, Inconsolata, "Roboto Mono", monospace',
fontSize: 14,
fontSizeLG: 16,
fontSizeXL: 20,
borderRadius: 8,
borderRadiusLG: 12,
borderRadiusSM: 6,
lineHeight: 1.5,
wireframe: false,
motion: true,
motionDurationSlow: '0.3s',
motionDurationMid: '0.2s',
motionDurationFast: '0.1s',
},
},
hubert: {
algorithm: 'dark',
token: {
colorPrimary: '#276EF1',
colorPrimaryHover: '#4285f4',
colorPrimaryActive: '#1557d6',
colorInfo: '#276EF1',
colorInfoHover: '#4285f4',
colorInfoActive: '#1557d6',
colorSuccess: '#3AA76D',
colorSuccessHover: '#4db87d',
colorSuccessActive: '#2d9657',
colorWarning: '#FFC043',
colorWarningHover: '#ffcd66',
colorWarningActive: '#e6ac26',
colorError: '#D44333',
colorErrorHover: '#dd5a4c',
colorErrorActive: '#bf3526',
colorBgBase: '#000000',
colorBgContainer: '#1a1a1a',
colorBgElevated: '#2a2a2a',
colorBgLayout: '#000000',
colorBgSpotlight: '#333333',
colorText: '#ffffff',
colorTextSecondary: '#cccccc',
colorTextTertiary: '#999999',
colorTextQuaternary: '#666666',
colorTextPlaceholder: '#999999',
colorTextLightSolid: '#ffffff',
colorBorder: '#333333',
colorBorderSecondary: '#1a1a1a',
colorFill: '#1a1a1a',
colorFillSecondary: '#2a2a2a',
colorFillTertiary: '#333333',
colorFillQuaternary: '#404040',
colorFillAlter: '#2a2a2a',
colorIcon: '#cccccc',
colorIconHover: '#ffffff',
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif',
fontFamilyCode:
'"SF Mono", Monaco, Inconsolata, "Roboto Mono", monospace',
fontSize: 14,
fontSizeLG: 16,
fontSizeXL: 20,
fontWeightStrong: 600,
borderRadius: 4,
borderRadiusLG: 6,
borderRadiusSM: 2,
lineHeight: 1.4,
lineWidthBold: 2,
wireframe: false,
motion: true,
motionDurationSlow: '0.3s',
motionDurationMid: '0.2s',
motionDurationFast: '0.1s',
},
},
bnb: {
algorithm: 'light',
token: {
colorPrimary: '#FF5A5F',
colorPrimaryHover: '#FF7479',
colorPrimaryActive: '#E5464B',
colorInfo: '#29696B',
colorInfoHover: '#3D7D7F',
colorInfoActive: '#1F5557',
colorSuccess: '#5BCACE',
colorSuccessHover: '#7DD4D8',
colorSuccessActive: '#49B6BA',
colorWarning: '#F4B02A',
colorWarningHover: '#F6C054',
colorWarningActive: '#E2A01E',
colorError: '#C32F0E',
colorErrorHover: '#D54428',
colorErrorActive: '#A8280C',
colorBgBase: '#ffffff',
colorBgContainer: '#fafafa',
colorBgElevated: '#ffffff',
colorBgLayout: '#f7f7f7',
colorText: '#222222',
colorTextSecondary: '#484848',
colorTextTertiary: '#767676',
colorTextQuaternary: '#b0b0b0',
colorTextPlaceholder: '#767676',
colorBorder: '#e8e8e8',
colorBorderSecondary: '#f0f0f0',
colorFill: '#f7f7f7',
colorFillSecondary: '#fafafa',
colorFillTertiary: '#fcfcfc',
colorFillQuaternary: '#ffffff',
colorIcon: '#767676',
colorIconHover: '#484848',
fontFamily:
'Circular, Circular Air Pro, Airbnb Cereal, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto',
fontFamilyCode:
'"SF Mono", Monaco, Inconsolata, "Roboto Mono", monospace',
fontSize: 14,
fontSizeLG: 16,
fontSizeXL: 20,
fontWeightStrong: 600,
borderRadius: 8,
borderRadiusLG: 12,
borderRadiusSM: 4,
lineHeight: 1.5,
wireframe: false,
motion: true,
motionDurationSlow: '0.3s',
motionDurationMid: '0.2s',
motionDurationFast: '0.1s',
},
},
};
export default exampleThemes;
@@ -49,6 +49,21 @@ describe('isProbablyHTML', () => {
const trickyText = 'a <= 10 and b > 10';
expect(isProbablyHTML(trickyText)).toBe(false);
});
it('should return false for strings with angle brackets that are not HTML', () => {
// Test case from issue #25561
expect(isProbablyHTML('<abcdef:12345>')).toBe(false);
// Other similar cases
expect(isProbablyHTML('<foo:bar>')).toBe(false);
expect(isProbablyHTML('<123>')).toBe(false);
expect(isProbablyHTML('<test@example.com>')).toBe(false);
expect(isProbablyHTML('<custom-element>')).toBe(false);
// Mathematical expressions
expect(isProbablyHTML('if x < 5 and y > 10')).toBe(false);
expect(isProbablyHTML('price < $100')).toBe(false);
});
});
describe('sanitizeHtmlIfNeeded', () => {
@@ -68,9 +68,87 @@ export function isProbablyHTML(text: string) {
return true;
}
// Check if the string contains common HTML patterns
if (!hasHtmlTagPattern(text)) {
return false;
}
const parser = new DOMParser();
const doc = parser.parseFromString(cleanedStr, 'text/html');
return Array.from(doc.body.childNodes).some(({ nodeType }) => nodeType === 1);
// Check if parsing created actual HTML elements (not just text nodes)
const elements = Array.from(doc.body.childNodes).filter(
node => node.nodeType === 1,
) as Element[];
// If no elements were created, it's not HTML
if (elements.length === 0) {
return false;
}
// Check if the elements are known HTML tags (not custom/unknown tags)
// This prevents strings like "<abcdef:12345>" from being treated as HTML
return elements.some(element => {
const tagName = element.tagName.toLowerCase();
// List of common HTML tags we want to recognize
const knownHtmlTags = [
'div',
'span',
'p',
'a',
'b',
'i',
'u',
'em',
'strong',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'table',
'tr',
'td',
'th',
'tbody',
'thead',
'tfoot',
'ul',
'ol',
'li',
'img',
'br',
'hr',
'pre',
'code',
'blockquote',
'section',
'article',
'nav',
'header',
'footer',
'form',
'input',
'button',
'select',
'option',
'textarea',
'label',
'fieldset',
'legend',
'video',
'audio',
'canvas',
'iframe',
'script',
'style',
'link',
'meta',
'title',
];
return knownHtmlTags.includes(tagName);
});
}
export function sanitizeHtmlIfNeeded(htmlString: string) {
@@ -43,7 +43,7 @@
"@storybook/types": "8.4.7",
"@types/react-loadable": "^5.5.11",
"core-js": "3.40.0",
"gh-pages": "^6.2.0",
"gh-pages": "^6.3.0",
"jquery": "^3.7.1",
"memoize-one": "^5.2.1",
"react": "^17.0.2",
@@ -25,7 +25,7 @@
],
"dependencies": {
"@deck.gl/aggregation-layers": "^9.1.13",
"@deck.gl/core": "^9.1.13",
"@deck.gl/core": "^9.1.14",
"@deck.gl/geo-layers": "^9.1.13",
"@deck.gl/layers": "^9.1.13",
"@deck.gl/react": "^9.1.13",
@@ -589,7 +589,7 @@ const config: ControlPanelConfig = {
name: 'show_cell_bars',
config: {
type: 'CheckboxControl',
label: t('Show Cell bars'),
label: t('Show cell bars'),
renderTrigger: true,
default: true,
description: t(
@@ -617,7 +617,7 @@ const config: ControlPanelConfig = {
name: 'color_pn',
config: {
type: 'CheckboxControl',
label: t('add colors to cell bars for +/-'),
label: t('Add colors to cell bars for +/-'),
renderTrigger: true,
default: true,
description: t(
@@ -631,7 +631,7 @@ const config: ControlPanelConfig = {
name: 'comparison_color_enabled',
config: {
type: 'CheckboxControl',
label: t('basic conditional formatting'),
label: t('Basic conditional formatting'),
renderTrigger: true,
visibility: ({ controls }) =>
!isEmpty(controls?.time_compare?.value),
@@ -672,7 +672,7 @@ const config: ControlPanelConfig = {
config: {
type: 'ConditionalFormattingControl',
renderTrigger: true,
label: t('Custom Conditional Formatting'),
label: t('Custom conditional formatting'),
extraColorChoices: [
{
value: ColorSchemeEnum.Green,
@@ -95,27 +95,27 @@ function getTotalValuePadding({
top: donut ? 'middle' : '0',
left: 'center',
};
const LEGEND_HEIGHT = 15;
const LEGEND_WIDTH = 215;
if (chartPadding.top) {
padding.top = donut
? `${50 + ((chartPadding.top - LEGEND_HEIGHT) / height / 2) * 100}%`
: `${((chartPadding.top + LEGEND_HEIGHT) / height) * 100}%`;
? `${50 + (chartPadding.top / height / 2) * 100}%`
: `${(chartPadding.top / height) * 100}%`;
}
if (chartPadding.bottom) {
padding.top = donut
? `${50 - ((chartPadding.bottom + LEGEND_HEIGHT) / height / 2) * 100}%`
? `${50 - (chartPadding.bottom / height / 2) * 100}%`
: '0';
}
if (chartPadding.left) {
padding.left = `${
50 + ((chartPadding.left - LEGEND_WIDTH) / width / 2) * 100
}%`;
// When legend is on the left, shift text right to center it in the available space
const leftPaddingPercent = (chartPadding.left / width) * 100;
const adjustedLeftPercent = 50 + leftPaddingPercent * 0.25;
padding.left = `${adjustedLeftPercent}%`;
}
if (chartPadding.right) {
padding.left = `${
50 - ((chartPadding.right + LEGEND_WIDTH) / width / 2) * 100
}%`;
// When legend is on the right, shift text left to center it in the available space
const rightPaddingPercent = (chartPadding.right / width) * 100;
const adjustedLeftPercent = 50 - rightPaddingPercent * 0.75;
padding.left = `${adjustedLeftPercent}%`;
}
return padding;
}
@@ -220,7 +220,7 @@ export default function transformProps(
name: otherName,
value: otherSum,
itemStyle: {
color: theme.colors.grayscale.dark1,
color: theme.colorText,
opacity:
filterState.selectedValues &&
!filterState.selectedValues.includes(otherName)
@@ -368,7 +368,7 @@ export default function transformProps(
const defaultLabel = {
formatter,
show: showLabels,
color: theme.colors.grayscale.dark2,
color: theme.colorText,
};
const chartPadding = getChartPadding(
@@ -403,7 +403,7 @@ export default function transformProps(
label: {
show: true,
fontWeight: 'bold',
backgroundColor: theme.colors.grayscale.light5,
backgroundColor: theme.colorBgContainer,
},
},
data: transformedData,
@@ -445,6 +445,7 @@ export default function transformProps(
text: t('Total: %s', numberFormatter(totalValue)),
fontSize: 16,
fontWeight: 'bold',
fill: theme.colorText,
},
z: 10,
}
@@ -71,6 +71,7 @@ export const DEFAULT_FORM_DATA: EchartsTimeseriesFormData = {
seriesType: EchartsTimeseriesSeriesType.Line,
stack: false,
tooltipTimeFormat: 'smart_date',
xAxisTimeFormat: 'smart_date',
truncateXAxis: true,
truncateYAxis: false,
yAxisBounds: [null, null],
@@ -174,6 +174,8 @@ function Echart(
if (!chartRef.current) {
chartRef.current = init(divRef.current, null, { locale });
}
// did mount
handleSizeChange({ width, height });
setDidMount(true);
});
}, [locale]);
@@ -235,9 +237,6 @@ function Echart(
echartOptions,
);
chartRef.current?.setOption(themedEchartOptions, true);
// did mount
handleSizeChange({ width, height });
}
}, [didMount, echartOptions, eventHandlers, zrEventHandlers, theme]);
@@ -221,6 +221,157 @@ describe('Pie label string template', () => {
});
});
describe('Total value positioning with legends', () => {
const getChartPropsWithLegend = (
showTotal = true,
showLegend = true,
legendOrientation = 'right',
donut = true,
): EchartsPieChartProps => {
const formData: SqlaFormData = {
colorScheme: 'bnbColors',
datasource: '3__table',
granularity_sqla: 'ds',
metric: 'sum__num',
groupby: ['category'],
viz_type: 'pie',
show_total: showTotal,
show_legend: showLegend,
legend_orientation: legendOrientation,
donut,
};
return new ChartProps({
formData,
width: 800,
height: 600,
queriesData: [
{
data: [
{ category: 'A', sum__num: 10, sum__num__contribution: 0.4 },
{ category: 'B', sum__num: 15, sum__num__contribution: 0.6 },
],
},
],
theme: supersetTheme,
}) as EchartsPieChartProps;
};
it('should center total text when legend is on the right', () => {
const props = getChartPropsWithLegend(true, true, 'right', true);
const transformed = transformProps(props);
expect(transformed.echartOptions.graphic).toEqual(
expect.objectContaining({
type: 'text',
left: expect.stringMatching(/^\d+(\.\d+)?%$/),
top: 'middle',
style: expect.objectContaining({
text: expect.stringContaining('Total:'),
}),
}),
);
// The left position should be less than 50% (shifted left)
const leftValue = parseFloat(
(transformed.echartOptions.graphic as any).left.replace('%', ''),
);
expect(leftValue).toBeLessThan(50);
expect(leftValue).toBeGreaterThan(30); // Should be reasonable positioning
});
it('should center total text when legend is on the left', () => {
const props = getChartPropsWithLegend(true, true, 'left', true);
const transformed = transformProps(props);
expect(transformed.echartOptions.graphic).toEqual(
expect.objectContaining({
type: 'text',
left: expect.stringMatching(/^\d+(\.\d+)?%$/),
top: 'middle',
}),
);
// The left position should be greater than 50% (shifted right)
const leftValue = parseFloat(
(transformed.echartOptions.graphic as any).left.replace('%', ''),
);
expect(leftValue).toBeGreaterThan(50);
expect(leftValue).toBeLessThan(70); // Should be reasonable positioning
});
it('should center total text when legend is on top', () => {
const props = getChartPropsWithLegend(true, true, 'top', true);
const transformed = transformProps(props);
expect(transformed.echartOptions.graphic).toEqual(
expect.objectContaining({
type: 'text',
left: 'center',
top: expect.stringMatching(/^\d+(\.\d+)?%$/),
}),
);
// The top position should be adjusted for top legend
const topValue = parseFloat(
(transformed.echartOptions.graphic as any).top.replace('%', ''),
);
expect(topValue).toBeGreaterThan(50); // Shifted down for top legend
});
it('should center total text when legend is on bottom', () => {
const props = getChartPropsWithLegend(true, true, 'bottom', true);
const transformed = transformProps(props);
expect(transformed.echartOptions.graphic).toEqual(
expect.objectContaining({
type: 'text',
left: 'center',
top: expect.stringMatching(/^\d+(\.\d+)?%$/),
}),
);
// The top position should be adjusted for bottom legend
const topValue = parseFloat(
(transformed.echartOptions.graphic as any).top.replace('%', ''),
);
expect(topValue).toBeLessThan(50); // Shifted up for bottom legend
});
it('should use default positioning when no legend is shown', () => {
const props = getChartPropsWithLegend(true, false, 'right', true);
const transformed = transformProps(props);
expect(transformed.echartOptions.graphic).toEqual(
expect.objectContaining({
type: 'text',
left: 'center',
top: 'middle',
}),
);
});
it('should handle regular pie chart (non-donut) positioning', () => {
const props = getChartPropsWithLegend(true, true, 'right', false);
const transformed = transformProps(props);
expect(transformed.echartOptions.graphic).toEqual(
expect.objectContaining({
type: 'text',
top: '0', // Non-donut charts use '0' as default top position
left: expect.stringMatching(/^\d+(\.\d+)?%$/), // Should still adjust left for right legend
}),
);
});
it('should not show total graphic when showTotal is false', () => {
const props = getChartPropsWithLegend(false, true, 'right', true);
const transformed = transformProps(props);
expect(transformed.echartOptions.graphic).toBeNull();
});
});
describe('Other category', () => {
const defaultFormData: SqlaFormData = {
colorScheme: 'bnbColors',
@@ -0,0 +1,204 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import controlPanel from '../../../src/Timeseries/Regular/Bar/controlPanel';
describe('Bar Chart Control Panel', () => {
describe('x_axis_time_format control', () => {
it('should include x_axis_time_format control in the panel', () => {
const config = controlPanel;
// Look for x_axis_time_format control in all sections and rows
let foundTimeFormatControl = false;
for (const section of config.controlPanelSections) {
if (section && section.controlSetRows) {
for (const row of section.controlSetRows) {
for (const control of row) {
if (
typeof control === 'object' &&
control !== null &&
'name' in control &&
control.name === 'x_axis_time_format'
) {
foundTimeFormatControl = true;
break;
}
}
if (foundTimeFormatControl) break;
}
if (foundTimeFormatControl) break;
}
}
expect(foundTimeFormatControl).toBe(true);
});
it('should have correct default value for x_axis_time_format', () => {
const config = controlPanel;
// Find the x_axis_time_format control
let timeFormatControl: any = null;
for (const section of config.controlPanelSections) {
if (section && section.controlSetRows) {
for (const row of section.controlSetRows) {
for (const control of row) {
if (
typeof control === 'object' &&
control !== null &&
'name' in control &&
control.name === 'x_axis_time_format'
) {
timeFormatControl = control;
break;
}
}
if (timeFormatControl) break;
}
if (timeFormatControl) break;
}
}
expect(timeFormatControl).toBeDefined();
expect(timeFormatControl.config).toBeDefined();
expect(timeFormatControl.config.default).toBe('smart_date');
});
it('should have visibility function for x_axis_time_format', () => {
const config = controlPanel;
// Find the x_axis_time_format control
let timeFormatControl: any = null;
for (const section of config.controlPanelSections) {
if (section && section.controlSetRows) {
for (const row of section.controlSetRows) {
for (const control of row) {
if (
typeof control === 'object' &&
control !== null &&
'name' in control &&
control.name === 'x_axis_time_format'
) {
timeFormatControl = control;
break;
}
}
if (timeFormatControl) break;
}
if (timeFormatControl) break;
}
}
expect(timeFormatControl).toBeDefined();
expect(timeFormatControl.config.visibility).toBeDefined();
expect(typeof timeFormatControl.config.visibility).toBe('function');
// The visibility function exists - the exact logic is tested implicitly through UI behavior
// The important part is that the control has proper visibility configuration
});
it('should have proper control configuration', () => {
const config = controlPanel;
// Find the x_axis_time_format control
let timeFormatControl: any = null;
for (const section of config.controlPanelSections) {
if (section && section.controlSetRows) {
for (const row of section.controlSetRows) {
for (const control of row) {
if (
typeof control === 'object' &&
control !== null &&
'name' in control &&
control.name === 'x_axis_time_format'
) {
timeFormatControl = control;
break;
}
}
if (timeFormatControl) break;
}
if (timeFormatControl) break;
}
}
expect(timeFormatControl).toBeDefined();
expect(timeFormatControl.config).toMatchObject({
default: 'smart_date',
disableStash: true,
resetOnHide: false,
});
// Should have a description that includes D3 time format docs
expect(timeFormatControl.config.description).toContain('D3');
});
});
describe('Control panel structure for bar charts', () => {
it('should have Chart Orientation section', () => {
const config = controlPanel;
const orientationSection = config.controlPanelSections.find(
section => section && section.label === 'Chart Orientation',
);
expect(orientationSection).toBeDefined();
expect(orientationSection!.expanded).toBe(true);
});
it('should have Chart Options section with X Axis controls', () => {
const config = controlPanel;
const chartOptionsSection = config.controlPanelSections.find(
section => section && section.label === 'Chart Options',
);
expect(chartOptionsSection).toBeDefined();
expect(chartOptionsSection!.expanded).toBe(true);
// Should contain X Axis subsection header - this is sufficient proof
expect(chartOptionsSection!.controlSetRows).toBeDefined();
expect(chartOptionsSection!.controlSetRows!.length).toBeGreaterThan(0);
});
it('should have proper form data overrides', () => {
const config = controlPanel;
expect(config.formDataOverrides).toBeDefined();
expect(typeof config.formDataOverrides).toBe('function');
// Test the form data override function
const mockFormData = {
datasource: '1__table',
viz_type: 'echarts_timeseries_bar',
metrics: ['test_metric'],
groupby: ['test_column'],
other_field: 'test',
};
const result = config.formDataOverrides!(mockFormData);
expect(result).toHaveProperty('metrics');
expect(result).toHaveProperty('groupby');
expect(result).toHaveProperty('other_field', 'test');
});
});
});
@@ -0,0 +1,353 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ChartProps, SqlaFormData, supersetTheme } from '@superset-ui/core';
import { EchartsTimeseriesChartProps } from '../../../src/types';
import transformProps from '../../../src/Timeseries/transformProps';
import { DEFAULT_FORM_DATA } from '../../../src/Timeseries/constants';
import { EchartsTimeseriesSeriesType } from '../../../src/Timeseries/types';
describe('Bar Chart X-axis Time Formatting', () => {
const baseFormData: SqlaFormData = {
...DEFAULT_FORM_DATA,
colorScheme: 'bnbColors',
datasource: '3__table',
granularity_sqla: '__timestamp',
metric: ['Sales', 'Marketing', 'Operations'],
groupby: [],
viz_type: 'echarts_timeseries_bar',
seriesType: EchartsTimeseriesSeriesType.Bar,
orientation: 'vertical',
};
const timeseriesData = [
{
data: [
{ Sales: 100, __timestamp: 1609459200000 }, // 2021-01-01
{ Marketing: 150, __timestamp: 1612137600000 }, // 2021-02-01
{ Operations: 200, __timestamp: 1614556800000 }, // 2021-03-01
],
colnames: ['Sales', 'Marketing', 'Operations', '__timestamp'],
coltypes: ['BIGINT', 'BIGINT', 'BIGINT', 'TIMESTAMP'],
},
];
const baseChartPropsConfig = {
width: 800,
height: 600,
queriesData: timeseriesData,
theme: supersetTheme,
};
describe('Default xAxisTimeFormat', () => {
it('should use smart_date as default xAxisTimeFormat', () => {
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: baseFormData,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
// Check that the x-axis has a formatter applied
expect(transformedProps.echartOptions.xAxis).toHaveProperty('axisLabel');
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
expect(typeof xAxis.axisLabel.formatter).toBe('function');
});
it('should apply xAxisTimeFormat from DEFAULT_FORM_DATA when not explicitly set', () => {
const formDataWithoutTimeFormat = {
...baseFormData,
};
delete formDataWithoutTimeFormat.xAxisTimeFormat;
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: formDataWithoutTimeFormat,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
// Should still have a formatter since DEFAULT_FORM_DATA includes xAxisTimeFormat
expect(transformedProps.echartOptions.xAxis).toHaveProperty('axisLabel');
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
});
});
describe('Custom xAxisTimeFormat', () => {
it('should respect custom xAxisTimeFormat when explicitly set', () => {
const customFormData = {
...baseFormData,
xAxisTimeFormat: '%Y-%m-%d',
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: customFormData,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
// Verify the formatter function exists and is applied
expect(transformedProps.echartOptions.xAxis).toHaveProperty('axisLabel');
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
expect(typeof xAxis.axisLabel.formatter).toBe('function');
// The key test is that a formatter exists - the actual formatting is handled by d3-time-format
const { formatter } = xAxis.axisLabel;
expect(formatter).toBeDefined();
expect(typeof formatter).toBe('function');
});
it('should handle different time format options', () => {
const timeFormats = [
'%Y-%m-%d',
'%Y/%m/%d',
'%m/%d/%Y',
'%b %d, %Y',
'smart_date',
];
timeFormats.forEach(timeFormat => {
const customFormData = {
...baseFormData,
xAxisTimeFormat: timeFormat,
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: customFormData,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
expect(typeof xAxis.axisLabel.formatter).toBe('function');
});
});
});
describe('Orientation-specific behavior', () => {
it('should apply time formatting to x-axis in vertical bar charts', () => {
const verticalFormData = {
...baseFormData,
orientation: 'vertical',
xAxisTimeFormat: '%Y-%m',
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: verticalFormData,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
// In vertical orientation, time should be on x-axis
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
expect(typeof xAxis.axisLabel.formatter).toBe('function');
});
it('should apply time formatting to y-axis in horizontal bar charts', () => {
const horizontalFormData = {
...baseFormData,
orientation: 'horizontal',
xAxisTimeFormat: '%Y-%m',
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: horizontalFormData,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
// In horizontal orientation, axes are swapped, so time should be on y-axis
const yAxis = transformedProps.echartOptions.yAxis as any;
expect(yAxis.axisLabel).toHaveProperty('formatter');
expect(typeof yAxis.axisLabel.formatter).toBe('function');
});
});
describe('Integration with existing features', () => {
it('should work with axis bounds', () => {
const formDataWithBounds = {
...baseFormData,
xAxisTimeFormat: '%Y-%m-%d',
truncateXAxis: true,
xAxisBounds: [null, null] as [number | null, number | null],
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: formDataWithBounds,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
// The xAxis should be configured with the time formatting
expect(transformedProps.echartOptions.xAxis).toBeDefined();
});
it('should work with label rotation', () => {
const formDataWithRotation = {
...baseFormData,
xAxisTimeFormat: '%Y-%m-%d',
xAxisLabelRotation: 45,
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: formDataWithRotation,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
expect(xAxis.axisLabel).toHaveProperty('rotate', 45);
});
it('should maintain time formatting consistency with tooltip', () => {
const formDataWithTooltip = {
...baseFormData,
xAxisTimeFormat: '%Y-%m-%d',
tooltipTimeFormat: '%Y-%m-%d',
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: formDataWithTooltip,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
// Both axis and tooltip should have formatters
const xAxis = transformedProps.echartOptions.xAxis as any;
expect(xAxis.axisLabel).toHaveProperty('formatter');
expect(transformedProps.xValueFormatter).toBeDefined();
expect(typeof transformedProps.xValueFormatter).toBe('function');
});
});
describe('Regression test for Issue #30373', () => {
it('should not be stuck on adaptive formatting', () => {
// Test the exact scenario described in the issue
const issueFormData = {
...baseFormData,
xAxisTimeFormat: '%Y-%m-%d %H:%M:%S', // Non-adaptive format
};
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: issueFormData,
});
const transformedProps = transformProps(
chartProps as EchartsTimeseriesChartProps,
);
// Verify formatter exists - this is the key fix, ensuring xAxisTimeFormat is used
const xAxis = transformedProps.echartOptions.xAxis as any;
const { formatter } = xAxis.axisLabel;
expect(formatter).toBeDefined();
expect(typeof formatter).toBe('function');
// The important part is that the xAxisTimeFormat is being used from formData
// The actual formatting is handled by the underlying time formatter
});
it('should allow changing from smart_date to other formats', () => {
// First create with smart_date (default)
const smartDateFormData = {
...baseFormData,
xAxisTimeFormat: 'smart_date',
};
const smartDateChartProps = new ChartProps({
...baseChartPropsConfig,
formData: smartDateFormData,
});
const smartDateProps = transformProps(
smartDateChartProps as EchartsTimeseriesChartProps,
);
// Then change to a different format
const customFormatFormData = {
...baseFormData,
xAxisTimeFormat: '%b %Y',
};
const customFormatChartProps = new ChartProps({
...baseChartPropsConfig,
formData: customFormatFormData,
});
const customFormatProps = transformProps(
customFormatChartProps as EchartsTimeseriesChartProps,
);
// Both should have formatters - the key is that they're not undefined
const smartDateXAxis = smartDateProps.echartOptions.xAxis as any;
const customFormatXAxis = customFormatProps.echartOptions.xAxis as any;
expect(smartDateXAxis.axisLabel.formatter).toBeDefined();
expect(customFormatXAxis.axisLabel.formatter).toBeDefined();
// Both should be functions that can format time
expect(typeof smartDateXAxis.axisLabel.formatter).toBe('function');
expect(typeof customFormatXAxis.axisLabel.formatter).toBe('function');
});
it('should have xAxisTimeFormat in formData by default', () => {
// This test specifically verifies our fix - that DEFAULT_FORM_DATA includes xAxisTimeFormat
const chartProps = new ChartProps({
...baseChartPropsConfig,
formData: baseFormData,
});
expect(chartProps.formData.xAxisTimeFormat).toBeDefined();
expect(chartProps.formData.xAxisTimeFormat).toBe('smart_date');
});
});
});
@@ -0,0 +1,43 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { DEFAULT_FORM_DATA } from '../../src/Timeseries/constants';
describe('Timeseries constants', () => {
describe('DEFAULT_FORM_DATA', () => {
it('should include xAxisTimeFormat in default form data', () => {
expect(DEFAULT_FORM_DATA).toHaveProperty('xAxisTimeFormat');
expect(DEFAULT_FORM_DATA.xAxisTimeFormat).toBe('smart_date');
});
it('should include tooltipTimeFormat in default form data', () => {
expect(DEFAULT_FORM_DATA).toHaveProperty('tooltipTimeFormat');
expect(DEFAULT_FORM_DATA.tooltipTimeFormat).toBe('smart_date');
});
it('should have consistent time format defaults', () => {
expect(DEFAULT_FORM_DATA.xAxisTimeFormat).toBe(
DEFAULT_FORM_DATA.tooltipTimeFormat,
);
});
it('should have vertical orientation as default', () => {
expect(DEFAULT_FORM_DATA.orientation).toBe('vertical');
});
});
});
@@ -646,7 +646,7 @@ const config: ControlPanelConfig = {
name: 'show_cell_bars',
config: {
type: 'CheckboxControl',
label: t('Show Cell bars'),
label: t('Show cell bars'),
renderTrigger: true,
default: true,
description: t(
@@ -674,7 +674,7 @@ const config: ControlPanelConfig = {
name: 'color_pn',
config: {
type: 'CheckboxControl',
label: t('add colors to cell bars for +/-'),
label: t('Add colors to cell bars for +/-'),
renderTrigger: true,
default: true,
description: t(
@@ -688,7 +688,7 @@ const config: ControlPanelConfig = {
name: 'comparison_color_enabled',
config: {
type: 'CheckboxControl',
label: t('basic conditional formatting'),
label: t('Basic conditional formatting'),
renderTrigger: true,
visibility: ({ controls }) =>
!isEmpty(controls?.time_compare?.value),
@@ -729,7 +729,7 @@ const config: ControlPanelConfig = {
config: {
type: 'ConditionalFormattingControl',
renderTrigger: true,
label: t('Custom Conditional Formatting'),
label: t('Custom conditional formatting'),
extraColorChoices: [
{
value: ColorSchemeEnum.Green,
+1 -1
View File
@@ -37,7 +37,7 @@ from superset.migrations.shared.security_converge import (
)
from superset.models.core import Database
logger = logging.getLogger("alembic")
logger = logging.getLogger("alembic.env")
Base: Type[Any] = declarative_base()
@@ -28,7 +28,7 @@ from superset.migrations.shared.utils import paginated_update, try_load_json
from superset.utils import json
from superset.utils.date_parser import get_since_until
logger = logging.getLogger("alembic")
logger = logging.getLogger("alembic.env")
Base = declarative_base()
@@ -29,7 +29,7 @@ from sqlalchemy import (
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Load, relationship, Session
logger = logging.getLogger(__name__)
logger = logging.getLogger("alembic.env")
Base = declarative_base()
+1 -1
View File
@@ -49,7 +49,7 @@ YELLOW = "\033[33m"
RED = "\033[31m"
LRED = "\033[91m"
logger = logging.getLogger("alembic")
logger = logging.getLogger("alembic.env")
DEFAULT_BATCH_SIZE = int(os.environ.get("BATCH_SIZE", 1000))
@@ -33,6 +33,8 @@ from superset.utils.core import generic_find_constraint_name
revision = "1226819ee0e3"
down_revision = "956a063c52b3"
logger = logging.getLogger("alembic.env")
naming_convention = {
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s"
@@ -61,7 +63,7 @@ def upgrade():
["datasource_name"],
)
except: # noqa: E722
logging.warning("Could not find or drop constraint on `columns`")
logger.warning("Could not find or drop constraint on `columns`")
def downgrade():
@@ -38,6 +38,8 @@ from superset.utils.core import generic_find_constraint_name
revision = "3b626e2a6783"
down_revision = "eca4694defa7"
logger = logging.getLogger("alembic.env")
def upgrade():
# cleanup after: https://github.com/airbnb/superset/pull/1078
@@ -60,7 +62,7 @@ def upgrade():
batch_op.drop_column("druid_datasource_id")
batch_op.drop_column("table_id")
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
# fixed issue: https://github.com/airbnb/superset/issues/466
try:
@@ -69,18 +71,18 @@ def upgrade():
None, "datasources", ["datasource_name"], ["datasource_name"]
)
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
try:
with op.batch_alter_table("query") as batch_op:
batch_op.create_unique_constraint("client_id", ["client_id"])
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
try:
with op.batch_alter_table("query") as batch_op:
batch_op.drop_column("name")
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
def downgrade():
@@ -88,7 +90,7 @@ def downgrade():
with op.batch_alter_table("tables") as batch_op:
batch_op.create_index("table_name", ["table_name"], unique=True)
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
try:
with op.batch_alter_table("slices") as batch_op:
@@ -113,7 +115,7 @@ def downgrade():
)
batch_op.create_foreign_key("slices_ibfk_2", "tables", ["table_id"], ["id"])
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
try:
fk_columns = generic_find_constraint_name(
@@ -125,11 +127,11 @@ def downgrade():
with op.batch_alter_table("columns") as batch_op:
batch_op.drop_constraint(fk_columns, type_="foreignkey")
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
op.add_column("query", sa.Column("name", sa.String(length=256), nullable=True))
try:
with op.batch_alter_table("query") as batch_op:
batch_op.drop_constraint("client_id", type_="unique")
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
@@ -31,6 +31,8 @@ import logging # noqa: E402
import sqlalchemy as sa # noqa: E402
from alembic import op # noqa: E402
logger = logging.getLogger("alembic.env")
def upgrade():
op.add_column("tables", sa.Column("params", sa.Text(), nullable=True))
@@ -40,4 +42,4 @@ def downgrade():
try:
op.drop_column("tables", "params")
except Exception as ex:
logging.warning(str(ex))
logger.warning(str(ex))
@@ -31,6 +31,8 @@ import logging # noqa: E402
import sqlalchemy as sa # noqa: E402
from alembic import op # noqa: E402
logger = logging.getLogger("alembic.env")
def upgrade():
op.add_column(
@@ -44,7 +46,7 @@ def upgrade():
op.create_unique_constraint(None, "dbs", ["verbose_name"])
op.create_unique_constraint(None, "clusters", ["verbose_name"])
except Exception:
logging.info("Constraint not created, expected when using sqlite")
logger.info("Constraint not created, expected when using sqlite")
def downgrade():
@@ -52,4 +54,4 @@ def downgrade():
op.drop_column("dbs", "verbose_name")
op.drop_column("clusters", "verbose_name")
except Exception as ex:
logging.exception(ex)
logger.exception(ex)
@@ -37,6 +37,8 @@ from superset.utils.core import (
revision = "4736ec66ce19"
down_revision = "f959a6652acd"
logger = logging.getLogger("alembic.env")
conv = {
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
@@ -119,13 +121,13 @@ def upgrade():
type_="unique",
)
except Exception as ex:
logging.warning(
logger.warning(
"Constraint drop failed, you may want to do this "
"manually on your database. For context, this is a known "
"issue around nondeterministic constraint names on Postgres "
"and perhaps more databases through SQLAlchemy."
)
logging.exception(ex)
logger.exception(ex)
def downgrade():
@@ -22,12 +22,16 @@ Create Date: 2018-05-09 23:45:14.296283
"""
import logging
import sqlalchemy as sa # noqa: E402
from alembic import op # noqa: E402
# revision identifiers, used by Alembic.
revision = "e502db2af7be"
down_revision = "5ccf602336a0"
import sqlalchemy as sa # noqa: E402
from alembic import op # noqa: E402
logger = logging.getLogger("alembic.env")
def upgrade():
@@ -38,4 +42,4 @@ def downgrade():
try:
op.drop_column("tables", "template_params")
except Exception as ex:
logging.warning(str(ex)) # noqa: F821
logger.warning(str(ex))
@@ -35,6 +35,8 @@ from superset.utils import json
revision = "fb13d49b72f9"
down_revision = "de021a1ca60d"
logger = logging.getLogger("alembic.env")
Base = declarative_base()
@@ -49,7 +51,7 @@ class Slice(Base):
def upgrade_slice(slc):
params = json.loads(slc.params)
logging.info(f"Upgrading {slc.slice_name}")
logger.info(f"Upgrading {slc.slice_name}")
cols = params.get("groupby")
metric = params.get("metric")
if cols:
@@ -79,8 +81,8 @@ def upgrade():
for slc in filter_box_slices.all():
try:
upgrade_slice(slc)
except Exception:
logging.exception(e) # noqa: F821
except Exception as e:
logger.exception(e)
session.commit()
session.close()
@@ -94,7 +96,7 @@ def downgrade():
for slc in filter_box_slices.all():
try:
params = json.loads(slc.params)
logging.info(f"Downgrading {slc.slice_name}")
logger.info(f"Downgrading {slc.slice_name}")
flts = params.get("filter_configs")
if not flts:
continue
@@ -102,7 +104,7 @@ def downgrade():
params["groupby"] = [o.get("column") for o in flts]
slc.params = json.dumps(params, sort_keys=True)
except Exception as ex:
logging.exception(ex)
logger.exception(ex)
session.commit()
session.close()
@@ -41,6 +41,8 @@ from superset.utils.core import ( # noqa: E402
Base = declarative_base()
logger = logging.getLogger("alembic.env")
class Slice(Base):
__tablename__ = "slices"
@@ -63,7 +65,7 @@ def upgrade():
if source != target:
slc.params = json.dumps(target, sort_keys=True)
except Exception as ex:
logging.warn(ex)
logger.warning(ex)
session.commit()
session.close()
@@ -37,6 +37,8 @@ from superset.utils.dashboard_filter_scopes_converter import convert_filter_scop
revision = "3325d4caccc8"
down_revision = "e96dbf2cfef0"
logger = logging.getLogger("alembic.env")
Base = declarative_base()
@@ -86,7 +88,7 @@ def upgrade():
if filters:
filter_scopes = convert_filter_scopes(json_metadata, filters)
json_metadata["filter_scopes"] = filter_scopes
logging.info(
logger.info(
f"Adding filter_scopes for dashboard {dashboard.id}: {json.dumps(filter_scopes)}" # noqa: E501
)
@@ -100,7 +102,7 @@ def upgrade():
else:
dashboard.json_metadata = None
except Exception as ex:
logging.exception(f"dashboard {dashboard.id} has error: {ex}")
logger.exception(f"dashboard {dashboard.id} has error: {ex}")
session.commit()
session.close()
@@ -38,6 +38,8 @@ from sqlalchemy_utils import UUIDType # noqa: E402
from superset import db # noqa: E402
logger = logging.getLogger("alembic.env")
add_uuid_column_to_import_mixin = import_module(
"superset.migrations.versions."
"2020-09-28_17-57_b56500de1855_add_uuid_column_to_import_mixin",
@@ -52,9 +54,9 @@ def has_uuid_column(table_name, bind):
columns = {column["name"] for column in inspector.get_columns(table_name)}
has_uuid_column = "uuid" in columns
if has_uuid_column:
logging.info("Table %s already has uuid column, skipping...", table_name)
logger.info("Table %s already has uuid column, skipping...", table_name)
else:
logging.info("Table %s doesn't have uuid column, adding...", table_name)
logger.info("Table %s doesn't have uuid column, adding...", table_name)
return has_uuid_column
@@ -38,6 +38,8 @@ down_revision = "31b2a1039d4a"
Base = declarative_base()
logger = logging.getLogger("alembic.env")
class Database(Base):
__tablename__ = "dbs"
@@ -56,7 +58,7 @@ def upgrade():
try:
extra = json.loads(database.extra)
except json.JSONDecodeError as ex:
logging.warning(str(ex))
logger.warning(str(ex))
continue
schemas_allowed_for_csv_upload = extra.get("schemas_allowed_for_csv_upload")
@@ -35,6 +35,8 @@ from sqlalchemy import func # noqa: E402
from superset import db # noqa: E402
from superset.connectors.sqla.models import SqlaTable # noqa: E402
logger = logging.getLogger("alembic.env")
def upgrade():
with op.batch_alter_table("tables") as batch_op:
@@ -62,12 +64,12 @@ def remove_value_if_too_long():
for row in rows:
row.fetch_values_predicate = None
logging.info("%d values deleted", len(rows))
logger.info("%d values deleted", len(rows))
session.commit()
session.close()
except Exception as ex:
logging.warning(ex)
logger.warning(ex)
def downgrade():
@@ -37,7 +37,7 @@ from superset.utils import json # noqa: E402
Base = declarative_base()
logger = logging.getLogger("alembic")
logger = logging.getLogger("alembic.env")
class Dashboard(Base):
@@ -37,6 +37,8 @@ from superset.utils import json # noqa: E402
Base = declarative_base()
logger = logging.getLogger("alembic.env")
class Database(Base):
__tablename__ = "dbs"
@@ -52,7 +54,7 @@ def upgrade():
try:
extra = json.loads(database.extra)
except json.JSONDecodeError as ex:
logging.warning(str(ex))
logger.warning(str(ex))
continue
if "schemas_allowed_for_csv_upload" in extra:
@@ -74,7 +76,7 @@ def downgrade():
try:
extra = json.loads(database.extra)
except json.JSONDecodeError as ex:
logging.warning(str(ex))
logger.warning(str(ex))
continue
if "schemas_allowed_for_file_upload" in extra:
@@ -37,7 +37,7 @@ from superset.utils import json # noqa: E402
Base = declarative_base()
logger = logging.getLogger("alembic")
logger = logging.getLogger("alembic.env")
class Slice(Base):
@@ -38,7 +38,7 @@ from superset.utils import json # noqa: E402
Base = declarative_base()
logger = logging.getLogger("alembic")
logger = logging.getLogger("alembic.env")
class Slice(Base):
@@ -37,7 +37,7 @@ from superset.utils import json # noqa: E402
Base = declarative_base()
logger = logging.getLogger(__name__)
logger = logging.getLogger("alembic.env")
class Slice(Base): # type: ignore
@@ -38,7 +38,7 @@ from superset.migrations.shared.utils import paginated_update # noqa: E402
from superset.utils import json # noqa: E402
Base = declarative_base()
logger = logging.getLogger(__name__)
logger = logging.getLogger("alembic.env")
class Dashboard(Base):
@@ -41,7 +41,7 @@ from superset.utils.date_parser import get_since_until
revision = "f84fde59123a"
down_revision = "9621c6d56ffb"
logger = logging.getLogger(__name__)
logger = logging.getLogger("alembic.env")
Base = declarative_base()
@@ -34,7 +34,7 @@ from superset.utils.core import generic_find_uq_constraint_name
revision = "df3d7e2eb9a4"
down_revision = "48cbb571fa3a"
logger = logging.getLogger(__name__)
logger = logging.getLogger("alembic.env")
def upgrade():
@@ -32,8 +32,7 @@ from sqlalchemy.ext.declarative import declarative_base
from superset import db
from superset.migrations.shared.utils import paginated_update
logger = logging.getLogger("alembic")
logger.setLevel(logging.INFO)
logger = logging.getLogger("alembic.env")
# revision identifiers, used by Alembic.
revision = "363a9b1e8992"
@@ -3382,7 +3382,7 @@ msgid "Custom"
msgstr "تقليد"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "التنسيق الشرطي"
msgid "Custom Plugin"
@@ -9862,7 +9862,7 @@ msgid "Show CREATE VIEW statement"
msgstr "عرض بيان إنشاء عرض"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "عرض أشرطة الخلايا"
msgid "Show Dashboard"
@@ -13915,7 +13915,7 @@ msgstr "يجب أن يكون `row_offset` أكبر من أو يساوي 0"
msgid "`width` must be greater or equal to 0"
msgstr "يجب أن يكون «العرض» أكبر أو يساوي 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13962,7 +13962,7 @@ msgid "background"
msgstr "خلفية"
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "التنسيق الشرطي"
msgid "basis"
@@ -3353,7 +3353,7 @@ msgstr "Actualment renderitzat: %s"
msgid "Custom"
msgstr "Personalitzat"
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Format Condicional Personalitzat"
msgid "Custom Plugin"
@@ -9647,7 +9647,7 @@ msgstr "Mostrar Bombolles"
msgid "Show CREATE VIEW statement"
msgstr "Mostrar sentència CREATE VIEW"
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Mostrar barres de cel·la"
msgid "Show Dashboard"
@@ -13708,7 +13708,7 @@ msgstr "`row_offset` ha de ser major o igual a 0"
msgid "`width` must be greater or equal to 0"
msgstr "`width` ha de ser major o igual a 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "afegir colors a les barres de cel·la per +/-"
msgid "aggregate"
@@ -13753,7 +13753,7 @@ msgstr "auto"
msgid "background"
msgstr "fons"
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "formatat condicional bàsic"
msgid "basis"
@@ -3494,7 +3494,7 @@ msgstr "Derzeit dargestellt: %s"
msgid "Custom"
msgstr "Angepasst"
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Benutzerdefinierte bedingte Formatierung"
msgid "Custom Plugin"
@@ -10043,7 +10043,7 @@ msgstr "Blasen anzeigen"
msgid "Show CREATE VIEW statement"
msgstr "CREATE VIEW-Anweisung anzeigen"
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Zellenbalken anzeigen"
msgid "Show Dashboard"
@@ -14358,7 +14358,7 @@ msgstr "\"row_offset\" muss größer oder gleich 0 sein"
msgid "`width` must be greater or equal to 0"
msgstr "\"Breite\" muss größer oder gleich 0 sein"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "Farben zu den Zellenbalken für +/- hinzufügen"
msgid "aggregate"
@@ -14403,7 +14403,7 @@ msgstr "automatisch"
msgid "background"
msgstr "Hintergrund"
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "grundlegende bedingte Formatierung"
msgid "basis"
@@ -3138,7 +3138,7 @@ msgstr ""
msgid "Custom"
msgstr ""
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr ""
msgid "Custom Plugin"
@@ -9141,7 +9141,7 @@ msgstr ""
msgid "Show CREATE VIEW statement"
msgstr ""
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr ""
msgid "Show Dashboard"
@@ -12795,7 +12795,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr ""
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -12840,7 +12840,7 @@ msgstr ""
msgid "background"
msgstr ""
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr ""
msgid "basis"
@@ -3138,7 +3138,7 @@ msgstr "Actualmente renderizado: %s"
msgid "Custom"
msgstr "Personalizado"
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Formato condicional personalizado"
msgid "Custom Plugin"
@@ -9141,7 +9141,7 @@ msgstr "Mostrar burbujas"
msgid "Show CREATE VIEW statement"
msgstr "Mostrar instrucción CREAR VISTA"
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Mostrar barras de celda"
msgid "Show Dashboard"
@@ -12795,7 +12795,7 @@ msgstr "«row_offset» debe ser mayor o igual a 0"
msgid "`width` must be greater or equal to 0"
msgstr "«width» debe ser mayor o igual a 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "añade colores a las barras de celdas para +/-"
msgid "aggregate"
@@ -12840,7 +12840,7 @@ msgstr "automático"
msgid "background"
msgstr "fondo"
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "formato condicional básico"
msgid "basis"
@@ -3376,7 +3376,7 @@ msgstr "در حال حاضر رندر شده: %s"
msgid "Custom"
msgstr "سفارشی"
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "قالب‌بندی شرطی سفارشی"
msgid "Custom Plugin"
@@ -9784,7 +9784,7 @@ msgstr "نمایش حباب‌ها"
msgid "Show CREATE VIEW statement"
msgstr "بیان CREATE VIEW را نشان بدهید"
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "نمودار میله‌ای سلول‌ها را نمایش بدهید"
msgid "Show Dashboard"
@@ -13905,7 +13905,7 @@ msgstr "`row_offset` باید بزرگتر از یا برابر با ۰ باشد
msgid "`width` must be greater or equal to 0"
msgstr "`عرض` باید بزرگتر یا برابر با ۰ باشد."
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "رنگ‌ها را به نوارهای سلول برای + و - اضافه کنید"
msgid "aggregate"
@@ -13950,7 +13950,7 @@ msgstr "خودکار"
msgid "background"
msgstr "پس‌زمینه"
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "فرمت‌بندی شرطی پایه"
msgid "basis"
@@ -3681,7 +3681,7 @@ msgid "Custom"
msgstr "Personnalisé"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Formatage conditionnel"
msgid "Custom Plugin"
@@ -10819,7 +10819,7 @@ msgid "Show CREATE VIEW statement"
msgstr "Afficher l’énoncé CREATE VIEW"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Afficher les barres de cellules"
msgid "Show Dashboard"
@@ -15453,7 +15453,7 @@ msgstr "« row_offset » doit être plus grand ou égal à 0"
msgid "`width` must be greater or equal to 0"
msgstr "« width » doit être plus grand ou égal à 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "ajouter des couleurs aux barres de cellules pour +/-"
msgid "aggregate"
@@ -15496,7 +15496,7 @@ msgstr "auto"
msgid "background"
msgstr "contexte"
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "formatage conditionnel basique"
#, fuzzy
@@ -3374,7 +3374,7 @@ msgid "Custom"
msgstr ""
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Formato Datetime"
msgid "Custom Plugin"
@@ -9873,7 +9873,7 @@ msgid "Show CREATE VIEW statement"
msgstr ""
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Grafico a Proiettile"
msgid "Show Dashboard"
@@ -13738,7 +13738,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr ""
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13787,7 +13787,7 @@ msgid "background"
msgstr ""
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "Formato Datetime"
msgid "basis"
@@ -3209,7 +3209,7 @@ msgstr "現在レンダリング中: %s"
msgid "Custom"
msgstr "カスタム"
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "カスタム条件付き書式"
msgid "Custom Plugin"
@@ -9277,7 +9277,7 @@ msgstr "バブルを表示"
msgid "Show CREATE VIEW statement"
msgstr "CREATE VIEW文を表示"
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "セルバーを表示"
msgid "Show Dashboard"
@@ -13058,7 +13058,7 @@ msgstr "「row_offset」は 0 以上でなければなりません。"
msgid "`width` must be greater or equal to 0"
msgstr "「幅」は 0 以上でなければなりません。"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13103,7 +13103,7 @@ msgstr "自動"
msgid "background"
msgstr "背景"
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "基本的な条件付き書式"
msgid "basis"
@@ -3352,7 +3352,7 @@ msgid "Custom"
msgstr ""
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "주석"
msgid "Custom Plugin"
@@ -9773,7 +9773,7 @@ msgid "Show CREATE VIEW statement"
msgstr ""
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "차트 추가"
msgid "Show Dashboard"
@@ -13592,7 +13592,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr ""
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13641,7 +13641,7 @@ msgid "background"
msgstr ""
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "주석"
msgid "basis"
+4 -4
View File
@@ -3141,7 +3141,7 @@ msgstr ""
msgid "Custom"
msgstr ""
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr ""
msgid "Custom Plugin"
@@ -9128,7 +9128,7 @@ msgstr ""
msgid "Show CREATE VIEW statement"
msgstr ""
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr ""
msgid "Show Dashboard"
@@ -12780,7 +12780,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr ""
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -12825,7 +12825,7 @@ msgstr ""
msgid "background"
msgstr ""
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr ""
msgid "basis"
@@ -3442,7 +3442,7 @@ msgid "Custom"
msgstr "Aangepast"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Voorwaardelijke opmaak"
msgid "Custom Plugin"
@@ -9958,7 +9958,7 @@ msgid "Show CREATE VIEW statement"
msgstr "Toon CREATE VIEW statement"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Toon cel balken"
msgid "Show Dashboard"
@@ -14170,7 +14170,7 @@ msgstr "`rij_offset` moet groter zijn dan of gelijk aan 0"
msgid "`width` must be greater or equal to 0"
msgstr "`breedte` moet groter of gelijk zijn aan 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -14217,7 +14217,7 @@ msgid "background"
msgstr "achtergrond"
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "Voorwaardelijke opmaak"
msgid "basis"
@@ -3557,7 +3557,7 @@ msgid "Custom"
msgstr "Niestandardowy"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Niestandardowe formatowanie warunkowe"
msgid "Custom Plugin"
@@ -10392,7 +10392,7 @@ msgid "Show CREATE VIEW statement"
msgstr "Pokaż instrukcję CREATE VIEW"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Pokaż paski komórek"
msgid "Show Dashboard"
@@ -14786,7 +14786,7 @@ msgstr "`row_offset` musi być większe lub równe 0"
msgid "`width` must be greater or equal to 0"
msgstr "`width` musi być większe lub równe 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "dodaj kolory do pasków komórek dla +/-"
msgid "aggregate"
@@ -14835,7 +14835,7 @@ msgid "background"
msgstr "tło"
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "Podstawowe formatowanie warunkowe"
#, fuzzy
@@ -3416,7 +3416,7 @@ msgid "Custom"
msgstr ""
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Metadados adicionais"
msgid "Custom Plugin"
@@ -10009,7 +10009,7 @@ msgid "Show CREATE VIEW statement"
msgstr ""
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Gráfico de bala"
msgid "Show Dashboard"
@@ -13939,7 +13939,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr ""
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13987,7 +13987,7 @@ msgid "background"
msgstr ""
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "Metadados adicionais"
msgid "basis"
@@ -3502,7 +3502,7 @@ msgid "Custom"
msgstr "Personalizado"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Formatação condicional"
msgid "Custom Plugin"
@@ -10106,7 +10106,7 @@ msgid "Show CREATE VIEW statement"
msgstr "Mostrar instrução CREATE VIEW"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Mostrar barras de células"
msgid "Show Dashboard"
@@ -14348,7 +14348,7 @@ msgstr "`row_offset` deve ser maior ou igual a 0"
msgid "`width` must be greater or equal to 0"
msgstr "`largura` deve ser maior ou igual a 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "adicionar cores para as barras para +/-"
msgid "aggregate"
@@ -14396,7 +14396,7 @@ msgid "background"
msgstr "fundo"
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "formatação condicional básica"
msgid "basis"
@@ -3410,7 +3410,7 @@ msgstr "Сейчас отрисовано: %s"
msgid "Custom"
msgstr "Пользовательский"
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Условное форматирование"
msgid "Custom Plugin"
@@ -9909,7 +9909,7 @@ msgstr "Показать пузыри"
msgid "Show CREATE VIEW statement"
msgstr "Показать выражение CREATE VIEW"
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Наложить гистограммы на ячейки"
msgid "Show Dashboard"
@@ -14016,7 +14016,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr "Ширина должна быть не менее нуля"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "Окрасить столбцы для +/-"
msgid "aggregate"
@@ -14062,7 +14062,7 @@ msgstr "автоматически"
msgid "background"
msgstr ""
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "Простое условное форматирование"
#, fuzzy
@@ -3168,7 +3168,7 @@ msgstr ""
msgid "Custom"
msgstr ""
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr ""
msgid "Custom Plugin"
@@ -9249,7 +9249,7 @@ msgid "Show CREATE VIEW statement"
msgstr ""
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Importovať dashboard"
msgid "Show Dashboard"
@@ -12929,7 +12929,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr ""
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -12974,7 +12974,7 @@ msgstr ""
msgid "background"
msgstr ""
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr ""
msgid "basis"
@@ -3406,7 +3406,7 @@ msgstr "Trenutno izrisano: %s"
msgid "Custom"
msgstr "Prilagojen"
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Prilagojeno pogojno oblikovanje"
msgid "Custom Plugin"
@@ -9819,7 +9819,7 @@ msgstr "Prikaži mehurčke"
msgid "Show CREATE VIEW statement"
msgstr "Prikaži CREATE VIEW stavek"
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Prikaži grafe v celicah"
msgid "Show Dashboard"
@@ -13928,7 +13928,7 @@ msgstr "`row_offset` mora biti večja ali enaka 0"
msgid "`width` must be greater or equal to 0"
msgstr "`width` mora biti večja ali enaka 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr "dodajte barvo za graf v celici za +/-"
msgid "aggregate"
@@ -13973,7 +13973,7 @@ msgstr "samodejno"
msgid "background"
msgstr "ozadje"
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "osnovno pogojno oblikovanje"
msgid "basis"
@@ -3184,7 +3184,7 @@ msgid "Custom"
msgstr ""
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Ek bilgi"
msgid "Custom Plugin"
@@ -9284,7 +9284,7 @@ msgstr ""
msgid "Show CREATE VIEW statement"
msgstr ""
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr ""
msgid "Show Dashboard"
@@ -12972,7 +12972,7 @@ msgstr ""
msgid "`width` must be greater or equal to 0"
msgstr ""
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13019,7 +13019,7 @@ msgid "background"
msgstr ""
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "Ek bilgi"
msgid "basis"
@@ -3436,7 +3436,7 @@ msgid "Custom"
msgstr "Звичайний"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "Умовне форматування"
msgid "Custom Plugin"
@@ -9968,7 +9968,7 @@ msgid "Show CREATE VIEW statement"
msgstr "Показати заяву про створення перегляду"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "Показати стільникові смуги"
msgid "Show Dashboard"
@@ -14148,7 +14148,7 @@ msgstr "`row_offset` повинен бути більшим або рівним
msgid "`width` must be greater or equal to 0"
msgstr "`width` повинна бути більшою або рівною 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -14195,7 +14195,7 @@ msgid "background"
msgstr "фон"
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "Умовне форматування"
msgid "basis"
@@ -3393,7 +3393,7 @@ msgid "Custom"
msgstr "自定义"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "条件格式设置"
msgid "Custom Plugin"
@@ -9908,7 +9908,7 @@ msgid "Show CREATE VIEW statement"
msgstr "显示 CREATE VIEW 语句"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "显示单元格的柱"
msgid "Show Dashboard"
@@ -13820,7 +13820,7 @@ msgstr "`行偏移量` 必须大于或等于0"
msgid "`width` must be greater or equal to 0"
msgstr "`宽度` 必须大于或等于0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13870,7 +13870,7 @@ msgid "background"
msgstr "背景"
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "条件格式设置"
#, fuzzy
@@ -3396,7 +3396,7 @@ msgid "Custom"
msgstr "自定義"
#, fuzzy
msgid "Custom Conditional Formatting"
msgid "Custom conditional formatting"
msgstr "條件格式設定"
msgid "Custom Plugin"
@@ -9922,7 +9922,7 @@ msgid "Show CREATE VIEW statement"
msgstr "顯示 CREATE VIEW 語句"
#, fuzzy
msgid "Show Cell bars"
msgid "Show cell bars"
msgstr "顯示單元格的柱"
msgid "Show Dashboard"
@@ -13834,7 +13834,7 @@ msgstr "`行偏移量` 必須大於或等於 0"
msgid "`width` must be greater or equal to 0"
msgstr "`寬度` 必須大於或等於 0"
msgid "add colors to cell bars for +/-"
msgid "Add colors to cell bars for +/-"
msgstr ""
msgid "aggregate"
@@ -13884,7 +13884,7 @@ msgid "background"
msgstr "背景"
#, fuzzy
msgid "basic conditional formatting"
msgid "Basic conditional formatting"
msgstr "條件格式設定"
#, fuzzy