diff --git a/.github/workflows/e2e_tests.yml b/.github/workflows/e2e_tests.yml index af3c26d294..ee8351ffdb 100644 --- a/.github/workflows/e2e_tests.yml +++ b/.github/workflows/e2e_tests.yml @@ -32,7 +32,7 @@ concurrency: jobs: run-e2e: name: Install Datalens and Run E2E Tests - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: echo distinct ID ${{ github.event.inputs.distinct_id }} run: echo ${{ github.event.inputs.distinct_id }} @@ -159,7 +159,7 @@ jobs: echo "reports/${{ github.head_ref || github.ref_name }}/${{ github.run_id }}/${{ github.run_attempt }}" > ./tests/artifacts/report-link echo "${{ github.event.pull_request.number }}" > ./tests/artifacts/report-pr - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: always() with: name: playwright-report diff --git a/.github/workflows/i18n-check.yml b/.github/workflows/i18n-check.yml index 482945d6e3..0343cbb38c 100644 --- a/.github/workflows/i18n-check.yml +++ b/.github/workflows/i18n-check.yml @@ -25,7 +25,7 @@ concurrency: jobs: i18n_check: runs-on: ubuntu-latest - if: github.actor != 'WeblateGravity' && github.event.pull_request.draft == false + if: github.actor != 'datalens-weblate-robot' && github.event.pull_request.draft == false steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/publish_platform.yaml b/.github/workflows/publish_platform.yaml index 9394fc31a3..4af10320c0 100644 --- a/.github/workflows/publish_platform.yaml +++ b/.github/workflows/publish_platform.yaml @@ -82,8 +82,9 @@ jobs: run: | mkdir -p ./workflow_ref echo "${{ env.NEW_BRANCH }}" > ./workflow_ref/ref - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: workflow_ref path: ./workflow_ref/ - retention-days: 30 \ No newline at end of file + retention-days: 30 + overwrite: true \ No newline at end of file diff --git a/.github/workflows/publish_platform_hotfix.yaml b/.github/workflows/publish_platform_hotfix.yaml index 3eaefa1cf9..6dfb1f7522 100644 --- a/.github/workflows/publish_platform_hotfix.yaml +++ b/.github/workflows/publish_platform_hotfix.yaml @@ -62,8 +62,9 @@ jobs: run: | mkdir -p ./workflow_ref echo "${{ env.NEW_BRANCH }}" > ./workflow_ref/ref - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: workflow_ref path: ./workflow_ref/ - retention-days: 30 \ No newline at end of file + retention-days: 30 + overwrite: true \ No newline at end of file diff --git a/.github/workflows/statoscope_tests.yml b/.github/workflows/statoscope_tests.yml index 148c0a4f14..637d56d17d 100644 --- a/.github/workflows/statoscope_tests.yml +++ b/.github/workflows/statoscope_tests.yml @@ -41,3 +41,4 @@ jobs: name: statoscope-report path: ./report/statoscope/ retention-days: 1 + overwrite: true diff --git a/.github/workflows/statoscope_upload_main_stats.yml b/.github/workflows/statoscope_upload_main_stats.yml index 87df3b777c..7ea8d5ef1c 100644 --- a/.github/workflows/statoscope_upload_main_stats.yml +++ b/.github/workflows/statoscope_upload_main_stats.yml @@ -20,4 +20,5 @@ jobs: - uses: actions/upload-artifact@v4 with: name: main-stats - path: ./reference.json \ No newline at end of file + path: ./reference.json + overwrite: true \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a7310be17c..ca013e5bbd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,12 +16,12 @@ "@diplodoc/transform": "^4.20.0", "@gravity-ui/app-layout": "^2.1.0", "@gravity-ui/browserslist-config": "^4.3.0", - "@gravity-ui/chartkit": "^5.18.1", - "@gravity-ui/dashkit": "^8.20.1", - "@gravity-ui/date-utils": "^2.3.0", + "@gravity-ui/chartkit": "^5.19.0", + "@gravity-ui/dashkit": "^8.20.2", + "@gravity-ui/date-utils": "^2.5.6", "@gravity-ui/expresskit": "^2.1.0", "@gravity-ui/gateway": "^3.1.1", - "@gravity-ui/i18n": "^1.6.0", + "@gravity-ui/i18n": "^1.7.0", "@gravity-ui/nodekit": "^1.7.0", "@node-rs/crc32": "^1.7.2", "ajv": "^8.12.0", @@ -65,20 +65,20 @@ "workerpool": "^9.1.1" }, "devDependencies": { - "@datalens-tech/ui-sandbox-modules": "^0.32.0", - "@gravity-ui/app-builder": "^0.13.0", - "@gravity-ui/components": "^3.12.3", - "@gravity-ui/date-components": "^2.10.2", + "@datalens-tech/ui-sandbox-modules": "^0.33.0", + "@gravity-ui/app-builder": "^0.13.1", + "@gravity-ui/components": "^3.12.5", + "@gravity-ui/date-components": "^2.11.0", "@gravity-ui/eslint-config": "^3.2.0", "@gravity-ui/icons": "^2.11.0", - "@gravity-ui/navigation": "^2.27.0", + "@gravity-ui/navigation": "^2.29.0", "@gravity-ui/prettier-config": "^1.1.0", - "@gravity-ui/react-data-table": "^2.0.1", - "@gravity-ui/sdk": "^1.2.1", + "@gravity-ui/react-data-table": "^2.1.1", + "@gravity-ui/sdk": "^1.5.1", "@gravity-ui/stylelint-config": "^4.0.1", "@gravity-ui/tsconfig": "^1.0.0", "@gravity-ui/ui-logger": "^1.1.0", - "@gravity-ui/uikit": "^6.31.0", + "@gravity-ui/uikit": "^6.37.0", "@jest/types": "^29.6.3", "@microsoft/fetch-event-source": "^2.0.1", "@playwright/test": "^1.48.2", @@ -4204,9 +4204,9 @@ } }, "node_modules/@datalens-tech/ui-sandbox-modules": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@datalens-tech/ui-sandbox-modules/-/ui-sandbox-modules-0.32.0.tgz", - "integrity": "sha512-syrgdOOFkJsMKLjjJSYqEYtZ9nrn5K8iJaa7NcWA1U5QAPDIosNkCAfKckc5iB4B28LYudH5CXxhNszGzXHHTw==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@datalens-tech/ui-sandbox-modules/-/ui-sandbox-modules-0.33.0.tgz", + "integrity": "sha512-gxj35QhnwGY//rcAm4XrackbTcQu5Qqf2YD4FRH1zkLX5jgc0018biTZhfepR9jwc0zQ7DF5sIR0CsGiYVuphQ==", "dev": true }, "node_modules/@datalens-tech/xlsx": { @@ -4459,10 +4459,11 @@ } }, "node_modules/@gravity-ui/app-builder": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/app-builder/-/app-builder-0.13.0.tgz", - "integrity": "sha512-eERuiX4O2trKxhLMZ3efiF7KVsmVj+EzeWq7u34bM8gkPm11DjX8mbHDb4qcH0cCwD9lu2bqQsPYkF806DFIMw==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@gravity-ui/app-builder/-/app-builder-0.13.1.tgz", + "integrity": "sha512-9pYigJb1EECIwgWYvjmIT7eT/hObALBFF4WL3ZKHtmIyJhyBpmaetGrZ90LXdgjKAfhqp1FKOPByhtHKHzvdGQ==", "dev": true, + "license": "MIT", "dependencies": { "@aws-sdk/client-s3": "^3.353.0", "@babel/core": "^7.25.0", @@ -4982,11 +4983,10 @@ } }, "node_modules/@gravity-ui/axios-wrapper": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@gravity-ui%2faxios-wrapper/-/axios-wrapper-1.4.1.tgz", - "integrity": "sha512-SbWoFtobG0WbodgWR9mTaUhfjWIEjHvx9NJpMFYV4cqEQug0Mr9yTKYOTUhEPRF27z5NxmbMZR+Dj99+8BNAUg==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@gravity-ui/axios-wrapper/-/axios-wrapper-1.5.1.tgz", + "integrity": "sha512-J9yjoKqzKnwovJfGdtq8vQXEtB0rUXOBpMLhkTurfq88aKuVHC7cI5t8xkLBDgaF//24Lt2VUV2WpGJ9YZUuhg==", "dev": true, - "license": "MIT", "peerDependencies": { "axios": "^1.3.4", "lodash": "^4.17.11" @@ -4998,12 +4998,12 @@ "integrity": "sha512-GhZemc/gPq/Kf4OYyXZpeZLgL69pI8oidWhdOKUHOWSYQyKviDDZDxrMzjZzvCWOxrpQVFtmqiCBMW8nqJivEQ==" }, "node_modules/@gravity-ui/chartkit": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/@gravity-ui/chartkit/-/chartkit-5.18.1.tgz", - "integrity": "sha512-XxDroLbp/ISQE102hjUQ2LIb/8LMtZ348kaVRd+FivsPwXS5oKXTPAyKzXcpTpqaNAupy824Nsw70wOhI4fkwQ==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/chartkit/-/chartkit-5.19.0.tgz", + "integrity": "sha512-CtjnX+F47+i0RpgL5h6sXzQvyd/BQ27yto/7kyikj1LUEbJZELGyebyZfbzhl6isFXPNWprpo91i5kt5M2oFnA==", "dependencies": { "@bem-react/classname": "^1.6.0", - "@gravity-ui/charts": "^0.4.1", + "@gravity-ui/charts": "^0.5.0", "@gravity-ui/date-utils": "^2.1.0", "@gravity-ui/i18n": "^1.0.0", "@gravity-ui/yagr": "^4.3.4", @@ -5017,9 +5017,9 @@ } }, "node_modules/@gravity-ui/charts": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@gravity-ui/charts/-/charts-0.4.1.tgz", - "integrity": "sha512-/coBYT+abt0S4uYAGWiTFe6qEROpVamx+ZxQqymfpRzxLrF4SoMTOTIJeGCq9atAZLHhTBhuBIMYTWDxXdI2Zg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/charts/-/charts-0.5.0.tgz", + "integrity": "sha512-WSoT1MZ+eSVnOk5nVS82K+Qc0UflJmAL41UhRu1ErxEecVevDHd5MiTeDP6nV9qCi2OBBalexy8xeVRdlX8Rrg==", "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/date-utils": "^2.5.4", @@ -5035,9 +5035,9 @@ } }, "node_modules/@gravity-ui/components": { - "version": "3.12.3", - "resolved": "https://registry.npmjs.org/@gravity-ui/components/-/components-3.12.3.tgz", - "integrity": "sha512-eWvZtWtt8tDnLYo9eU8zTEPfC1O3FLSnmnv82SkybYIBH00R9CzQNixKTCmOR91ULTxvl5G1QsFyaLAYznCcpQ==", + "version": "3.12.5", + "resolved": "https://registry.npmjs.org/@gravity-ui/components/-/components-3.12.5.tgz", + "integrity": "sha512-NNL11YF1BC4heIN9BOGv4ffO1U9HeP841JSQZFd0mC4OzgaUI53bLVSUzXIH8NWzPeE8/iC4YoXohIOjZnJnIQ==", "dev": true, "dependencies": { "@bem-react/classname": "^1.6.0", @@ -5055,9 +5055,9 @@ } }, "node_modules/@gravity-ui/dashkit": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@gravity-ui/dashkit/-/dashkit-8.20.1.tgz", - "integrity": "sha512-+cPJHNCpc5OPH23fxJ0UF9Oh9LLigiSW5AvYyB8ZMQQjNrDYGE+wYbWMn1CmqnrC+AArO8WUcwCBa4uUEhzaPw==", + "version": "8.20.2", + "resolved": "https://registry.npmjs.org/@gravity-ui/dashkit/-/dashkit-8.20.2.tgz", + "integrity": "sha512-LfmL4Qc9WApK1U5Q69LNIwyxZ1NJcA3Bfk2L6z2b0xF1o7IyUtHVugN/CDgz6LDRri7OGQBuam4RzoMOgPR8qg==", "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/icons": "^2.8.1", @@ -5073,9 +5073,9 @@ } }, "node_modules/@gravity-ui/date-components": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-components/-/date-components-2.10.2.tgz", - "integrity": "sha512-QMjFdoB3b7GwerytmqxA/pXCokujNTD6/yD+h4ER+jN/aUSTmVDMkYyiPQJ507SJ3U0qW9erVu4kpBZ0QOt/gg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-components/-/date-components-2.11.0.tgz", + "integrity": "sha512-raaoXQ5Uk256difnuQ6Ga4T2/IleZoF2+vE6Sl/HkmYYSNo74YoBhoY1Lo9VxcdZsqTw7uawKaRMqEBzCb3MVQ==", "dev": true, "dependencies": { "@bem-react/classname": "^1.6.0", @@ -5090,9 +5090,9 @@ } }, "node_modules/@gravity-ui/date-utils": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.5.4.tgz", - "integrity": "sha512-LoQGG4h2bqLf6Np4G57H+klhsZSWlLG7DWr2NcolIsZpIkrmdeUASUF0z0WvOSJxQecjRhg2ir7prJUcZ04uQw==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.5.6.tgz", + "integrity": "sha512-EjaN5b8jvnBlfU/db5QUHj6ooPz/uSRqvFYiPH/ydkCTnhusZhUpTk+xn8hnA7PPLbj3hMnJReF9fWxsfM6Y5w==", "dependencies": { "dayjs": "1.11.10", "lodash": "^4.17.0" @@ -5132,7 +5132,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@gravity-ui/expresskit/-/expresskit-2.1.0.tgz", "integrity": "sha512-HDOC/edMtzjtOEL8EpFaa3w991NblBryhSB9yW9PAwB5FMr7WDa8/LHeorfSOTi+4wtzPQpM23bIT4MlmhisUQ==", - "license": "MIT", "dependencies": { "accept-language-parser": "^1.5.0", "body-parser": "^1.20.1", @@ -5175,9 +5174,9 @@ } }, "node_modules/@gravity-ui/i18n": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/i18n/-/i18n-1.6.0.tgz", - "integrity": "sha512-ftMLGZy7migLEtPkZa8jM6onipIeEOnEg9976RRpg3f39H+Q2bYYAGMjU+NJpWQ90ZDp6ztYLt5WAMEg248tEg==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/i18n/-/i18n-1.7.0.tgz", + "integrity": "sha512-jZotOX73lMVARsNZ5L8rquDhyCIcHnX7GwT32m6vrnqy6iKBfBdOuAnAalUbnoVJoasfvYiSyX3kwusetyZgfQ==" }, "node_modules/@gravity-ui/icons": { "version": "2.11.0", @@ -5193,9 +5192,9 @@ } }, "node_modules/@gravity-ui/navigation": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/navigation/-/navigation-2.27.0.tgz", - "integrity": "sha512-PzG1hzcHGkLkdVpD02YMOxShfH/uMzaOLEThGLUYh6Ktv3iM3dv1vl8BU+KAf8jYU/3KJNb2ucjM3WcNhfOcRw==", + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/navigation/-/navigation-2.29.0.tgz", + "integrity": "sha512-aQ9BYrnEWxMkCRJKpDxydSm9CKwo7NM2bZj1e3vRkSb/Yunq99rejxerA4vcGsgrI8s5y/+c1nerad5bUdnurA==", "dev": true, "dependencies": { "react-transition-group": "^4.4.1", @@ -5248,9 +5247,9 @@ } }, "node_modules/@gravity-ui/react-data-table": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@gravity-ui/react-data-table/-/react-data-table-2.0.1.tgz", - "integrity": "sha512-b926wU0jHEJyLS28VnYLD88IICYqUI6ys1YEnM/+vIUcyJ/9fUP56xQFCrlLZnxbqww6TIXEQ9RC3GJ5qJwdaA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@gravity-ui/react-data-table/-/react-data-table-2.1.1.tgz", + "integrity": "sha512-7h5Idn1hRrdjVr46xDfJ57I5Zu9n4biV8ytuYCKBoj2LpuH4t93VHLGy+E1CTx87gjoDLPCVI6FEGAI/iyQJ3Q==", "dev": true, "dependencies": { "@bem-react/classname": ">=1.6.0", @@ -5262,12 +5261,12 @@ } }, "node_modules/@gravity-ui/sdk": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@gravity-ui/sdk/-/sdk-1.2.1.tgz", - "integrity": "sha512-xbBqKdi9/5LpDdrNklAZz1dBryLRxkCf+BlEuMnIZHBhcLruZbD9HPPia3cnTLx1T2MYULBxGeMpwC6s/raZdw==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@gravity-ui/sdk/-/sdk-1.5.1.tgz", + "integrity": "sha512-wp3cYx+T7Z4Ku65M0dUwloJkNDtu2HAFvnbClyztSj9oTYQnWTK7vxCW4NhNghiuBvoC+en92EL/G8zcvlmx6A==", "dev": true, "dependencies": { - "@gravity-ui/axios-wrapper": "^1.4.1", + "@gravity-ui/axios-wrapper": "^1.5.1", "axios": "^1.4.0", "axios-retry": "^3.5.0", "lodash": "^4.17.21" @@ -5309,9 +5308,9 @@ "license": "MIT" }, "node_modules/@gravity-ui/uikit": { - "version": "6.31.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/uikit/-/uikit-6.31.0.tgz", - "integrity": "sha512-iNuCZPMZzPMChhB0HUuEQBF56bSWBF31IkHF25o8O6qGStX9TRv/GSE37ZfDE1YLbSu149vuhYG1+B5LbTyQOA==", + "version": "6.37.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/uikit/-/uikit-6.37.0.tgz", + "integrity": "sha512-XwtD0+HFYaJv5CiRceuHATD97hZJxigF/8swwYlJx7SZauiR5GMOqB/3+yY/nYcJkWte5H/cC1JnVp3nHv5ELw==", "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/i18n": "^1.6.0", @@ -5331,8 +5330,8 @@ "tslib": "^2.6.2" }, "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@gravity-ui/yagr": { @@ -5347,25 +5346,25 @@ } }, "node_modules/@grpc/grpc-js": { - "version": "1.9.11", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.11.tgz", - "integrity": "sha512-QDhMfbTROOXUhLHMroow8f3EHiCKUOh6UwxMP5S3EuXMnWMNSVIhatGZRwkpg9OUTYdZPsDUVH3cOAkWhGFUJw==", + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.4.tgz", + "integrity": "sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==", "dependencies": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" }, "engines": { - "node": "^8.13.0 || >=10.10.0" + "node": ">=12.10.0" } }, "node_modules/@grpc/proto-loader": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", - "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", - "protobufjs": "^7.2.4", + "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { @@ -7211,6 +7210,15 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/@jsonjoy.com/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", @@ -7318,126 +7326,6 @@ "@node-rs/crc32-win32-x64-msvc": "1.7.2" } }, - "node_modules/@node-rs/crc32-android-arm-eabi": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm-eabi/-/crc32-android-arm-eabi-1.7.2.tgz", - "integrity": "sha512-6IoXQTHt9U/1Ejz/MPbAk3mtcAGcS1WUvg2YfEtezLCmzbDpQO3OTA9fZpu3z2AhBuLHiKMKDVcfrWybRiWBJw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-android-arm64": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm64/-/crc32-android-arm64-1.7.2.tgz", - "integrity": "sha512-SMEd6cN+034LTv9kFmCGMZjBNTf39xXIcgqq05JM9A55ywUvXdoXnFOttrQ9x/iZgqANNU6Ms5uZCAJbNA2dZA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-darwin-arm64": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-arm64/-/crc32-darwin-arm64-1.7.2.tgz", - "integrity": "sha512-sPJisK5pyZ+iBs9KuGsvu0Z+Qshw4GvOgaHjPktQ+suz0p00Yts3zl5D6PpGaaW4EAKTo8zCUIlVEArV0vglvw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-darwin-x64": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-x64/-/crc32-darwin-x64-1.7.2.tgz", - "integrity": "sha512-+/lgHYJaZdXU+7fhGYTnXvGkeSqZE3UwPyKAUO5YSL0nIpFHMybZMnvqjcoxrfx0QfMFOwVEbd7vfVh+1GpwhA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-freebsd-x64": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-freebsd-x64/-/crc32-freebsd-x64-1.7.2.tgz", - "integrity": "sha512-OgkxnkiGdztcBilm7m31Sb6zx89ghK4WpZz9WVVU86PIHQH0sfrZEebdomw6R7mMnQuqbnRwjTS5r1nchVMPzQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm-gnueabihf": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm-gnueabihf/-/crc32-linux-arm-gnueabihf-1.7.2.tgz", - "integrity": "sha512-hTY83MQML8WrMnD3dmzjrcCn0Sqgw0w2wRc1Ji2dCaE0fDqra47W5KBQXx4hKZYFwNr5KreTqdvD3Ejf/mKzEA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm64-gnu": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-gnu/-/crc32-linux-arm64-gnu-1.7.2.tgz", - "integrity": "sha512-4p6DZ9YT+CBSi+72OclzI5hBin15brqrbLLHFePPl4AhAazg6+ReTv3C4DnyJqyL0ZHZamiA9zDtOlvHo0nk0Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm64-musl": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-musl/-/crc32-linux-arm64-musl-1.7.2.tgz", - "integrity": "sha512-/shZkkNyDyDjaxU5rYFY4aoajLjBqdfKQYZCcA6XS27FiGzHQ3petgP0I5Zjm+Jf75G7gLT8NQXiQWIzkgo2xw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@node-rs/crc32-linux-x64-gnu": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-gnu/-/crc32-linux-x64-gnu-1.7.2.tgz", @@ -7468,51 +7356,6 @@ "node": ">= 10" } }, - "node_modules/@node-rs/crc32-win32-arm64-msvc": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-arm64-msvc/-/crc32-win32-arm64-msvc-1.7.2.tgz", - "integrity": "sha512-vj+HWzwy86wNBY+1vW+QPje/MrJppufGCYIisFwvghBzk6WtClNGEjbQqotieIxDNohcmHREQEeg8wY8PMCvew==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-win32-ia32-msvc": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-ia32-msvc/-/crc32-win32-ia32-msvc-1.7.2.tgz", - "integrity": "sha512-YQQtPkHvqbMEJmaMzEH3diYHk0q9zWb+Tkzij9d4OZZzpt4HM6j8FuiIB37BJ0CQmgMiDZEBYsX3KOfYxxO0VA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-win32-x64-msvc": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-x64-msvc/-/crc32-win32-x64-msvc-1.7.2.tgz", - "integrity": "sha512-DnluAFM6X8qsYVI1VaFQtI6ukigIQ2P4eVcEuNQ3d1lF5fs0RYAKY7Ajqrdk298TSGZ2joMiqfJksTHBsQoxtA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7587,146 +7430,6 @@ "@parcel/watcher-win32-x64": "2.4.1" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", - "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", - "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", - "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", - "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", - "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/watcher-linux-x64-glibc": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", @@ -7767,66 +7470,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", - "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", - "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", - "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -16487,9 +16130,9 @@ } }, "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -16511,7 +16154,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -16526,6 +16169,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express-csp-header": { @@ -16558,9 +16205,10 @@ } }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" }, "node_modules/express/node_modules/statuses": { "version": "2.0.1", @@ -17028,8 +16676,10 @@ "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", - "license": "MIT", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -21884,116 +21534,6 @@ "lightningcss-win32-x64-msvc": "1.21.5" } }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.21.5.tgz", - "integrity": "sha512-z05hyLX85WY0UfhkFUOrWEFqD69lpVAmgl3aDzMKlIZJGygbhbegqb4PV8qfUrKKNBauut/qVNPKZglhTaDDxA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.21.5.tgz", - "integrity": "sha512-MSJhmej/U9MrdPxDk7+FWhO8+UqVoZUHG4VvKT5RQ4RJtqtANTiWiI97LvoVNMtdMnHaKs1Pkji6wHUFxjJsHQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.21.5.tgz", - "integrity": "sha512-xN6+5/JsMrbZHL1lPl+MiNJ3Xza12ueBKPepiyDCFQzlhFRTj7D0LG+cfNTzPBTO8KcYQynLpl1iBB8LGp3Xtw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.21.5.tgz", - "integrity": "sha512-KfzFNhC4XTbmG3ma/xcTs/IhCwieW89XALIusKmnV0N618ZDXEB0XjWOYQRCXeK9mfqPdbTBpurEHV/XZtkniQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.21.5.tgz", - "integrity": "sha512-bc0GytQO5Mn9QM6szaZ+31fQHNdidgpM1sSCwzPItz8hg3wOvKl8039rU0veMJV3ZgC9z0ypNRceLrSHeRHmXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lightningcss-linux-x64-gnu": { "version": "1.21.5", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.21.5.tgz", @@ -22038,28 +21578,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.21.5.tgz", - "integrity": "sha512-A8cSi8lUpBeVmoF+DqqW7cd0FemDbCuKr490IXdjyeI+KL8adpSKUs8tcqO0OXPh1EoDqK7JNkD/dELmd4Iz5g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -23376,9 +22894,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -24441,6 +23959,20 @@ "node": ">=18" } }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/pngjs": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", diff --git a/package.json b/package.json index 1bbbf0a0ff..8e6a276bb1 100644 --- a/package.json +++ b/package.json @@ -60,12 +60,12 @@ "@diplodoc/transform": "^4.20.0", "@gravity-ui/app-layout": "^2.1.0", "@gravity-ui/browserslist-config": "^4.3.0", - "@gravity-ui/chartkit": "^5.18.1", - "@gravity-ui/dashkit": "^8.20.1", - "@gravity-ui/date-utils": "^2.3.0", + "@gravity-ui/chartkit": "^5.19.0", + "@gravity-ui/dashkit": "^8.20.2", + "@gravity-ui/date-utils": "^2.5.6", "@gravity-ui/expresskit": "^2.1.0", "@gravity-ui/gateway": "^3.1.1", - "@gravity-ui/i18n": "^1.6.0", + "@gravity-ui/i18n": "^1.7.0", "@gravity-ui/nodekit": "^1.7.0", "@node-rs/crc32": "^1.7.2", "ajv": "^8.12.0", @@ -109,22 +109,20 @@ "workerpool": "^9.1.1" }, "devDependencies": { - "@datalens-tech/ui-sandbox-modules": "^0.32.0", - "@tanstack/react-table": "^8.12.0", - "@tanstack/react-virtual": "^3.8.1", - "@gravity-ui/app-builder": "^0.13.0", - "@gravity-ui/components": "^3.12.3", - "@gravity-ui/date-components": "^2.10.2", + "@datalens-tech/ui-sandbox-modules": "^0.33.0", + "@gravity-ui/app-builder": "^0.13.1", + "@gravity-ui/components": "^3.12.5", + "@gravity-ui/date-components": "^2.11.0", "@gravity-ui/eslint-config": "^3.2.0", "@gravity-ui/icons": "^2.11.0", - "@gravity-ui/navigation": "^2.27.0", + "@gravity-ui/navigation": "^2.29.0", "@gravity-ui/prettier-config": "^1.1.0", - "@gravity-ui/react-data-table": "^2.0.1", - "@gravity-ui/sdk": "^1.2.1", + "@gravity-ui/react-data-table": "^2.1.1", + "@gravity-ui/sdk": "^1.5.1", "@gravity-ui/stylelint-config": "^4.0.1", "@gravity-ui/tsconfig": "^1.0.0", "@gravity-ui/ui-logger": "^1.1.0", - "@gravity-ui/uikit": "^6.31.0", + "@gravity-ui/uikit": "^6.37.0", "@jest/types": "^29.6.3", "@microsoft/fetch-event-source": "^2.0.1", "@playwright/test": "^1.48.2", @@ -133,6 +131,8 @@ "@statoscope/webpack-ui": "^5.28.2", "@stripe/react-stripe-js": "^1.8.1", "@stripe/stripe-js": "^1.30.0", + "@tanstack/react-table": "^8.12.0", + "@tanstack/react-virtual": "^3.8.1", "@testing-library/jest-dom": "^5.16.2", "@testing-library/react": "^12.1.4", "@types/cookie-session": "^2.0.49", diff --git a/scripts/e2e/us-dump.sh b/scripts/e2e/us-dump.sh index 5d0e68ceba..b5a5cb22ce 100644 --- a/scripts/e2e/us-dump.sh +++ b/scripts/e2e/us-dump.sh @@ -40,8 +40,9 @@ if [ $CONNECTION_CHECK_RESULT_STATUS_CODE -ne 0 ]; then exit 1 fi -DUMP_CMD="pg_dump --dbname=$US_CONNECTION --column-inserts -a -t workbooks -t entries -t revisions -t links" -docker exec -it $US_CONTAINER_ID /bin/sh -c "$DUMP_CMD" | grep -Ev "^(--|SET|SELECT pg_catalog.set_config)" >$DUMP_TMP +DUMP_CMD="pg_dump --dbname=$US_CONNECTION --disable-triggers --column-inserts -a -t collections -t workbooks -t entries -t revisions -t links" +docker exec -it $US_CONTAINER_ID /bin/sh -c "$DUMP_CMD" | +tee >(grep -Ev "^(--|SET|SELECT pg_catalog.set_config|pg_dump:)" >$DUMP_TMP) | grep "pg_dump:" DUMP_RESULT_STATUS_CODE=$? if [ $DUMP_RESULT_STATUS_CODE -ne 0 ]; then diff --git a/src/@types/nodekit.d.ts b/src/@types/nodekit.d.ts index ddd6c0383e..8976ad596b 100644 --- a/src/@types/nodekit.d.ts +++ b/src/@types/nodekit.d.ts @@ -4,7 +4,7 @@ import type {Request, Response} from '@gravity-ui/expresskit'; import type {RedisConfig} from '../server/components/cache-client'; import type {ChartTemplates} from '../server/components/charts-engine/components/chart-generator'; import type {AppEnvironment} from '../shared'; -import type {FeaturesConfig} from '../src/components/features/types'; +import type {FeatureConfig} from '../shared/types'; export interface SharedAppConfig { endpoints: Endpoints; @@ -91,7 +91,7 @@ export interface SharedAppConfig { } export interface SharedAppDynamicConfig { - features?: FeaturesConfig; + features?: FeatureConfig; } export interface SharedAppContextParams { diff --git a/src/i18n-keysets/dash.dialogs-common.edit/en.json b/src/i18n-keysets/dash.dialogs-common.edit/en.json index db0fcba7f5..7e84ebf635 100644 --- a/src/i18n-keysets/dash.dialogs-common.edit/en.json +++ b/src/i18n-keysets/dash.dialogs-common.edit/en.json @@ -1,3 +1,4 @@ { - "button_back": "Back" + "button_back": "Back", + "title_widget-settings": "Widget settings" } diff --git a/src/i18n-keysets/dash.dialogs-common.edit/ru.json b/src/i18n-keysets/dash.dialogs-common.edit/ru.json index e87a861332..824f2c624b 100644 --- a/src/i18n-keysets/dash.dialogs-common.edit/ru.json +++ b/src/i18n-keysets/dash.dialogs-common.edit/ru.json @@ -1,3 +1,4 @@ { - "button_back": "Назад" + "button_back": "Назад", + "title_widget-settings": "Настройки виджета" } diff --git a/src/i18n-keysets/dash.palette-background/en.json b/src/i18n-keysets/dash.palette-background/en.json index 14b9d08242..57037ba4ce 100644 --- a/src/i18n-keysets/dash.palette-background/en.json +++ b/src/i18n-keysets/dash.palette-background/en.json @@ -1,4 +1,5 @@ { + "tooltip_click-to-select": "Select value", "value_default": "Basic", "value_transparent": "Transparent" } diff --git a/src/i18n-keysets/dash.palette-background/ru.json b/src/i18n-keysets/dash.palette-background/ru.json index 381704bd17..36c038369a 100644 --- a/src/i18n-keysets/dash.palette-background/ru.json +++ b/src/i18n-keysets/dash.palette-background/ru.json @@ -1,4 +1,5 @@ { + "tooltip_click-to-select": "Выберите значение", "value_default": "Базовый", "value_transparent": "Прозрачный" } diff --git a/src/i18n-keysets/dash.title-dialog.edit/en.json b/src/i18n-keysets/dash.title-dialog.edit/en.json index 1ec4f0ad40..3e5faa31de 100644 --- a/src/i18n-keysets/dash.title-dialog.edit/en.json +++ b/src/i18n-keysets/dash.title-dialog.edit/en.json @@ -4,6 +4,7 @@ "button_save": "Save", "context_fill-title": "Enter title", "field_show-in-toc": "Display in contents", + "label_size": "Size", "label_title": "Title", "toast_required-field": "The field cannot be empty", "value_default": "Title" diff --git a/src/i18n-keysets/dash.title-dialog.edit/ru.json b/src/i18n-keysets/dash.title-dialog.edit/ru.json index 871e1fe5f6..9e78db8459 100644 --- a/src/i18n-keysets/dash.title-dialog.edit/ru.json +++ b/src/i18n-keysets/dash.title-dialog.edit/ru.json @@ -4,6 +4,7 @@ "button_save": "Сохранить", "context_fill-title": "Введите заголовок", "field_show-in-toc": "Отображать в оглавлении", + "label_size": "Размер", "label_title": "Заголовок", "toast_required-field": "Поле должно быть заполнено", "value_default": "Заголовок" diff --git a/src/i18n-keysets/wizard/en.json b/src/i18n-keysets/wizard/en.json index 9b3897b5e9..95dc2cc31f 100644 --- a/src/i18n-keysets/wizard/en.json +++ b/src/i18n-keysets/wizard/en.json @@ -169,6 +169,7 @@ "label_holidays": "Holidays on the chart", "label_horizontal": "Horizontal", "label_hour": "Hour", + "label_html": "HTML", "label_ignore": "Ignore", "label_integer": "Integer", "label_invalid-name": "The chart with the specified name already exists", @@ -193,8 +194,9 @@ "label_logarithmic": "Logarithmic", "label_manual": "Manual", "label_markdown": "Markdown", - "label_markdown-tooltip": "The field value will be formatted according to the Markdown language", "label_markup": "Markup", + "label_markup-type": "Markup type", + "label_markup-type-tooltip": "The field value will be formatted according to the selected markup language", "label_max": "Maximum", "label_message-link-copied": "Link copied", "label_min": "Minimum", diff --git a/src/i18n-keysets/wizard/ru.json b/src/i18n-keysets/wizard/ru.json index 10b1431510..26c36dc16d 100644 --- a/src/i18n-keysets/wizard/ru.json +++ b/src/i18n-keysets/wizard/ru.json @@ -169,6 +169,7 @@ "label_holidays": "Выходные на графике", "label_horizontal": "Горизонтальные", "label_hour": "Час", + "label_html": "HTML", "label_ignore": "Не отображать", "label_integer": "Целое число", "label_invalid-name": "Чарт с таким именем уже сущестует", @@ -193,8 +194,9 @@ "label_logarithmic": "Логарифмическая", "label_manual": "Вручную", "label_markdown": "Markdown", - "label_markdown-tooltip": "Значение поля будет отформатировано в соответствии с разметкой Markdown", "label_markup": "Разметка", + "label_markup-type": "Разметка", + "label_markup-type-tooltip": "Значение поля будет отформатировано в соответствии с выбранным языком разметки", "label_max": "Максимум", "label_message-link-copied": "Ссылка скопирована", "label_min": "Минимум", diff --git a/src/server/components/charts-engine/components/processor/control-builder.ts b/src/server/components/charts-engine/components/processor/control-builder.ts index 7bdbd5b3c0..d5731191ca 100644 --- a/src/server/components/charts-engine/components/processor/control-builder.ts +++ b/src/server/components/charts-engine/components/processor/control-builder.ts @@ -41,6 +41,7 @@ export const getControlBuilder = async (args: ChartBuilderArgs): Promise { if (typeof config.data.shared === 'string') { shared = JSON.parse(config.data.shared); diff --git a/src/server/components/charts-engine/components/processor/index.ts b/src/server/components/charts-engine/components/processor/index.ts index 362cf51f98..802a0d1a13 100644 --- a/src/server/components/charts-engine/components/processor/index.ts +++ b/src/server/components/charts-engine/components/processor/index.ts @@ -48,7 +48,7 @@ import type { UiTabExports, UserConfig, } from './types'; -import {getMessageFromUnknownError, isChartWithJSAndHtmlAllowed} from './utils'; +import {cleanJSONFn, getMessageFromUnknownError, isChartWithJSAndHtmlAllowed} from './utils'; const { CONFIG_LOADING_ERROR, @@ -794,13 +794,13 @@ export class Processor { if (!uiOnly && jsTabResults) { result.data = processedData; - const resultConfig = merge( + let resultConfig = merge( {}, userConfig, jsTabResults.runtimeMetadata.userConfigOverride, ); - const resultLibraryConfig = mergeWith( + let resultLibraryConfig = mergeWith( {}, libraryConfig, jsTabResults.runtimeMetadata.libraryConfigOverride, @@ -823,13 +823,17 @@ export class Processor { if (!isChartWithJSAndHtmlAllowed({createdAt: config.createdAt})) { resultConfig.enableJsAndHtml = false; } - const enableJsAndHtml = get(resultConfig, 'enableJsAndHtml', true); - const stringify = + const enableJsAndHtml = get(resultConfig, 'enableJsAndHtml', false); + const disableJSONFn = isEnabledServerFeature(ctx, Feature.NoJsonFn) || req.cookies[DISABLE_JSONFN_SWITCH_MODE_COOKIE_NAME] === DISABLE || - enableJsAndHtml === false - ? JSON.stringify - : JSONfn.stringify; + enableJsAndHtml === false; + const stringify = disableJSONFn ? JSON.stringify : JSONfn.stringify; + + if (builder.type === 'CHART_EDITOR' && disableJSONFn) { + resultConfig = cleanJSONFn(resultConfig); + resultLibraryConfig = cleanJSONFn(resultLibraryConfig); + } result.config = stringify(resultConfig); result.publicAuthor = config.publicAuthor; diff --git a/src/server/components/charts-engine/components/processor/types.ts b/src/server/components/charts-engine/components/processor/types.ts index 028c996ba6..a7c36e22bd 100644 --- a/src/server/components/charts-engine/components/processor/types.ts +++ b/src/server/components/charts-engine/components/processor/types.ts @@ -143,6 +143,7 @@ export type ChartBuilderResult = { }; export type ChartBuilder = { + type?: 'CHART_EDITOR' | 'WIZARD' | 'CONTROL'; buildShared: () => Promise; buildModules: (args: { subrequestHeaders: Record; diff --git a/src/server/components/charts-engine/components/processor/utils.ts b/src/server/components/charts-engine/components/processor/utils.ts index a01373e90e..50401fc51b 100644 --- a/src/server/components/charts-engine/components/processor/utils.ts +++ b/src/server/components/charts-engine/components/processor/utils.ts @@ -37,3 +37,29 @@ export function isChartWithJSAndHtmlAllowed(config: {createdAt: string}) { return new Date(config.createdAt).valueOf() < ESCAPE_CHART_FIELDS_DATE; } + +export function cleanJSONFn(value: T): T { + if (Array.isArray(value)) { + return value.map(cleanJSONFn) as T; + } + if (typeof value === 'object' && value !== null) { + const replaced: Record = {}; + Object.keys(value).forEach((key) => { + const currentValue = (value as Record)[key]; + replaced[key] = cleanJSONFn(currentValue); + }); + return replaced as T; + } + if (typeof value !== 'string') { + return value; + } + if (value.length < 8) { + return value; + } + const prefix = value.substring(0, 8); + + if (prefix === '_NuFrRa_') { + return undefined as T; + } + return value; +} diff --git a/src/server/components/charts-engine/components/processor/worker-chart-builder.ts b/src/server/components/charts-engine/components/processor/worker-chart-builder.ts index 61c56cd2e5..40501fb4d7 100644 --- a/src/server/components/charts-engine/components/processor/worker-chart-builder.ts +++ b/src/server/components/charts-engine/components/processor/worker-chart-builder.ts @@ -64,6 +64,7 @@ export const getWizardChartBuilder = async ( }; const chartBuilder: ChartBuilder = { + type: 'WIZARD', buildShared: async () => { if (typeof config.data.shared === 'string') { shared = JSON.parse(config.data.shared); diff --git a/src/server/components/features/features-list/EnableEditHistoryQL.ts b/src/server/components/features/features-list/EnableEditHistoryQL.ts deleted file mode 100644 index 027367946e..0000000000 --- a/src/server/components/features/features-list/EnableEditHistoryQL.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {Feature} from '../../../../shared'; -import {createFeatureConfig} from '../utils'; - -export default createFeatureConfig({ - name: Feature.EnableEditHistoryQL, - state: { - development: true, - production: false, - }, -}); diff --git a/src/server/components/features/features-list/GroupControls.ts b/src/server/components/features/features-list/GroupControls.ts deleted file mode 100644 index 717ab748ca..0000000000 --- a/src/server/components/features/features-list/GroupControls.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {Feature} from '../../../../shared'; -import {createFeatureConfig} from '../utils'; - -export default createFeatureConfig({ - name: Feature.GroupControls, - state: { - development: true, - production: true, - }, -}); diff --git a/src/server/components/features/features-list/ChartWithFnLogging.ts b/src/server/components/features/features-list/HtmlInWizard.ts similarity index 84% rename from src/server/components/features/features-list/ChartWithFnLogging.ts rename to src/server/components/features/features-list/HtmlInWizard.ts index 70af7045a2..5a27754727 100644 --- a/src/server/components/features/features-list/ChartWithFnLogging.ts +++ b/src/server/components/features/features-list/HtmlInWizard.ts @@ -2,7 +2,7 @@ import {Feature} from '../../../../shared'; import {createFeatureConfig} from '../utils'; export default createFeatureConfig({ - name: Feature.ChartWithFnLogging, + name: Feature.HtmlInWizard, state: { development: false, production: false, diff --git a/src/server/controllers/navigate.ts b/src/server/controllers/navigate.ts index 9bab2cc30b..855ad6b519 100644 --- a/src/server/controllers/navigate.ts +++ b/src/server/controllers/navigate.ts @@ -56,7 +56,7 @@ export default async (req: Request, res: Response) => { return res.redirect(302, wizardUrl); } else if (ENTRY_TYPES.editor.includes(type)) { - const editorUrl = reqUrl.replace('navigate', 'ql'); + const editorUrl = reqUrl.replace('navigate', 'editor'); req.ctx.log('Navigate to editor', {editorUrl}); diff --git a/src/server/middlewares/x-dl-context.ts b/src/server/middlewares/x-dl-context.ts index 9a83443c1d..8ca6be6e38 100644 --- a/src/server/middlewares/x-dl-context.ts +++ b/src/server/middlewares/x-dl-context.ts @@ -10,7 +10,11 @@ import { type DlContext = Record; -export default function xDlContext() { +export default function xDlContext({ + plugins = [], +}: { + plugins?: Array<(req: Request, context: DlContext) => DlContext>; +} = {}) { return function xDlContextMiddleware(req: Request, _: Response, next: NextFunction) { const {folderId: folderIdHeader} = req.ctx.config.headersMap; @@ -48,7 +52,15 @@ export default function xDlContext() { context.displayMode = dispayMode; } - req.headers[DL_CONTEXT_HEADER] = JSON.stringify(context); + req.headers[DL_CONTEXT_HEADER] = JSON.stringify( + plugins.length > 0 + ? plugins.reduce( + (memo, plugin) => ({...memo, ...plugin(req, memo)}), + context, + ) + : context, + ); + req.originalContext.set( 'tenantId', tenantId && Array.isArray(tenantId) ? tenantId.join(',') : tenantId, diff --git a/src/server/modes/charts/init-charts-engine.ts b/src/server/modes/charts/init-charts-engine.ts index 8baf24d6df..516945136e 100644 --- a/src/server/modes/charts/init-charts-engine.ts +++ b/src/server/modes/charts/init-charts-engine.ts @@ -3,12 +3,7 @@ import type {AppConfig, AppContext} from '@gravity-ui/nodekit'; import get from 'lodash/get'; import sizeof from 'object-sizeof'; -import { - AppEnvironment, - Feature, - isEnabledServerFeature, - isObjectWithFunction, -} from '../../../shared'; +import {AppEnvironment} from '../../../shared'; import CacheClient from '../../components/cache-client'; import {ChartsEngine} from '../../components/charts-engine'; import {getDefaultRunners} from '../../components/charts-engine/runners'; @@ -30,7 +25,6 @@ export function initChartsEngine({ afterAuth: AppMiddleware[]; }) { const getTime = () => new Date().toISOString().replace('T', ' ').split('.')[0]; - const shouldLogChartWithFunction = isEnabledServerFeature(ctx, Feature.ChartWithFnLogging); const telemetryCallbacks: TelemetryCallbacks = { onConfigFetched: ({id, statusCode, requestId, latency = 0, traceId, tenantId, userId}) => { @@ -116,23 +110,10 @@ export function initChartsEngine({ }, onTabsExecuted: ({result, entryId}) => { - const { - config: chartConfig, - highchartsConfig, - sources, - sourceData, - processedData, - } = result; + const {sources, sourceData, processedData} = result; const chartEntryId = entryId || ''; const datetime = Date.now(); - if ( - shouldLogChartWithFunction && - (isObjectWithFunction(chartConfig) || isObjectWithFunction(highchartsConfig)) - ) { - ctx.stats('chartsWithFn', {datetime, entryId: chartEntryId}); - } - let rowsCount = 0; let columnsCount = 0; if (sourceData && typeof sourceData === 'object') { diff --git a/src/server/modes/charts/plugins/datalens/highcharts/highcharts.ts b/src/server/modes/charts/plugins/datalens/highcharts/highcharts.ts index 30c9a80d78..339112382c 100644 --- a/src/server/modes/charts/plugins/datalens/highcharts/highcharts.ts +++ b/src/server/modes/charts/plugins/datalens/highcharts/highcharts.ts @@ -15,6 +15,7 @@ import { WizardVisualizationId, isDateField, } from '../../../../../../shared'; +import {PERCENT_VISUALIZATIONS} from '../../../../../../shared/constants/visualization'; import type {IgnoreProps} from '../utils/axis-helpers'; import {applyPlaceholderSettingsToAxis} from '../utils/axis-helpers'; import {mapChartsConfigToServerConfig} from '../utils/config-helpers'; @@ -342,6 +343,12 @@ const applyCommonAxisSettings = ({ }); } + // Due to fractional values (presumably) highcharts sometimes incorrectly calculates the maximum + // in this case, the chart is displayed correctly, but the maximum value on the y axis becomes more than 100 percent + if (PERCENT_VISUALIZATIONS.has(visualization.id) && !('max' in yAxis)) { + set(yAxis, 'max', 100); + } + return {xAxis, yAxis}; }; diff --git a/src/server/modes/charts/plugins/datalens/preparers/backend-pivot-table/table-head-generator.ts b/src/server/modes/charts/plugins/datalens/preparers/backend-pivot-table/table-head-generator.ts index f5c3a41c5a..770c20f6b1 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/backend-pivot-table/table-head-generator.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/backend-pivot-table/table-head-generator.ts @@ -123,12 +123,15 @@ export const getRowHeaderCellMetadata = (args: GetHeaderCellMetadataArgs): Chart // Formatting a column cell if (isNumericalDataType(field.data_type)) { cell.type = 'number'; - cell.value = isNaN(Number(value)) ? value : Number(value); - cell.formattedValue = chartKitFormatNumberWrapper(cell.value, { - lang: 'ru', - ...getFormatOptions(field), - }); cell.fieldId = field.guid; + + if (value !== null) { + cell.value = isNaN(Number(value)) ? value : Number(value); + cell.formattedValue = chartKitFormatNumberWrapper(cell.value, { + lang: 'ru', + ...getFormatOptions(field), + }); + } } else if (isDateField(field) && value) { cell.formattedValue = formatDate({ valueType: field.data_type, diff --git a/src/server/modes/charts/plugins/datalens/preparers/bar-x/prepare-bar-x.ts b/src/server/modes/charts/plugins/datalens/preparers/bar-x/prepare-bar-x.ts index 8658c58951..f84b75e916 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/bar-x/prepare-bar-x.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/bar-x/prepare-bar-x.ts @@ -14,6 +14,7 @@ import { getXAxisMode, isDateField, isDimensionField, + isHtmlField, isMarkdownField, isMarkupField, isMeasureField, @@ -114,6 +115,7 @@ export function prepareBarX(args: PrepareFunctionArgs) { const labelsLength = labels && labels.length; const isMarkdownLabel = isMarkdownField(labelItem); const isMarkupLabel = isMarkupField(labelItem); + const isHtmlLabel = isHtmlField(labelItem); const segmentField = segments[0]; const segmentIndexInOrder = getSegmentsIndexInOrder(order, segmentField, idToTitle); @@ -332,7 +334,10 @@ export function prepareBarX(args: PrepareFunctionArgs) { id: line.id, title: line.title || 'Null', tooltip: line.tooltip, - dataLabels: {...line.dataLabels, useHTML: isMarkdownLabel || isMarkupLabel}, + dataLabels: { + ...line.dataLabels, + useHTML: isMarkdownLabel || isMarkupLabel || isHtmlLabel, + }, data: categories .map((category, i) => { const lineData = line.data[category]; @@ -385,6 +390,7 @@ export function prepareBarX(args: PrepareFunctionArgs) { point.label = getLabelValue(innerLabels?.[category], { isMarkdownLabel, isMarkupLabel, + isHtmlLabel, }); if (isActionParamsEnable) { @@ -485,6 +491,10 @@ export function prepareBarX(args: PrepareFunctionArgs) { ChartEditor.updateConfig({useMarkup: true}); } + if (isHtmlLabel) { + ChartEditor.updateConfig({useHtml: true}); + } + if (isXCategoryAxis) { return { graphs, diff --git a/src/server/modes/charts/plugins/datalens/preparers/bar-y/prepare-bar-y-data.ts b/src/server/modes/charts/plugins/datalens/preparers/bar-y/prepare-bar-y-data.ts index e9eb6bae89..23bdf2fecb 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/bar-y/prepare-bar-y-data.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/bar-y/prepare-bar-y-data.ts @@ -10,6 +10,7 @@ import { getFakeTitleOrTitle, getXAxisMode, isDateField, + isHtmlField, isMarkdownField, isMarkupField, isMeasureField, @@ -99,6 +100,7 @@ export function prepareBarYData({ const labelItem = labels?.[0]; const isMarkdownLabel = isMarkdownField(labelItem); const isMarkupLabel = isMarkupField(labelItem); + const isHtmlLabel = isHtmlField(labelItem); const isColorItemExist = Boolean(colorItem && colorItem.type !== 'PSEUDO'); const isColorizeByMeasure = isMeasureField(colorItem); @@ -312,7 +314,7 @@ export function prepareBarYData({ dataLabels: { enabled: Boolean(labelItem), ...line.dataLabels, - useHTML: isMarkdownLabel || isMarkupLabel, + useHTML: isMarkdownLabel || isMarkupLabel || isHtmlLabel, }, data: categories .map((category, i) => { @@ -353,6 +355,7 @@ export function prepareBarYData({ point.label = getLabelValue(innerLabels?.[category], { isMarkdownLabel, isMarkupLabel, + isHtmlLabel, }); if (isActionParamsEnable) { @@ -448,6 +451,10 @@ export function prepareBarYData({ ChartEditor.updateConfig({useMarkup: true}); } + if (isHtmlLabel) { + ChartEditor.updateConfig({useHtml: true}); + } + if (isXCategoryAxis) { return { graphs, diff --git a/src/server/modes/charts/plugins/datalens/preparers/geopoint/index.ts b/src/server/modes/charts/plugins/datalens/preparers/geopoint/index.ts index 161212470a..de39da01e4 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/geopoint/index.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/geopoint/index.ts @@ -9,6 +9,7 @@ import type { } from '../../../../../../../shared'; import { Feature, + MARKUP_TYPE, MINIMUM_FRACTION_DIGITS, WRAPPED_MARKDOWN_KEY, getFakeTitleOrTitle, @@ -335,7 +336,7 @@ function prepareGeopoint(options: PrepareFunctionArgs, {isClusteredPoints = fals ); const text = itemTitle ? `${itemTitle}: ${value}` : value; - if (tooltipField?.isMarkdown) { + if (tooltipField?.markupType === MARKUP_TYPE.markdown) { pointData[WRAPPED_MARKDOWN_KEY] = text; } else { pointData.text = shouldEscapeUserValue ? escape(text) : text; @@ -369,10 +370,14 @@ function prepareGeopoint(options: PrepareFunctionArgs, {isClusteredPoints = fals }); }); - if (tooltips.some((item) => item.isMarkdown)) { + if (tooltips.some((item) => item.markupType === MARKUP_TYPE.markdown)) { ChartEditor.updateConfig({useMarkdown: true}); } + if (tooltips.some((item) => item.markupType === MARKUP_TYPE.html)) { + ChartEditor.updateConfig({useHtml: true}); + } + let mapOptions: GeopointMapOptions = { opacity: ALPHA, showCustomLegend: true, diff --git a/src/server/modes/charts/plugins/datalens/preparers/geopolygon.ts b/src/server/modes/charts/plugins/datalens/preparers/geopolygon.ts index 3fa381d16b..b94abf0ddf 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/geopolygon.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/geopolygon.ts @@ -11,11 +11,14 @@ import type { } from '../../../../../../shared'; import { DATASET_FIELD_TYPES, + MARKUP_TYPE, MINIMUM_FRACTION_DIGITS, WRAPPED_MARKDOWN_KEY, getFakeTitleOrTitle, + isHtmlField, isMarkdownField, } from '../../../../../../shared'; +import {wrapHtml} from '../../../../../../shared/utils/ui-sandbox'; import {hexToRgb} from '../utils/color-helpers'; import {GEO_MAP_LAYERS_LEVEL} from '../utils/constants'; import type {Coordinate} from '../utils/geo-helpers'; @@ -241,16 +244,23 @@ function prepareGeopolygon(options: PrepareFunctionArgs) { const itemTitle = shouldUseFieldTitle ? getFakeTitleOrTitle(tooltip as ServerField) : ''; const tooltipText = itemTitle ? `${itemTitle}: ${formattedText}` : formattedText; const isMarkupField = tooltip?.data_type === DATASET_FIELD_TYPES.MARKUP; + const useHtml = isHtmlField(tooltip); - if (isMarkupField || isMarkdownField(tooltip)) { + if (isMarkupField || isMarkdownField(tooltip) || useHtml) { polygon.properties.rawText = true; } + if (useHtml) { + ChartEditor.updateConfig({useHtml: true}); + } + let tooltipData; if (isMarkupField) { tooltipData = {key: itemTitle, value: formattedText}; - } else if (tooltip?.isMarkdown) { + } else if (tooltip?.markupType === MARKUP_TYPE.markdown) { tooltipData = {[WRAPPED_MARKDOWN_KEY]: tooltipText}; + } else if (tooltip?.markupType === MARKUP_TYPE.html) { + tooltipData = {text: wrapHtml(tooltipText)}; } else { tooltipData = {text: tooltipText}; } diff --git a/src/server/modes/charts/plugins/datalens/preparers/line/prepare-line-data.ts b/src/server/modes/charts/plugins/datalens/preparers/line/prepare-line-data.ts index bd35f4ec5a..a5947ee8ba 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/line/prepare-line-data.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/line/prepare-line-data.ts @@ -11,6 +11,7 @@ import { getFakeTitleOrTitle, getXAxisMode, isDateField, + isHtmlField, isMarkdownField, isMarkupField, isMeasureField, @@ -109,6 +110,7 @@ export function prepareLineData(args: PrepareFunctionArgs) { const labelsLength = labels && labels.length; const isMarkdownLabel = isMarkdownField(labelItem); const isMarkupLabel = isMarkupField(labelItem); + const isHtmlLabel = isHtmlField(labelItem); const segmentField = segments[0]; const segmentIndexInOrder = getSegmentsIndexInOrder(order, segmentField, idToTitle); @@ -345,7 +347,10 @@ export function prepareLineData(args: PrepareFunctionArgs) { id: line.id, title: line.title || 'Null', tooltip: line.tooltip, - dataLabels: {...line.dataLabels, useHTML: isMarkdownLabel || isMarkupLabel}, + dataLabels: { + ...line.dataLabels, + useHTML: isMarkdownLabel || isMarkupLabel || isHtmlLabel, + }, data: categories .map((category, i) => { const lineData = line.data[category]; @@ -415,6 +420,7 @@ export function prepareLineData(args: PrepareFunctionArgs) { point.label = getLabelValue(innerLabels?.[category], { isMarkdownLabel, isMarkupLabel, + isHtmlLabel, }); if (isActionParamsEnable) { @@ -532,6 +538,10 @@ export function prepareLineData(args: PrepareFunctionArgs) { ChartEditor.updateConfig({useMarkup: true}); } + if (isHtmlLabel) { + ChartEditor.updateConfig({useHtml: true}); + } + if (isXCategoryAxis) { return { graphs, diff --git a/src/server/modes/charts/plugins/datalens/preparers/pie/d3.ts b/src/server/modes/charts/plugins/datalens/preparers/pie/d3.ts index a284feed0f..3aabf0fe1e 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/pie/d3.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/pie/d3.ts @@ -1,110 +1,108 @@ -import type { - ChartKitWidgetData, - PieSeries, - PieSeriesData, -} from '@gravity-ui/chartkit/build/types/widget-data'; +import type {PieSeries, PieSeriesData} from '@gravity-ui/chartkit'; -import type {SeriesExportSettings, ServerField} from '../../../../../../../shared'; +import type {SeriesExportSettings} from '../../../../../../../shared'; import {WizardVisualizationId, formatNumber, getFormatOptions} from '../../../../../../../shared'; -import {getFormattedLabel} from '../../d3/utils/dataLabels'; +import {getFakeTitleOrTitle} from '../../../../../../../shared/modules/fields'; +import {isMarkdownField, isMarkupField} from '../../../../../../../shared/types/index'; import {getExportColumnSettings} from '../../utils/export-helpers'; -import type {PrepareFunctionArgs} from '../types'; +import type {PiePoint, PrepareFunctionArgs} from '../types'; -import type {PieConfig} from './prepare-pie-data'; import preparePieData from './prepare-pie-data'; +import {getFormattedValue, isColoringByMeasure} from './utils'; -type MapPieSeriesArgs = { - graph: PieConfig; - isLabelsEnabled?: boolean; - labelField?: ServerField; - measureField?: ServerField; - visualizationId: WizardVisualizationId; - totals?: string | null; - ChartEditor: PrepareFunctionArgs['ChartEditor']; -}; - -type ExtendedPieSeriesData = PieSeriesData & { +type ExtendedPieSeriesData = Omit & { drillDownFilterValue?: string; + formattedValue: string | null; + percentage: number; + label?: PiePoint['label']; }; -type ExtendedPieSeries = PieSeries & { +type ExtendedPieSeries = Omit & { custom?: { totals?: string; exportSettings?: SeriesExportSettings; }; + data: ExtendedPieSeriesData[]; }; -function mapPieSeries(args: MapPieSeriesArgs) { - const {graph, isLabelsEnabled, measureField, labelField, visualizationId, totals, ChartEditor} = - args; +export function prepareD3Pie(args: PrepareFunctionArgs) { + const {labels, visualizationId, ChartEditor, colorsConfig, idToDataType} = args; + const {graphs, label, measure, totals} = preparePieData(args); + const isLabelsEnabled = Boolean(labels?.length && label && measure?.hideLabelMode !== 'hide'); + const isMarkdownLabel = isMarkdownField(label); + const isMarkupLabel = isMarkupField(label); - const seriesConfig: ExtendedPieSeries = { - type: 'pie', - dataLabels: { - enabled: isLabelsEnabled, - }, - data: - graph.data?.map((item) => { - const dataItem: ExtendedPieSeriesData = { - value: item.y, - color: String(item.color), - name: item.name, - custom: item.custom, - drillDownFilterValue: item.drillDownFilterValue, - }; + let data: ExtendedPieSeries[] = []; - if (isLabelsEnabled) { - dataItem.label = getFormattedLabel(item.label as string | number, labelField); - } + if (measure && graphs.length > 0) { + const graph = graphs[0]; + const total = graph.data?.reduce((sum, d) => sum + (d.y || 0), 0) ?? 0; + const seriesConfig: ExtendedPieSeries = { + type: 'pie', + dataLabels: { + enabled: isLabelsEnabled, + html: isMarkdownLabel || isMarkupLabel, + }, + data: + graph.data?.map((item) => { + return { + ...item, + value: item.y, + color: String(item.color), + formattedValue: getFormattedValue(String(item.y), { + ...measure, + data_type: idToDataType[measure.guid], + }), + percentage: item.y / total, + }; + }) ?? [], + }; - return dataItem; - }) || [], - }; + seriesConfig.custom = { + exportSettings: { + columns: [ + { + name: ChartEditor.getTranslation('chartkit.data-provider', 'categories'), + field: 'name', + }, + getExportColumnSettings({path: 'value', field: measure}), + ], + }, + }; - seriesConfig.custom = { - exportSettings: { - columns: [ - { - name: ChartEditor.getTranslation('chartkit.data-provider', 'categories'), - field: 'name', - }, - getExportColumnSettings({path: 'value', field: measureField}), - ], - }, - }; + if (visualizationId === WizardVisualizationId.DonutD3) { + seriesConfig.innerRadius = '50%'; - if (visualizationId === WizardVisualizationId.DonutD3) { - seriesConfig.innerRadius = '50%'; - - if (measureField && totals) { - seriesConfig.custom = { - ...seriesConfig.custom, - totals: formatNumber(Number(totals), getFormatOptions(measureField)), - }; + if (measure && totals) { + seriesConfig.custom = { + ...seriesConfig.custom, + totals: formatNumber(Number(totals), getFormatOptions(measure)), + }; + } } - } - return seriesConfig; -} + data.push(seriesConfig); + } else { + data = []; + } -export function prepareD3Pie(args: PrepareFunctionArgs): ChartKitWidgetData { - const {labels, visualizationId, ChartEditor} = args; - const {graphs, label, measure, totals} = preparePieData(args); - const isLabelsEnabled = Boolean(labels?.length && label && measure?.hideLabelMode !== 'hide'); + let legend; + if (graphs.length && isColoringByMeasure(args)) { + legend = { + enabled: true, + type: 'continuous', + title: {text: getFakeTitleOrTitle(measure)}, + colorScale: { + colors: colorsConfig.gradientColors, + stops: colorsConfig.gradientColors.length === 2 ? [0, 1] : [0, 0.5, 1], + }, + }; + } return { series: { - data: graphs.map((graph) => - mapPieSeries({ - graph, - labelField: label, - isLabelsEnabled, - visualizationId: visualizationId as WizardVisualizationId, - totals, - measureField: measure, - ChartEditor, - }), - ), + data, }, + legend, }; } diff --git a/src/server/modes/charts/plugins/datalens/preparers/pie/prepare-pie-data.ts b/src/server/modes/charts/plugins/datalens/preparers/pie/prepare-pie-data.ts index 1108f8d43f..a453c025c5 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/pie/prepare-pie-data.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/pie/prepare-pie-data.ts @@ -6,6 +6,7 @@ import { getDistinctValue, getFakeTitleOrTitle, isFieldHierarchy, + isHtmlField, isMarkdownField, isMarkupField, isMeasureValue, @@ -14,6 +15,7 @@ import { wrapMarkupValue, } from '../../../../../../../shared'; import {wrapMarkdownValue} from '../../../../../../../shared/utils/markdown'; +import {wrapHtml} from '../../../../../../../shared/utils/ui-sandbox'; import type {ChartColorsConfig} from '../../types'; import type {ColorValue} from '../../utils/color-helpers'; import {getColorsByMeasureField, getThresholdValues} from '../../utils/color-helpers'; @@ -129,6 +131,7 @@ export function preparePieData(args: PrepareFunctionArgs) { : -1; const isMarkdownLabel = isMarkdownField(labelItem); const isMarkupLabel = isMarkupField(labelItem); + const isHtmlLabel = isHtmlField(labelItem); const measureIndex = findIndexInOrder(order, measure, idToTitle[measure.guid]); const measureDataType = idToDataType[measure.guid] || measure.data_type; @@ -183,7 +186,7 @@ export function preparePieData(args: PrepareFunctionArgs) { ? MINIMUM_FRACTION_DIGITS : 0, }), - useHTML: isMarkdownLabel || isMarkupLabel, + useHTML: (isMarkdownLabel || isMarkupLabel || isHtmlLabel) ?? undefined, }, }; @@ -248,6 +251,8 @@ export function preparePieData(args: PrepareFunctionArgs) { point.label = wrapMarkdownValue(labelValue); } else if (labelValue && isMarkupLabel) { point.label = wrapMarkupValue(labelValue); + } else if (labelValue && isHtmlLabel) { + point.label = wrapHtml(labelValue); } else { point.label = getFormattedValue(labelValue, { ...labelField, @@ -302,6 +307,10 @@ export function preparePieData(args: PrepareFunctionArgs) { ChartEditor.updateConfig({useMarkup: true}); } + if (isHtmlLabel) { + ChartEditor.updateConfig({useHtml: true}); + } + return {graphs: [pie], totals: totals.find((value) => value), label: labelField, measure}; } diff --git a/src/server/modes/charts/plugins/datalens/preparers/scatter/prepare-scatter.ts b/src/server/modes/charts/plugins/datalens/preparers/scatter/prepare-scatter.ts index 21f9787031..121854496e 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/scatter/prepare-scatter.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/scatter/prepare-scatter.ts @@ -1,7 +1,12 @@ import type {Highcharts} from '@gravity-ui/chartkit/highcharts'; import escape from 'lodash/escape'; -import type {PointSizeConfig, ServerField, WrappedMarkup} from '../../../../../../../shared'; +import type { + PointSizeConfig, + ServerField, + WrappedHTML, + WrappedMarkup, +} from '../../../../../../../shared'; import { Feature, MINIMUM_FRACTION_DIGITS, @@ -9,6 +14,7 @@ import { getFakeTitleOrTitle, getFormatOptions, isDateField, + isHtmlField, isMarkdownField, isMarkupField, isStringField, @@ -16,6 +22,7 @@ import { } from '../../../../../../../shared'; import type {WrappedMarkdown} from '../../../../../../../shared/utils/markdown'; import {wrapMarkdownValue} from '../../../../../../../shared/utils/markdown'; +import {wrapHtml} from '../../../../../../../shared/utils/ui-sandbox'; import type {ChartColorsConfig} from '../../types'; import type {ExtendedSeriesScatterOptions} from '../../utils/color-helpers'; import { @@ -184,9 +191,11 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu }), }); } else { - let value: string | WrappedMarkdown = xValue as string; + let value: string | WrappedMarkdown | WrappedHTML = xValue as string; if (isMarkdownField(x)) { value = wrapMarkdownValue(value); + } else if (isHtmlField(x)) { + value = wrapHtml(value); } else if (shouldEscapeUserValue) { value = escape(value); } @@ -237,10 +246,13 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu }), }); } else { - let yLabel: string | WrappedMarkdown = - yValue && shouldEscapeUserValue ? escape(yValue as string) : (yValue as string); - if (isMarkdownField(x)) { - yLabel = wrapMarkdownValue(String(yLabel)); + let yLabel: string | WrappedMarkdown | WrappedHTML = String(yValue as string); + if (isMarkdownField(y)) { + yLabel = wrapMarkdownValue(yLabel); + } else if (isHtmlField(y)) { + yLabel = wrapHtml(yLabel); + } else if (shouldEscapeUserValue) { + yLabel = escape(yLabel); } point.yLabel = yLabel; @@ -264,7 +276,8 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu const zTitle = idToTitle[z.guid]; const zi = findIndexInOrder(order, z, zTitle); zValueRaw = values[zi]; - let formattedZValue: string | null | WrappedMarkdown | WrappedMarkup = zValueRaw; + let formattedZValue: string | null | WrappedMarkdown | WrappedMarkup | WrappedHTML = + zValueRaw; if (isNumericalDataType(z.data_type) && z.formatting) { formattedZValue = chartKitFormatNumberWrapper(Number(formattedZValue), { @@ -276,6 +289,8 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu if (isStringField(z)) { if (isMarkdownField(z)) { formattedZValue = wrapMarkdownValue(zValueRaw as string); + } else if (isHtmlField(z)) { + formattedZValue = wrapHtml(zValueRaw as string); } else if (shouldEscapeUserValue) { formattedZValue = escape(formattedZValue as string); } @@ -320,9 +335,11 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu const i = findIndexInOrder(order, color, cTitle); const colorValue = values[i] && shouldEscapeUserValue ? escape(String(values[i])) : values[i]; - let colorLabel: string | null | WrappedMarkdown = colorValue; + let colorLabel: string | null | WrappedMarkdown | WrappedHTML = colorValue; if (isMarkdownField(color)) { colorLabel = wrapMarkdownValue(String(colorValue)); + } else if (isHtmlField(color)) { + colorLabel = wrapHtml(String(colorValue)); } if (gradientMode) { @@ -357,9 +374,11 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu const cTitle = idToTitle[shape.guid]; const i = findIndexInOrder(order, shape, cTitle); const shapeValue = escape(values[i] as string) || ''; - let shapeLabel: WrappedMarkdown | string = shapeValue; + let shapeLabel: WrappedMarkdown | string | WrappedHTML = shapeValue; if (isMarkdownField(shape)) { - shapeLabel = wrapMarkdownValue(String(shapeValue)); + shapeLabel = wrapMarkdownValue(shapeValue); + } else if (isHtmlField(shape)) { + shapeLabel = wrapHtml(shapeValue); } point.shapeValue = shapeValue; @@ -421,6 +440,10 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu graphs.forEach((g) => { g.name = wrapMarkdownValue(g.name as string); }); + } else if (isHtmlField(color) || isHtmlField(shape)) { + graphs.forEach((g) => { + g.name = wrapHtml(g.name as string); + }); } let categories: (string | number | WrappedMarkdown)[] | undefined; @@ -442,6 +465,11 @@ export function prepareScatter(options: PrepareFunctionArgs): PrepareScatterResu ChartEditor.updateConfig({useMarkup: true}); } + const hasHtml = [x, y, z, size, color, shape].some((field) => isHtmlField(field)); + if (hasHtml) { + ChartEditor.updateConfig({useHtml: true}); + } + graphs.forEach((graph) => { graph.keys = Array.from(keys); graph.custom = { diff --git a/src/server/modes/charts/plugins/datalens/preparers/scatter/types.ts b/src/server/modes/charts/plugins/datalens/preparers/scatter/types.ts index a3a93d35c9..f383fb2c80 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/scatter/types.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/scatter/types.ts @@ -1,13 +1,14 @@ +import type {WrappedHTML} from '../../../../../../../shared'; import type {WrappedMarkdown} from '../../../../../../../shared/utils/markdown'; import type {ExtendedPointOptionsObject} from '../../utils/color-helpers'; export type ScatterPoint = ExtendedPointOptionsObject & { - xLabel?: string | WrappedMarkdown; - yLabel?: string | WrappedMarkdown; - cLabel?: string | null | WrappedMarkdown; - sLabel?: string | WrappedMarkdown; + xLabel?: string | WrappedMarkdown | WrappedHTML; + yLabel?: string | WrappedMarkdown | WrappedHTML; + cLabel?: string | null | WrappedMarkdown | WrappedHTML; + sLabel?: string | WrappedMarkdown | WrappedHTML; sizeValue?: number | null; - sizeLabel?: string | null | WrappedMarkdown; + sizeLabel?: string | null | WrappedMarkdown | WrappedHTML; x?: number; y?: number; value?: number; diff --git a/src/server/modes/charts/plugins/datalens/preparers/treemap/highcharts.ts b/src/server/modes/charts/plugins/datalens/preparers/treemap/highcharts.ts index 14119c09b9..5819b593d4 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/treemap/highcharts.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/treemap/highcharts.ts @@ -4,10 +4,12 @@ import { Feature, MINIMUM_FRACTION_DIGITS, isDateField, + isHtmlField, isMarkdownField, } from '../../../../../../../shared'; import type {WrappedMarkdown} from '../../../../../../../shared/utils/markdown'; import {wrapMarkdownValue} from '../../../../../../../shared/utils/markdown'; +import {wrapHtml} from '../../../../../../../shared/utils/ui-sandbox'; import { mapAndColorizeHashTableByGradient, mapAndColorizeHashTableByPalette, @@ -48,6 +50,7 @@ export function prepareHighchartsTreemap({ const d = placeholders[0].items; const dTypes = d.map((item) => item.data_type); const useMarkdown = d?.some(isMarkdownField); + const useHtml = d?.some(isHtmlField); // Measures const m = placeholders[1].items; @@ -204,6 +207,8 @@ export function prepareHighchartsTreemap({ let name: any[] = dPath; if (useMarkdown) { name = dPath.map((item) => (item ? wrapMarkdownValue(item) : item)); + } else if (useHtml) { + name = dPath.map((item) => (item ? wrapHtml(item) : item)); } lastDimensionItem.name = name as any; @@ -274,6 +279,10 @@ export function prepareHighchartsTreemap({ ChartEditor.updateConfig({useMarkdown: true}); } + if (useHtml) { + ChartEditor.updateConfig({useHtml: true}); + } + const graphs = [ { type: 'treemap', @@ -290,7 +299,7 @@ export function prepareHighchartsTreemap({ style: { cursor: 'pointer', }, - ...(useMarkdown && { + ...((useMarkdown || useHtml) && { useHTML: true, }), }, diff --git a/src/server/modes/charts/plugins/datalens/preparers/types.ts b/src/server/modes/charts/plugins/datalens/preparers/types.ts index 59abb52cf1..ac9aeb3770 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/types.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/types.ts @@ -14,6 +14,7 @@ import type { ServerSort, ServerTooltip, ServerTooltipConfig, + WrappedHTML, WrappedMarkup, } from '../../../../../../shared'; import type {ApiV2RequestField} from '../../../../../../shared/types/bi-api/v2'; @@ -94,6 +95,6 @@ export type PiePoint = { color?: string; colorGuid?: string; colorValue?: string | number; - label?: string | number | null | WrappedMarkdown | WrappedMarkup; + label?: string | number | null | WrappedMarkdown | WrappedMarkup | WrappedHTML; custom?: object; }; diff --git a/src/server/modes/charts/plugins/datalens/utils/color-helpers.ts b/src/server/modes/charts/plugins/datalens/utils/color-helpers.ts index 9e5af0e96c..36deaa51be 100644 --- a/src/server/modes/charts/plugins/datalens/utils/color-helpers.ts +++ b/src/server/modes/charts/plugins/datalens/utils/color-helpers.ts @@ -5,6 +5,7 @@ import type { RGBColor, RGBGradient, TableCellsRow, + WrappedHTML, WrappedMarkup, } from '../../../../../../shared'; import { @@ -30,7 +31,7 @@ export type ExtendedPointOptionsObject = Omit< colorValue?: string | null; colorGuid?: string; shapeValue?: string | null; - name?: string | WrappedMarkdown | WrappedMarkup; + name?: string | WrappedMarkdown | WrappedMarkup | WrappedHTML; }; export type ExtendedSeriesScatterOptions = Omit< @@ -39,7 +40,7 @@ export type ExtendedSeriesScatterOptions = Omit< > & { title?: string; data?: ExtendedPointOptionsObject[]; - name?: string | WrappedMarkdown; + name?: string | WrappedMarkdown | WrappedHTML; }; interface GradientThresholdValues { diff --git a/src/server/modes/charts/plugins/datalens/utils/misc-helpers.ts b/src/server/modes/charts/plugins/datalens/utils/misc-helpers.ts index b147b88515..eb57df94af 100644 --- a/src/server/modes/charts/plugins/datalens/utils/misc-helpers.ts +++ b/src/server/modes/charts/plugins/datalens/utils/misc-helpers.ts @@ -24,6 +24,7 @@ import { wrapMarkupValue, } from '../../../../../../shared'; import {wrapMarkdownValue} from '../../../../../../shared/utils/markdown'; +import {wrapHtml} from '../../../../../../shared/utils/ui-sandbox'; import type {ChartKitFormatSettings, ResultDataOrder} from '../preparers/types'; import type { ChartColorsConfig, @@ -379,9 +380,9 @@ export function isLegendEnabled(chartSetting?: ServerCommonSharedExtraSettings) export function getLabelValue( value: undefined | string, - options: {isMarkdownLabel?: boolean; isMarkupLabel?: boolean} = {}, + options: {isMarkdownLabel?: boolean; isMarkupLabel?: boolean; isHtmlLabel?: boolean} = {}, ) { - const {isMarkdownLabel, isMarkupLabel} = options; + const {isMarkdownLabel, isMarkupLabel, isHtmlLabel} = options; if (value === undefined) { return ''; @@ -395,6 +396,10 @@ export function getLabelValue( return wrapMarkupValue(value); } + if (isHtmlLabel) { + return wrapHtml(value); + } + return value; } diff --git a/src/server/modes/charts/plugins/ql/module/library-config/build-library-config.ts b/src/server/modes/charts/plugins/ql/module/library-config/build-library-config.ts index 508f1ec9f4..d727f54593 100644 --- a/src/server/modes/charts/plugins/ql/module/library-config/build-library-config.ts +++ b/src/server/modes/charts/plugins/ql/module/library-config/build-library-config.ts @@ -39,7 +39,7 @@ export function buildLibraryConfig({shared, ChartEditor, features}: BuildLibrary hierarchies: [], links: [], updates: [], - version: ChartsConfigVersion.V11, + version: ChartsConfigVersion.V12, datasetsIds: [], datasetsPartialFields: [], } as ServerChartsConfig, diff --git a/src/shared/constants/qa/collections.ts b/src/shared/constants/qa/collections.ts new file mode 100644 index 0000000000..a4b6cd78bc --- /dev/null +++ b/src/shared/constants/qa/collections.ts @@ -0,0 +1,6 @@ +export const enum CollectionContentTableQa { + Table = 'coll-content-table', + CollectionLinkRow = 'coll-content-table-coll-link-row', + WorkbookLinkRow = 'coll-content-table-workbook-link-row', + CollectionTitleCell = 'coll-content-table-coll-title-cell', +} diff --git a/src/shared/constants/qa/connections.ts b/src/shared/constants/qa/connections.ts index dc1eb07981..8c39b21fa5 100644 --- a/src/shared/constants/qa/connections.ts +++ b/src/shared/constants/qa/connections.ts @@ -1,8 +1,13 @@ export const ConnectionsBaseQA = { S3_ACTION_BUTTON: 'conn-s3-action-btn', + S3_UPLOAD_BUTTON: 'conn-s3-upload-btn', SUBMIT_ACTION_BUTTON: 'conn-submit-action-btn', }; +export const ConnectionsWorkspaceQA = { + WORKSPACE: 'conn-workspace', +}; + export const ConnectionsFormQA = { AUTO_CREATE_DASH_CHECKBOX: 'conn-auto-create-dash-checkbox', CREATE_CHYT_TOKEN_AUTH_NAV: 'conn-create-token-auth-nav', diff --git a/src/shared/constants/qa/index.ts b/src/shared/constants/qa/index.ts index ea7d2efff0..723027be92 100644 --- a/src/shared/constants/qa/index.ts +++ b/src/shared/constants/qa/index.ts @@ -1,14 +1,15 @@ +export {VisualizationsQa} from './visualization'; +export * from './chart'; +export * from './collections'; export * from './components'; export * from './connections'; -export * from './chart'; -export * from './editor'; -export * from './datasets'; +export * from './control'; export * from './dash'; +export * from './datasets'; export * from './dl-navigation'; -export * from './wizard'; -export * from './control'; -export * from './ql'; +export * from './editor'; export * from './field-editor'; -export {VisualizationsQa} from './visualization'; -export * from './uikit'; +export * from './ql'; export * from './settings'; +export * from './uikit'; +export * from './wizard'; diff --git a/src/shared/constants/qa/wizard.ts b/src/shared/constants/qa/wizard.ts index 5ff750503b..a503f73a47 100644 --- a/src/shared/constants/qa/wizard.ts +++ b/src/shared/constants/qa/wizard.ts @@ -41,7 +41,7 @@ export const enum DialogColumnSettingsQa { export const enum DialogFieldSettingsQa { FieldTitleInput = 'dialog-title-input', - MarkdownEnableButton = 'dialog-field-md-switcher', + MarkupTypeRadioButtons = 'dialog-field-markup-type', } export const enum DialogFieldBackgroundSettingsQa { diff --git a/src/shared/constants/qa/workbooks.ts b/src/shared/constants/qa/workbooks.ts index d43b324c84..68a1f9e18b 100644 --- a/src/shared/constants/qa/workbooks.ts +++ b/src/shared/constants/qa/workbooks.ts @@ -1,5 +1,6 @@ -export enum WorkbookPage { +export enum WorkbookPageQa { ListItem = 'workbook-page-list-item', MenuDropDownBtn = 'workbook-page-list-item-menu-btn', MenuItemDuplicate = 'workbook-page-list-item-menu-item-duplicate', + Filters = 'workbook-page-filters', } diff --git a/src/shared/modules/charts-shared.ts b/src/shared/modules/charts-shared.ts index 147a71bdb5..0df2936acf 100644 --- a/src/shared/modules/charts-shared.ts +++ b/src/shared/modules/charts-shared.ts @@ -1,6 +1,5 @@ import {dateTime, dateTimeParse} from '@gravity-ui/date-utils'; import type {DurationUnit} from '@gravity-ui/date-utils'; -import isFunction from 'lodash/isFunction'; import type {ServerDatasetField} from '../types'; @@ -349,7 +348,3 @@ export function isObjectWith( return false; } - -export function isObjectWithFunction(value: unknown) { - return isObjectWith(value, isFunction, []); -} diff --git a/src/shared/modules/config/wizard/__test__/mapChartsConfigToLatestVersion.test.ts b/src/shared/modules/config/wizard/__test__/mapChartsConfigToLatestVersion.test.ts index 51e84d586c..8ea46133e9 100644 --- a/src/shared/modules/config/wizard/__test__/mapChartsConfigToLatestVersion.test.ts +++ b/src/shared/modules/config/wizard/__test__/mapChartsConfigToLatestVersion.test.ts @@ -8,6 +8,6 @@ describe('mapChartsConfigToLatestVersion', () => { const result = mapChartsConfigToLatestVersion(mockedConfigWithNumericVersion); - expect(result).toEqual({version: '11'}); + expect(result).toEqual({version: '12'}); }); }); diff --git a/src/shared/modules/config/wizard/mapChartsConfigToLatestVersion.ts b/src/shared/modules/config/wizard/mapChartsConfigToLatestVersion.ts index e548420dcc..732d4016af 100644 --- a/src/shared/modules/config/wizard/mapChartsConfigToLatestVersion.ts +++ b/src/shared/modules/config/wizard/mapChartsConfigToLatestVersion.ts @@ -3,6 +3,7 @@ import {ChartsConfigVersion} from '../../../types'; import {mapV1ConfigToV2} from './v1/mapV1ConfigToV2'; import {mapV10ConfigToV11} from './v10/mapV10ConfigToV11'; +import {mapV11ConfigToV12} from './v11/mapV11ConfigToV12'; import {mapV2ConfigToV3} from './v2/mapV2ConfigToV3'; import {mapV3ConfigToV4, migrateDatetime} from './v3/mapV3ConfigToV4'; import {mapV4ConfigToV5} from './v4/mapV4ConfigToV5'; @@ -68,5 +69,9 @@ export const mapChartsConfigToLatestVersion = ( config = mapV10ConfigToV11(config); } + if (config.version === ChartsConfigVersion.V11) { + config = mapV11ConfigToV12(config); + } + return config as ChartsConfig; }; diff --git a/src/shared/modules/config/wizard/v11/mapV11ConfigToV12.ts b/src/shared/modules/config/wizard/v11/mapV11ConfigToV12.ts new file mode 100644 index 0000000000..6157832130 --- /dev/null +++ b/src/shared/modules/config/wizard/v11/mapV11ConfigToV12.ts @@ -0,0 +1,24 @@ +import set from 'lodash/set'; + +import type {V11ChartsConfig, V12ChartsConfig} from '../../../../types'; +import {ChartsConfigVersion, MARKUP_TYPE} from '../../../../types'; + +function replaceObjectField(item: unknown) { + if (item && typeof item === 'object') { + if ('isMarkdown' in item) { + delete item['isMarkdown']; + set(item, 'markupType', MARKUP_TYPE.markdown); + } else { + Object.values(item).forEach(replaceObjectField); + } + } +} + +export const mapV11ConfigToV12 = (config: V11ChartsConfig): V12ChartsConfig => { + replaceObjectField(config); + + return { + ...config, + version: ChartsConfigVersion.V12, + }; +}; diff --git a/src/shared/modules/markdown/markdown.ts b/src/shared/modules/markdown/markdown.ts index 614f41f759..6c2bae4eb0 100644 --- a/src/shared/modules/markdown/markdown.ts +++ b/src/shared/modules/markdown/markdown.ts @@ -73,9 +73,20 @@ export function renderHTML(args: RenderHtmlArgs): RenderHtmlOutput { plugins.push(...additionalPlugins); } + // temp terms bug fix until the editor supports transform plugin + const preparedTextWithTermDefs = text.replace( + /^\s*?\\\[\\\*([\wа-я]+)\\\]:(.*?\S+?.*?)$/gim, + '[*$1]:$2', + ); + + const preparedTextWithTermLinks = preparedTextWithTermDefs.replace( + /(\[.+?\])\(\*(%.+?)\)/g, + (_, p1, p2) => `${p1}(*${decodeURIComponent(p2)})`, + ); + const { result: {html, meta}, - } = yfmTransform(text, { + } = yfmTransform(preparedTextWithTermLinks, { plugins, lang, vars: {}, diff --git a/src/shared/schema/bi/types/forms.ts b/src/shared/schema/bi/types/forms.ts index e64479aa6d..ad956b886d 100644 --- a/src/shared/schema/bi/types/forms.ts +++ b/src/shared/schema/bi/types/forms.ts @@ -4,7 +4,6 @@ import type { CheckboxProps, RadioButtonProps, RadioGroupProps, - SelectOption, SelectProps, TextAreaProps, TextInputProps, @@ -52,7 +51,7 @@ export type SelectItem = BaseItem & BaseControlItem & { id: 'select'; // option.data?.description is occupied for meta information in the select option. - availableValues?: SelectOption[]; + availableValues?: SelectProps['options']; hintText?: MarkdownString; controlProps?: Partial; loading?: boolean; diff --git a/src/shared/types/chartkit/d3/scatter.ts b/src/shared/types/chartkit/d3/scatter.ts index b19a69e9be..f21bc1cfb8 100644 --- a/src/shared/types/chartkit/d3/scatter.ts +++ b/src/shared/types/chartkit/d3/scatter.ts @@ -1,14 +1,15 @@ +import type {WrappedHTML} from '../../..'; import type {WrappedMarkup} from '../../../utils'; import type {WrappedMarkdown} from '../../../utils/markdown'; import type {SeriesExportSettings} from '../../wizard'; export type PointCustomData = { - name?: string | number | WrappedMarkdown | WrappedMarkup; - xLabel?: string | WrappedMarkdown; - yLabel?: string | WrappedMarkdown; - cLabel?: string | null | WrappedMarkdown; - sLabel?: string | null | WrappedMarkdown; - sizeLabel?: string | null | WrappedMarkdown; + name?: string | number | WrappedMarkdown | WrappedMarkup | WrappedHTML; + xLabel?: string | WrappedMarkdown | WrappedHTML; + yLabel?: string | WrappedMarkdown | WrappedHTML; + cLabel?: string | null | WrappedMarkdown | WrappedHTML; + sLabel?: string | null | WrappedMarkdown | WrappedHTML; + sizeLabel?: string | null | WrappedMarkdown | WrappedHTML; }; export type ScatterSeriesCustomData = { diff --git a/src/shared/types/charts.ts b/src/shared/types/charts.ts index 66ff853acb..587c8df86f 100644 --- a/src/shared/types/charts.ts +++ b/src/shared/types/charts.ts @@ -273,3 +273,11 @@ export interface ChartsStats extends Timings { columnsCount: number | null; rowsCount: number | null; } + +export const MARKUP_TYPE = { + none: 'none', + markdown: 'md', + html: 'html', +}; + +export type MarkupType = (typeof MARKUP_TYPE)[keyof typeof MARKUP_TYPE]; diff --git a/src/shared/types/config/wizard/index.ts b/src/shared/types/config/wizard/index.ts index a7de8637a3..7a5d2393bd 100644 --- a/src/shared/types/config/wizard/index.ts +++ b/src/shared/types/config/wizard/index.ts @@ -1,18 +1,21 @@ -import type {Shared, SharedData, V11PlaceholderSettings, V11TooltipConfig} from '../../index'; +import type {Shared, SharedData} from '../../index'; import type {V10ChartsConfig} from './v10'; +import type {V11ChartsConfig} from './v11'; import type { - V11ChartsConfig, - V11ChartsConfigDatasetField, - V11ColorsConfig, - V11CommonPlaceholders, - V11CommonSharedExtraSettings, - V11Field, - V11Filter, - V11Formatting, - V11HierarchyField, - V11Layer, -} from './v11'; + V12ChartsConfig, + V12ChartsConfigDatasetField, + V12ColorsConfig, + V12CommonPlaceholders, + V12CommonSharedExtraSettings, + V12Field, + V12Filter, + V12Formatting, + V12HierarchyField, + V12Layer, + V12PlaceholderSettings, + V12TooltipConfig, +} from './v12'; import type {V2ChartsConfig} from './v2'; import type {V3ChartsConfig} from './v3'; import type {V4ChartsConfig} from './v4'; @@ -32,8 +35,9 @@ export * from './v8'; export * from './v9'; export * from './v10'; export * from './v11'; +export * from './v12'; -export type ChartsConfig = V11ChartsConfig; +export type ChartsConfig = V12ChartsConfig; export type PreviousChartsConfigs = | Shared | V2ChartsConfig @@ -44,8 +48,9 @@ export type PreviousChartsConfigs = | V7ChartsConfig | V8ChartsConfig | V9ChartsConfig - | V10ChartsConfig; -export type CommonPlaceholders = V11CommonPlaceholders; + | V10ChartsConfig + | V11ChartsConfig; +export type CommonPlaceholders = V12CommonPlaceholders; export type ExtendedChartsConfig = ChartsConfig | PreviousChartsConfigs; @@ -71,28 +76,28 @@ export type ServerLayerSettings = NonNullable< ChartsConfig['visualization']['layers'] >[0]['layerSettings']; -export type ServerFieldFormatting = V11Formatting; +export type ServerFieldFormatting = V12Formatting; export type ServerShapesConfig = ChartsConfig['shapesConfig']; -export type ServerColorsConfig = V11ColorsConfig; +export type ServerColorsConfig = V12ColorsConfig; export type ServerPointSizeConfig = NonNullable; -export type ServerField = V11Field; +export type ServerField = V12Field; -export type ServerFilter = V11Filter; +export type ServerFilter = V12Filter; -export type ServerDatasetField = V11ChartsConfigDatasetField; +export type ServerDatasetField = V12ChartsConfigDatasetField; -export type ServerVisualizationLayer = V11Layer; +export type ServerVisualizationLayer = V12Layer; export type ServerLink = ChartsConfig['links'][0]; -export type ServerHierarchy = V11HierarchyField; +export type ServerHierarchy = V12HierarchyField; -export type ServerCommonSharedExtraSettings = V11CommonSharedExtraSettings; +export type ServerCommonSharedExtraSettings = V12CommonSharedExtraSettings; -export type ServerPlaceholderSettings = V11PlaceholderSettings; +export type ServerPlaceholderSettings = V12PlaceholderSettings; -export type ServerTooltipConfig = V11TooltipConfig; +export type ServerTooltipConfig = V12TooltipConfig; diff --git a/src/shared/types/config/wizard/v12.ts b/src/shared/types/config/wizard/v12.ts new file mode 100644 index 0000000000..905a357f26 --- /dev/null +++ b/src/shared/types/config/wizard/v12.ts @@ -0,0 +1,319 @@ +import type {MarkupType, WidgetSizeType} from '../../..'; +import type {ColorMode} from '../../../constants'; +import type {DatasetFieldCalcMode, ParameterDefaultValue} from '../../dataset'; +import type { + AxisLabelFormatMode, + AxisMode, + AxisNullsMode, + ChartsConfigVersion, + ColumnSettings, + HintSettings, + IndicatorTitleMode, + LabelsPositions, + NumberFormatType, + NumberFormatUnit, + TableBarsSettings, + TableFieldBackgroundSettings, + TableSubTotalsSettings, +} from '../../wizard'; + +export type V12ChartsConfig = { + title?: string; + colors: V12Color[]; + colorsConfig?: V12ColorsConfig; + extraSettings: V12CommonSharedExtraSettings | undefined; + filters: V12Filter[]; + geopointsConfig?: V12PointSizeConfig; + hierarchies: V12HierarchyField[]; + labels: V12Label[]; + links: V12Link[]; + sort: V12Sort[]; + tooltips: V12Tooltip[]; + tooltipConfig?: V12TooltipConfig; + type: 'datalens'; + updates: V12Update[]; + visualization: V12Visualization; + shapes: V12Shape[]; + shapesConfig?: V12ShapesConfig; + version: ChartsConfigVersion.V12; + datasetsIds: string[]; + datasetsPartialFields: V12ChartsConfigDatasetField[][]; + segments: V12Field[]; + chartType?: string; +}; + +export type V12Update = { + action: 'add_field' | 'add' | 'update_field' | 'update' | 'delete' | 'delete_field'; + field: any; + debug_info?: string; +}; + +export interface V12CommonSharedExtraSettings { + title?: string; + titleMode?: 'show' | 'hide'; + indicatorTitleMode?: IndicatorTitleMode; + legendMode?: 'show' | 'hide'; + metricFontSize?: string; + metricFontColor?: string; + tooltip?: 'show' | 'hide'; + tooltipSum?: 'on' | 'off'; + limit?: number; + pagination?: 'on' | 'off'; + navigatorMode?: string; + navigatorSeriesName?: string; + totals?: 'on' | 'off'; + pivotFallback?: 'on' | 'off'; + pivotInlineSort?: 'on' | 'off'; + stacking?: 'on' | 'off'; + overlap?: 'on' | 'off'; + feed?: string; + navigatorSettings?: V12NavigatorSettings; + enableGPTInsights?: boolean; + labelsPosition?: LabelsPositions; + pinnedColumns?: number; + size?: WidgetSizeType; +} + +export type V12NavigatorSettings = { + navigatorMode: string; + isNavigatorAvailable: boolean; + selectedLines: string[]; + linesMode: string; + periodSettings: { + type: string; + value: string; + period: string; + }; +}; + +export type V12Filter = { + guid: string; + datasetId: string; + disabled?: string; + filter: { + operation: { + code: string; + }; + value?: string | string[]; + }; + type: string; + title: string; + calc_mode: DatasetFieldCalcMode; +} & V12ClientOnlyFields; + +export type V12Sort = { + guid: string; + title: string; + source?: string; + datasetId: string; + direction: string; + data_type: string; + format?: string; + type: string; + default_value?: ParameterDefaultValue; +} & V12ClientOnlyFields; + +export type V12Link = { + id: string; + fields: Record; +}; + +export type V12LinkField = { + field: { + title: string; + guid: string; + }; + dataset: { + id: string; + realName: string; + }; +}; + +export type V12Visualization = { + id: string; + highchartsId?: string; + selectedLayerId?: string; + layers?: V12Layer[]; + placeholders: V12Placeholder[]; +}; + +export type V12LayerSettings = { + id: string; + name: string; + type: string; + alpha: number; + valid: boolean; +}; + +export type V12CommonPlaceholders = { + colors: V12Color[]; + labels: V12Label[]; + tooltips: V12Tooltip[]; + filters: V12Filter[]; + sort: V12Sort[]; + shapes?: V12Shape[]; + colorsConfig?: V12ColorsConfig; + geopointsConfig?: V12PointSizeConfig; + shapesConfig?: V12ShapesConfig; + tooltipConfig?: V12TooltipConfig; +}; + +export type V12Layer = { + id: string; + commonPlaceholders: V12CommonPlaceholders; + layerSettings: V12LayerSettings; + placeholders: V12Placeholder[]; +}; + +export type V12PlaceholderSettings = { + groupping?: 'disabled' | 'off'; + autoscale?: boolean; + scale?: 'auto' | 'manual'; + scaleValue?: '0-max' | [string, string]; + title?: 'auto' | 'manual' | 'off'; + titleValue?: 'string'; + type?: 'logarithmic'; + grid?: 'on' | 'off'; + gridStep?: 'manual'; + gridStepValue?: number; + hideLabels?: 'yes' | 'no'; + labelsView?: 'horizontal' | 'vertical' | 'angle'; + nulls?: AxisNullsMode; + holidays?: 'on' | 'off'; + axisFormatMode?: AxisLabelFormatMode; + axisModeMap?: Record; + disableAxisMode?: boolean; + /* Whether axis, including axis title, line, ticks and labels, should be visible + * @default 'show' + **/ + axisVisibility?: 'show' | 'hide'; +}; + +export type V12Placeholder = { + id: string; + settings?: V12PlaceholderSettings; + required?: boolean; + capacity?: number; + items: V12Field[]; +}; + +export type V12Color = { + datasetId: string; + guid: string; + title: string; + type: string; + data_type: string; + formatting?: V12Formatting; + calc_mode: DatasetFieldCalcMode; +} & V12ClientOnlyFields; + +export type V12Shape = { + datasetId: string; + guid: string; + title: string; + originalTitle?: string; + type: string; + data_type: string; + calc_mode: DatasetFieldCalcMode; +} & V12ClientOnlyFields; + +export type V12Tooltip = { + datasetId: string; + guid: string; + title: string; + formatting?: V12Formatting; + data_type: string; + calc_mode: DatasetFieldCalcMode; +} & V12ClientOnlyFields; + +export type V12Formatting = { + format?: NumberFormatType; + showRankDelimiter?: boolean; + prefix?: string; + postfix?: string; + unit?: NumberFormatUnit; + precision?: number; + labelMode?: string; +}; + +export type V12Label = { + datasetId: string; + type: string; + title: string; + guid: string; + formatting?: V12Formatting; + format?: string; + data_type: string; + calc_mode: DatasetFieldCalcMode; +}; + +export type V12HierarchyField = { + data_type: string; + fields: V12Field[]; + type: string; +}; + +export type V12PointSizeConfig = { + radius: number; + minRadius: number; + maxRadius: number; +}; + +export type V12Field = { + data_type: string; + fields?: V12Field[]; + type: string; + title: string; + guid: string; + formatting?: V12Formatting; + format?: string; + datasetId: string; + source?: string; + datasetName?: string; + hideLabelMode?: string; + calc_mode: DatasetFieldCalcMode; + default_value?: ParameterDefaultValue; + barsSettings?: TableBarsSettings; + subTotalsSettings?: TableSubTotalsSettings; + backgroundSettings?: TableFieldBackgroundSettings; + columnSettings?: ColumnSettings; + hintSettings?: HintSettings; +} & V12ClientOnlyFields; + +export type V12ColorsConfig = { + thresholdsMode?: string; + leftThreshold?: string; + middleThreshold?: string; + rightThreshold?: string; + gradientPalette?: string; + gradientMode?: string; + polygonBorders?: string; + reversed?: boolean; + fieldGuid?: string; + mountedColors?: Record; + coloredByMeasure?: boolean; + palette?: string; + colorMode?: ColorMode; +}; + +export type V12ShapesConfig = { + mountedShapes?: Record; + fieldGuid?: string; +}; + +export type V12TooltipConfig = { + color?: 'on' | 'off'; + fieldTitle?: 'on' | 'off'; +}; + +export type V12ChartsConfigDatasetField = { + guid: string; + title: string; + calc_mode?: DatasetFieldCalcMode; +}; + +export type V12ClientOnlyFields = { + fakeTitle?: string; + originalTitle?: string; + markupType?: MarkupType; +}; diff --git a/src/shared/types/dash.ts b/src/shared/types/dash.ts index e0c78bcf4e..7ffa9bd692 100644 --- a/src/shared/types/dash.ts +++ b/src/shared/types/dash.ts @@ -1,6 +1,5 @@ import type {ItemDropProps} from '@gravity-ui/dashkit'; -import type {DASH_INFO_HEADER} from '../constants'; import type {Operations} from '../modules'; import type {ClientChartsConfig, Dictionary, Entry, EntryScope, StringParams} from './index'; @@ -9,7 +8,7 @@ export enum ControlType { Dash = 'control_dash', } -export type DashChartRequestContext = Record; +export type DashChartRequestContext = Record; export enum DashTabItemType { Title = 'title', @@ -121,8 +120,8 @@ export type DashTabItem = | DashTabItemImage; type BackgroundSettings = { + enabled?: boolean; color: string; - enabled: boolean; }; export interface DashTabItemBase { diff --git a/src/shared/types/feature.ts b/src/shared/types/feature.ts index 8e007e76e8..ed20fc34ba 100644 --- a/src/shared/types/feature.ts +++ b/src/shared/types/feature.ts @@ -19,6 +19,7 @@ export enum Feature { FetchDocumentation = 'FetchDocumentation', Comments = 'Comments', EmptySelector = 'emptySelector', + // Check access rights when processing ChartEditor charts ChartEditorDeveloperModeCheck = 'ChartEditorDeveloperModeCheck', QLPrometheus = 'QLPrometheus', QLMonitoring = 'QLMonitoring', @@ -28,13 +29,16 @@ export enum Feature { DashBoardSupportDescription = 'DashBoardSupportDescription', DashAutorefresh = 'DashAutorefresh', GSheetsV2Enabled = 'GSheetsV2Enabled', + // Show request body in the Inspector dialog ShowInspectorDetails = 'ShowInspectorDetails', + // Prohibiting the serialization of functions in the chart configs NoJsonFn = 'NoJsonFn', GSheetGoogleAuthEnabled = 'GSheetGoogleAuthEnabled', DatasetsRLS = 'DatasetsRLS', + // The ability to upload xlsx files for file connections XlsxFilesEnabled = 'XlsxFilesEnabled', XlsxChartExportEnabled = 'XlsxChartExportEnabled', - GroupControls = 'GroupControls', + // Escaping field values in chart tooltips (only scatter, treemap, geopoints visualizations) EscapeUserHtmlInDefaultHcTooltip = 'EscapeUserHtmlInDefaultHcTooltip', HolidaysOnChart = 'HolidaysOnChart', ReadOnlyMode = 'ReadOnlyMode', @@ -59,7 +63,6 @@ export enum Feature { MultipleColorsInVisualization = 'MultipleColorsInVisualization', ConnectionBasedControl = 'ConnectionBasedControl', EnableServerlessEditor = 'EnableServerlessEditor', - ChartWithFnLogging = 'ChartWithFnLogging', EnableFooter = 'EnableFooter', MassRemoveCollectionsWorkbooks = 'MassRemoveCollectionsWorkbooks', /* Enable dashboard fixed header */ @@ -69,8 +72,6 @@ export enum Feature { NewTableWidgetForCE = 'NewTableWidgetForCE', /** Use BI data for connector icons rendering (connections, ql, workbooks, navigation) */ EnableBIConnectorIcons = 'EnableBIConnectorIcons', - /** Enable undo/redo buttons & hotkeys in ql */ - EnableEditHistoryQL = 'EnableEditHistoryQL', /** Enable undo/redo buttons & hotkeys in datasets */ EnableEditHistoryDatasets = 'EnableEditHistoryDataset', /** Depends on US feature UseMovePermAction. @@ -79,6 +80,8 @@ export enum Feature { UseMovePermAction = 'UseMovePermAction', /** An empty chart for drawing something unusual */ BlankChart = 'BlankChart', + /** Add a setting to display html in wizard */ + HtmlInWizard = 'HtmlInWizard', /** Additional chart config for making requests by widget events */ ChartActions = 'ChartActions', } diff --git a/src/shared/types/utility-types.ts b/src/shared/types/utility-types.ts index 35d9e84b77..a897b0b5e7 100644 --- a/src/shared/types/utility-types.ts +++ b/src/shared/types/utility-types.ts @@ -40,3 +40,5 @@ export type NonNullableBy = Omit & NoUndefinedField< type ObjectKeys = `${Exclude}`; export const objectKeys = Object.keys as (value: T) => Array>; + +export type ValueOf = T[keyof T]; diff --git a/src/shared/types/wizard/field.ts b/src/shared/types/wizard/field.ts index d865004196..8db804abfc 100644 --- a/src/shared/types/wizard/field.ts +++ b/src/shared/types/wizard/field.ts @@ -1,4 +1,5 @@ -import type {FilterBody} from '../charts'; +import {MARKUP_TYPE} from '../charts'; +import type {FilterBody, MarkupType} from '../charts'; import type {ServerField} from '../config/wizard'; import type {DatasetField, DatasetFieldType} from '../dataset'; import {DATASET_FIELD_TYPES} from '../dataset'; @@ -44,7 +45,7 @@ export interface WizardDatasetField extends DatasetField { backgroundSettings?: TableFieldBackgroundSettings; distincts?: string[]; hintSettings?: HintSettings; - isMarkdown?: boolean; + markupType?: MarkupType; } export type HintSettings = { @@ -118,8 +119,12 @@ export function isStringField(field: {data_type: string}) { return field.data_type === DATASET_FIELD_TYPES.STRING; } -export function isMarkdownField(field?: {data_type: string; isMarkdown?: boolean}) { - return field && isStringField(field) && field.isMarkdown; +export function isMarkdownField(field?: {data_type: string; markupType?: MarkupType}) { + return Boolean(field && isStringField(field) && field.markupType === MARKUP_TYPE.markdown); +} + +export function isHtmlField(field?: {data_type: string; markupType?: MarkupType}) { + return Boolean(field && isStringField(field) && field.markupType === MARKUP_TYPE.html); } export function isNumberField(field?: {data_type: string}): field is NumberField { diff --git a/src/shared/types/wizard/versions.ts b/src/shared/types/wizard/versions.ts index 2ee9e78858..69f52047be 100644 --- a/src/shared/types/wizard/versions.ts +++ b/src/shared/types/wizard/versions.ts @@ -25,4 +25,6 @@ export enum ChartsConfigVersion { V10 = '10', // Added new field for displaying the title in the indicator charts. V11 = '11', + // isMarkdown boolean field is converted to a string markupType. + V12 = '12', } diff --git a/src/shared/utils/ui-sandbox.ts b/src/shared/utils/ui-sandbox.ts index a6012391a6..5669732165 100644 --- a/src/shared/utils/ui-sandbox.ts +++ b/src/shared/utils/ui-sandbox.ts @@ -1,7 +1,7 @@ import {WRAPPED_HTML_KEY} from '../constants'; import type {ChartKitHtmlItem} from '../types'; -export function wrapHtml(value: ChartKitHtmlItem) { +export function wrapHtml(value: ChartKitHtmlItem | string) { return { [WRAPPED_HTML_KEY]: value, }; diff --git a/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/CollectionNoCreatePermissionDialog.tsx b/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/CollectionNoCreatePermissionDialog.tsx index aaa45440ca..2895b0fc9a 100644 --- a/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/CollectionNoCreatePermissionDialog.tsx +++ b/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/CollectionNoCreatePermissionDialog.tsx @@ -1,9 +1,10 @@ import React from 'react'; import {I18n} from 'i18n'; -import {YfmWrapperContent as YfmWrapper} from '../../YfmWrapper/YfmWrapperContent'; import DialogInfo from 'ui/components/DialogInfo/DialogInfo'; + import DialogManager from '../../DialogManager/DialogManager'; +import {YfmWrapperContent as YfmWrapper} from '../../YfmWrapper/YfmWrapperContent'; const i18n = I18n.keyset('component.dialog-collection-no-create-permission.view'); export const DIALOG_NO_CREATE_COLLECTION_PERMISSION = Symbol('DIALOG_CREATE_WORKBOOK'); @@ -14,30 +15,26 @@ export type Props = { }; export type OpenDialogCollectionNoCreatePermissionArgs = { - id: typeof DIALOG_NO_CREATE_COLLECTION_PERMISSION, - props: Props -} + id: typeof DIALOG_NO_CREATE_COLLECTION_PERMISSION; + props: Props; +}; -export const CollectionNoCreatePermissionDialog = React.memo( - ({visible, onClose}) => { - return ( - - } - isWarning={true} - /> - ); - }, -); +export const CollectionNoCreatePermissionDialog = React.memo(({visible, onClose}) => { + return ( + } + isWarning={true} + /> + ); +}); CollectionNoCreatePermissionDialog.displayName = 'CollectionNoCreatePermissionDialog'; -DialogManager.registerDialog(DIALOG_NO_CREATE_COLLECTION_PERMISSION, CollectionNoCreatePermissionDialog); \ No newline at end of file +DialogManager.registerDialog( + DIALOG_NO_CREATE_COLLECTION_PERMISSION, + CollectionNoCreatePermissionDialog, +); diff --git a/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/index.ts b/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/index.ts index 4ff297d7a4..678ee4c4b1 100644 --- a/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/index.ts +++ b/src/ui/components/CollectionsStructure/CollectionNoCreatePermissionDialog/index.ts @@ -1 +1 @@ -export * from './CollectionNoCreatePermissionDialog' +export * from './CollectionNoCreatePermissionDialog'; diff --git a/src/ui/components/CollectionsStructure/CreateWorkbookDialog.tsx b/src/ui/components/CollectionsStructure/CreateWorkbookDialog.tsx index e19524ddf7..1cf8e0b90a 100644 --- a/src/ui/components/CollectionsStructure/CreateWorkbookDialog.tsx +++ b/src/ui/components/CollectionsStructure/CreateWorkbookDialog.tsx @@ -29,39 +29,50 @@ type Props = { onApply?: (result: CreateWorkbookResponse | null) => void | Promise; }; -export const CreateWorkbookDialog: React.FC = (props) => { +export const CreateWorkbookDialog: React.FC = ({ + collectionId, + open, + dialogTitle, + defaultWorkbookTitle, + onClose, + onApply, +}) => { const dispatch: AppDispatch = useDispatch(); - const {open, dialogTitle, defaultWorkbookTitle, onClose} = props; - const handleApply = async ({title, description}: {title: string; description?: string}) => { - const {collectionId, onApply} = props; + const isLoading = useSelector(selectCreateWorkbookIsLoading); - const result = await dispatch( - createWorkbook({ - title, - description: description ?? '', - collectionId, - }), - ); + const [isExternalLoading, setIsExternalLoading] = React.useState(false); - if (onApply) { - const promise = onApply(result); - if (promise) { - await promise; - } - } + const handleApply = React.useCallback( + async ({title, description}: {title: string; description?: string}) => { + const result = await dispatch( + createWorkbook({ + title, + description: description ?? '', + collectionId, + }), + ); - return result; - }; + if (onApply) { + const promise = onApply(result); + if (promise) { + setIsExternalLoading(true); + await promise; + setIsExternalLoading(false); + } + } - const isLoading = useSelector(selectCreateWorkbookIsLoading); + return result; + }, + [collectionId, dispatch, onApply], + ); return ( DashChartRequestContext; + dataProviderContextGetter?: (widgetId: string) => DashChartRequestContext; setWidgetCurrentTab?: (payload: {widgetId: string; tabId: string}) => void; } diff --git a/src/ui/components/DashKit/plugins/Control/Control.tsx b/src/ui/components/DashKit/plugins/Control/Control.tsx index 3780cd7e80..f09533afdd 100644 --- a/src/ui/components/DashKit/plugins/Control/Control.tsx +++ b/src/ui/components/DashKit/plugins/Control/Control.tsx @@ -427,7 +427,9 @@ class Control extends React.PureComponent { const {getDistincts} = this.props; - const headers = this?.context?.dataProviderContextGetter?.(); + const headers = this?.context?.dataProviderContextGetter?.(this.props.id); return (getDistincts as Exclude)?.( params, diff --git a/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx b/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx index 20bdba4bd0..0c036c834d 100644 --- a/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx +++ b/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx @@ -99,7 +99,7 @@ type ControlProps = { }) => void; silentLoading: boolean; getDistincts?: ControlSettings['getDistincts']; - requestHeaders?: Record; + requestHeaders?: () => Record; onChange: ({ params, callChangeByClick, @@ -226,7 +226,7 @@ export const Control = ({ ...(workbookId ? {workbookId} : {}), }, cancelToken: payloadCancellation.token, - headers: requestHeaders, + headers: requestHeaders?.(), }; cancelCurrentRunRequest(); diff --git a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx index 34b79976a8..6462c64955 100644 --- a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx +++ b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx @@ -686,7 +686,7 @@ class GroupControl extends React.PureComponent { const {getDistincts} = this.props; - const headers = this?.context?.dataProviderContextGetter?.(); + const headers = this?.context?.dataProviderContextGetter?.(this.props.id); return (getDistincts as Exclude)?.( params, @@ -700,10 +700,17 @@ class GroupControl extends React.PureComponent { + if (this.context?.dataProviderContextGetter) { + return this.context.dataProviderContextGetter(this.props.id); + } + + return {}; + }; + private renderControl(item: DashTabItemControlSingle) { const {workbookId} = this.props; const {silentLoading} = this.state; - const dataProviderContextGetter = this?.context?.dataProviderContextGetter?.(); return ( ); } diff --git a/src/ui/components/DashKit/plugins/Image/Image.tsx b/src/ui/components/DashKit/plugins/Image/Image.tsx index 0bf4ad729e..bc8797979e 100644 --- a/src/ui/components/DashKit/plugins/Image/Image.tsx +++ b/src/ui/components/DashKit/plugins/Image/Image.tsx @@ -4,6 +4,7 @@ import type {Plugin, PluginWidgetProps} from '@gravity-ui/dashkit'; import block from 'bem-cn-lite'; import type {DashTabItemImage} from 'shared'; import {DashTabItemType} from 'shared'; +import {CustomPaletteColors} from 'ui/units/dash/containers/Dialogs/components/PaletteBackground/PaletteBackground'; import {useBeforeLoad} from '../../../../hooks/useBeforeLoad'; import {getPreparedWrapSettings} from '../../utils'; @@ -31,7 +32,9 @@ function PluginImage(props: Props, _ref?: React.LegacyRef) { w: null, }; const backgroundEnabled = Boolean( - background?.enabled && background?.color && background?.color !== 'transparent', + background?.enabled !== false && + background?.color && + background?.color !== CustomPaletteColors.NONE, ); const {classMod, style} = React.useMemo(() => { return getPreparedWrapSettings(backgroundEnabled, background?.color); diff --git a/src/ui/components/DashKit/plugins/RendererWrapper/RendererWrapper.scss b/src/ui/components/DashKit/plugins/RendererWrapper/RendererWrapper.scss index e3a3517395..769b1da315 100644 --- a/src/ui/components/DashKit/plugins/RendererWrapper/RendererWrapper.scss +++ b/src/ui/components/DashKit/plugins/RendererWrapper/RendererWrapper.scss @@ -6,6 +6,7 @@ &_widget { width: 100%; + position: relative; } &_with-default-color { diff --git a/src/ui/components/DashKit/plugins/Text/Text.tsx b/src/ui/components/DashKit/plugins/Text/Text.tsx index c10ede5e3a..4952ffad52 100644 --- a/src/ui/components/DashKit/plugins/Text/Text.tsx +++ b/src/ui/components/DashKit/plugins/Text/Text.tsx @@ -12,6 +12,7 @@ import { } from 'ui/components/DashKit/utils'; import {YFM_MARKDOWN_CLASSNAME} from 'ui/constants/yfm'; import {usePrevious} from 'ui/hooks'; +import {CustomPaletteColors} from 'ui/units/dash/containers/Dialogs/components/PaletteBackground/PaletteBackground'; import {useBeforeLoad} from '../../../../hooks/useBeforeLoad'; import {YfmWrapper} from '../../../YfmWrapper/YfmWrapper'; @@ -149,9 +150,9 @@ const textPlugin = { const data = props.data as DashTabItemText['data']; const showBgColor = Boolean( - data.background?.enabled && + data.background?.enabled !== false && data.background?.color && - data.background?.color !== 'transparent', + data.background?.color !== CustomPaletteColors.NONE, ); const {classMod, style} = getPreparedWrapSettings(showBgColor, data.background?.color); @@ -186,7 +187,6 @@ const textPlugin = { currentLayout.w, classMod, data.background?.color, - data.background?.enabled, ]); /** diff --git a/src/ui/components/DashKit/plugins/Title/Title.tsx b/src/ui/components/DashKit/plugins/Title/Title.tsx index 8c1b58cce8..874bb4733e 100644 --- a/src/ui/components/DashKit/plugins/Title/Title.tsx +++ b/src/ui/components/DashKit/plugins/Title/Title.tsx @@ -13,6 +13,7 @@ import { adjustWidgetLayout as dashkitAdjustWidgetLayout, getPreparedWrapSettings, } from 'ui/components/DashKit/utils'; +import {CustomPaletteColors} from 'ui/units/dash/containers/Dialogs/components/PaletteBackground/PaletteBackground'; import {useBeforeLoad} from '../../../../hooks/useBeforeLoad'; import {RendererWrapper} from '../RendererWrapper/RendererWrapper'; @@ -95,9 +96,9 @@ const titlePlugin: PluginTitle = { const content = ; const showBgColor = Boolean( - data.background?.enabled && + data.background?.enabled !== false && data.background?.color && - data.background?.color !== 'transparent', + data.background?.color !== CustomPaletteColors.NONE, ); const {classMod, style} = getPreparedWrapSettings(showBgColor, data.background?.color); @@ -119,7 +120,6 @@ const titlePlugin: PluginTitle = { currentLayout.w, classMod, data.background?.color, - data.background?.enabled, data.size, data.text, ]); @@ -159,7 +159,6 @@ const titlePlugin: PluginTitle = { currentLayout.w, data.text, data.size, - data.background?.enabled, calculateAnchor, showAnchor, ]); diff --git a/src/ui/components/DashKit/plugins/Widget/types.ts b/src/ui/components/DashKit/plugins/Widget/types.ts index 57af5d45f3..c0e2389724 100644 --- a/src/ui/components/DashKit/plugins/Widget/types.ts +++ b/src/ui/components/DashKit/plugins/Widget/types.ts @@ -21,7 +21,7 @@ export type CurrentTab = { autoHeight?: boolean; enableActionParams?: boolean; background?: { - enabled: boolean; + enabled?: boolean; color: string; }; }; diff --git a/src/ui/components/DialogChartWidget/DialogChartWidget.scss b/src/ui/components/DialogChartWidget/DialogChartWidget.scss index f16c7a214d..9b7cfd2533 100644 --- a/src/ui/components/DialogChartWidget/DialogChartWidget.scss +++ b/src/ui/components/DialogChartWidget/DialogChartWidget.scss @@ -40,21 +40,23 @@ flex-direction: column; } - &__help-tooltip { - line-height: 16px; - margin-left: 5px; - } - &__navigation-input-container { display: grid; grid-auto-rows: 40px; align-items: center; } - &__textarea-wrapper { - display: flex; + &__textarea { height: 80px; - padding: 6px 0; + width: 330px; + } + + &__row { + margin-bottom: var(--g-spacing-2); + } + + &__checkbox { + margin-block-start: var(--g-spacing-2); } .widget-item-dialog__line { @@ -82,12 +84,6 @@ align-items: center; } - &__input { - width: 330px; - margin-right: 10px; - display: inline-flex; - } - &__add-param-button { margin-left: 175px; } @@ -116,17 +112,6 @@ } } - &__caption { - &_inactive { - opacity: 0.3; - } - } - - &__caption-text { - position: relative; - top: 1px; - } - &__error { color: var(--g-color-text-danger); padding: 10px; diff --git a/src/ui/components/DialogChartWidget/DialogChartWidget.tsx b/src/ui/components/DialogChartWidget/DialogChartWidget.tsx index 71072c27ff..4e771bb0a8 100644 --- a/src/ui/components/DialogChartWidget/DialogChartWidget.tsx +++ b/src/ui/components/DialogChartWidget/DialogChartWidget.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import {HelpPopover} from '@gravity-ui/components'; -import {Checkbox, Dialog, Link, Popup, TextArea, TextInput} from '@gravity-ui/uikit'; +import {FormRow, HelpPopover} from '@gravity-ui/components'; +import {Checkbox, Dialog, Link, Popup, Text, TextArea, TextInput} from '@gravity-ui/uikit'; import block from 'bem-cn-lite'; import {i18n} from 'i18n'; import type {CustomCommands, Spec} from 'immutability-helper'; @@ -62,21 +62,6 @@ const isWidgetTypeWithAutoHeight = (widgetType?: WidgetKind) => { ); }; -type LineProps = { - className?: string; - caption: React.ReactNode; - children?: React.ReactNode; -}; - -function Line(props: LineProps) { - return ( -
-
{props.caption}
-
{props.children}
-
- ); -} - type AfterSettingsWidgetCallback = ((selectedWidgetType: WidgetKind) => void) | null; export interface DialogChartWidgetFeatureProps { @@ -122,6 +107,11 @@ type DialogChartWidgetState = { hierarchies?: HierarchyField[]; }; +const INPUT_FILTERING_ID = 'chartFilteringField'; +const INPUT_NAME_ID = 'chartNameField'; +const INPUT_DESCRIPTION_ID = 'chartDescriptionField'; +const INPUT_AUTOHEIGHT_ID = 'chartAutoheightField'; + // TODO: put in defaultPath navigation key from entry class DialogChartWidget extends React.PureComponent< DialogChartWidgetProps, @@ -141,7 +131,6 @@ class DialogChartWidget extends React.PureComponent< isDefault: true, description: '', background: { - enabled: false, color: 'transparent', }, }, @@ -365,29 +354,6 @@ class DialogChartWidget extends React.PureComponent< }); }; - handleBackgroundEnabledChanged = () => { - const {data, tabIndex} = this.state; - - if (!data.tabs[tabIndex].background) { - data.tabs[tabIndex].background = { - enabled: false, - color: 'transparent', - }; - } - - this.setState({ - data: update(data, { - tabs: { - [tabIndex]: { - background: { - enabled: {$set: !data.tabs[tabIndex].background?.enabled}, - }, - }, - }, - }), - }); - }; - handleBackgroundColorSelected = (color: string) => { const {data, tabIndex} = this.state; @@ -551,32 +517,32 @@ class DialogChartWidget extends React.PureComponent< canUseFiltration && data.tabs[tabIndex].enableActionParams, ); - const caption = ( -
- - {i18n('dash.widget-dialog.edit', 'label_filtering-other-charts')} - - -
+ const helpPopover = ( + ); return ( - +
- {i18n('dash.widget-dialog.edit', 'field_enable-filtering-other-charts')} - + /> {this.getHierarchyWarning()}
-
+ ); }; @@ -591,27 +557,24 @@ class DialogChartWidget extends React.PureComponent< changeNavigationPath, } = this.props; - const autoHeightCheckboxCaption = ( -
- - {i18n('dash.widget-dialog.edit', 'field_autoheight')} - - -
+ const autoHeightHelpPopover = ( + ); const {title, chartId, description, autoHeight, background} = data.tabs[tabIndex]; return ( - + )} - - +
- - -
-