From 005b616adb9db358de0b32b961d8159badcb674b Mon Sep 17 00:00:00 2001 From: YuryShkoda Date: Mon, 6 Jul 2026 15:44:27 +0300 Subject: [PATCH] chore(deps): upgrade Handsontable to v18 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bump handsontable and @handsontable/angular-wrapper 17.1 -> 18.0 and adapt to its stricter TypeScript-core types: moved handsontable/common and deep walkontable imports to their new public export paths, added explicit generics/casts where getData()/getCellMeta()/getSelected() are now typed unknown/nullable instead of the loose v17 shapes, and updated the AutocompleteEditor override to the new open() signature. Also allowlists @handsontable/angular-wrapper@18.0.0 and handsontable@18.0.0 in licenseChecker.js — both versions report the same non-SPDX "SEE LICENSE IN LICENSE.txt" field that license-checker mis-resolves as a disallowed custom license, same as prior versions. --- .vscode/settings.json | 1 + client/licenseChecker.js | 2 +- client/package-lock.json | 733 +----------------- client/package.json | 4 +- client/src/app/editor/editor.component.ts | 22 +- .../multi-dataset/multi-dataset.component.ts | 22 +- .../editors/numericAutocomplete.ts | 10 +- .../app/shared/hot-export/hot-export.util.ts | 12 +- client/src/app/viewer/viewer.component.ts | 4 +- 9 files changed, 59 insertions(+), 751 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index e809de2..7184c39 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "cSpell.words": [ + "Handsontable", "Licence", "SYSERRORTEXT", "SYSWARNINGTEXT", diff --git a/client/licenseChecker.js b/client/licenseChecker.js index 52151df..f0dd03f 100644 --- a/client/licenseChecker.js +++ b/client/licenseChecker.js @@ -10,7 +10,7 @@ const check = (cwd) => { onlyAllow: 'AFLv2.1;Apache 2.0;Apache-2.0;Apache*;Artistic-2.0;0BSD;BSD*;BSD-2-Clause;BSD-3-Clause;CC0-1.0;CC-BY-3.0;CC-BY-4.0;ISC;MIT;MPL-2.0;ODC-By-1.0;Python-2.0;Unlicense;', excludePackages: - '@cds/city@1.1.0;@handsontable/angular-wrapper@16.0.1;@handsontable/angular-wrapper@17.1.0;handsontable@^16.0.1;handsontable@16.2.0;handsontable@17.1.0;hyperformula@2.7.1;hyperformula@3.0.0;hyperformula@3.1.0;hyperformula@3.2.0;hyperformula@3.3.0;jackspeak@3.4.3;path-scurry@1.11.1;package-json-from-dist@1.0.1;buffers@0.1.1' + '@cds/city@1.1.0;@handsontable/angular-wrapper@16.0.1;@handsontable/angular-wrapper@17.1.0;@handsontable/angular-wrapper@18.0.0;handsontable@^16.0.1;handsontable@16.2.0;handsontable@17.1.0;handsontable@18.0.0;hyperformula@2.7.1;hyperformula@3.0.0;hyperformula@3.1.0;hyperformula@3.2.0;hyperformula@3.3.0;jackspeak@3.4.3;path-scurry@1.11.1;package-json-from-dist@1.0.1;buffers@0.1.1' }, (error, json) => { if (error) { diff --git a/client/package-lock.json b/client/package-lock.json index 150c55c..f01951a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -20,7 +20,7 @@ "@clr/angular": "file:libraries/clr-angular-17.9.0.tgz", "@clr/icons": "^13.0.2", "@clr/ui": "file:libraries/clr-ui-17.9.0.tgz", - "@handsontable/angular-wrapper": "^17.1.0", + "@handsontable/angular-wrapper": "^18.0.0", "@sasjs/adapter": "^4.17.0", "@sasjs/utils": "^3.5.3", "@sheet/crypto": "file:libraries/sheet-crypto.tgz", @@ -33,7 +33,7 @@ "d3-graphviz": "^5.0.2", "exceljs": "^4.4.0", "fs-extra": "^7.0.1", - "handsontable": "^17.1.0", + "handsontable": "^18.0.0", "https-browserify": "1.0.0", "hyperformula": "^2.5.0", "iconv-lite": "^0.5.0", @@ -3714,20 +3714,6 @@ "node": ">=14.17.0" } }, - "node_modules/@egjs/hammerjs": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", - "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/hammerjs": "^2.0.36" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", @@ -4361,25 +4347,19 @@ } }, "node_modules/@handsontable/angular-wrapper": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@handsontable/angular-wrapper/-/angular-wrapper-17.1.0.tgz", - "integrity": "sha512-5jUCb4E1eZcy/CJ3T39/cxauy9NoQh+wNWTDW9ZhIIudr/00HvfJlcEozN5RWSYxfGNw71prVM2y16DSd+ct9A==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@handsontable/angular-wrapper/-/angular-wrapper-18.0.0.tgz", + "integrity": "sha512-1DTV9lqE7vn2sZbB2hyrMcqhjnGWzYAHPGDGKuJlppzugjZcobYTPIFv5Dn9NOBUrKxRyPXI5dUb5SqwzYbJNw==", "license": "SEE LICENSE IN LICENSE.txt", "optionalDependencies": { "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/core": ">=16.0.0 <22.0.0", - "handsontable": "^17.0.0", + "@angular/core": ">=16.0.0 <23.0.0", + "handsontable": "^18.0.0", "rxjs": "^7.0.0" } }, - "node_modules/@handsontable/pikaday": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@handsontable/pikaday/-/pikaday-1.0.0.tgz", - "integrity": "sha512-1VN6N38t5/DcjJ7y7XUYrDx1LuzvvzlrFdBdMG90Qo1xc8+LXHqbWbsTEm5Ec5gXTEbDEO53vUT35R+2COmOyg==", - "license": "(0BSD OR MIT)" - }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -6088,9 +6068,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6108,9 +6085,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6128,9 +6102,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6148,9 +6119,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6168,9 +6136,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6188,9 +6153,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6208,9 +6170,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7346,9 +7305,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7370,9 +7326,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7394,9 +7347,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7418,9 +7368,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7442,9 +7389,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7466,9 +7410,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7694,9 +7635,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7711,9 +7649,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7728,9 +7663,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7745,9 +7677,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7762,9 +7691,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7779,9 +7705,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7796,9 +7719,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7813,9 +7733,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7830,9 +7747,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7847,9 +7761,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7864,9 +7775,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7881,9 +7789,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7898,9 +7803,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -8668,14 +8570,6 @@ "@types/node": "*" } }, - "node_modules/@types/hammerjs": { - "version": "2.0.46", - "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz", - "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/@types/http-errors": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", @@ -9072,29 +8966,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", - "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.59.1", - "@typescript-eslint/types": "^8.59.1", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.31.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz", @@ -9127,24 +8998,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", - "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, "node_modules/@typescript-eslint/type-utils": { "version": "8.31.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.31.1.tgz", @@ -9207,21 +9060,6 @@ "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", - "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.31.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz", @@ -9289,168 +9127,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.1.tgz", - "integrity": "sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/typescript-estree": "8.59.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", - "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", - "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/project-service": "8.59.1", - "@typescript-eslint/tsconfig-utils": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", - "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "8.59.1", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "peer": true, - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.31.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz", @@ -9662,13 +9338,6 @@ "@xtuc/long": "4.2.2" } }, - "node_modules/@webcomponents/custom-elements": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@webcomponents/custom-elements/-/custom-elements-1.6.0.tgz", - "integrity": "sha512-CqTpxOlUCPWRNUPZDxT5v2NnHXA4oox612iUGnmTUGQFhZ1Gkj8kirtl/2wcF6MqX7+PqqicZzOCBKKfIn0dww==", - "license": "BSD-3-Clause", - "peer": true - }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -10569,15 +10238,6 @@ "node": "*" } }, - "node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/binary": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", @@ -10754,14 +10414,6 @@ "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", "license": "MIT" }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true, - "license": "ISC", - "peer": true - }, "node_modules/browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -11713,20 +11365,6 @@ "node": ">=4.0.0" } }, - "node_modules/component-emitter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-2.0.0.tgz", - "integrity": "sha512-4m5s3Me2xxlVKG9PkZpQqHQR7bgpnN7joDMJ4yvVkVXngjoITG76IaZmzmywSeRTeTpc6N6r3H3+KyUurV8OYw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/compress-commons": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", @@ -13234,15 +12872,6 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/dompurify": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.5.tgz", - "integrity": "sha512-OrwIBKsdNSVEeubdJ1HBv/wNENRM9ytAVCv7YXt//A3vPdVMNuACRqK9mXCGCBW2ln7BT/A4X0jXHo2Gu89miA==", - "license": "(MPL-2.0 OR Apache-2.0)", - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" - } - }, "node_modules/domutils": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", @@ -15405,30 +15034,10 @@ } }, "node_modules/handsontable": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/handsontable/-/handsontable-17.1.0.tgz", - "integrity": "sha512-3afpoGQT04i11IYge4gZNHp4Io3RFoLi+vVk4yTc2oHGjuBJBhjVVlTnOcYM8N9Ay1ikjSh4T3ZiwFVYEsgJrA==", - "license": "SEE LICENSE IN LICENSE.txt", - "dependencies": { - "@handsontable/pikaday": "^1.0.0", - "dompurify": "^3.1.7", - "moment": "2.30.1", - "numbro": "2.5.0" - }, - "optionalDependencies": { - "hyperformula": "^3.0.0" - } - }, - "node_modules/handsontable/node_modules/hyperformula": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/hyperformula/-/hyperformula-3.3.0.tgz", - "integrity": "sha512-Mkc7AxP9WQDM4xHo1/XpAwzcpMLkwMand4HO9rfRzP502TBzoR1Z96zoCzRrwXodLSVyh+MD7FvzRVALDxmRFQ==", - "license": "GPL-3.0-only", - "optional": true, - "dependencies": { - "chevrotain": "^6.5.0", - "tiny-emitter": "^2.1.0" - } + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/handsontable/-/handsontable-18.0.0.tgz", + "integrity": "sha512-U4H6gDrwGTfjahSyoGHhFHZvOZWB7ReQ3iBvJUIcZPdqdppdZ+FSYNovw+3MH1guJfGgRIhoLYnbSm8Gd6Ft8w==", + "license": "SEE LICENSE IN LICENSE.txt" }, "node_modules/has-flag": { "version": "4.0.0", @@ -15540,17 +15149,6 @@ "node": ">= 0.4" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "he": "bin/he" - } - }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -17499,14 +17097,6 @@ "node": ">=10" } }, - "node_modules/keycharm": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", - "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", - "dev": true, - "license": "(Apache-2.0 OR MIT)", - "peer": true - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -19192,196 +18782,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mocha": { - "version": "11.7.5", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", - "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "browser-stdout": "^1.3.1", - "chokidar": "^4.0.1", - "debug": "^4.3.5", - "diff": "^7.0.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^10.4.5", - "he": "^1.2.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^9.0.5", - "ms": "^2.1.3", - "picocolors": "^1.1.1", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^9.2.0", - "yargs": "^17.7.2", - "yargs-parser": "^21.1.1", - "yargs-unparser": "^2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0", - "peer": true - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/diff": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", - "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "peer": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "peer": true, - "engines": { - "node": ">=12" - } - }, "node_modules/mochawesome": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.4.tgz", @@ -20171,18 +19571,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/numbro": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/numbro/-/numbro-2.5.0.tgz", - "integrity": "sha512-xDcctDimhzko/e+y+Q2/8i3qNC9Svw1QgOkSkQoO0kIPI473tR9QRbo2KP88Ty9p8WbPy+3OpTaAIzehtuHq+A==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^8 || ^9" - }, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -25051,22 +24439,6 @@ "dev": true, "license": "MIT" }, - "node_modules/vis-data": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-8.0.3.tgz", - "integrity": "sha512-jhnb6rJNqkKR1Qmlay0VuDXY9ZlvAnYN1udsrP4U+krgZEq7C0yNSKdZqmnCe13mdnf9AdVcdDGFOzy2mpPoqw==", - "dev": true, - "license": "(Apache-2.0 OR MIT)", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/visjs" - }, - "peerDependencies": { - "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^13.0.0", - "vis-util": ">=6.0.0" - } - }, "node_modules/vis-network": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-10.0.2.tgz", @@ -25086,25 +24458,6 @@ "vis-util": ">=6.0.0" } }, - "node_modules/vis-util": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-6.0.0.tgz", - "integrity": "sha512-qtpts3HRma0zPe4bO7t9A2uejkRNj8Z2Tb6do6lN85iPNWExFkUiVhdAq5uLGIUqBFduyYeqWJKv/jMkxX0R5g==", - "dev": true, - "license": "(Apache-2.0 OR MIT)", - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/visjs" - }, - "peerDependencies": { - "@egjs/hammerjs": "^2.0.0", - "component-emitter": "^1.3.0 || ^2.0.0" - } - }, "node_modules/vite": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", @@ -26298,14 +25651,6 @@ "dev": true, "license": "MIT" }, - "node_modules/workerpool": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", - "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", - "dev": true, - "license": "Apache-2.0", - "peer": true - }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -26454,62 +25799,6 @@ "decamelize": "^1.2.0" } }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/yargs/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", diff --git a/client/package.json b/client/package.json index 12bf047..bb5c53a 100644 --- a/client/package.json +++ b/client/package.json @@ -54,7 +54,7 @@ "@clr/angular": "file:libraries/clr-angular-17.9.0.tgz", "@clr/icons": "^13.0.2", "@clr/ui": "file:libraries/clr-ui-17.9.0.tgz", - "@handsontable/angular-wrapper": "^17.1.0", + "@handsontable/angular-wrapper": "^18.0.0", "@sasjs/adapter": "^4.17.0", "@sasjs/utils": "^3.5.3", "@sheet/crypto": "file:libraries/sheet-crypto.tgz", @@ -67,7 +67,7 @@ "d3-graphviz": "^5.0.2", "exceljs": "^4.4.0", "fs-extra": "^7.0.1", - "handsontable": "^17.1.0", + "handsontable": "^18.0.0", "https-browserify": "1.0.0", "hyperformula": "^2.5.0", "iconv-lite": "^0.5.0", diff --git a/client/src/app/editor/editor.component.ts b/client/src/app/editor/editor.component.ts index fa87bbc..de8d13c 100644 --- a/client/src/app/editor/editor.component.ts +++ b/client/src/app/editor/editor.component.ts @@ -11,7 +11,7 @@ import { ViewEncapsulation } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import Handsontable from 'handsontable' +import Handsontable, { CellRange } from 'handsontable' import { Subject, Subscription } from 'rxjs' import { sanitiseForSas } from '../shared/utils/sanitise' import { SasStoreService } from '../services/sas-store.service' @@ -21,7 +21,6 @@ type AOA = any[][] import { HotTableComponent } from '@handsontable/angular-wrapper' import { UploadFile } from '@sasjs/adapter' import { isSpecialMissing } from '@sasjs/utils/input/validators' -import CellRange from 'handsontable/3rdparty/walkontable/src/cell/range' import { CellValidationSource } from '../models/CellValidationSource' import { FileUploader } from '../models/FileUploader.class' import { FilterGroup, FilterQuery } from '../models/FilterQuery' @@ -161,8 +160,11 @@ export class EditorComponent implements OnInit, AfterViewInit, OnDestroy { items: { edit_row: { name: 'Edit row', - hidden() { - const hot: Handsontable.Core = this + // HOT 18's MenuItemConfig types `hidden` as a plain `() => boolean` with + // no `this` type, so an object-literal method here has `this` inferred + // as the surrounding item config unless declared explicitly. + hidden(this: Handsontable.Core) { + const hot = this // Hide editing actions in read-only (view) mode. if (hot.getSettings().readOnly) return true @@ -1399,7 +1401,9 @@ export class EditorComponent implements OnInit, AfterViewInit, OnDestroy { hot.removeCellMeta(rowIndex, col, 'valid') hot.removeCellMeta(rowIndex, col, 'dupKey') // Remove our custom class from cell metadata - const cellMeta = hot.getCellMeta(rowIndex, col) + // getCellMeta() defaults to Record in HOT 18; pin it to + // CellMeta so `.className` keeps its real string | string[] type below. + const cellMeta = hot.getCellMeta(rowIndex, col) if (cellMeta.className) { let cleanedClassName: string if (Array.isArray(cellMeta.className)) { @@ -2246,8 +2250,10 @@ export class EditorComponent implements OnInit, AfterViewInit, OnDestroy { validationSourceIndex ].values.map((el) => el.RAW_VALUE) + // `.source` (dropdown/autocomplete list) is typed unknown[] | Function here since + // getCellMeta() isn't given a type param; cast to the array branch we actually use. const cellHadSource = - (hot.getCellMeta(row, column).source || []).length < 1 + ((hot.getCellMeta(row, column).source as unknown[]) || []).length < 1 const cellHasValue = cellData !== ' ' hot.batch(() => { @@ -3123,7 +3129,9 @@ export class EditorComponent implements OnInit, AfterViewInit, OnDestroy { let textInfo = 'No info found' if (this.hotInstance) { - const hotSelected: [number, number, number, number][] = + // getSelected() is typed number[][] in HOT 18 (was a 4-tuple + // array before); loosen the annotation to match. + const hotSelected: number[][] = this.hotInstance.getSelected() || [] const selectedCol: number = hotSelected ? hotSelected[0][1] diff --git a/client/src/app/multi-dataset/multi-dataset.component.ts b/client/src/app/multi-dataset/multi-dataset.component.ts index e187928..ed5237c 100644 --- a/client/src/app/multi-dataset/multi-dataset.component.ts +++ b/client/src/app/multi-dataset/multi-dataset.component.ts @@ -22,10 +22,9 @@ import { ExcelRule } from '../models/TableData' import { HotTableInterface } from '../models/HotTable.interface' import { Col } from '../shared/dc-validator/models/col.model' import { SpreadsheetService } from '../services/spreadsheet.service' -import Handsontable from 'handsontable' +import Handsontable, { CellChange, ChangeSource } from 'handsontable' import { HotTableComponent } from '@handsontable/angular-wrapper' import { EditorsStageDataSASResponse } from '../models/sas/editors-stagedata.model' -import { CellChange, ChangeSource } from 'handsontable/common' import { baseAfterGetColHeader } from '../shared/utils/hot.utils' import { ColumnSettings } from 'handsontable/settings' import { UploadFile } from '@sasjs/adapter' @@ -502,7 +501,9 @@ export class MultiDatasetComponent implements OnInit, AfterViewInit { if (changes) { for (let change of changes) { if (change && change[3]) { - change[3] = change[3].toUpperCase() + // CellValue is `unknown` in HOT 18 (was a concrete union before); + // this column is always a dataset name string. + change[3] = (change[3] as string).toUpperCase() } } } @@ -552,7 +553,9 @@ export class MultiDatasetComponent implements OnInit, AfterViewInit { dynamicCellValidations() { if (!this.hotInstanceUserDataset) return - const hotData = this.hotInstanceUserDataset.getData() + // getData() returns unknown[][] in HOT 18 (was CellValue[][]); this grid's + // data is always library/table name strings. + const hotData = this.hotInstanceUserDataset.getData() as string[][] hotData.forEach((row, rowIndex) => { const library = row[0] @@ -573,10 +576,12 @@ export class MultiDatasetComponent implements OnInit, AfterViewInit { if (dataAtRow && dataAtRow[0] && dataAtRow[1]) { if (!this.matchedDatasets.includes(dataset)) { + // getCellMetaAtRow() returns Record[] in HOT 18, so + // `.col` needs casting back to number for setCellMeta() (same below). cellMetaAtRow.forEach((cellMeta) => { this.hotInstanceUserDataset.setCellMeta( row, - cellMeta.col, + cellMeta.col as number, 'className', 'not-matched' ) @@ -585,7 +590,7 @@ export class MultiDatasetComponent implements OnInit, AfterViewInit { cellMetaAtRow.forEach((cellMeta) => { this.hotInstanceUserDataset.setCellMeta( row, - cellMeta.col, + cellMeta.col as number, 'className', '' ) @@ -595,7 +600,7 @@ export class MultiDatasetComponent implements OnInit, AfterViewInit { cellMetaAtRow.forEach((cellMeta) => { this.hotInstanceUserDataset.setCellMeta( row, - cellMeta.col, + cellMeta.col as number, 'className', '' ) @@ -991,7 +996,8 @@ export class MultiDatasetComponent implements OnInit, AfterViewInit { private getDatasetsFromHot(): string[] { if (!this.hotInstanceUserDataset) return [] - const hotData = this.hotInstanceUserDataset.getData() + // getData() returns unknown[][] in HOT 18; see dynamicCellValidations() above. + const hotData = this.hotInstanceUserDataset.getData() as string[][] return hotData .filter((row) => row[0]?.length && row[1]?.length) diff --git a/client/src/app/shared/dc-validator/editors/numericAutocomplete.ts b/client/src/app/shared/dc-validator/editors/numericAutocomplete.ts index d242927..8d459e3 100644 --- a/client/src/app/shared/dc-validator/editors/numericAutocomplete.ts +++ b/client/src/app/shared/dc-validator/editors/numericAutocomplete.ts @@ -1,10 +1,9 @@ -import Handsontable from 'handsontable' -import Core from 'handsontable/core' +import Handsontable, { HotInstance } from 'handsontable' export class CustomAutocompleteEditor extends Handsontable.editors.AutocompleteEditor { - constructor(instance: Core) { + constructor(instance: HotInstance) { super(instance) } @@ -13,8 +12,9 @@ export class CustomAutocompleteEditor } // Listbox open - open(event?: Event | undefined): void { - super.open(event) + // HOT 18's AutocompleteEditor.open() takes no arguments (was `event?: Event`). + open(): void { + super.open() if (this.isCellNumeric()) { this.htContainer.classList.add('numericListbox') diff --git a/client/src/app/shared/hot-export/hot-export.util.ts b/client/src/app/shared/hot-export/hot-export.util.ts index 487535c..721f8f3 100644 --- a/client/src/app/shared/hot-export/hot-export.util.ts +++ b/client/src/app/shared/hot-export/hot-export.util.ts @@ -52,12 +52,14 @@ export async function exportGrid( // Mirror HOT's own export item: only honor a selection that spans more than // one cell. A right-click places a single-cell cursor, and the corner click // is select-all (negative coords) — both mean "export the whole table". - const isCornerSelectAll = !!sel && sel.from.row < 0 && sel.from.col < 0 + // sel.from/to.row/col are typed nullable (CellCoords allows an unset state), + // but a range returned by getSelectedRangeLast() always has real coordinates. + const isCornerSelectAll = !!sel && sel.from.row! < 0 && sel.from.col! < 0 if (sel && !sel.isSingleCell() && !isCornerSelectAll) { - const top = Math.max(0, Math.min(sel.from.row, sel.to.row)) - const left = Math.max(0, Math.min(sel.from.col, sel.to.col)) - const bottom = Math.max(sel.from.row, sel.to.row) - const right = Math.max(sel.from.col, sel.to.col) + const top = Math.max(0, Math.min(sel.from.row!, sel.to.row!)) + const left = Math.max(0, Math.min(sel.from.col!, sel.to.col!)) + const bottom = Math.max(sel.from.row!, sel.to.row!) + const right = Math.max(sel.from.col!, sel.to.col!) opts['range'] = [top, Math.max(left, skipLeadingCols), bottom, right] } diff --git a/client/src/app/viewer/viewer.component.ts b/client/src/app/viewer/viewer.component.ts index 73888dc..93f7aeb 100644 --- a/client/src/app/viewer/viewer.component.ts +++ b/client/src/app/viewer/viewer.component.ts @@ -228,7 +228,9 @@ export class ViewerComponent !this.isTableSwitching ) { try { - const hotSelected: [number, number, number, number][] = + // getSelected() is typed number[][] in HOT 18 (was a 4-tuple + // array before); loosen the annotation to match. + const hotSelected: number[][] = this.hotInstance.getSelected() || [] const selectedCol: number = hotSelected ? hotSelected[0][1] : -1 const colName = this.hotInstance.colToProp(selectedCol)