From 7c063912bbaf4496358ae5408e1808f560c608d7 Mon Sep 17 00:00:00 2001 From: Caleb Shafer <31107829+calebmshafer@users.noreply.github.com> Date: Wed, 24 Mar 2021 19:00:56 -0400 Subject: [PATCH 01/50] Add saveChanges to ensure the updated DbGuid is persisted (#1029) --- .../fix-checkpoint-dbguid_2021-03-24-20-51.json | 11 +++++++++++ core/backend/src/CheckpointManager.ts | 1 + 2 files changed, 12 insertions(+) create mode 100644 common/changes/@bentley/imodeljs-backend/fix-checkpoint-dbguid_2021-03-24-20-51.json diff --git a/common/changes/@bentley/imodeljs-backend/fix-checkpoint-dbguid_2021-03-24-20-51.json b/common/changes/@bentley/imodeljs-backend/fix-checkpoint-dbguid_2021-03-24-20-51.json new file mode 100644 index 00000000000..3862fb39ed3 --- /dev/null +++ b/common/changes/@bentley/imodeljs-backend/fix-checkpoint-dbguid_2021-03-24-20-51.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-backend", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-backend", + "email": "31107829+calebmshafer@users.noreply.github.com" +} \ No newline at end of file diff --git a/core/backend/src/CheckpointManager.ts b/core/backend/src/CheckpointManager.ts index b48dee985c6..443cc7d7fcd 100644 --- a/core/backend/src/CheckpointManager.ts +++ b/core/backend/src/CheckpointManager.ts @@ -290,6 +290,7 @@ export class V1CheckpointManager { requestContext.enter(); } } finally { + db.saveChanges(); db.close(); } From 4de19f15fb2a451e0e7d5011a4388a77baceebb9 Mon Sep 17 00:00:00 2001 From: DaumantasJankauskas <47949861+DaumantasJankauskas@users.noreply.github.com> Date: Thu, 25 Mar 2021 05:53:42 +0200 Subject: [PATCH 02/50] Update xmldom (#1015) * update xmldom to 0.5.0 Co-authored-by: Caleb Shafer <31107829+calebmshafer@users.noreply.github.com> --- clients/itwin/package.json | 4 +- .../updateXmldom_2021-03-23-11-10.json | 11 ++++ .../updateXmldom_2021-03-23-11-10.json | 11 ++++ .../updateXmldom_2021-03-23-11-10.json | 11 ++++ .../updateXmldom_2021-03-23-11-10.json | 11 ++++ common/config/rush/pnpm-lock.yaml | 56 +++++++++---------- core/ecschema-locaters/package.json | 4 +- core/ecschema-metadata/package.json | 4 +- tools/ecschema2ts/package.json | 4 +- 9 files changed, 80 insertions(+), 36 deletions(-) create mode 100644 common/changes/@bentley/ecschema-locaters/updateXmldom_2021-03-23-11-10.json create mode 100644 common/changes/@bentley/ecschema-metadata/updateXmldom_2021-03-23-11-10.json create mode 100644 common/changes/@bentley/ecschema2ts/updateXmldom_2021-03-23-11-10.json create mode 100644 common/changes/@bentley/itwin-client/updateXmldom_2021-03-23-11-10.json diff --git a/clients/itwin/package.json b/clients/itwin/package.json index 65efebe62ae..a021e075f4b 100644 --- a/clients/itwin/package.json +++ b/clients/itwin/package.json @@ -50,7 +50,7 @@ "@types/node": "10.14.1", "@types/qs": "^6.5.0", "@types/superagent": "^4.1.7", - "@types/xmldom": "^0.1.29", + "@types/xmldom": "^0.1.30", "chai": "^4.1.2", "eslint": "^6.8.0", "mocha": "^5.2.0", @@ -66,7 +66,7 @@ "js-base64": "^2.4.5", "qs": "^6.5.1", "superagent": "^5.2.2", - "xmldom": "^0.1.27", + "xmldom": "^0.5.0", "xpath": "0.0.27" }, "nyc": { diff --git a/common/changes/@bentley/ecschema-locaters/updateXmldom_2021-03-23-11-10.json b/common/changes/@bentley/ecschema-locaters/updateXmldom_2021-03-23-11-10.json new file mode 100644 index 00000000000..2896b650840 --- /dev/null +++ b/common/changes/@bentley/ecschema-locaters/updateXmldom_2021-03-23-11-10.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ecschema-locaters", + "comment": "update xmldom to 0.5.0", + "type": "none" + } + ], + "packageName": "@bentley/ecschema-locaters", + "email": "47949861+DaumantasJankauskas@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/ecschema-metadata/updateXmldom_2021-03-23-11-10.json b/common/changes/@bentley/ecschema-metadata/updateXmldom_2021-03-23-11-10.json new file mode 100644 index 00000000000..22e510022fb --- /dev/null +++ b/common/changes/@bentley/ecschema-metadata/updateXmldom_2021-03-23-11-10.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ecschema-metadata", + "comment": "update xmldom to 0.5.0", + "type": "none" + } + ], + "packageName": "@bentley/ecschema-metadata", + "email": "47949861+DaumantasJankauskas@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/ecschema2ts/updateXmldom_2021-03-23-11-10.json b/common/changes/@bentley/ecschema2ts/updateXmldom_2021-03-23-11-10.json new file mode 100644 index 00000000000..0b7325da4d3 --- /dev/null +++ b/common/changes/@bentley/ecschema2ts/updateXmldom_2021-03-23-11-10.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ecschema2ts", + "comment": "update xmldom to 0.5.0", + "type": "none" + } + ], + "packageName": "@bentley/ecschema2ts", + "email": "47949861+DaumantasJankauskas@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/itwin-client/updateXmldom_2021-03-23-11-10.json b/common/changes/@bentley/itwin-client/updateXmldom_2021-03-23-11-10.json new file mode 100644 index 00000000000..46747a4057f --- /dev/null +++ b/common/changes/@bentley/itwin-client/updateXmldom_2021-03-23-11-10.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/itwin-client", + "comment": "update xmldom to 0.5.0", + "type": "none" + } + ], + "packageName": "@bentley/itwin-client", + "email": "47949861+DaumantasJankauskas@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 82433820bf9..ed3964e67a5 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -126,7 +126,7 @@ dependencies: '@types/faker': 4.1.12 '@types/file-saver': 2.0.1 '@types/flatbuffers': 1.10.0 - '@types/formidable': 1.2.0 + '@types/formidable': 1.2.1 '@types/fs-extra': 4.0.11 '@types/glob': 5.0.36 '@types/i18next': 8.4.6 @@ -387,7 +387,7 @@ dependencies: wms-capabilities: 0.4.0 ws: 7.4.4 xml-js: 1.6.11 - xmldom: 0.1.31 + xmldom: 0.5.0 xmlhttprequest: 1.8.0 xpath: 0.0.27 yargonaut: 1.1.4 @@ -2908,12 +2908,12 @@ packages: dev: false resolution: integrity: sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA== - /@types/formidable/1.2.0: + /@types/formidable/1.2.1: dependencies: '@types/node': 12.20.6 dev: false resolution: - integrity: sha512-Gpj8Jc/M29THMBThhvprrY1eJe2+9E/LhyiLrzwgTT5X/FNkpqxmnH8KuX7SLSSOYnVWsxoZZEspXzc4+UR17Q== + integrity: sha512-4sVIjd51AADf4YnpsdqNQh7n3ZRLo16w+w6F7zzKjK6dBsQc9Vrq8GQLpHOOWq0V8Fe2bbp2EpihHx57iVgm5Q== /@types/fs-extra/4.0.11: dependencies: '@types/node': 12.20.6 @@ -2923,14 +2923,14 @@ packages: /@types/glob/5.0.36: dependencies: '@types/events': 3.0.0 - '@types/minimatch': 3.0.3 + '@types/minimatch': 3.0.4 '@types/node': 12.20.6 dev: false resolution: integrity: sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg== /@types/glob/7.1.3: dependencies: - '@types/minimatch': 3.0.3 + '@types/minimatch': 3.0.4 '@types/node': 10.14.1 dev: false resolution: @@ -3065,6 +3065,10 @@ packages: dev: false resolution: integrity: sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + /@types/minimatch/3.0.4: + dev: false + resolution: + integrity: sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== /@types/minipass/2.2.0: dependencies: '@types/node': 10.14.1 @@ -3956,7 +3960,7 @@ packages: request: 2.88.2 underscore: 1.12.1 uuid: 3.4.0 - xmldom: 0.1.31 + xmldom: 0.5.0 xpath.js: 1.1.0 dev: false engines: @@ -5145,8 +5149,6 @@ packages: hasBin: true resolution: integrity: sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== - caniuse-lite: 1.0.30001197 - electron-to-chromium: 1.3.683 /browserslist/4.11.1: dependencies: caniuse-lite: 1.0.30001204 @@ -8896,7 +8898,7 @@ packages: integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= /fork-ts-checker-webpack-plugin/4.1.6: dependencies: - '@babel/code-frame': 7.12.13 + '@babel/code-frame': 7.10.4 chalk: 2.4.2 micromatch: 3.1.10 minimatch: 3.0.4 @@ -10155,7 +10157,6 @@ packages: dev: false resolution: integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - ansi-escapes: 4.3.1 /inquirer/7.3.3: dependencies: ansi-escapes: 4.3.2 @@ -19574,13 +19575,12 @@ packages: dev: false resolution: integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - /xmldom/0.1.31: - deprecated: Deprecated due to CVE-2021-21366 resolved in 0.5.0 + /xmldom/0.5.0: dev: false engines: - node: '>=0.1' + node: '>=10.0.0' resolution: - integrity: sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== + integrity: sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA== /xmlhttprequest/1.8.0: dev: false engines: @@ -20089,11 +20089,11 @@ packages: nyc: 14.1.1 rimraf: 3.0.2 typescript: 4.1.5 - xmldom: 0.1.31 + xmldom: 0.5.0 dev: false name: '@rush-temp/ecschema-locaters' resolution: - integrity: sha512-RuTH+ml7s7kGaVNDKTQrPql8EUvgZeqlZg+jIJOjGcNgt9ZcsgUPzYIsyMkrkwsQZJ3VPwLNOdtllAlVkL8uAg== + integrity: sha512-3lKdUOaNdJZaHgTUXCouq2qe/IIsTnsw+2XjauhhhP1h5ZO5FVESeAHOARC8un2Pnt79bwM0TQ2yiiHTF8eZbg== tarball: 'file:projects/ecschema-locaters.tgz' version: 0.0.0 'file:projects/ecschema-metadata.tgz': @@ -20119,12 +20119,12 @@ packages: rimraf: 3.0.2 sinon: 9.2.4 typescript: 4.1.5 - xmldom: 0.1.31 + xmldom: 0.5.0 xmlhttprequest: 1.8.0 dev: false name: '@rush-temp/ecschema-metadata' resolution: - integrity: sha512-OjBRoUyuhfKYLLZx4s/zBm+sdCVnSJ8p7JCxgzGA5GaUewo6ZvPKXq25PROW5RFQSkJoFXrSb/J3vk9xS8pbjw== + integrity: sha512-Dte6cjTDZc5yIxXodN6ij2NQNm7MR+82f3mau/6+5O1bLM8FYlgFjmhGtQHs+ZW5xogvkoP3SaBi9W+haUoEvg== tarball: 'file:projects/ecschema-metadata.tgz' version: 0.0.0 'file:projects/ecschema2ts.tgz': @@ -20147,11 +20147,11 @@ packages: rimraf: 3.0.2 source-map-support: 0.5.19 typescript: 4.1.5 - xmldom: 0.1.31 + xmldom: 0.5.0 dev: false name: '@rush-temp/ecschema2ts' resolution: - integrity: sha512-dajB5yXn33vjWjqE6fTpkcgIkc9gDjbjYm2KelpIxaLRZ/adXUI0fXqxOgXh1Ky9+4pE+UcadVrbkd+lFpATDw== + integrity: sha512-wFuGZbaJShnGvuqQYU6a7/2wUEzs923VvPMSavW5dkLygaYRp8ikLBEPvTlm186pzz9Jivo51GGahnoGhsXauQ== tarball: 'file:projects/ecschema2ts.tgz' version: 0.0.0 'file:projects/electron-manager.tgz_debug@2.6.9': @@ -20405,7 +20405,7 @@ packages: dev: false name: '@rush-temp/extension-webpack-tools' resolution: - integrity: sha512-XrDtgZsUSR6XEbZgupyki07Fsby8GOwvDQDyBxj2+t5V5CMhWDDOi6YuUFNcsQokQU4qikCls2VWUXkoZpjHDQ== + integrity: sha512-H2XQrEaIJA6NITpyQY0Qo+2BSre2mG227w1gwd649rWiVEH7TJwmk8KsfUR/Ca0vGUrsgmJZHRFJsocLHpi/8A== tarball: 'file:projects/extension-webpack-tools.tgz' version: 0.0.0 'file:projects/frontend-application-insights-client.tgz': @@ -20687,7 +20687,7 @@ packages: '@types/chai': 4.2.15 '@types/chai-as-promised': 7.1.3 '@types/deep-assign': 0.1.1 - '@types/formidable': 1.2.0 + '@types/formidable': 1.2.1 '@types/fs-extra': 4.0.11 '@types/glob': 5.0.36 '@types/js-base64': 2.3.2 @@ -20730,7 +20730,7 @@ packages: peerDependencies: debug: '*' resolution: - integrity: sha512-1jt3seUZG5drv8EZwIrvHOf9I5+mGXDQHTcLBgYwgAA2jWkW0kZXMwWNVuavV/ZJm9FfONo325R1BMPpuUj1Lg== + integrity: sha512-jKhJbVzdiYauKYa2O+HR6kiqEh3//u724jyyVzDfvI/5ui181/FnlkiQVm+9JfTtINiU0dh/3YPpbXTLcLDQUA== tarball: 'file:projects/imodeljs-backend.tgz' version: 0.0.0 'file:projects/imodeljs-common.tgz': @@ -20977,12 +20977,12 @@ packages: superagent: 5.3.1 typescript: 4.1.5 webpack: 4.42.0_webpack@4.42.0 - xmldom: 0.1.31 + xmldom: 0.5.0 xpath: 0.0.27 dev: false name: '@rush-temp/itwin-client' resolution: - integrity: sha512-V0iQGM9cGHVEtJGBtSsyBvafLLHySfAMfv4QBpI3yYUUuE13jlV9Duu9l6tscT3p4EzTBMfEP6d3jVeUuYFrjA== + integrity: sha512-tzeDWnk50+c057AD0HL/zBawsdW6vh2AGJiWkGOQ86JGXmplhRu3Rxs4FuDZfzs8bDu6ZmPkcEd6igcvRxmrXw== tarball: 'file:projects/itwin-client.tgz' version: 0.0.0 'file:projects/linear-referencing-backend.tgz': @@ -22345,7 +22345,7 @@ specifiers: '@types/webpack': ^4.41.2 '@types/webpack-sources': ^0.1.6 '@types/ws': ^6.0.4 - '@types/xmldom': ^0.1.29 + '@types/xmldom': ^0.1.30 '@types/yargs': ^12.0.5 '@typescript-eslint/eslint-plugin': 4.11.1 '@typescript-eslint/parser': 4.11.1 @@ -22553,7 +22553,7 @@ specifiers: wms-capabilities: 0.4.0 ws: ^7.2.0 xml-js: ~1.6.11 - xmldom: ^0.1.27 + xmldom: ^0.5.0 xmlhttprequest: ^1.8.0 xpath: 0.0.27 yargonaut: ^1.1.2 diff --git a/core/ecschema-locaters/package.json b/core/ecschema-locaters/package.json index 99c319ab453..d765dbb5859 100644 --- a/core/ecschema-locaters/package.json +++ b/core/ecschema-locaters/package.json @@ -40,7 +40,7 @@ "@types/mocha": "^5.2.5", "@types/node": "10.14.1", "@types/sinon": "^9.0.0", - "@types/xmldom": "^0.1.29", + "@types/xmldom": "^0.1.30", "chai": "^4.1.2", "chai-as-promised": "^7", "eslint": "^6.8.0", @@ -48,7 +48,7 @@ "nyc": "^14.0.0", "rimraf": "^3.0.2", "typescript": "~4.1.0", - "xmldom": "^0.1.27" + "xmldom": "^0.5.0" }, "dependencies": { "glob": "^7.1.2" diff --git a/core/ecschema-metadata/package.json b/core/ecschema-metadata/package.json index 42a2114ac46..0be539af7f5 100644 --- a/core/ecschema-metadata/package.json +++ b/core/ecschema-metadata/package.json @@ -46,7 +46,7 @@ "@types/mocha": "^5.2.5", "@types/node": "10.14.1", "@types/sinon": "^9.0.0", - "@types/xmldom": "^0.1.29", + "@types/xmldom": "^0.1.30", "benchmark": "^2.1.4", "chai": "^4.1.2", "chai-as-promised": "^7", @@ -57,7 +57,7 @@ "rimraf": "^3.0.2", "sinon": "^9.0.2", "typescript": "~4.1.0", - "xmldom": "^0.1.27", + "xmldom": "^0.5.0", "xmlhttprequest": "^1.8.0" }, "peerDependencies": { diff --git a/tools/ecschema2ts/package.json b/tools/ecschema2ts/package.json index 158c03a79d6..c34ff47a34a 100644 --- a/tools/ecschema2ts/package.json +++ b/tools/ecschema2ts/package.json @@ -42,7 +42,7 @@ "@types/fs-extra": "^4.0.7", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", - "@types/xmldom": "^0.1.29", + "@types/xmldom": "^0.1.30", "chai": "^4.1.2", "chai-string": "^1.5.0", "cpx": "^1.5.0", @@ -69,7 +69,7 @@ "chalk": "^3.0.0", "commander": "^2.14.1", "fs-extra": "^8.1.0", - "xmldom": "^0.1.27" + "xmldom": "^0.5.0" }, "nyc": { "nycrc-path": "./node_modules/@bentley/build-tools/.nycrc" From 8fa7815b8c0b441e2035ae9f8e9fc2b4c51831ac Mon Sep 17 00:00:00 2001 From: imodeljs-admin <38288322+imodeljs-admin@users.noreply.github.com> Date: Thu, 25 Mar 2021 05:01:47 +0000 Subject: [PATCH 03/50] 2.15.0-dev.7 --- .../backend-application-insights/package.json | 18 ++-- clients/context-registry/package.json | 18 ++-- clients/extension/package.json | 20 ++--- .../package.json | 18 ++-- clients/frontend-authorization/package.json | 14 +-- clients/imodelhub/package.json | 24 ++--- clients/itwin/package.json | 14 +-- clients/product-settings/package.json | 22 ++--- clients/projectshare/package.json | 22 ++--- clients/rbac/package.json | 20 ++--- clients/reality-data/package.json | 22 ++--- clients/telemetry/package.json | 16 ++-- clients/usage-logging/package.json | 22 ++--- common/config/rush/version-policies.json | 2 +- core/backend-itwin-client/package.json | 46 +++++----- core/backend/package.json | 52 +++++------ core/bentley/package.json | 6 +- core/common/package.json | 26 +++--- core/ecschema-locaters/package.json | 10 +-- core/ecschema-metadata/package.json | 14 +-- core/electron-manager/package.json | 26 +++--- core/express-server/package.json | 8 +- core/frontend-devtools/package.json | 22 ++--- core/frontend/package.json | 72 +++++++-------- core/geometry/package.json | 10 +-- core/hypermodeling/package.json | 32 +++---- core/i18n/package.json | 10 +-- core/imodel-bridge/package.json | 40 ++++----- core/logger-config/package.json | 10 +-- core/markup/package.json | 28 +++--- core/mobile-manager/package.json | 34 +++---- core/orbitgt/package.json | 8 +- core/quantity/package.json | 10 +-- core/webgl-compatibility/package.json | 12 +-- domains/analytical/backend/package.json | 18 ++-- .../linear-referencing/backend/package.json | 22 ++--- .../linear-referencing/common/package.json | 14 +-- .../physical-material/backend/package.json | 18 ++-- editor/backend/package.json | 24 ++--- editor/common/package.json | 18 ++-- editor/frontend/package.json | 28 +++--- example-code/app/package.json | 28 +++--- example-code/snippets/package.json | 26 +++--- extensions/geonames/package.json | 24 ++--- extensions/iot-demo/package.json | 30 +++---- extensions/map-layers/package.json | 58 ++++++------ full-stack-tests/core/package.json | 52 +++++------ .../imodelhub-client/package.json | 26 +++--- full-stack-tests/native-app/package.json | 40 ++++----- full-stack-tests/presentation/package.json | 40 ++++----- full-stack-tests/rpc-interface/package.json | 42 ++++----- full-stack-tests/rpc/package.json | 22 ++--- presentation/backend/package.json | 26 +++--- presentation/common/package.json | 18 ++-- presentation/components/package.json | 42 ++++----- presentation/frontend/package.json | 32 +++---- presentation/testing/package.json | 30 +++---- test-apps/analysis-importer/package.json | 14 +-- .../display-performance-test-app/package.json | 42 ++++----- test-apps/display-test-app/package.json | 50 +++++------ test-apps/export-gltf/package.json | 14 +-- test-apps/export-obj/package.json | 14 +-- test-apps/imjs-importer/package.json | 22 ++--- test-apps/imodel-from-geojson/package.json | 14 +-- test-apps/imodel-from-orbitgt/package.json | 16 ++-- .../imodel-from-reality-model/package.json | 14 +-- test-apps/imodel-transformer/package.json | 14 +-- test-apps/ninezone-test-app/package.json | 12 +-- test-apps/presentation-test-app/package.json | 38 ++++---- .../synchro-schedule-importer/package.json | 14 +-- test-apps/ui-test-app/package.json | 82 ++++++++--------- test-apps/ui-test-extension/package.json | 36 ++++---- tools/backend-webpack/package.json | 4 +- tools/build/package.json | 4 +- tools/certa/package.json | 6 +- tools/config-loader/package.json | 6 +- tools/ecschema2ts/package.json | 28 +++--- tools/eslint-plugin/package.json | 2 +- tools/extension-cli/package.json | 32 +++---- tools/extension-webpack/package.json | 4 +- tools/oidc-signin-tool/package.json | 16 ++-- tools/perf-tools/package.json | 6 +- tools/webpack-core/package.json | 6 +- ui/abstract/package.json | 18 ++-- ui/components/package.json | 38 ++++---- ui/core/package.json | 22 ++--- ui/framework/package.json | 88 +++++++++---------- ui/ninezone/package.json | 18 ++-- 88 files changed, 1050 insertions(+), 1050 deletions(-) diff --git a/clients/backend-application-insights/package.json b/clients/backend-application-insights/package.json index b000ed515b8..e9425c60674 100644 --- a/clients/backend-application-insights/package.json +++ b/clients/backend-application-insights/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/backend-application-insights-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Backend Application Insights Client", "main": "lib/backend-application-insights-client.js", "typings": "lib/backend-application-insights-client", @@ -30,19 +30,19 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", "applicationinsights": "^1.7.5" }, "peerDependencies": { - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/context-registry/package.json b/clients/context-registry/package.json index 0563dc09c73..54d9a84a6c1 100644 --- a/clients/context-registry/package.json +++ b/clients/context-registry/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/context-registry-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Context Registry Client", "main": "lib/context-registry-client.js", "typings": "lib/context-registry-client", @@ -39,16 +39,16 @@ "deep-assign": "^2.0.0" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/deep-assign": "^0.1.0", "@types/mocha": "^5.2.5", diff --git a/clients/extension/package.json b/clients/extension/package.json index 87d11c4ec89..c22aceb0239 100644 --- a/clients/extension/package.json +++ b/clients/extension/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/extension-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "IModel.js Extension Client", "main": "lib/extension-client.js", "typings": "lib/extension-client", @@ -36,17 +36,17 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6" + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/frontend-application-insights/package.json b/clients/frontend-application-insights/package.json index c5b1559e974..887dea3a3df 100644 --- a/clients/frontend-application-insights/package.json +++ b/clients/frontend-application-insights/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/frontend-application-insights-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Frontend Application Insights Client", "main": "lib/frontend-application-insights-client.js", "typings": "lib/frontend-application-insights-client", @@ -31,19 +31,19 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/telemetry-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/telemetry-client": "2.15.0-dev.7", "@microsoft/applicationinsights-web": "^2.5.5" }, "peerDependencies": { - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/frontend-authorization/package.json b/clients/frontend-authorization/package.json index ec76b5cc69a..a0787193f6a 100644 --- a/clients/frontend-authorization/package.json +++ b/clients/frontend-authorization/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/frontend-authorization-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Frontend Authorization Client", "main": "lib/frontend-authorization-client.js", "typings": "lib/frontend-authorization-client", @@ -34,14 +34,14 @@ "oidc-client": "^1.9.1" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "@types/node": "10.14.1", "eslint": "^6.8.0", "rimraf": "^3.0.2", diff --git a/clients/imodelhub/package.json b/clients/imodelhub/package.json index a9506412be6..c33f57eec4f 100644 --- a/clients/imodelhub/package.json +++ b/clients/imodelhub/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodelhub-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js iModelHub Client", "main": "lib/imodelhub-client.js", "typings": "lib/imodelhub-client", @@ -33,23 +33,23 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/context-registry-client": "2.15.0-dev.6", + "@bentley/context-registry-client": "2.15.0-dev.7", "deep-assign": "^2.0.0", "js-base64": "^2.4.5" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/frontend-authorization-client": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/rbac-client": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/frontend-authorization-client": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/rbac-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "@types/deep-assign": "^0.1.0", "@types/js-base64": "^2.3.1", "@types/node": "10.14.1", diff --git a/clients/itwin/package.json b/clients/itwin/package.json index a021e075f4b..d8763bd581f 100644 --- a/clients/itwin/package.json +++ b/clients/itwin/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/itwin-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Base client package for iTwin applications", "main": "lib/itwin-client.js", "typings": "lib/itwin-client", @@ -30,18 +30,18 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/deep-assign": "^0.1.0", "@types/js-base64": "^2.3.1", diff --git a/clients/product-settings/package.json b/clients/product-settings/package.json index 8e5e439e07b..e204b22f8ba 100644 --- a/clients/product-settings/package.json +++ b/clients/product-settings/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/product-settings-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Product Settings Client", "main": "lib/product-settings-client.js", "typings": "lib/product-settings-client", @@ -36,18 +36,18 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/projectshare/package.json b/clients/projectshare/package.json index a7748e5bd20..ac466f8e1b6 100644 --- a/clients/projectshare/package.json +++ b/clients/projectshare/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/projectshare-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js ProjectShare Client", "main": "lib/projectshare-client.js", "typings": "lib/projectshare-client", @@ -36,18 +36,18 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/rbac/package.json b/clients/rbac/package.json index 96ef6a47650..dafc434b540 100644 --- a/clients/rbac/package.json +++ b/clients/rbac/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/rbac-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js RBAC Client", "main": "lib/rbac-client.js", "typings": "lib/rbac-client", @@ -36,19 +36,19 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6" + "@bentley/bentleyjs-core": "2.15.0-dev.7" }, "peerDependencies": { - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/reality-data/package.json b/clients/reality-data/package.json index 02a428b5936..a864685897a 100644 --- a/clients/reality-data/package.json +++ b/clients/reality-data/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/reality-data-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Reality Data Client", "main": "lib/reality-data-client.js", "typings": "lib/reality-data-client", @@ -36,20 +36,20 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6" + "@bentley/bentleyjs-core": "2.15.0-dev.7" }, "peerDependencies": { - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/telemetry/package.json b/clients/telemetry/package.json index 79b4592ede1..eeb51870ba5 100644 --- a/clients/telemetry/package.json +++ b/clients/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/telemetry-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Telemetry Client", "main": "lib/telemetry-client.js", "typings": "lib/telemetry-client", @@ -31,17 +31,17 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6" + "@bentley/bentleyjs-core": "2.15.0-dev.7" }, "peerDependencies": { - "@bentley/itwin-client": "^2.15.0-dev.6" + "@bentley/itwin-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/clients/usage-logging/package.json b/clients/usage-logging/package.json index 744a4b86425..2880bca5c99 100644 --- a/clients/usage-logging/package.json +++ b/clients/usage-logging/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/usage-logging-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Usage Logging Client", "main": "lib/usage-logging-client.js", "typings": "lib/usage-logging-client", @@ -36,20 +36,20 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6" + "@bentley/bentleyjs-core": "2.15.0-dev.7" }, "peerDependencies": { - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/telemetry-client": "^2.15.0-dev.6" + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/telemetry-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/telemetry-client": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/telemetry-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/common/config/rush/version-policies.json b/common/config/rush/version-policies.json index dfeea262195..f04ff6f6067 100644 --- a/common/config/rush/version-policies.json +++ b/common/config/rush/version-policies.json @@ -2,7 +2,7 @@ { "policyName": "prerelease-monorepo-lockStep", "definitionName": "lockStepVersion", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "nextBump": "prerelease" } ] diff --git a/core/backend-itwin-client/package.json b/core/backend-itwin-client/package.json index a9620a1b097..b67d89a90c3 100644 --- a/core/backend-itwin-client/package.json +++ b/core/backend-itwin-client/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/backend-itwin-client", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Clients for various Bentley Services used by iModel.js at the backend", "main": "lib/backend-itwin-client.js", "browser": { @@ -38,33 +38,33 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/frontend-authorization-client": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodelhub-client": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/rbac-client": "^2.15.0-dev.6", - "@bentley/telemetry-client": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/frontend-authorization-client": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodelhub-client": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/rbac-client": "^2.15.0-dev.7", + "@bentley/telemetry-client": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/telemetry-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/telemetry-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/deep-assign": "^0.1.0", "@types/fs-extra": "^4.0.7", @@ -91,7 +91,7 @@ }, "dependencies": { "@azure-tools/azcopy-node": "^2.0.0", - "@bentley/usage-logging-client": "2.15.0-dev.6", + "@bentley/usage-logging-client": "2.15.0-dev.7", "applicationinsights": "^1.7.5", "deep-assign": "^2.0.0", "fs-extra": "^8.1.0", diff --git a/core/backend/package.json b/core/backend/package.json index f5d08bc33d7..ba293900ca2 100644 --- a/core/backend/package.json +++ b/core/backend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-backend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js backend components", "main": "lib/imodeljs-backend.js", "typings": "lib/imodeljs-backend", @@ -55,35 +55,35 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/backend-itwin-client": "^2.15.0-dev.6", - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/ecschema-metadata": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodelhub-client": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/rbac-client": "^2.15.0-dev.6", - "@bentley/telemetry-client": "^2.15.0-dev.6" + "@bentley/backend-itwin-client": "^2.15.0-dev.7", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/ecschema-metadata": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodelhub-client": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/rbac-client": "^2.15.0-dev.7", + "@bentley/telemetry-client": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/ecschema-metadata": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/perf-tools": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/telemetry-client": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/ecschema-metadata": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/perf-tools": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/telemetry-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/deep-assign": "^0.1.0", @@ -121,8 +121,8 @@ "dependencies": { "@bentley/imodeljs-native": "2.15.0", "@azure/storage-blob": "10.4.0", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/usage-logging-client": "2.15.0-dev.6", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/usage-logging-client": "2.15.0-dev.7", "deep-assign": "^2.0.0", "form-data": "^2.3.2", "fs-extra": "^8.1.0", diff --git a/core/bentley/package.json b/core/bentley/package.json index b7bceec5164..6438613f34f 100644 --- a/core/bentley/package.json +++ b/core/bentley/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/bentleyjs-core", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Bentley JavaScript core components", "main": "lib/bentleyjs-core.js", "typings": "lib/bentleyjs-core", @@ -32,8 +32,8 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/mocha": "^5.2.5", diff --git a/core/common/package.json b/core/common/package.json index 299a4c948ae..a664d873245 100644 --- a/core/common/package.json +++ b/core/common/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-common", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js components common to frontend and backend", "main": "lib/imodeljs-common.js", "typings": "lib/imodeljs-common", @@ -37,20 +37,20 @@ "semver": "^5.5.0" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodelhub-client": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/rbac-client": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodelhub-client": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/rbac-client": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/flatbuffers": "~1.10.0", "@types/js-base64": "^2.3.1", diff --git a/core/ecschema-locaters/package.json b/core/ecschema-locaters/package.json index d765dbb5859..e3e9ef2d241 100644 --- a/core/ecschema-locaters/package.json +++ b/core/ecschema-locaters/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/ecschema-locaters", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "EC Schema file locaters", "license": "MIT", "main": "lib/ecschema-locaters.js", @@ -31,9 +31,9 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/ecschema-metadata": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/ecschema-metadata": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/glob": "^5.0.35", @@ -54,7 +54,7 @@ "glob": "^7.1.2" }, "peerDependencies": { - "@bentley/ecschema-metadata": "^2.15.0-dev.6" + "@bentley/ecschema-metadata": "^2.15.0-dev.7" }, "nyc": { "nycrc-path": "./node_modules/@bentley/build-tools/.nycrc", diff --git a/core/ecschema-metadata/package.json b/core/ecschema-metadata/package.json index 0be539af7f5..a949cfc5186 100644 --- a/core/ecschema-metadata/package.json +++ b/core/ecschema-metadata/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/ecschema-metadata", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "ECObjects core concepts in typescript", "license": "MIT", "main": "lib/ecschema-metadata.js", @@ -33,10 +33,10 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", "@bentley/units-schema": "^1.0.5", "@types/almost-equal": "1.1.0", "@types/benchmark": "^2.1.0", @@ -61,8 +61,8 @@ "xmlhttprequest": "^1.8.0" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7" }, "dependencies": { "almost-equal": "^1.1.0" diff --git a/core/electron-manager/package.json b/core/electron-manager/package.json index 7f3b3cd7308..99049946cca 100644 --- a/core/electron-manager/package.json +++ b/core/electron-manager/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/electron-manager", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iTwin.js ElectronHost and ElectronApp", "license": "MIT", "engines": { @@ -30,21 +30,21 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", "electron": "^11.1.0" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "@types/node": "10.14.1", "electron": "^11.1.0", "eslint": "^6.8.0", diff --git a/core/express-server/package.json b/core/express-server/package.json index 48a248f3ab7..8855296370f 100644 --- a/core/express-server/package.json +++ b/core/express-server/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/express-server", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js express utilities", "main": "lib/ExpressServer.js", "typings": "lib/ExpressServer", @@ -32,9 +32,9 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", "@types/body-parser": "^1.17.0", "@types/chai": "^4.1.4", "@types/express": "^4.16.1", diff --git a/core/frontend-devtools/package.json b/core/frontend-devtools/package.json index cbb377f1b21..19545d1ca4d 100644 --- a/core/frontend-devtools/package.json +++ b/core/frontend-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/frontend-devtools", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Debug menu and supporting UI widgets", "main": "lib/frontend-devtools.js", "imodeljsSharedLibrary": true, @@ -33,19 +33,19 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "file-saver": "^2.0.2" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/extension-webpack-tools": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/extension-webpack-tools": "2.15.0-dev.7", "@types/file-saver": "^2.0.1", "@types/node": "10.14.1", "cpx": "^1.5.0", diff --git a/core/frontend/package.json b/core/frontend/package.json index 4c90fd25c8d..b906aad56ee 100644 --- a/core/frontend/package.json +++ b/core/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-frontend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js frontend components", "main": "lib/imodeljs-frontend.js", "typings": "lib/imodeljs-frontend", @@ -36,43 +36,43 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/frontend-authorization-client": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodelhub-client": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6", - "@bentley/imodeljs-quantity": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/orbitgt-core": "^2.15.0-dev.6", - "@bentley/product-settings-client": "^2.15.0-dev.6", - "@bentley/rbac-client": "^2.15.0-dev.6", - "@bentley/telemetry-client": "^2.15.0-dev.6", - "@bentley/ui-abstract": "^2.15.0-dev.6", - "@bentley/webgl-compatibility": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/frontend-authorization-client": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodelhub-client": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7", + "@bentley/imodeljs-quantity": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/orbitgt-core": "^2.15.0-dev.7", + "@bentley/product-settings-client": "^2.15.0-dev.7", + "@bentley/rbac-client": "^2.15.0-dev.7", + "@bentley/telemetry-client": "^2.15.0-dev.7", + "@bentley/ui-abstract": "^2.15.0-dev.7", + "@bentley/webgl-compatibility": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/orbitgt-core": "2.15.0-dev.6", - "@bentley/product-settings-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/telemetry-client": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/webgl-compatibility": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/orbitgt-core": "2.15.0-dev.7", + "@bentley/product-settings-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/telemetry-client": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/webgl-compatibility": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/js-base64": "^2.3.1", @@ -99,10 +99,10 @@ ], "dependencies": { "@azure/storage-blob": "10.4.0", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/extension-client": "2.15.0-dev.6", - "@bentley/reality-data-client": "2.15.0-dev.6", - "@bentley/usage-logging-client": "2.15.0-dev.6", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/extension-client": "2.15.0-dev.7", + "@bentley/reality-data-client": "2.15.0-dev.7", + "@bentley/usage-logging-client": "2.15.0-dev.7", "fuse.js": "^3.3.0", "js-base64": "^2.4.5", "ldclient-js": "^2.6.0", diff --git a/core/geometry/package.json b/core/geometry/package.json index 354d0e417de..fa0f0cbf67a 100644 --- a/core/geometry/package.json +++ b/core/geometry/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/geometry-core", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Bentley Core Geometry library", "main": "lib/geometry-core.js", "typings": "lib/geometry-core", @@ -32,12 +32,12 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/flatbuffers": "~1.10.0", "@types/mocha": "^5.2.5", diff --git a/core/hypermodeling/package.json b/core/hypermodeling/package.json index 0131d460310..f8ba4ae4726 100644 --- a/core/hypermodeling/package.json +++ b/core/hypermodeling/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/hypermodeling-frontend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js hypermodeling package", "main": "lib/hypermodeling-frontend.js", "typings": "lib/hypermodeling-frontend", @@ -35,23 +35,23 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6", - "@bentley/ui-abstract": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7", + "@bentley/ui-abstract": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/core/i18n/package.json b/core/i18n/package.json index ad993832d59..c784a98172a 100644 --- a/core/i18n/package.json +++ b/core/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-i18n", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js localization code", "main": "lib/imodeljs-i18n", "typings": "lib/imodeljs-i18n", @@ -30,16 +30,16 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/i18next": "^8.4.2", "@types/i18next-browser-languagedetector": "^2.0.1", "@types/node": "10.14.1", diff --git a/core/imodel-bridge/package.json b/core/imodel-bridge/package.json index b0df5e68887..23c8d24a05a 100644 --- a/core/imodel-bridge/package.json +++ b/core/imodel-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodel-bridge", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js bridge components", "main": "lib/imodel-bridge.js", "typings": "lib/imodel-bridge", @@ -40,31 +40,31 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/backend-itwin-client": "^2.15.0-dev.6", - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/context-registry-client": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodelhub-client": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/rbac-client": "^2.15.0-dev.6" + "@bentley/backend-itwin-client": "^2.15.0-dev.7", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/context-registry-client": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodelhub-client": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/rbac-client": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/core/logger-config/package.json b/core/logger-config/package.json index 521ad6e7193..f751b7e87cc 100644 --- a/core/logger-config/package.json +++ b/core/logger-config/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/logger-config", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Logger configuration", "main": "lib/logger-config.js", "typings": "lib/logger-config", @@ -30,16 +30,16 @@ "iModel" ], "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", "bunyan": "^1.8.12", "bunyan-seq": "^0.2.0", "request": "^2.88.0", "request-promise": "^4.2.0" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/bunyan": "^1.8.4", "@types/bunyan-seq": "^0.2.0", "@types/node": "10.14.1", diff --git a/core/markup/package.json b/core/markup/package.json index b1545612cc6..dd4243d22ae 100644 --- a/core/markup/package.json +++ b/core/markup/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-markup", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js markup package", "main": "lib/imodeljs-markup.js", "imodeljsSharedLibrary": true, @@ -39,21 +39,21 @@ "@svgdotjs/svg.js": "3.0.13" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/core/mobile-manager/package.json b/core/mobile-manager/package.json index 2dff8a28fb7..d33729c64c4 100644 --- a/core/mobile-manager/package.json +++ b/core/mobile-manager/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/mobile-manager", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iTwin.js MobileHost and MobileApp", "license": "MIT", "engines": { @@ -31,26 +31,26 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/frontend-authorization-client": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/imodelhub-client": "^2.15.0-dev.6", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/frontend-authorization-client": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/imodelhub-client": "^2.15.0-dev.7", "ws": "^7.2.0", "js-base64": "^2.4.5" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", "@types/node": "10.14.1", "@types/mocha": "^5.2.5", "@types/chai": "^4.1.4", diff --git a/core/orbitgt/package.json b/core/orbitgt/package.json index bdb2656935b..7ebba56b16e 100644 --- a/core/orbitgt/package.json +++ b/core/orbitgt/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/orbitgt-core", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "", "main": "lib/imodeljs-orbitgt.js", "typings": "lib/imodeljs-orbitgt", @@ -29,9 +29,9 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/core/quantity/package.json b/core/quantity/package.json index c04c72f844a..d1bb9d1538b 100644 --- a/core/quantity/package.json +++ b/core/quantity/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-quantity", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Quantity parsing, formatting and conversions for iModel.js", "main": "lib/imodeljs-quantity.js", "typings": "lib/imodeljs-quantity", @@ -31,9 +31,9 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/glob": "^5.0.35", @@ -50,7 +50,7 @@ "typescript": "~4.1.0" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7" }, "nyc": { "nycrc-path": "./node_modules/@bentley/build-tools/.nycrc" diff --git a/core/webgl-compatibility/package.json b/core/webgl-compatibility/package.json index f56f9d27250..9a8233131eb 100644 --- a/core/webgl-compatibility/package.json +++ b/core/webgl-compatibility/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/webgl-compatibility", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "APIs for determining the level of compatibility of a browser+device with the iModel.js rendering system.", "license": "MIT", "main": "lib/webgl-compatibility.js", @@ -33,13 +33,13 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/domains/analytical/backend/package.json b/domains/analytical/backend/package.json index 1b3d39d0707..66a81195c33 100644 --- a/domains/analytical/backend/package.json +++ b/domains/analytical/backend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/analytical-backend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "main": "lib/analytical-backend.js", "typings": "lib/analytical-backend", "license": "MIT", @@ -32,20 +32,20 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/fs-extra": "^4.0.7", "@types/mocha": "^5.2.5", diff --git a/domains/linear-referencing/backend/package.json b/domains/linear-referencing/backend/package.json index eff31c99bd1..27f57d4b3f8 100644 --- a/domains/linear-referencing/backend/package.json +++ b/domains/linear-referencing/backend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/linear-referencing-backend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "main": "lib/linear-referencing-backend.js", "typings": "lib/linear-referencing-backend", "license": "MIT", @@ -32,22 +32,22 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/linear-referencing-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/linear-referencing-common": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/linear-referencing-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/linear-referencing-common": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/fs-extra": "^4.0.7", "@types/mocha": "^5.2.5", diff --git a/domains/linear-referencing/common/package.json b/domains/linear-referencing/common/package.json index e1ea72dde85..81b26377a76 100644 --- a/domains/linear-referencing/common/package.json +++ b/domains/linear-referencing/common/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/linear-referencing-common", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "main": "lib/linear-referencing-common.js", "typings": "lib/linear-referencing-common", "license": "MIT", @@ -31,18 +31,18 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/fs-extra": "^4.0.7", "@types/mocha": "^5.2.5", diff --git a/domains/physical-material/backend/package.json b/domains/physical-material/backend/package.json index ea02b99e83e..4113c5a58c8 100644 --- a/domains/physical-material/backend/package.json +++ b/domains/physical-material/backend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/physical-material-backend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "main": "lib/physical-material-backend.js", "typings": "lib/physical-material-backend", "license": "MIT", @@ -31,20 +31,20 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/fs-extra": "^4.0.7", "@types/mocha": "^5.2.5", diff --git a/editor/backend/package.json b/editor/backend/package.json index ddd847ee1d9..92166ba4a21 100644 --- a/editor/backend/package.json +++ b/editor/backend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-editor-backend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js editor backend", "main": "lib/imodeljs-editor-backend.js", "typings": "lib/imodeljs-editor-backend", @@ -34,22 +34,22 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/deep-assign": "^0.1.0", @@ -70,7 +70,7 @@ "typescript": "~4.1.0" }, "dependencies": { - "@bentley/imodeljs-editor-common": "2.15.0-dev.6" + "@bentley/imodeljs-editor-common": "2.15.0-dev.7" }, "nyc": { "nycrc-path": "./node_modules/@bentley/build-tools/.nycrc" diff --git a/editor/common/package.json b/editor/common/package.json index 0750c2b494a..4d5d3b0c57c 100644 --- a/editor/common/package.json +++ b/editor/common/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-editor-common", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js editing properties common to frontend and backend", "main": "lib/imodeljs-editor-common.js", "typings": "lib/imodeljs-editor-common", @@ -33,16 +33,16 @@ }, "dependencies": {}, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/editor/frontend/package.json b/editor/frontend/package.json index c0218eed9b6..39486ffab69 100644 --- a/editor/frontend/package.json +++ b/editor/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodeljs-editor-frontend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js frontend components", "main": "lib/imodeljs-editor-frontend.js", "typings": "lib/imodeljs-editor-frontend", @@ -34,21 +34,21 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", @@ -69,10 +69,10 @@ "NOTE: imodeljs-editor-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed" ], "dependencies": { - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/imodeljs-editor-common": "2.15.0-dev.6" + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/imodeljs-editor-common": "2.15.0-dev.7" }, "nyc": { "nycrc-path": "./node_modules/@bentley/build-tools/.nycrc" diff --git a/example-code/app/package.json b/example-code/app/package.json index 0f45d7e68a3..49b1d233cd8 100644 --- a/example-code/app/package.json +++ b/example-code/app/package.json @@ -18,17 +18,17 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/logger-config": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/logger-config": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", "body-parser": "^1.18.2", "chai": "^4.1.2", "electron": "^11.1.0", @@ -43,9 +43,9 @@ "webpack": "4.42.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/body-parser": "^1.17.0", "@types/chai": "^4.1.4", "@types/express": "^4.16.1", diff --git a/example-code/snippets/package.json b/example-code/snippets/package.json index da5f64acfbd..9850fe9f6b7 100644 --- a/example-code/snippets/package.json +++ b/example-code/snippets/package.json @@ -17,16 +17,16 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "body-parser": "^1.18.2", "chai": "^4.1.2", "electron": "^11.1.0", @@ -41,9 +41,9 @@ "webpack": "4.42.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/body-parser": "^1.17.0", "@types/chai": "^4.1.4", "@types/express": "^4.16.1", diff --git a/extensions/geonames/package.json b/extensions/geonames/package.json index 25436f31bd8..cf91219e21f 100644 --- a/extensions/geonames/package.json +++ b/extensions/geonames/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/geonames-extension", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Geolocation Extension", "main": "index.js", "license": "MIT", @@ -25,10 +25,10 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/extension-webpack-tools": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/extension-webpack-tools": "2.15.0-dev.7", "@types/node": "10.14.1", "cpx": "^1.5.0", "eslint": "^6.8.0", @@ -36,13 +36,13 @@ "typescript": "~4.1.0" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "svg-sprite-loader": "4.2.1" }, "eslintConfig": { diff --git a/extensions/iot-demo/package.json b/extensions/iot-demo/package.json index cb1927896c0..0443fc58426 100644 --- a/extensions/iot-demo/package.json +++ b/extensions/iot-demo/package.json @@ -27,9 +27,9 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/extension-webpack-tools": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/extension-webpack-tools": "2.15.0-dev.7", "@types/react": "16.9.43", "@types/classnames": "^2.2.3", "cpx": "^1.5.0", @@ -38,18 +38,18 @@ "typescript": "~4.1.0" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-framework": "2.15.0-dev.6", - "@bentley/ui-ninezone": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-framework": "2.15.0-dev.7", + "@bentley/ui-ninezone": "2.15.0-dev.7", "classnames": "^2.2.5", "react": "^16.8.0", "svg-sprite-loader": "4.2.1" diff --git a/extensions/map-layers/package.json b/extensions/map-layers/package.json index 8a992dc3c33..c811abd3d9e 100644 --- a/extensions/map-layers/package.json +++ b/extensions/map-layers/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/map-layers", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Extension that adds a Map Layers Widget", "main": "lib/map-layers.js", "typings": "lib/map-layers", @@ -33,23 +33,23 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/extension-webpack-tools": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/extension-webpack-tools": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-framework": "2.15.0-dev.6", - "@bentley/ui-ninezone": "2.15.0-dev.6", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-framework": "2.15.0-dev.7", + "@bentley/ui-ninezone": "2.15.0-dev.7", "@testing-library/react": "^8.0.1", "@testing-library/react-hooks": "^3.2.1", "@types/classnames": "^2.2.3", @@ -88,18 +88,18 @@ "react-select": "3.1.0" }, "peerDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-framework": "2.15.0-dev.6", - "@bentley/ui-ninezone": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-framework": "2.15.0-dev.7", + "@bentley/ui-ninezone": "2.15.0-dev.7", "react": "^16.8.0", "react-dom": "^16.8.0" }, diff --git a/full-stack-tests/core/package.json b/full-stack-tests/core/package.json index f6826a3d287..5306218b0fb 100644 --- a/full-stack-tests/core/package.json +++ b/full-stack-tests/core/package.json @@ -24,38 +24,38 @@ }, "repository": {}, "dependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/express-server": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/hypermodeling-frontend": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-editor-backend": "2.15.0-dev.6", - "@bentley/imodeljs-editor-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-editor-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-markup": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/express-server": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/hypermodeling-frontend": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-editor-backend": "2.15.0-dev.7", + "@bentley/imodeljs-editor-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-editor-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-markup": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "chai": "^4.1.2", "chai-as-promised": "^7", "fs-extra": "^8.1.0", "electron": "^11.1.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/product-settings-client": "2.15.0-dev.6", - "@bentley/extension-webpack-tools": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/product-settings-client": "2.15.0-dev.7", + "@bentley/extension-webpack-tools": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/fs-extra": "^4.0.7", diff --git a/full-stack-tests/imodelhub-client/package.json b/full-stack-tests/imodelhub-client/package.json index bffc3e629ac..a50e6cf4c8e 100644 --- a/full-stack-tests/imodelhub-client/package.json +++ b/full-stack-tests/imodelhub-client/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/imodelhub-client-tests", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "main": "lib/imodelhub-client-tests.js", "description": "Tests the iModelHub client", "license": "MIT", @@ -36,14 +36,14 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "chai": "^4.1.2", "deep-assign": "^2.0.0", "fs-extra": "^8.1.0", @@ -52,10 +52,10 @@ "nock": "^12.0.3" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/deep-assign": "^0.1.0", "@types/fs-extra": "^4.0.7", diff --git a/full-stack-tests/native-app/package.json b/full-stack-tests/native-app/package.json index b4e935b2bf5..8c8d702ca80 100644 --- a/full-stack-tests/native-app/package.json +++ b/full-stack-tests/native-app/package.json @@ -20,31 +20,31 @@ }, "repository": {}, "dependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/express-server": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-markup": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/express-server": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-markup": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", "chai": "^4.1.2", "fs-extra": "^8.1.0", "electron": "^11.1.0" }, "devDependencies": { - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/fs-extra": "^4.0.7", "@types/mocha": "^5.2.5", diff --git a/full-stack-tests/presentation/package.json b/full-stack-tests/presentation/package.json index 708d629b39f..b55a452989f 100644 --- a/full-stack-tests/presentation/package.json +++ b/full-stack-tests/presentation/package.json @@ -22,23 +22,23 @@ "cover": "npm run test" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-backend": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/presentation-components": "2.15.0-dev.6", - "@bentley/presentation-testing": "2.15.0-dev.6", - "@bentley/product-settings-client": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-backend": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/presentation-components": "2.15.0-dev.7", + "@bentley/presentation-testing": "2.15.0-dev.7", + "@bentley/product-settings-client": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", "@testing-library/react-hooks": "^3.2.1", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", @@ -71,9 +71,9 @@ "xmlhttprequest": "^1.8.0" }, "devDependencies": { - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/react": "16.9.43", "@types/react-dom": "^16.8.0", "@types/testing-library__react-hooks": "^3.1.0", diff --git a/full-stack-tests/rpc-interface/package.json b/full-stack-tests/rpc-interface/package.json index d72db0c0800..3206e13dcd3 100644 --- a/full-stack-tests/rpc-interface/package.json +++ b/full-stack-tests/rpc-interface/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/rpcinterface-full-stack-tests", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Test the full iModel.js stack (frontend and backend) using standard RPC interfaces", "license": "MIT", "scripts": { @@ -34,23 +34,23 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/oidc-signin-tool": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/oidc-signin-tool": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "chai": "^4.1.2", "chai-as-promised": "^7", "dotenv": "^8.2.0", @@ -60,9 +60,9 @@ "puppeteer": "chrome-86" }, "devDependencies": { - "@bentley/express-server": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/presentation-backend": "2.15.0-dev.6", + "@bentley/express-server": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/presentation-backend": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/dotenv": "^6.1.1", diff --git a/full-stack-tests/rpc/package.json b/full-stack-tests/rpc/package.json index 935f477ee3f..152134d8b14 100644 --- a/full-stack-tests/rpc/package.json +++ b/full-stack-tests/rpc/package.json @@ -18,14 +18,14 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/express-server": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", - "@bentley/mobile-manager": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/express-server": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", + "@bentley/mobile-manager": "2.15.0-dev.7", "chai": "^4.1.2", "electron": "^11.1.0", "express": "^4.16.3", @@ -33,9 +33,9 @@ "spdy": "^4.0.1" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/express": "^4.16.1", "@types/mocha": "^5.2.5", diff --git a/presentation/backend/package.json b/presentation/backend/package.json index 4fb9e610543..d8675455e49 100644 --- a/presentation/backend/package.json +++ b/presentation/backend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/presentation-backend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Backend of iModel.js Presentation library", "license": "MIT", "repository": { @@ -37,20 +37,20 @@ "test:watch": "npm test -- --reporter min --watch-extensions ts --watch" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-backend": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-quantity": "^2.15.0-dev.6", - "@bentley/presentation-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-backend": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-quantity": "^2.15.0-dev.7", + "@bentley/presentation-common": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/chai-jest-snapshot": "^1.3.0", diff --git a/presentation/common/package.json b/presentation/common/package.json index 9edc06d91fa..729e8383480 100644 --- a/presentation/common/package.json +++ b/presentation/common/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/presentation-common", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Common pieces for iModel.js presentation packages", "imodeljsSharedLibrary": true, "license": "MIT", @@ -43,16 +43,16 @@ "test:watch": "npm test -- --reporter min --watch-extensions ts --watch" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-quantity": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-quantity": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/chai-jest-snapshot": "^1.3.0", diff --git a/presentation/components/package.json b/presentation/components/package.json index 834f92dbd40..5ad1570eb72 100644 --- a/presentation/components/package.json +++ b/presentation/components/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/presentation-components", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "React components based on iModel.js Presentation library", "main": "lib/presentation-components.js", "typings": "lib/presentation-components", @@ -47,30 +47,30 @@ "rxjs": "^6.6.2" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6", - "@bentley/presentation-common": "^2.15.0-dev.6", - "@bentley/presentation-frontend": "^2.15.0-dev.6", - "@bentley/ui-abstract": "^2.15.0-dev.6", - "@bentley/ui-components": "^2.15.0-dev.6", - "@bentley/ui-core": "^2.15.0-dev.6", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7", + "@bentley/presentation-common": "^2.15.0-dev.7", + "@bentley/presentation-frontend": "^2.15.0-dev.7", + "@bentley/ui-abstract": "^2.15.0-dev.7", + "@bentley/ui-components": "^2.15.0-dev.7", + "@bentley/ui-core": "^2.15.0-dev.7", "react": "^16.8.0", "react-dom": "^16.8.0" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", "@testing-library/react": "^8.0.1", "@testing-library/react-hooks": "^3.2.1", "@types/chai": "^4.1.4", diff --git a/presentation/frontend/package.json b/presentation/frontend/package.json index 2e22c76c3da..6b36023eabb 100644 --- a/presentation/frontend/package.json +++ b/presentation/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/presentation-frontend", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Frontend of iModel.js Presentation library", "main": "lib/presentation-frontend.js", "typings": "lib/presentation-frontend", @@ -43,23 +43,23 @@ "lodash": "^4.17.10" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6", - "@bentley/presentation-common": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7", + "@bentley/presentation-common": "^2.15.0-dev.7" }, "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/product-settings-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/product-settings-client": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/chai-jest-snapshot": "^1.3.0", diff --git a/presentation/testing/package.json b/presentation/testing/package.json index 01863125821..47ddfe7f56d 100644 --- a/presentation/testing/package.json +++ b/presentation/testing/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/presentation-testing", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "", "license": "MIT", "repository": { @@ -38,20 +38,20 @@ "ignore-styles": "^5.0.1" }, "dependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/presentation-backend": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-components": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/presentation-backend": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-components": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/chai-jest-snapshot": "^1.3.0", diff --git a/test-apps/analysis-importer/package.json b/test-apps/analysis-importer/package.json index 046a25a22ae..6265067a72e 100644 --- a/test-apps/analysis-importer/package.json +++ b/test-apps/analysis-importer/package.json @@ -15,16 +15,16 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "body-parser": "^1.18.2" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/body-parser": "^1.17.0", "@types/express": "^4.16.1", "@types/node": "10.14.1", diff --git a/test-apps/display-performance-test-app/package.json b/test-apps/display-performance-test-app/package.json index 7a46fa8678b..8ef8b7a471f 100644 --- a/test-apps/display-performance-test-app/package.json +++ b/test-apps/display-performance-test-app/package.json @@ -33,30 +33,30 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", - "@bentley/mobile-manager": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/projectshare-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", + "@bentley/mobile-manager": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/projectshare-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", "body-parser": "^1.18.2" }, "devDependencies": { - "@bentley/perf-tools": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/perf-tools": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", "@types/body-parser": "^1.17.0", "@types/express": "^4.16.1", diff --git a/test-apps/display-test-app/package.json b/test-apps/display-test-app/package.json index 04ba1dc7d5e..98f41c2791b 100644 --- a/test-apps/display-test-app/package.json +++ b/test-apps/display-test-app/package.json @@ -37,34 +37,34 @@ "dependencies": { "@bentley/icons-generic": "^1.0.15", "@bentley/icons-generic-webfont": "^1.0.15", - "@bentley/frontend-devtools": "2.15.0-dev.6", - "@bentley/hypermodeling-frontend": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", - "@bentley/mobile-manager": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-markup": "2.15.0-dev.6", - "@bentley/imodeljs-editor-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-editor-backend": "2.15.0-dev.6", - "@bentley/imodeljs-editor-common": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/webgl-compatibility": "2.15.0-dev.6", + "@bentley/frontend-devtools": "2.15.0-dev.7", + "@bentley/hypermodeling-frontend": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", + "@bentley/mobile-manager": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-markup": "2.15.0-dev.7", + "@bentley/imodeljs-editor-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-editor-backend": "2.15.0-dev.7", + "@bentley/imodeljs-editor-common": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/webgl-compatibility": "2.15.0-dev.7", "body-parser": "^1.18.2" }, "devDependencies": { - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", "@types/body-parser": "^1.17.0", "@types/express": "^4.16.1", diff --git a/test-apps/export-gltf/package.json b/test-apps/export-gltf/package.json index 6c97663bf41..caeb4725af4 100644 --- a/test-apps/export-gltf/package.json +++ b/test-apps/export-gltf/package.json @@ -14,16 +14,16 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/node": "10.14.1", "@types/yargs": "^12.0.5", "eslint": "^6.8.0", diff --git a/test-apps/export-obj/package.json b/test-apps/export-obj/package.json index e49ee031278..0439718236f 100644 --- a/test-apps/export-obj/package.json +++ b/test-apps/export-obj/package.json @@ -14,16 +14,16 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/node": "10.14.1", "@types/yargs": "^12.0.5", "eslint": "^6.8.0", diff --git a/test-apps/imjs-importer/package.json b/test-apps/imjs-importer/package.json index 0cc343984c8..b2093f098bf 100644 --- a/test-apps/imjs-importer/package.json +++ b/test-apps/imjs-importer/package.json @@ -24,21 +24,21 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/logger-config": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/logger-config": "2.15.0-dev.7", "chai": "^4.1.2", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/test-apps/imodel-from-geojson/package.json b/test-apps/imodel-from-geojson/package.json index 38e7a0f2587..164f11f8673 100644 --- a/test-apps/imodel-from-geojson/package.json +++ b/test-apps/imodel-from-geojson/package.json @@ -14,18 +14,18 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", "fs-extra": "^8.1.0", "request-promise-native": "^1.0.5", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/fs-extra": "^4.0.7", "@types/lodash": "^4.14.0", "@types/node": "10.14.1", diff --git a/test-apps/imodel-from-orbitgt/package.json b/test-apps/imodel-from-orbitgt/package.json index 694ea18b320..8ca00f05e42 100644 --- a/test-apps/imodel-from-orbitgt/package.json +++ b/test-apps/imodel-from-orbitgt/package.json @@ -14,19 +14,19 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/orbitgt-core": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/orbitgt-core": "2.15.0-dev.7", "request-promise-native": "^1.0.5", "request": "^2.88.0", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/fs-extra": "^4.0.7", "@types/lodash": "^4.14.0", "@types/node": "10.14.1", diff --git a/test-apps/imodel-from-reality-model/package.json b/test-apps/imodel-from-reality-model/package.json index 0feaeede328..61b3d7e1c60 100644 --- a/test-apps/imodel-from-reality-model/package.json +++ b/test-apps/imodel-from-reality-model/package.json @@ -14,19 +14,19 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", "fs-extra": "^8.1.0", "request-promise-native": "^1.0.5", "request": "^2.88.0", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/fs-extra": "^4.0.7", "@types/lodash": "^4.14.0", "@types/node": "10.14.1", diff --git a/test-apps/imodel-transformer/package.json b/test-apps/imodel-transformer/package.json index 298b1377ab2..5cdb14352e1 100644 --- a/test-apps/imodel-transformer/package.json +++ b/test-apps/imodel-transformer/package.json @@ -15,18 +15,18 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", "fs-extra": "^8.1.0", "request-promise-native": "^1.0.5", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/fs-extra": "^4.0.7", diff --git a/test-apps/ninezone-test-app/package.json b/test-apps/ninezone-test-app/package.json index 6251b547524..37254b41e1e 100644 --- a/test-apps/ninezone-test-app/package.json +++ b/test-apps/ninezone-test-app/package.json @@ -19,8 +19,8 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", "@types/classnames": "^2.2.3", "@types/react": "16.9.43", @@ -30,10 +30,10 @@ }, "dependencies": { "@bentley/icons-generic-webfont": "^1.0.15", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-ninezone": "2.15.0-dev.6", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-ninezone": "2.15.0-dev.7", "classnames": "^2.2.5", "highlight.js": "~10.6.0", "raf-schd": "^4.0.0", diff --git a/test-apps/presentation-test-app/package.json b/test-apps/presentation-test-app/package.json index 70953a8f46a..4a6cad94047 100644 --- a/test-apps/presentation-test-app/package.json +++ b/test-apps/presentation-test-app/package.json @@ -30,32 +30,32 @@ "cover": "" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", - "@bentley/express-server": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", + "@bentley/express-server": "2.15.0-dev.7", "@bentley/icons-generic-webfont": "^1.0.15", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-backend": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/presentation-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-backend": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/presentation-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", "react": "^16.8.0", "react-dom": "^16.8.0", "react-select": "3.1.0", "semver": "^5.5.0" }, "devDependencies": { - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", "@types/bunyan": "^1.8.4", "@types/react": "16.9.43", diff --git a/test-apps/synchro-schedule-importer/package.json b/test-apps/synchro-schedule-importer/package.json index 7ab1d54a60a..6e957fc7c1e 100644 --- a/test-apps/synchro-schedule-importer/package.json +++ b/test-apps/synchro-schedule-importer/package.json @@ -16,17 +16,17 @@ }, "repository": {}, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", "fs-extra": "^8.1.0", "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/fs-extra": "^4.0.7", "@types/lodash": "^4.14.0", "@types/node": "10.14.1", diff --git a/test-apps/ui-test-app/package.json b/test-apps/ui-test-app/package.json index d63724bbbca..449489458ca 100644 --- a/test-apps/ui-test-app/package.json +++ b/test-apps/ui-test-app/package.json @@ -44,12 +44,12 @@ ], "devDependencies": { "@axe-core/react": "^4.1.1", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/logger-config": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/imodeljs-markup": "2.15.0-dev.6", - "@bentley/frontend-devtools": "2.15.0-dev.6", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/logger-config": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/imodeljs-markup": "2.15.0-dev.7", + "@bentley/frontend-devtools": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", "@types/classnames": "^2.2.3", "@types/lorem-ipsum": "^1.0.2", @@ -76,43 +76,43 @@ "semver": "^5.5.0" }, "dependencies": { - "@bentley/backend-application-insights-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", - "@bentley/mobile-manager": "2.15.0-dev.6", - "@bentley/express-server": "2.15.0-dev.6", - "@bentley/frontend-application-insights-client": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", + "@bentley/backend-application-insights-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", + "@bentley/mobile-manager": "2.15.0-dev.7", + "@bentley/express-server": "2.15.0-dev.7", + "@bentley/frontend-application-insights-client": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", "@bentley/icons-generic-webfont": "^1.0.15", "@bentley/icons-generic": "^1.0.15", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/frontend-devtools": "2.15.0-dev.6", - "@bentley/hypermodeling-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-markup": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-editor-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-editor-backend": "2.15.0-dev.6", - "@bentley/imodeljs-editor-common": "2.15.0-dev.6", - "@bentley/presentation-backend": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-components": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/projectshare-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-ninezone": "2.15.0-dev.6", - "@bentley/ui-framework": "2.15.0-dev.6", - "@bentley/map-layers": "2.15.0-dev.6", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/frontend-devtools": "2.15.0-dev.7", + "@bentley/hypermodeling-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-markup": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-editor-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-editor-backend": "2.15.0-dev.7", + "@bentley/imodeljs-editor-common": "2.15.0-dev.7", + "@bentley/presentation-backend": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-components": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/projectshare-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-ninezone": "2.15.0-dev.7", + "@bentley/ui-framework": "2.15.0-dev.7", + "@bentley/map-layers": "2.15.0-dev.7", "classnames": "^2.2.5", "lorem-ipsum": "^2.0.3", "mobx": "^5.8.0", diff --git a/test-apps/ui-test-extension/package.json b/test-apps/ui-test-extension/package.json index 87ea616fc77..725826b508d 100644 --- a/test-apps/ui-test-extension/package.json +++ b/test-apps/ui-test-extension/package.json @@ -28,9 +28,9 @@ }, "license": "MIT", "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/extension-webpack-tools": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/extension-webpack-tools": "2.15.0-dev.7", "@types/react": "16.9.43", "@types/classnames": "^2.2.3", "@types/react-select": "3.0.26", @@ -41,21 +41,21 @@ "svg-sprite-loader": "4.2.1" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-framework": "2.15.0-dev.6", - "@bentley/ui-ninezone": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/presentation-components": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-framework": "2.15.0-dev.7", + "@bentley/ui-ninezone": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/presentation-components": "2.15.0-dev.7", "classnames": "^2.2.5", "react": "^16.8.0", "react-compound-slider": "^2.5.0", diff --git a/tools/backend-webpack/package.json b/tools/backend-webpack/package.json index 0c2a4dc5a34..95aa08c2d80 100644 --- a/tools/backend-webpack/package.json +++ b/tools/backend-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/backend-webpack-tools", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Configuration and scripts for iModel.js agents and backends.", "license": "MIT", "repository": { @@ -24,7 +24,7 @@ "backend-webpack-tools": "./bin/backend-webpack-tools.js" }, "dependencies": { - "@bentley/webpack-tools-core": "2.15.0-dev.6", + "@bentley/webpack-tools-core": "2.15.0-dev.7", "case-sensitive-paths-webpack-plugin": "^2.1.2", "chalk": "^3.0.0", "concurrently": "^3.6.1", diff --git a/tools/build/package.json b/tools/build/package.json index 1e6828f158e..77502c8c410 100644 --- a/tools/build/package.json +++ b/tools/build/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/build-tools", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Bentley build tools", "license": "MIT", "repository": { @@ -58,7 +58,7 @@ "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/node": "10.14.1", "eslint": "^6.8.0" }, diff --git a/tools/certa/package.json b/tools/certa/package.json index 8626f64eee0..a5fd5e1bc03 100644 --- a/tools/certa/package.json +++ b/tools/certa/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/certa", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "A mocha-based integration test runner", "license": "MIT", "main": "bin/certa.js", @@ -44,8 +44,8 @@ "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/detect-port": "~1.1.0", "@types/express": "^4.16.1", diff --git a/tools/config-loader/package.json b/tools/config-loader/package.json index 4fc4becdbee..23392f1a1e4 100644 --- a/tools/config-loader/package.json +++ b/tools/config-loader/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/config-loader", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Configuration loader", "license": "MIT", "repository": { @@ -35,8 +35,8 @@ "json5": "^2.1.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/json5": "0.0.30", "@types/node": "10.14.1", "eslint": "^6.8.0", diff --git a/tools/ecschema2ts/package.json b/tools/ecschema2ts/package.json index c34ff47a34a..c891fdfc4b3 100644 --- a/tools/ecschema2ts/package.json +++ b/tools/ecschema2ts/package.json @@ -2,7 +2,7 @@ "name": "@bentley/ecschema2ts", "description": "Command line tools that takes an ECSchema xml file and outputs a typescript module", "license": "MIT", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "bin": { "ecschema2ts": "./bin/index.js" }, @@ -35,8 +35,8 @@ "url": "http://www.bentley.com" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-string": "^1.4.1", "@types/fs-extra": "^4.0.7", @@ -54,17 +54,17 @@ "typescript": "~4.1.0" }, "dependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/ecschema-locaters": "2.15.0-dev.6", - "@bentley/ecschema-metadata": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/ecschema-locaters": "2.15.0-dev.7", + "@bentley/ecschema-metadata": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "chai-string": "^1.5.0", "chalk": "^3.0.0", "commander": "^2.14.1", diff --git a/tools/eslint-plugin/package.json b/tools/eslint-plugin/package.json index d0a616cacab..ee532bc67d8 100644 --- a/tools/eslint-plugin/package.json +++ b/tools/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/eslint-plugin", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "ESLint plugin with default configuration and custom rules for iModel.js projects", "license": "MIT", "keywords": [ diff --git a/tools/extension-cli/package.json b/tools/extension-cli/package.json index ad676fef002..be65ff5a198 100644 --- a/tools/extension-cli/package.json +++ b/tools/extension-cli/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/extension-cli", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "A CLI client for publishing iModel.js Extensions", "license": "MIT", "main": "bin/extension-cli.js", @@ -32,19 +32,19 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/backend-itwin-client": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/context-registry-client": "2.15.0-dev.6", - "@bentley/ecschema-metadata": "2.15.0-dev.6", - "@bentley/extension-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-backend": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/electron-manager": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", - "@bentley/telemetry-client": "2.15.0-dev.6", + "@bentley/backend-itwin-client": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/context-registry-client": "2.15.0-dev.7", + "@bentley/ecschema-metadata": "2.15.0-dev.7", + "@bentley/extension-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-backend": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/electron-manager": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", + "@bentley/telemetry-client": "2.15.0-dev.7", "electron": "^11.1.0", "fast-sha256": "1.3.0", "rimraf": "^3.0.2", @@ -53,8 +53,8 @@ "yargs": "^16.0.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/mocha": "^5.2.5", "@types/node": "10.14.1", diff --git a/tools/extension-webpack/package.json b/tools/extension-webpack/package.json index b82a7e3373b..6bb6b940f06 100644 --- a/tools/extension-webpack/package.json +++ b/tools/extension-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/extension-webpack-tools", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Configuration and scripts for iModel.js Extensions.", "license": "MIT", "repository": { @@ -26,7 +26,7 @@ "types": "./index.d.ts", "dependencies": { "@babel/core": "7.7.4", - "@bentley/webpack-tools-core": "2.15.0-dev.6", + "@bentley/webpack-tools-core": "2.15.0-dev.7", "@svgr/webpack": "4.3.3", "babel-loader": "8.1.0", "babel-plugin-named-asset-import": "^0.3.5", diff --git a/tools/oidc-signin-tool/package.json b/tools/oidc-signin-tool/package.json index d730e64d8f0..05722b22dc0 100644 --- a/tools/oidc-signin-tool/package.json +++ b/tools/oidc-signin-tool/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/oidc-signin-tool", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "OIDC Signin Helper", "main": "lib/index.js", "typings": "lib/index", @@ -31,17 +31,17 @@ "url": "http://www.bentley.com" }, "dependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/certa": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/certa": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", "openid-client": "^3.15.3", "puppeteer": "chrome-86" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/mocha": "^5.2.5", diff --git a/tools/perf-tools/package.json b/tools/perf-tools/package.json index cd4f8571be5..0abbd23f455 100644 --- a/tools/perf-tools/package.json +++ b/tools/perf-tools/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/perf-tools", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Tools for collecting and reporting performance data", "license": "MIT", "repository": { @@ -31,8 +31,8 @@ "fs-extra": "^8.1.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/fs-extra": "^4.0.7", "eslint": "^6.8.0", "rimraf": "^3.0.2", diff --git a/tools/webpack-core/package.json b/tools/webpack-core/package.json index 4ebf663ea8c..42c8b774612 100644 --- a/tools/webpack-core/package.json +++ b/tools/webpack-core/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/webpack-tools-core", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "Set of Webpack Plugins and Loaders used for building iModel.js applications", "license": "MIT", "repository": { @@ -37,8 +37,8 @@ "webpack": "4.42.0" }, "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", "@types/fs-extra": "^4.0.7", "@types/glob": "^5.0.35", "@types/node": "10.14.1", diff --git a/ui/abstract/package.json b/ui/abstract/package.json index aa37c99932d..1d0a59b63f9 100644 --- a/ui/abstract/package.json +++ b/ui/abstract/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/ui-abstract", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js UI abstractions", "main": "lib/ui-abstract.js", "typings": "lib/ui-abstract", @@ -33,20 +33,20 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6" + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7" }, "//devDependencies": [ "NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install", "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", "@types/chai": "^4.1.4", "@types/chai-as-promised": "^7", "@types/chai-jest-snapshot": "^1.3.0", diff --git a/ui/components/package.json b/ui/components/package.json index da3bba95b69..1db63d4d585 100644 --- a/ui/components/package.json +++ b/ui/components/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/ui-components", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js UI complex components", "main": "lib/ui-components.js", "typings": "lib/ui-components", @@ -33,14 +33,14 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6", - "@bentley/imodeljs-quantity": "^2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-core": "^2.15.0-dev.6", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7", + "@bentley/imodeljs-quantity": "^2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-core": "^2.15.0-dev.7", "react": "^16.8.0", "react-dom": "^16.8.0" }, @@ -49,16 +49,16 @@ "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", "@testing-library/react": "^8.0.1", "@testing-library/react-hooks": "^3.2.1", "@types/chai": "^4.1.4", diff --git a/ui/core/package.json b/ui/core/package.json index 283d19f5169..360f3101fbf 100644 --- a/ui/core/package.json +++ b/ui/core/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/ui-core", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js UI core components", "main": "lib/ui-core.js", "typings": "lib/ui-core", @@ -35,10 +35,10 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6", - "@bentley/ui-abstract": "^2.15.0-dev.6", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7", + "@bentley/ui-abstract": "^2.15.0-dev.7", "react": "^16.8.0", "react-dom": "^16.8.0" }, @@ -47,13 +47,13 @@ "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", - "@bentley/ui-abstract": "2.15.0-dev.6", + "@bentley/ui-abstract": "2.15.0-dev.7", "@testing-library/react": "^8.0.1", "@testing-library/react-hooks": "^3.2.1", "@types/chai": "^4.1.4", diff --git a/ui/framework/package.json b/ui/framework/package.json index 7947d2cd46d..5aa5e80da94 100644 --- a/ui/framework/package.json +++ b/ui/framework/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/ui-framework", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "UI framework", "main": "lib/ui-framework.js", "typings": "lib/ui-framework", @@ -34,24 +34,24 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/bentleyjs-core": "^2.15.0-dev.6", - "@bentley/frontend-authorization-client": "^2.15.0-dev.6", - "@bentley/geometry-core": "^2.15.0-dev.6", - "@bentley/imodelhub-client": "^2.15.0-dev.6", - "@bentley/imodeljs-common": "^2.15.0-dev.6", - "@bentley/imodeljs-frontend": "^2.15.0-dev.6", - "@bentley/imodeljs-quantity": "^2.15.0-dev.6", - "@bentley/imodeljs-i18n": "^2.15.0-dev.6", - "@bentley/imodeljs-markup": "^2.15.0-dev.6", - "@bentley/itwin-client": "^2.15.0-dev.6", - "@bentley/presentation-common": "^2.15.0-dev.6", - "@bentley/presentation-frontend": "^2.15.0-dev.6", - "@bentley/product-settings-client": "^2.15.0-dev.6", - "@bentley/rbac-client": "^2.15.0-dev.6", - "@bentley/ui-abstract": "^2.15.0-dev.6", - "@bentley/ui-components": "^2.15.0-dev.6", - "@bentley/ui-core": "^2.15.0-dev.6", - "@bentley/ui-ninezone": "^2.15.0-dev.6", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", + "@bentley/frontend-authorization-client": "^2.15.0-dev.7", + "@bentley/geometry-core": "^2.15.0-dev.7", + "@bentley/imodelhub-client": "^2.15.0-dev.7", + "@bentley/imodeljs-common": "^2.15.0-dev.7", + "@bentley/imodeljs-frontend": "^2.15.0-dev.7", + "@bentley/imodeljs-quantity": "^2.15.0-dev.7", + "@bentley/imodeljs-i18n": "^2.15.0-dev.7", + "@bentley/imodeljs-markup": "^2.15.0-dev.7", + "@bentley/itwin-client": "^2.15.0-dev.7", + "@bentley/presentation-common": "^2.15.0-dev.7", + "@bentley/presentation-frontend": "^2.15.0-dev.7", + "@bentley/product-settings-client": "^2.15.0-dev.7", + "@bentley/rbac-client": "^2.15.0-dev.7", + "@bentley/ui-abstract": "^2.15.0-dev.7", + "@bentley/ui-components": "^2.15.0-dev.7", + "@bentley/ui-core": "^2.15.0-dev.7", + "@bentley/ui-ninezone": "^2.15.0-dev.7", "react": "^16.8.0", "react-dom": "^16.8.0", "react-redux": "^7.2.0", @@ -62,30 +62,30 @@ "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/bentleyjs-core": "2.15.0-dev.6", - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/config-loader": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/frontend-authorization-client": "2.15.0-dev.6", - "@bentley/geometry-core": "2.15.0-dev.6", - "@bentley/imodelhub-client": "2.15.0-dev.6", - "@bentley/imodeljs-common": "2.15.0-dev.6", - "@bentley/imodeljs-frontend": "2.15.0-dev.6", - "@bentley/imodeljs-quantity": "2.15.0-dev.6", - "@bentley/imodeljs-i18n": "2.15.0-dev.6", - "@bentley/imodeljs-markup": "2.15.0-dev.6", - "@bentley/itwin-client": "2.15.0-dev.6", - "@bentley/presentation-common": "2.15.0-dev.6", - "@bentley/presentation-frontend": "2.15.0-dev.6", - "@bentley/presentation-testing": "2.15.0-dev.6", - "@bentley/product-settings-client": "2.15.0-dev.6", - "@bentley/rbac-client": "2.15.0-dev.6", + "@bentley/bentleyjs-core": "2.15.0-dev.7", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/config-loader": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/frontend-authorization-client": "2.15.0-dev.7", + "@bentley/geometry-core": "2.15.0-dev.7", + "@bentley/imodelhub-client": "2.15.0-dev.7", + "@bentley/imodeljs-common": "2.15.0-dev.7", + "@bentley/imodeljs-frontend": "2.15.0-dev.7", + "@bentley/imodeljs-quantity": "2.15.0-dev.7", + "@bentley/imodeljs-i18n": "2.15.0-dev.7", + "@bentley/imodeljs-markup": "2.15.0-dev.7", + "@bentley/itwin-client": "2.15.0-dev.7", + "@bentley/presentation-common": "2.15.0-dev.7", + "@bentley/presentation-frontend": "2.15.0-dev.7", + "@bentley/presentation-testing": "2.15.0-dev.7", + "@bentley/product-settings-client": "2.15.0-dev.7", + "@bentley/rbac-client": "2.15.0-dev.7", "@bentley/react-scripts": "3.4.9", - "@bentley/telemetry-client": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-components": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/ui-ninezone": "2.15.0-dev.6", + "@bentley/telemetry-client": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-components": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/ui-ninezone": "2.15.0-dev.7", "@testing-library/react": "^8.0.1", "@testing-library/react-hooks": "^3.2.1", "@types/chai": "^4.1.4", @@ -137,10 +137,10 @@ "NOTE: imodeljs-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed" ], "dependencies": { - "@bentley/context-registry-client": "2.15.0-dev.6", + "@bentley/context-registry-client": "2.15.0-dev.7", "@bentley/icons-generic": "^1.0.15", "@bentley/icons-generic-webfont": "^1.0.15", - "@bentley/presentation-components": "2.15.0-dev.6", + "@bentley/presentation-components": "2.15.0-dev.7", "classnames": "^2.2.5", "immer": "8.0.1", "lodash": "^4.17.10", diff --git a/ui/ninezone/package.json b/ui/ninezone/package.json index 97c912ae633..38ffc7dda95 100644 --- a/ui/ninezone/package.json +++ b/ui/ninezone/package.json @@ -1,6 +1,6 @@ { "name": "@bentley/ui-ninezone", - "version": "2.15.0-dev.6", + "version": "2.15.0-dev.7", "description": "iModel.js Nine-zone React UI components", "main": "lib/ui-ninezone.js", "typings": "lib/ui-ninezone", @@ -33,9 +33,9 @@ "url": "http://www.bentley.com" }, "peerDependencies": { - "@bentley/ui-abstract": "^2.15.0-dev.6", - "@bentley/ui-core": "^2.15.0-dev.6", - "@bentley/bentleyjs-core": "^2.15.0-dev.6", + "@bentley/ui-abstract": "^2.15.0-dev.7", + "@bentley/ui-core": "^2.15.0-dev.7", + "@bentley/bentleyjs-core": "^2.15.0-dev.7", "react": "^16.8.0", "react-dom": "^16.8.0" }, @@ -44,11 +44,11 @@ "NOTE: All tools used by scripts in this package must be listed as devDependencies" ], "devDependencies": { - "@bentley/build-tools": "2.15.0-dev.6", - "@bentley/eslint-plugin": "2.15.0-dev.6", - "@bentley/ui-abstract": "2.15.0-dev.6", - "@bentley/ui-core": "2.15.0-dev.6", - "@bentley/bentleyjs-core": "2.15.0-dev.6", + "@bentley/build-tools": "2.15.0-dev.7", + "@bentley/eslint-plugin": "2.15.0-dev.7", + "@bentley/ui-abstract": "2.15.0-dev.7", + "@bentley/ui-core": "2.15.0-dev.7", + "@bentley/bentleyjs-core": "2.15.0-dev.7", "@testing-library/react": "^8.0.1", "@testing-library/react-hooks": "^3.2.1", "@types/chai": "^4.1.4", From 29550cc32ec36219a76d5a00d39d644f2d6a960f Mon Sep 17 00:00:00 2001 From: Dan East <51122937+DanEastBentley@users.noreply.github.com> Date: Thu, 25 Mar 2021 06:19:02 -0400 Subject: [PATCH 04/50] Added NativeHost.settingsStore (#1018) * wip * cleanup * move NativeApp to beta * rush change * Saving & restoring Electron main window size, position & maximized state * extract-api * extract-api * rush change * fix NativeAppStorage tests * Saving & restoring as number & boolean values * Better type checking of StorageValue * Added type checking methods to NativeAppStorage. Using one storage file for ElectronWindowState with setting namespaces. * further cleanup of NativeAppStorage * add NativeHost.settingsStore * change table name to app_settings * Fixed lint, extract-api and cover issues * fix lint errors * extract-api * extract-api * rush change * Added @packageDocumentation for NativeAppStorage * NextVersion.md Co-authored-by: Keith Bentley <33296803+kabentley@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- clients/itwin/src/Token.ts | 5 +- common/api/electron-manager.api.md | 23 ++- common/api/imodeljs-backend.api.md | 32 +++- common/api/imodeljs-frontend.api.md | 16 +- .../api/summary/imodeljs-backend.exports.csv | 3 +- .../api/summary/imodeljs-frontend.exports.csv | 8 +- .../nativeapp-storage_2021-03-23-11-26.json | 11 ++ ...ectron-position-size_2021-03-23-13-55.json | 11 ++ .../nativeapp-storage_2021-03-23-11-26.json | 11 ++ ...ectron-position-size_2021-03-23-13-55.json | 11 ++ ...ectron-position-size_2021-03-24-13-27.json | 11 ++ .../nativeapp-storage_2021-03-23-11-26.json | 11 ++ .../nativeapp-storage_2021-03-23-11-26.json | 11 ++ core/backend/src/NativeAppStorage.ts | 169 ++++++++++-------- core/backend/src/NativeHost.ts | 27 ++- core/backend/src/imodeljs-backend.ts | 7 +- .../test/standalone/NativeAppStorage.test.ts | 20 ++- .../backend/ElectronAuthorizationBackend.ts | 4 +- .../src/backend/ElectronHost.ts | 62 ++++++- core/frontend/src/NativeApp.ts | 109 +++-------- docs/changehistory/NextVersion.md | 8 + .../standalone/NativeAppStorage.test.ts | 3 +- .../display-test-app/src/backend/Backend.ts | 15 +- .../src/backend/DtaElectronMain.ts | 28 +-- .../display-test-app/src/frontend/FileOpen.ts | 1 + .../src/backend/electron/ElectronMain.ts | 15 +- 26 files changed, 413 insertions(+), 219 deletions(-) create mode 100644 common/changes/@bentley/electron-manager/nativeapp-storage_2021-03-23-11-26.json create mode 100644 common/changes/@bentley/electron-manager/ui-uitestapp-electron-position-size_2021-03-23-13-55.json create mode 100644 common/changes/@bentley/imodeljs-backend/nativeapp-storage_2021-03-23-11-26.json create mode 100644 common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-23-13-55.json create mode 100644 common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-24-13-27.json create mode 100644 common/changes/@bentley/imodeljs-frontend/nativeapp-storage_2021-03-23-11-26.json create mode 100644 common/changes/@bentley/itwin-client/nativeapp-storage_2021-03-23-11-26.json diff --git a/clients/itwin/src/Token.ts b/clients/itwin/src/Token.ts index c57708bb179..895bef0c6bf 100644 --- a/clients/itwin/src/Token.ts +++ b/clients/itwin/src/Token.ts @@ -105,7 +105,6 @@ export class AccessToken { * Convert this AccessToken to a string that can be passed across the wire * Users should overwrite this method in a subclass of AccessToken if their token is not converted to a string in this way. * @param includePrefix Include the token prefix to identify the type of token - "Bearer" for JSON Web Tokens (JWTs) - * @beta */ public toTokenString(includePrefix: IncludePrefix = IncludePrefix.Yes): string { const jwt = this._tokenString; @@ -131,7 +130,6 @@ export class AccessToken { * - The token is NOT validated in any way other than the basic prefix check described above * @param tokenStr String representation of the token * @throws [[BentleyError]] If the token does not have the required prefix - * @beta */ public static fromTokenString(tokenStr: string): AccessToken { const accessToken: AccessToken = AccessToken.generateProperTokenType(tokenStr); @@ -152,7 +150,6 @@ export class AccessToken { * Creates a strongly typed AccessToken object from an untyped JSON with the same properties as [[AccessToken]] * @param jsonObj * @throws [BentleyError]($bentley) if the supplied tokenResponse is undefined, or does not contain an "access_token" field - * @beta */ public static fromJson(jsonObj: AccessTokenProps): AccessToken { const jwt = jsonObj.tokenString; @@ -172,7 +169,7 @@ export class AccessToken { } /** - * Creates AccessToken from the typical token responses obtained from Authorization servers + * Creates an AccessToken from the typical token responses obtained from Authorization servers * - The fields from the token response to different names in AccessToken to keep with naming guidelines * - Only basic validation is done - the input tokenResponse must be defined, and have an "access_token" field in it * @param tokenResponse Response containing the token string as obtained from the authorization server diff --git a/common/api/electron-manager.api.md b/common/api/electron-manager.api.md index 2bb3422a2d3..8df6c9bb76d 100644 --- a/common/api/electron-manager.api.md +++ b/common/api/electron-manager.api.md @@ -39,12 +39,14 @@ export class ElectronHost { static get electron(): typeof Electron; // (undocumented) static frontendURL: string; + static getWindowMaximizedSetting(windowName: string): boolean | undefined; + static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined; // (undocumented) static get ipcMain(): Electron.IpcMain; // (undocumented) static get isValid(): boolean; static get mainWindow(): BrowserWindow | undefined; - static openMainWindow(windowOptions?: BrowserWindowConstructorOptions): Promise; + static openMainWindow(windowOptions?: ElectronHostWindowOptions): Promise; // (undocumented) static rpcConfig: RpcConfiguration; static startup(opts?: ElectronHostOpts): Promise; @@ -54,6 +56,7 @@ export class ElectronHost { // @beta export interface ElectronHostOptions { + applicationName?: string; developmentServer?: boolean; frontendPort?: number; frontendURL?: string; @@ -69,6 +72,24 @@ export interface ElectronHostOpts extends NativeHostOpts { electronHost?: ElectronHostOptions; } +// @beta (undocumented) +export interface ElectronHostWindowOptions extends BrowserWindowConstructorOptions { + // (undocumented) + storeWindowName?: string; +} + +// @beta +export interface WindowSizeAndPositionProps { + // (undocumented) + height: number; + // (undocumented) + width: number; + // (undocumented) + x: number; + // (undocumented) + y: number; +} + // (No @packageDocumentation comment for this package) diff --git a/common/api/imodeljs-backend.api.md b/common/api/imodeljs-backend.api.md index b198e1f0eba..20bc9425951 100644 --- a/common/api/imodeljs-backend.api.md +++ b/common/api/imodeljs-backend.api.md @@ -180,6 +180,7 @@ import { SpatialViewDefinitionProps } from '@bentley/imodeljs-common'; import { StandaloneOpenOptions } from '@bentley/imodeljs-common'; import { StandardViewIndex } from '@bentley/geometry-core'; import { StatusCodeWithMessage } from '@bentley/bentleyjs-core'; +import { StorageValue } from '@bentley/imodeljs-common'; import { SubCategoryAppearance } from '@bentley/imodeljs-common'; import { SubCategoryProps } from '@bentley/imodeljs-common'; import { SubjectProps } from '@bentley/imodeljs-common'; @@ -3440,6 +3441,28 @@ export abstract class NativeAppAuthorizationBackend extends ImsAuthorizationClie abstract signOut(): Promise; } +// @beta +export class NativeAppStorage { + close(deleteFile?: boolean): void; + // @internal + static closeAll(): void; + static find(name: string): NativeAppStorage; + getBoolean(key: string): boolean | undefined; + getData(key: string): StorageValue | undefined; + getKeys(): string[]; + getNumber(key: string): number | undefined; + // @internal (undocumented) + static getStorageNames(): string[]; + getString(key: string): string | undefined; + getUint8Array(key: string): Uint8Array | undefined; + // (undocumented) + readonly id: string; + static open(name: string): NativeAppStorage; + removeAll(): void; + removeData(key: string): void; + setData(key: string, value: StorageValue): void; + } + // @beta export class NativeHost { static get appSettingsCacheDir(): string; @@ -3454,12 +3477,19 @@ export class NativeHost { static readonly onInternetConnectivityChanged: BeEvent<(status: InternetConnectivityStatus) => void>; static readonly onUserStateChanged: BeEvent<(token?: AccessToken | undefined) => void>; static overrideInternetConnectivity(_overridenBy: OverriddenBy, status: InternetConnectivityStatus): void; + // (undocumented) + static get settingsStore(): NativeAppStorage; static shutdown(): Promise; static startup(opt?: NativeHostOpts): Promise; } // @beta (undocumented) -export type NativeHostOpts = IpcHostOpts; +export interface NativeHostOpts extends IpcHostOpts { + // (undocumented) + nativeHost?: { + applicationName?: string; + }; +} export { NativeLoggerCategory } diff --git a/common/api/imodeljs-frontend.api.md b/common/api/imodeljs-frontend.api.md index 106db1823ac..271e02e9f6c 100644 --- a/common/api/imodeljs-frontend.api.md +++ b/common/api/imodeljs-frontend.api.md @@ -6411,13 +6411,13 @@ export enum ModifyElementSource { Unknown = 0 } -// @alpha +// @beta export class NativeApp { // (undocumented) static callNativeHost>(methodName: T, ...args: Parameters): Promise>; // (undocumented) static checkInternetConnectivity(): Promise; - static closeStorage(storage: Storage, deleteId: boolean): Promise; + static closeStorage(storage: Storage, deleteStorage?: boolean): Promise; static deleteBriefcase(fileName: string): Promise; // (undocumented) static getBriefcaseFileName(props: BriefcaseProps): Promise; @@ -6438,7 +6438,7 @@ export class NativeApp { static startup(ipc: IpcSocketFrontend, opts?: NativeAppOpts): Promise; } -// @alpha +// @beta export class NativeAppAuthorization { constructor(config: NativeAppAuthorizationConfiguration); // (undocumented) @@ -6471,7 +6471,7 @@ export class NativeAppLogger { static logWarning(category: string, message: string, getMetaData?: GetMetaDataFunction): void; } -// @alpha +// @beta export interface NativeAppOpts extends IpcAppOptions { // (undocumented) nativeApp?: { @@ -9302,19 +9302,15 @@ export enum StartOrResume { Start = 1 } -// @alpha +// @beta export class Storage { - constructor(id: string, _isOpen?: boolean); - close(deleteIt?: boolean): Promise; - // @internal + constructor(id: string); getData(key: string): Promise; getKeys(): Promise; // (undocumented) readonly id: string; - get isOpen(): boolean; removeAll(): Promise; removeData(key: string): Promise; - // @internal setData(key: string, value: StorageValue): Promise; } diff --git a/common/api/summary/imodeljs-backend.exports.csv b/common/api/summary/imodeljs-backend.exports.csv index 474bebbc6ac..7002c27de1a 100644 --- a/common/api/summary/imodeljs-backend.exports.csv +++ b/common/api/summary/imodeljs-backend.exports.csv @@ -225,8 +225,9 @@ internal;MetaDataRegistry public;Model public;ModelSelector internal;class NativeAppAuthorizationBackend +beta;NativeAppStorage beta;NativeHost -beta;NativeHostOpts = IpcHostOpts +beta;NativeHostOpts public;OrthographicViewDefinition public;class PhysicalElement public;PhysicalElementAssemblesElements diff --git a/common/api/summary/imodeljs-frontend.exports.csv b/common/api/summary/imodeljs-frontend.exports.csv index 0deeb40d013..79652e86de1 100644 --- a/common/api/summary/imodeljs-frontend.exports.csv +++ b/common/api/summary/imodeljs-frontend.exports.csv @@ -342,10 +342,10 @@ alpha;ModelDisplayTransformProvider public;ModelSelectorState public;ModelState alpha;ModifyElementSource -alpha;NativeApp -alpha;NativeAppAuthorization +beta;NativeApp +beta;NativeAppAuthorization internal;NativeAppLogger -alpha;NativeAppOpts +beta;NativeAppOpts internal;NoRenderApp beta;class NotificationHandler public;NotificationManager @@ -488,7 +488,7 @@ public;StandardView public;StandardViewId public;StandardViewTool public;StartOrResume -alpha;Storage +beta;Storage internal;SubCategoriesCache internal;SubCategoriesCache internal;SubCategoriesRequest diff --git a/common/changes/@bentley/electron-manager/nativeapp-storage_2021-03-23-11-26.json b/common/changes/@bentley/electron-manager/nativeapp-storage_2021-03-23-11-26.json new file mode 100644 index 00000000000..ae43777d92a --- /dev/null +++ b/common/changes/@bentley/electron-manager/nativeapp-storage_2021-03-23-11-26.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/electron-manager", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/electron-manager", + "email": "33296803+kabentley@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/electron-manager/ui-uitestapp-electron-position-size_2021-03-23-13-55.json b/common/changes/@bentley/electron-manager/ui-uitestapp-electron-position-size_2021-03-23-13-55.json new file mode 100644 index 00000000000..f2bdcf8b347 --- /dev/null +++ b/common/changes/@bentley/electron-manager/ui-uitestapp-electron-position-size_2021-03-23-13-55.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/electron-manager", + "comment": "Saving & restoring Electron main window size, position & maximized state", + "type": "none" + } + ], + "packageName": "@bentley/electron-manager", + "email": "51122937+DanEastBentley@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/imodeljs-backend/nativeapp-storage_2021-03-23-11-26.json b/common/changes/@bentley/imodeljs-backend/nativeapp-storage_2021-03-23-11-26.json new file mode 100644 index 00000000000..dd040d3facb --- /dev/null +++ b/common/changes/@bentley/imodeljs-backend/nativeapp-storage_2021-03-23-11-26.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-backend", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-backend", + "email": "33296803+kabentley@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-23-13-55.json b/common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-23-13-55.json new file mode 100644 index 00000000000..63816290cf1 --- /dev/null +++ b/common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-23-13-55.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-backend", + "comment": "Saving & restoring Electron main window size, position & maximized state", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-backend", + "email": "51122937+DanEastBentley@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-24-13-27.json b/common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-24-13-27.json new file mode 100644 index 00000000000..85e53d381d0 --- /dev/null +++ b/common/changes/@bentley/imodeljs-backend/ui-uitestapp-electron-position-size_2021-03-24-13-27.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-backend", + "comment": "add NativeHost.settingsStore", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-backend", + "email": "33296803+kabentley@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/imodeljs-frontend/nativeapp-storage_2021-03-23-11-26.json b/common/changes/@bentley/imodeljs-frontend/nativeapp-storage_2021-03-23-11-26.json new file mode 100644 index 00000000000..8f5f4b08451 --- /dev/null +++ b/common/changes/@bentley/imodeljs-frontend/nativeapp-storage_2021-03-23-11-26.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-frontend", + "comment": "promote NativeApp to beta", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-frontend", + "email": "33296803+kabentley@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/itwin-client/nativeapp-storage_2021-03-23-11-26.json b/common/changes/@bentley/itwin-client/nativeapp-storage_2021-03-23-11-26.json new file mode 100644 index 00000000000..852052a589e --- /dev/null +++ b/common/changes/@bentley/itwin-client/nativeapp-storage_2021-03-23-11-26.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/itwin-client", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/itwin-client", + "email": "33296803+kabentley@users.noreply.github.com" +} \ No newline at end of file diff --git a/core/backend/src/NativeAppStorage.ts b/core/backend/src/NativeAppStorage.ts index 1baaaa0f6ef..e78effe2f87 100644 --- a/core/backend/src/NativeAppStorage.ts +++ b/core/backend/src/NativeAppStorage.ts @@ -2,8 +2,12 @@ * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import * as path from "path"; -import { DbResult } from "@bentley/bentleyjs-core"; +/** @packageDocumentation + * @module NativeApp + */ + +import { join } from "path"; +import { DbResult, IModelStatus } from "@bentley/bentleyjs-core"; import { IModelError, StorageValue } from "@bentley/imodeljs-common"; import { ECDb, ECDbOpenMode } from "./ECDb"; import { IModelHost } from "./IModelHost"; @@ -11,21 +15,18 @@ import { IModelJsFs } from "./IModelJsFs"; import { NativeHost } from "./NativeHost"; /** - * Native app storage allow key value pair to be persisted in a sqlite db in app cache. - * This is exposed to frontend through [[NativeApp]] - * @internal + * A local file stored in the [[NativeHost.appSettingsCacheDir]] for storing key/value pairs. + * @beta */ export class NativeAppStorage { - private static readonly _version = 1; - private static readonly _ext = `.v${NativeAppStorage._version}.ecdb`; + private static readonly _ext = ".settings-db"; private static _storages = new Map(); private static _init: boolean = false; private constructor(private _ecdb: ECDb, public readonly id: string) { } + + /** Set the value for a key */ public setData(key: string, value: StorageValue): void { - if (!this._ecdb.isOpen) { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cache is not open or disposed"); - } - const rc = this._ecdb.withPreparedSqliteStatement("INSERT INTO [app_cache]([key],[type],[val])VALUES(?,?,?) ON CONFLICT([key]) DO UPDATE SET [type]=excluded.[type], [val]=excluded.[val]", (stmt) => { + const rc = this._ecdb.withPreparedSqliteStatement("INSERT INTO app_setting(key,type,val)VALUES(?,?,?) ON CONFLICT(key) DO UPDATE SET type=excluded.type,val=excluded.val", (stmt) => { let type: string | undefined = value === null ? "null" : typeof value; if (type === "object") { if (value instanceof Uint8Array) { @@ -42,56 +43,72 @@ export class NativeAppStorage { stmt.bindValue(3, value); return stmt.step(); }); - if (rc !== DbResult.BE_SQLITE_DONE) { + if (rc !== DbResult.BE_SQLITE_DONE) throw new IModelError(rc, "SQLite error"); - } else { - this._ecdb.saveChanges(); - } + + this._ecdb.saveChanges(); } + /** Get the value for a key from this Storage. If key is not present, return undefined. */ public getData(key: string): StorageValue | undefined { - if (!this._ecdb.isOpen) { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cache is not open or disposed"); - } - return this._ecdb.withPreparedSqliteStatement("SELECT [type],[val] FROM [app_cache] WHERE [key] = ?", (stmt) => { + return this._ecdb.withPreparedSqliteStatement("SELECT type,val FROM app_setting WHERE key=?", (stmt) => { stmt.bindValue(1, key); - const rc = stmt.step(); - if (rc === DbResult.BE_SQLITE_ROW) { - const type = stmt.getValue(0).getString(); - if (type === "number") { + if (DbResult.BE_SQLITE_ROW !== stmt.step()) + return undefined; + switch (stmt.getValue(0).getString()) { + case "number": return stmt.getValue(1).getDouble(); - } else if (type === "string") { + case "string": return stmt.getValue(1).getString(); - } else if (type === "boolean") { + case "boolean": return Boolean(stmt.getValue(1).getInteger()); - } else if (type === "Uint8Array") { + case "Uint8Array": return stmt.getValue(1).getBlob(); - } else if (type === "null") { + case "null": return null; - } else { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Unsupported value type in cache"); - } } - return undefined; + throw new IModelError(DbResult.BE_SQLITE_ERROR, "Unsupported type in cache"); }); } + + /** Get the value for a key as a string. If it is not present, or not of type string, return undefined */ + public getString(key: string): string | undefined { + const val = this.getData(key); + return typeof val === "string" ? val : undefined; + } + + /** Get the value for a key as a number. If it is not present, or not of type number, return undefined */ + public getNumber(key: string): number | undefined { + const val = this.getData(key); + return typeof val === "number" ? val : undefined; + } + + /** Get the value for a key as a boolean. If it is not present, or not of type boolean, return undefined */ + public getBoolean(key: string): boolean | undefined { + const val = this.getData(key); + return typeof val === "boolean" ? val : undefined; + } + + /** Get the value for a key as a Uint8Array. If it is not present, or not of type Uint8Array, return undefined */ + public getUint8Array(key: string): Uint8Array | undefined { + const val = this.getData(key); + return val instanceof Uint8Array ? val : undefined; + } + + /** Get all key names in this Storage */ public getKeys(): string[] { - if (!this._ecdb.isOpen) { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cache is not open or disposed"); - } const keys = new Array(); - this._ecdb.withPreparedSqliteStatement("SELECT [key] FROM [app_cache]", (stmt) => { + this._ecdb.withPreparedSqliteStatement("SELECT key FROM app_setting", (stmt) => { while (DbResult.BE_SQLITE_ROW === stmt.step()) { keys.push(stmt.getValue(0).getString()); } }); return keys; } + + /** Remove a key/value pair from this Storage */ public removeData(key: string) { - if (!this._ecdb.isOpen) { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cache is not open or disposed"); - } - const rc = this._ecdb.withPreparedSqliteStatement("DELETE FROM [app_cache] WHERE [key] = ?", (stmt) => { + const rc = this._ecdb.withPreparedSqliteStatement("DELETE FROM app_setting WHERE key=?", (stmt) => { stmt.bindValue(1, key); return stmt.step(); }); @@ -99,78 +116,82 @@ export class NativeAppStorage { throw new IModelError(rc, "SQLite error"); } } + + /** Remove all key/value pairs */ public removeAll() { - if (!this._ecdb.isOpen) { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cache is not open or disposed"); - } - const rc = this._ecdb.withPreparedSqliteStatement("DELETE FROM [app_cache]", (stmt) => { + const rc = this._ecdb.withPreparedSqliteStatement("DELETE FROM app_setting", (stmt) => { return stmt.step(); }); if (rc !== DbResult.BE_SQLITE_DONE) { throw new IModelError(rc, "SQLite error"); } } + + /** Close this Storage. */ public close(deleteFile: boolean = false) { - if (!this._ecdb.isOpen) { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cache is not open or disposed"); - } - const storageFile = path.join(NativeHost.appSettingsCacheDir, this.id); + const storageFile = join(NativeHost.appSettingsCacheDir, this.id); this._ecdb.saveChanges(); this._ecdb.closeDb(); - if (deleteFile) { + (this._ecdb as any) = undefined; + if (deleteFile) IModelJsFs.removeSync(storageFile); - } NativeAppStorage._storages.delete(this.id); } + private static init(ecdb: ECDb): DbResult { - if (!ecdb.isOpen) { - throw new IModelError(DbResult.BE_SQLITE_ERROR, "Cache is not open or disposed"); - } - return ecdb.withPreparedSqliteStatement("CREATE TABLE [app_cache]([key] PRIMARY KEY, [type], [val]);", (stmt) => { + return ecdb.withPreparedSqliteStatement("CREATE TABLE app_setting(key PRIMARY KEY,type,val);", (stmt) => { return stmt.step(); }); } - public static find(name: string): NativeAppStorage | undefined { - return this._storages.get(name); + + /** find and open storage by its name. */ + public static find(name: string): NativeAppStorage { + const storage = this._storages.get(name); + if (undefined === storage) + throw new IModelError(IModelStatus.FileNotFound, `Storage ${name} not open`); + return storage; } + + /** Close all opened Storages. + * @internal + */ public static closeAll() { - this._storages.forEach((value) => { - value.close(); - }); + this._storages.forEach((value) => value.close()); this._storages.clear(); } + + /** @internal */ public static getStorageNames(): string[] { - return IModelJsFs.readdirSync(NativeHost.appSettingsCacheDir).filter((_) => _.endsWith(this._ext)); + return IModelJsFs.readdirSync(NativeHost.appSettingsCacheDir).filter((name) => name.endsWith(this._ext)); } + + /** Open or find a Storage by name. */ public static open(name: string): NativeAppStorage { if (!this._init) { - IModelHost.onBeforeShutdown.addOnce(() => { - this.closeAll(); - }); + IModelHost.onBeforeShutdown.addOnce(() => this.closeAll()); this._init = true; } const fileName = name + this._ext; - if (!IModelJsFs.existsSync(NativeHost.appSettingsCacheDir)) { + if (!IModelJsFs.existsSync(NativeHost.appSettingsCacheDir)) IModelJsFs.recursiveMkDirSync(NativeHost.appSettingsCacheDir); - } - const storageFile = path.join(NativeHost.appSettingsCacheDir, fileName); - let storage = this.find(fileName); - if (!storage) { - const ecdb: ECDb = new ECDb(); + + const storageFile = join(NativeHost.appSettingsCacheDir, fileName); + try { + return this.find(fileName); // see if it's already open + } catch (err) { + const ecdb = new ECDb(); if (IModelJsFs.existsSync(storageFile)) { ecdb.openDb(storageFile, ECDbOpenMode.ReadWrite); } else { ecdb.createDb(storageFile); const rc = this.init(ecdb); - if (rc !== DbResult.BE_SQLITE_DONE) { + if (rc !== DbResult.BE_SQLITE_DONE) throw new IModelError(rc, "SQLite error"); - } else { - ecdb.saveChanges(); - } + ecdb.saveChanges(); } - storage = new NativeAppStorage(ecdb, fileName); + const storage = new NativeAppStorage(ecdb, fileName); this._storages.set(fileName, storage); + return storage; } - return storage; } } diff --git a/core/backend/src/NativeHost.ts b/core/backend/src/NativeHost.ts index a72886c1d2f..82730991d84 100644 --- a/core/backend/src/NativeHost.ts +++ b/core/backend/src/NativeHost.ts @@ -135,7 +135,7 @@ class NativeAppHandler extends IpcHandler implements NativeAppFunctions { } public async storageMgrClose(storageId: string, deleteIt: boolean): Promise { - NativeAppStorage.find(storageId)?.close(deleteIt); + NativeAppStorage.find(storageId).close(deleteIt); } public async storageMgrNames(): Promise { @@ -143,30 +143,32 @@ class NativeAppHandler extends IpcHandler implements NativeAppFunctions { } public async storageGet(storageId: string, key: string): Promise { - return NativeAppStorage.find(storageId)?.getData(key); + return NativeAppStorage.find(storageId).getData(key); } public async storageSet(storageId: string, key: string, value: StorageValue): Promise { - NativeAppStorage.find(storageId)?.setData(key, value); + NativeAppStorage.find(storageId).setData(key, value); } public async storageRemove(storageId: string, key: string): Promise { - NativeAppStorage.find(storageId)?.removeData(key); + NativeAppStorage.find(storageId).removeData(key); } public async storageKeys(storageId: string): Promise { - const storage = NativeAppStorage.find(storageId)!; - return storage.getKeys(); + return NativeAppStorage.find(storageId).getKeys(); } public async storageRemoveAll(storageId: string): Promise { - const storage = NativeAppStorage.find(storageId)!; - storage.removeAll(); + NativeAppStorage.find(storageId).removeAll(); } } /** @beta */ -export type NativeHostOpts = IpcHostOpts; +export interface NativeHostOpts extends IpcHostOpts { + nativeHost?: { + applicationName?: string; + }; +} /** * Used by desktop/mobile native applications @@ -174,6 +176,7 @@ export type NativeHostOpts = IpcHostOpts; */ export class NativeHost { private static _reachability?: InternetConnectivityStatus; + private static _applicationName: string; private constructor() { } /** @internal */ @@ -201,6 +204,10 @@ export class NativeHost { private static _isValid = false; public static get isValid(): boolean { return this._isValid; } + public static get settingsStore() { + return NativeAppStorage.open(this._applicationName); + } + /** * Start the backend of a native app. * @param opt @@ -213,7 +220,9 @@ export class NativeHost { NativeHost.notifyNativeFrontend("notifyInternetConnectivityChanged", status)); this.onUserStateChanged.addListener((token?: AccessToken) => NativeHost.notifyNativeFrontend("notifyUserStateChanged", token?.toJSON())); + this._applicationName = opt?.nativeHost?.applicationName ?? "iTwinApp"; } + await IpcHost.startup(opt); if (IpcHost.isValid) // for tests, we use NativeHost but don't have a frontend NativeAppHandler.register(); diff --git a/core/backend/src/imodeljs-backend.ts b/core/backend/src/imodeljs-backend.ts index 3bdacfa7d15..c139f2bfd1a 100644 --- a/core/backend/src/imodeljs-backend.ts +++ b/core/backend/src/imodeljs-backend.ts @@ -39,12 +39,13 @@ export * from "./domains/GenericElements"; export { IModelJsNative, NativeLoggerCategory } from "@bentley/imodeljs-native"; export * from "./IModelCloneContext"; export * from "./IModelHost"; -export * from "./IpcHost"; -export * from "./NativeHost"; export * from "./IModelExporter"; export * from "./IModelImporter"; -export * from "./IModelTransformer"; export * from "./IModelSchemaLoader"; +export * from "./IModelTransformer"; +export * from "./IpcHost"; +export * from "./NativeAppStorage"; +export * from "./NativeHost"; export * from "./AutoPush"; export * from "./BackendRequestContext"; export * from "./CloudStorageBackend"; diff --git a/core/backend/src/test/standalone/NativeAppStorage.test.ts b/core/backend/src/test/standalone/NativeAppStorage.test.ts index a0d9a69ab67..168a7938651 100644 --- a/core/backend/src/test/standalone/NativeAppStorage.test.ts +++ b/core/backend/src/test/standalone/NativeAppStorage.test.ts @@ -69,25 +69,42 @@ describe("NativeApp storage backend", () => { test1.setData("key1", 2222); assert.isNumber(test1.getData("key1")); assert.equal(test1.getData("key1"), 2222); + assert.equal(test1.getNumber("key1"), 2222); + assert.equal(test1.getString("key1"), undefined); + assert.equal(test1.getUint8Array("key1"), undefined); + assert.equal(test1.getBoolean("key1"), undefined); test1.setData("key1", "Hello, World"); assert.isString(test1.getData("key1")); assert.equal(test1.getData("key1"), "Hello, World"); + assert.equal(test1.getString("key1"), "Hello, World"); + assert.equal(test1.getUint8Array("key1"), undefined); + assert.equal(test1.getBoolean("key1"), undefined); + assert.equal(test1.getNumber("key1"), undefined); test1.setData("key1", true); assert.isBoolean(test1.getData("key1")); assert.equal(test1.getData("key1"), true); + assert.equal(test1.getBoolean("key1"), true); + assert.equal(test1.getString("key1"), undefined); + assert.equal(test1.getUint8Array("key1"), undefined); + assert.equal(test1.getNumber("key1"), undefined); test1.setData("key1", false); assert.isBoolean(test1.getData("key1")); assert.equal(test1.getData("key1"), false); + assert.equal(test1.getBoolean("key1"), false); const testArray = new Uint8Array([1, 2, 3, 4, 5]); test1.setData("key1", testArray); assert.isTrue(test1.getData("key1") instanceof Uint8Array); - assert.equal((test1.getData("key1") as Uint8Array).length, testArray.length); + assert.equal(test1.getUint8Array("key1")!.length, testArray.length); + assert.equal(test1.getBoolean("key1"), undefined); + assert.equal(test1.getString("key1"), undefined); + assert.equal(test1.getNumber("key1"), undefined); test1.removeAll(); assert.equal(test1.getKeys().length, 0); + test1.close(true); }); it("Storage open/close test", () => { @@ -103,4 +120,5 @@ describe("NativeApp storage backend", () => { storage.close(true); }); }); + }); diff --git a/core/electron-manager/src/backend/ElectronAuthorizationBackend.ts b/core/electron-manager/src/backend/ElectronAuthorizationBackend.ts index 2d045df69ba..188838480d5 100644 --- a/core/electron-manager/src/backend/ElectronAuthorizationBackend.ts +++ b/core/electron-manager/src/backend/ElectronAuthorizationBackend.ts @@ -72,9 +72,9 @@ export class ElectronAuthorizationBackend extends NativeAppAuthorizationBackend if (tokenResponse === undefined || tokenResponse.refreshToken === undefined) return undefined; try { - Logger.logTrace(loggerCategory, "Refreshing token from storage"); return await this.refreshAccessToken(tokenResponse.refreshToken); } catch (err) { + Logger.logError(loggerCategory, `Error refreshing access token`, () => err); return undefined; } } @@ -99,7 +99,7 @@ export class ElectronAuthorizationBackend extends NativeAppAuthorizationBackend // Create the authorization request const nativeConfig = this._config!; const authReqJson: AuthorizationRequestJson = { - client_id: nativeConfig.clientId, // eslint-disable-line @typescript-eslint/naming-convention + client_id: nativeConfig.clientId, // eslint-disable-line @typescript-eslint/naming-convention redirect_uri: nativeConfig.redirectUri, // eslint-disable-line @typescript-eslint/naming-convention scope: nativeConfig.scope, response_type: AuthorizationRequest.RESPONSE_TYPE_CODE, // eslint-disable-line @typescript-eslint/naming-convention diff --git a/core/electron-manager/src/backend/ElectronHost.ts b/core/electron-manager/src/backend/ElectronHost.ts index d0bb4a9c064..7298a7f5a1a 100644 --- a/core/electron-manager/src/backend/ElectronHost.ts +++ b/core/electron-manager/src/backend/ElectronHost.ts @@ -17,7 +17,7 @@ import { IModelError, IpcListener, IpcSocketBackend, RemoveFunction, RpcConfigur import { ElectronRpcConfiguration, ElectronRpcManager } from "../common/ElectronRpcManager"; import { ElectronAuthorizationBackend } from "./ElectronAuthorizationBackend"; -// cSpell:ignore signin devserver webcontents copyfile +// cSpell:ignore signin devserver webcontents copyfile unmaximize eopt class ElectronIpc implements IpcSocketBackend { public addListener(channel: string, listener: IpcListener): RemoveFunction { @@ -57,6 +57,8 @@ export interface ElectronHostOptions { rpcInterfaces?: RpcInterfaceDefinition[]; /** list of [IpcHandler]($common) classes to register */ ipcHandlers?: (typeof IpcHandler)[]; + /** name of application. Used for naming settings file. */ + applicationName?: string; } /** @beta */ @@ -64,6 +66,21 @@ export interface ElectronHostOpts extends NativeHostOpts { electronHost?: ElectronHostOptions; } +/** @beta */ +export interface ElectronHostWindowOptions extends BrowserWindowConstructorOptions { + storeWindowName?: string; +} + +/** the size and position of a window as stored in the settings file. + * @beta + */ +export interface WindowSizeAndPositionProps { + width: number; + height: number; + x: number; + y: number; +} + /** * The backend for Electron-based desktop applications * @beta @@ -113,7 +130,7 @@ export class ElectronHost { return assetPath; } - private static _openWindow(options: BrowserWindowConstructorOptions = {}) { + private static _openWindow(options?: ElectronHostWindowOptions) { const opts: BrowserWindowConstructorOptions = { autoHideMenuBar: true, webPreferences: { @@ -133,16 +150,53 @@ export class ElectronHost { this._mainWindow.on("closed", () => this._mainWindow = undefined); this._mainWindow.loadURL(this.frontendURL); // eslint-disable-line @typescript-eslint/no-floating-promises + /** Monitors and saves main window size, position and maximized state */ + if (options?.storeWindowName) { + const mainWindow = this._mainWindow; + const name = options.storeWindowName; + const saveWindowPosition = () => { + const resolution = mainWindow.getSize(); + const position = mainWindow.getPosition(); + const pos: WindowSizeAndPositionProps = { + width: resolution[0], + height: resolution[1], + x: position[0], + y: position[1], + }; + NativeHost.settingsStore.setData(`windowPos-${name}`, JSON.stringify(pos)); + }; + const saveMaximized = (maximized: boolean) => { + if (!maximized) + saveWindowPosition(); + NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized); + }; + + mainWindow.on("resized", () => saveWindowPosition()); + mainWindow.on("moved", () => saveWindowPosition()); + mainWindow.on("maximize", () => saveMaximized(true)); + mainWindow.on("unmaximize", () => saveMaximized(false)); + } } /** The "main" BrowserWindow for this application. */ public static get mainWindow() { return this._mainWindow; } + /** Gets window size and position for a window, by name, from settings file, if present */ + public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined { + const saved = NativeHost.settingsStore.getString(`windowPos-${windowName}`); + return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined; + } + + /** Gets "window maximized" flag for a window, by name, from settings file if present */ + public static getWindowMaximizedSetting(windowName: string): boolean | undefined { + return NativeHost.settingsStore.getBoolean(`windowMaximized-${windowName}`); + } + /** * Open the main Window when the app is ready. * @param windowOptions Options for constructing the main BrowserWindow. See: https://electronjs.org/docs/api/browser-window#new-browserwindowoptions */ - public static async openMainWindow(windowOptions?: BrowserWindowConstructorOptions): Promise { + public static async openMainWindow(windowOptions?: ElectronHostWindowOptions): Promise { const app = this.app; // quit the application when all windows are closed (unless we're running on MacOS) app.on("window-all-closed", () => { @@ -179,6 +233,7 @@ export class ElectronHost { this._openWindow(windowOptions); } + public static get isValid() { return this._ipc !== undefined; } /** @@ -207,6 +262,7 @@ export class ElectronHost { this.appIconPath = path.join(this.webResourcesPath, eopt?.iconName ?? "appicon.ico"); this.rpcConfig = ElectronRpcManager.initializeBackend(this._ipc, eopt?.rpcInterfaces); } + opts = opts ?? {}; opts.ipcHost = opts.ipcHost ?? {}; opts.ipcHost.socket = this._ipc; diff --git a/core/frontend/src/NativeApp.ts b/core/frontend/src/NativeApp.ts index 0d328e0afa2..ce12735fddd 100644 --- a/core/frontend/src/NativeApp.ts +++ b/core/frontend/src/NativeApp.ts @@ -49,7 +49,7 @@ class NativeAppNotifyHandler extends NotificationHandler implements NativeAppNot * and then listens for the `onUserStateChanged` event to cache the accessToken. The token is cached * here on the frontend because it is used for every RPC operation, even when we're running as a NativeApp. * We must therefore check for expiration and request refreshes as/when necessary. - * @alpha + * @beta */ export class NativeAppAuthorization { private _config: NativeAppAuthorizationConfiguration; @@ -101,7 +101,7 @@ export class NativeAppAuthorization { /** * Options for [[NativeApp.startup]] - * @alpha + * @beta */ export interface NativeAppOpts extends IpcAppOptions { nativeApp?: { @@ -113,7 +113,7 @@ export interface NativeAppOpts extends IpcAppOptions { /** * The frontend of a native application * @see [Native Applications]($docs/learning/NativeApps.md) - * @alpha + * @beta */ export class NativeApp { public static async callNativeHost>(methodName: T, ...args: Parameters) { @@ -234,134 +234,77 @@ export class NativeApp { await this.callNativeHost("deleteBriefcaseFiles", fileName); } - /** - * Gets briefcases - * @returns list of BriefcaseProps in cache - */ + /** Get a list of all briefcase files held in the local briefcase cache directory */ public static async getCachedBriefcases(iModelId?: GuidString): Promise { return this.callNativeHost("getCachedBriefcases", iModelId); } /** - * Opens storage. This automatically create the storage with that name if it does not exist - * @param name Should confirm to a filename rules without extension. - * @returns storage object that represent the [[Storage]] object. + * Open a [[Storage]]. Creates a new Storage with that name if it does not already exist. + * @param name Should be a local filename without an extension. + * @returns a Promise for the [[Storage]]. */ public static async openStorage(name: string): Promise { - if (this._storages.has(name)) { + if (this._storages.has(name)) return this._storages.get(name)!; - } + const storage = new Storage(await this.callNativeHost("storageMgrOpen", name)); this._storages.set(storage.id, storage); return storage; } /** - * Closes storage cache + * Close a Storage and optionally delete it. * @param storage normally not call directly instead use Storage.close() - * @param deleteId if set attempt is made to delete the storage from disk permanently. + * @param deleteStorage if true, delete the storage from disk after closing it. */ - public static async closeStorage(storage: Storage, deleteId: boolean): Promise { - if (!this._storages.has(storage.id)) { - throw new Error(`Storage [Id=${storage.id}] not found`); - } - await this.callNativeHost("storageMgrClose", storage.id, deleteId); - (storage as any)._isOpen = false; + public static async closeStorage(storage: Storage, deleteStorage: boolean = false): Promise { + if (!this._storages.has(storage.id)) + throw new Error(`Storage [Id=${storage.id}] not open`); + + await this.callNativeHost("storageMgrClose", storage.id, deleteStorage); this._storages.delete(storage.id); } - /** - * Gets storage names - * @returns return list of storage available on disk. - */ + /** Get the list of existing Storages on the local disk. */ public static async getStorageNames(): Promise { return NativeApp.callNativeHost("storageMgrNames"); } } /** - * A local disk-based cache for key value pairs available for NativeApps. + * A local disk-based cache for key value pairs for NativeApps. * @note This should be used only for local caching, since its not guaranteed to exist permanently. - * @alpha + * @beta */ export class Storage { - constructor(public readonly id: string, private _isOpen: boolean = true) { } + constructor(public readonly id: string) { } - /** - * Gets data against a key - * @param key a string that represent a key. - * @returns data return value against the key - * @internal - */ + /** Get the value for a key */ public async getData(key: string): Promise { - if (!this._isOpen) { - throw new Error(`Storage [Id=${this.id}] is not open`); - } return NativeApp.callNativeHost("storageGet", this.id, key); } - /** - * Sets data against a key - * @param key a string that represent a key - * @param value a value that need to be persisted - * @internal - */ + /** Set value for a key */ public async setData(key: string, value: StorageValue): Promise { - if (!this._isOpen) { - throw new Error(`Storage [Id=${this.id}] is not open`); - } return NativeApp.callNativeHost("storageSet", this.id, key, value); } /** - * Return all keys. - * @note This could be expensive and may block backend depending on size and number of keys - * @returns keys a string array of all the keys in storage + * Return an array of all keys in this Storage. + * @note This can be expensive, depending on the number of keys present. */ public async getKeys(): Promise { - if (!this._isOpen) { - throw new Error(`Storage [Id=${this.id}] is not open`); - } return NativeApp.callNativeHost("storageKeys", this.id); } - /** - * Remove all keys - * @note Delete all keys and data. - */ + /** Remove a key and its data. */ public async removeData(key: string): Promise { - if (!this._isOpen) { - throw new Error(`Storage [Id=${this.id}] is not open`); - } return NativeApp.callNativeHost("storageRemove", this.id, key); } - /** - * Remove all keys - * @note Delete all keys and data. - */ + /** Remove all keys and their data. */ public async removeAll(): Promise { - if (!this._isOpen) { - throw new Error(`Storage [Id=${this.id}] is not open`); - } return NativeApp.callNativeHost("storageRemoveAll", this.id); } - - /** - * Closes storage and optionally delete it permanently - * @param [deleteIt] if set a attempt is made to delete the storage from disk. - */ - public async close(deleteIt: boolean = false): Promise { - if (!this._isOpen) { - throw new Error(`Storage [Id=${this.id}] is not open`); - } - return NativeApp.closeStorage(this, deleteIt); - } - - /** - * Can be check to see if the storage is still open - */ - public get isOpen(): boolean { - return this._isOpen; - } } diff --git a/docs/changehistory/NextVersion.md b/docs/changehistory/NextVersion.md index a1883815616..c9d1525de2e 100644 --- a/docs/changehistory/NextVersion.md +++ b/docs/changehistory/NextVersion.md @@ -49,6 +49,14 @@ Shader precompilation will cease once all shader programs have been compiled, or To disable this functionality, set the `doIdleWork` property of the `RenderSystem.Options` object passed to `IModelApp.startup` to false. +## Added NativeHost.settingsStore for storing user-level settings for native applications + +The @beta class `NativeHost` now has a member [NativeHost.settingsStore]($backend) that may be used by native applications to store user-level data in a file in the [[NativeHost.appSettingsCacheDir]($backend) directory. It uses the [NativeAppStorage]($backend) api to store and load key/value pairs. Note that these settings are stored in a local file that may be deleted by the user, so it should only be used for a local cache of values that may be restored elsewhere. + +## NativeApp is now @beta + +The class [NativeApp]($frontend) has been promoted from @alpha to @beta. `NativeApp` is relevant for both Electron and mobile applications. Please provide feedback if you have issues or concerns on its use. + ## Breaking Api Changes ### @bentley/imodeljs-quantity package diff --git a/full-stack-tests/native-app/src/frontend/standalone/NativeAppStorage.test.ts b/full-stack-tests/native-app/src/frontend/standalone/NativeAppStorage.test.ts index d9cbd87abb2..4477b0ce5d6 100644 --- a/full-stack-tests/native-app/src/frontend/standalone/NativeAppStorage.test.ts +++ b/full-stack-tests/native-app/src/frontend/standalone/NativeAppStorage.test.ts @@ -39,7 +39,7 @@ describe("NativeApp Storage frontend", () => { } } assert.equal((await test1.getKeys()).length, dataset.length); - await test1.close(true); + await NativeApp.closeStorage(test1, true); }); it("Override and type check", async () => { @@ -80,6 +80,7 @@ describe("NativeApp Storage frontend", () => { assert.equal((await test1.getData("key1") as Uint8Array).length, testArray.length); await test1.removeData("key1"); assert.isUndefined(await test1.getData("key1")); + await NativeApp.closeStorage(test1, true); }); }); diff --git a/test-apps/display-test-app/src/backend/Backend.ts b/test-apps/display-test-app/src/backend/Backend.ts index a044386cd39..db1209d7e03 100644 --- a/test-apps/display-test-app/src/backend/Backend.ts +++ b/test-apps/display-test-app/src/backend/Backend.ts @@ -245,18 +245,25 @@ export const initializeDtaBackend = async (electronHost?: ElectronHostOptions) = if (undefined !== logLevelEnv) logLevel = Logger.parseLogLevel(logLevelEnv); } + const opts = { + iModelHost, + electronHost, + nativeHost: { + applicationName: "display-test-app", + }, + }; /** register the implementation of our RPCs. */ RpcManager.registerImpl(DtaRpcInterface, DisplayTestAppRpc); if (ProcessDetector.isElectronAppBackend) { - await ElectronHost.startup({ electronHost, iModelHost }); + await ElectronHost.startup(opts); EditCommandAdmin.register(BasicManipulationCommand); } else if (ProcessDetector.isIOSAppBackend) { - await IOSHost.startup({ iModelHost }); + await IOSHost.startup(opts); } else if (ProcessDetector.isAndroidAppBackend) { - await AndroidHost.startup({ iModelHost }); + await AndroidHost.startup(opts); } else { - await LocalhostIpcHost.startup({ iModelHost }); + await LocalhostIpcHost.startup(opts); } // Set up logging (by default, no logging is enabled) diff --git a/test-apps/display-test-app/src/backend/DtaElectronMain.ts b/test-apps/display-test-app/src/backend/DtaElectronMain.ts index 4e35f14306f..27b1cd5d79d 100644 --- a/test-apps/display-test-app/src/backend/DtaElectronMain.ts +++ b/test-apps/display-test-app/src/backend/DtaElectronMain.ts @@ -9,24 +9,25 @@ import { dtaChannel, DtaIpcInterface } from "../common/DtaIpcInterface"; import { getRpcInterfaces, initializeDtaBackend } from "./Backend"; import { IpcHandler } from "@bentley/imodeljs-backend"; +const mainWindowName = "mainWindow"; const getWindowSize = () => { - let width = 1280; - let height = 800; const sizeStr = process.env.SVT_WINDOW_SIZE; if (typeof sizeStr === "string") { const parts = sizeStr.split(","); if (parts.length === 2) { - const w = Number.parseInt(parts[0], 10); - const h = Number.parseInt(parts[1], 10); + let width = Number.parseInt(parts[0], 10); + let height = Number.parseInt(parts[1], 10); - if (!Number.isNaN(w)) - width = w; + if (Number.isNaN(width)) + width = 1280; - if (!Number.isNaN(h)) - height = h; + if (Number.isNaN(height)) + height = 1024; + return { width, height, x: 100, y: 100 }; } } - return { width, height }; + + return ElectronHost.getWindowSizeSetting(mainWindowName); }; class DtaHandler extends IpcHandler implements DtaIpcInterface { @@ -52,11 +53,12 @@ const dtaElectronMain = async () => { await initializeDtaBackend(opts); - const autoOpenDevTools = (undefined === process.env.SVT_NO_DEV_TOOLS); - const maximizeWindow = (undefined === process.env.SVT_NO_MAXIMIZE_WINDOW); + // Restore previous window size, position and maximized state + const sizeAndPosition = getWindowSize(); + const maximizeWindow = undefined === sizeAndPosition || ElectronHost.getWindowMaximizedSetting(mainWindowName); // after backend is initialized, start display-test-app frontend process and open the window - await ElectronHost.openMainWindow({ ...getWindowSize(), show: !maximizeWindow, title: "Display Test App" }); + await ElectronHost.openMainWindow({ ...sizeAndPosition, show: !maximizeWindow, title: "Display Test App", storeWindowName: mainWindowName }); assert(ElectronHost.mainWindow !== undefined); if (maximizeWindow) { @@ -64,7 +66,7 @@ const dtaElectronMain = async () => { ElectronHost.mainWindow.show(); } - if (autoOpenDevTools) + if (undefined === process.env.SVT_NO_DEV_TOOLS) ElectronHost.mainWindow.webContents.toggleDevTools(); // Handle custom keyboard shortcuts diff --git a/test-apps/display-test-app/src/frontend/FileOpen.ts b/test-apps/display-test-app/src/frontend/FileOpen.ts index 3bfde3c6b60..7c4fbe8e9cf 100644 --- a/test-apps/display-test-app/src/frontend/FileOpen.ts +++ b/test-apps/display-test-app/src/frontend/FileOpen.ts @@ -16,6 +16,7 @@ export async function selectFileName(selector: BrowserFileSelector | undefined): if (ProcessDetector.isElectronAppFrontend) { const opts: OpenDialogOptions = { properties: ["openFile"], + title: "Open iModel", filters: [{ name: "iModels", extensions: ["ibim", "bim"] }], }; diff --git a/test-apps/ui-test-app/src/backend/electron/ElectronMain.ts b/test-apps/ui-test-app/src/backend/electron/ElectronMain.ts index a330fb0379a..bf9f9d88470 100644 --- a/test-apps/ui-test-app/src/backend/electron/ElectronMain.ts +++ b/test-apps/ui-test-app/src/backend/electron/ElectronMain.ts @@ -11,8 +11,8 @@ import { BasicManipulationCommand, EditCommandAdmin } from "@bentley/imodeljs-ed /** * Initializes Electron backend */ -const autoOpenDevTools = (undefined === process.env.SVT_NO_DEV_TOOLS); -const maximizeWindow = (undefined === process.env.SVT_NO_MAXIMIZE_WINDOW); +const windowTitle = "Ui Test App"; +const mainWindowName = "mainWindow"; export async function initializeElectron() { const electronHost: ElectronHostOptions = { @@ -21,7 +21,7 @@ export async function initializeElectron() { developmentServer: process.env.NODE_ENV === "development", }; - await ElectronHost.startup({ electronHost }); + await ElectronHost.startup({ electronHost, nativeHost: { applicationName: "ui-test-app" } }); EditCommandAdmin.register(BasicManipulationCommand); // Handle custom keyboard shortcuts @@ -37,13 +37,18 @@ export async function initializeElectron() { }); }); - await ElectronHost.openMainWindow({ width: 800, height: 650, show: !maximizeWindow, title: "Ui Test App" }); + // Restore previous window size, position and maximized state + const sizeAndPosition = ElectronHost.getWindowSizeSetting(mainWindowName); + const maximizeWindow = undefined === sizeAndPosition || ElectronHost.getWindowMaximizedSetting(mainWindowName); + + await ElectronHost.openMainWindow({ ...sizeAndPosition, show: !maximizeWindow, title: windowTitle, storeWindowName: mainWindowName }); assert(ElectronHost.mainWindow !== undefined); if (maximizeWindow) { ElectronHost.mainWindow.maximize(); // maximize before showing to avoid resize event on startup ElectronHost.mainWindow.show(); } - if (autoOpenDevTools) + + if ((undefined === process.env.imjs_TESTAPP_NO_DEV_TOOLS)) ElectronHost.mainWindow.webContents.toggleDevTools(); } From 5798d80e785ad3c28c177d09444dc8f858350c6a Mon Sep 17 00:00:00 2001 From: bsteinbk <65047615+bsteinbk@users.noreply.github.com> Date: Thu, 25 Mar 2021 09:01:12 -0400 Subject: [PATCH 05/50] Fix number editor used in tool settings (#1034) * Fix numberEditor by blocking editor container from processing enter key * rush change * extract-api Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- common/api/ui-abstract.api.md | 2 ++ common/api/ui-components.api.md | 4 ++- ...ttingNumberEditorFix_2021-03-25-03-11.json | 11 ++++++ ...ttingNumberEditorFix_2021-03-25-03-11.json | 11 ++++++ .../public/locales/en/SampleApp.json | 3 +- .../src/frontend/tools/ToolWithSettings.ts | 21 +++++++++-- .../PropertyDescriptionHelper.test.ts | 36 ++++++++++++++++++- .../src/ui-abstract/properties/Description.ts | 26 +++++++++++++- .../test/editors/NumericInputEditor.test.tsx | 21 +++++++++++ .../editors/NumericInputEditor.tsx | 20 +++++++++-- 10 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 common/changes/@bentley/ui-abstract/toolSettingNumberEditorFix_2021-03-25-03-11.json create mode 100644 common/changes/@bentley/ui-components/toolSettingNumberEditorFix_2021-03-25-03-11.json diff --git a/common/api/ui-abstract.api.md b/common/api/ui-abstract.api.md index d2d7fa78611..9c6214884b8 100644 --- a/common/api/ui-abstract.api.md +++ b/common/api/ui-abstract.api.md @@ -1489,6 +1489,8 @@ export class PropertyDescriptionHelper { // @alpha static buildImageCheckBoxDescription(name: string, label: string, imageOff: string, imageOn: string, additionalParams?: BasePropertyEditorParams[]): PropertyDescription; // @alpha + static buildNumberEditorDescription(name: string, label: string, overrideParams?: RangeEditorParams, additionalParams?: BasePropertyEditorParams[]): PropertyDescription; + // @alpha static buildTextEditorDescription(name: string, label: string, additionalParams?: BasePropertyEditorParams[]): PropertyDescription; // @alpha static buildToggleDescription(name: string, label: string, additionalParams?: BasePropertyEditorParams[]): PropertyDescription; diff --git a/common/api/ui-components.api.md b/common/api/ui-components.api.md index 3f25d18c733..c69e4342ecd 100644 --- a/common/api/ui-components.api.md +++ b/common/api/ui-components.api.md @@ -3105,7 +3105,7 @@ export class NumericInputEditor extends React.PureComponent; // (undocumented) - get hasFocus(): boolean; + hasFocus: boolean; // (undocumented) get htmlElement(): HTMLElement | null; // @internal (undocumented) @@ -3116,6 +3116,8 @@ export class NumericInputEditor extends React.PureComponent( + PropertyDescriptionHelper.buildNumberEditorDescription("numberVal", IModelApp.i18n.translate("SampleApp:tools.ToolWithSettings.Prompts.Number"), + { + type: PropertyEditorParamTypes.Range, + step: 2, + precision: 0, + minimum: 0, + maximum: 1000, + } as RangeEditorParams), 14.0 ); + // ------------- display station value as text --------------- private _stationFormatterSpec?: FormatterSpec; public get stationFormatterSpec(): FormatterSpec | undefined { @@ -384,8 +395,9 @@ export class ToolWithSettings extends PrimitiveTool { toolSettings.push(this.cityProperty.toDialogItem({ rowPriority: 10, columnIndex: 2 })); toolSettings.push(this.stateProperty.toDialogItem({ rowPriority: 10, columnIndex: 4 })); toolSettings.push(this.coordinateProperty.toDialogItem({ rowPriority: 15, columnIndex: 2 })); - toolSettings.push(this.stationProperty.toDialogItem({ rowPriority: 16, columnIndex: 2 })); - const lengthLock = this.useLengthProperty.toDialogItem({ rowPriority: 20, columnIndex: 0 }); + toolSettings.push(this.numberProperty.toDialogItem({ rowPriority: 16, columnIndex: 2 })); + toolSettings.push(this.stationProperty.toDialogItem({ rowPriority: 17, columnIndex: 2 })); + const lengthLock = this.useLengthProperty.toDialogItem({ rowPriority: 18, columnIndex: 0 }); toolSettings.push(this.lengthProperty.toDialogItem({ rowPriority: 20, columnIndex: 2 }, lengthLock)); toolSettings.push(this.surveyLengthProperty.toDialogItem({ rowPriority: 21, columnIndex: 2 })); toolSettings.push(this.angleProperty.toDialogItem({ rowPriority: 25, columnIndex: 2 })); @@ -431,6 +443,9 @@ export class ToolWithSettings extends PrimitiveTool { } else if (updatedValue.propertyName === this.lengthProperty.name) { this.lengthProperty.value = updatedValue.value.value as number; this.showInfoFromUi(updatedValue); + } else if (updatedValue.propertyName === this.numberProperty.name) { + this.numberProperty.value = updatedValue.value.value as number; + this.showInfoFromUi(updatedValue); } else if (updatedValue.propertyName === this.surveyLengthProperty.name) { this.surveyLengthProperty.value = updatedValue.value.value as number; this.showInfoFromUi(updatedValue); diff --git a/ui/abstract/src/test/properties/PropertyDescriptionHelper.test.ts b/ui/abstract/src/test/properties/PropertyDescriptionHelper.test.ts index 7aa1576f980..8acfbdf268a 100644 --- a/ui/abstract/src/test/properties/PropertyDescriptionHelper.test.ts +++ b/ui/abstract/src/test/properties/PropertyDescriptionHelper.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { expect } from "chai"; import { - EnumerationChoice, PropertyDescriptionHelper, PropertyEditorParamTypes, SuppressLabelEditorParams, + EnumerationChoice, PropertyDescriptionHelper, PropertyEditorParamTypes, RangeEditorParams, SuppressLabelEditorParams, } from "../../ui-abstract"; // cSpell:ignore Picklist @@ -67,6 +67,40 @@ describe("PropertyDescriptionHelper", () => { }); }); + describe("NumberEditor Description", () => { + const typename = "number"; + it("should build correctly", () => { + const editor = "numeric-input"; + const editorDescription = PropertyDescriptionHelper.buildNumberEditorDescription(testName, testLabel); + expect(editorDescription.name).to.eq(testName); + expect(editorDescription.typename).to.eq(typename); + expect(editorDescription.displayLabel).to.eq(testLabel); + expect(editorDescription.editor?.name).to.eq(editor); + expect(editorDescription.editor?.params?.length).to.eq(1); + expect(editorDescription.editor?.params?.[0].type).to.eq(PropertyEditorParamTypes.Range); + + }); + + it("should build with additional editor params correctly", () => { + const editor = "numeric-input"; + const numberParam = { + type: PropertyEditorParamTypes.Range, + step: 2, + precision: 0, + minimum: 0, + maximum: 1000, + } as RangeEditorParams; + const editorDescription = PropertyDescriptionHelper.buildNumberEditorDescription(testName, testLabel, numberParam, additionParam); + expect(editorDescription.name).to.eq(testName); + expect(editorDescription.typename).to.eq(typename); + expect(editorDescription.displayLabel).to.eq(testLabel); + expect(editorDescription.editor?.name).to.eq(editor); + expect(editorDescription.editor?.params?.length).to.eq(2); + expect(editorDescription.editor?.params?.[0].type).to.eq(PropertyEditorParamTypes.Range); + expect(editorDescription.editor?.params?.[1].type).to.eq(PropertyEditorParamTypes.SuppressEditorLabel); + }); + }); + describe("EnumPicklistEditor Description", () => { const choices = [ { label: "Red", value: 1 }, diff --git a/ui/abstract/src/ui-abstract/properties/Description.ts b/ui/abstract/src/ui-abstract/properties/Description.ts index dd0f2d39ea2..fe2bbfc1644 100644 --- a/ui/abstract/src/ui-abstract/properties/Description.ts +++ b/ui/abstract/src/ui-abstract/properties/Description.ts @@ -6,7 +6,7 @@ * @module Properties */ -import { BasePropertyEditorParams, ColorEditorParams, ImageCheckBoxParams, PropertyEditorParams, PropertyEditorParamTypes } from "./EditorParams"; +import { BasePropertyEditorParams, ColorEditorParams, ImageCheckBoxParams, PropertyEditorParams, PropertyEditorParamTypes, RangeEditorParams } from "./EditorParams"; // cSpell:ignore Picklist @@ -106,6 +106,30 @@ export class PropertyDescriptionHelper { }; } + /** Builds an editor that uses [NumberInput]($ui-core) control + * @alpha + */ + public static buildNumberEditorDescription(name: string, label: string, overrideParams?: RangeEditorParams, additionalParams: BasePropertyEditorParams[] = []): PropertyDescription { + const editorParams = [{ + type: PropertyEditorParamTypes.Range, + step: 1, + precision: 0, + ...overrideParams, + } as RangeEditorParams, ...additionalParams]; + + const editor = { + name: "numeric-input", + params: editorParams, + }; + + return { + name, + displayLabel: label, + typename: "number", + editor, + }; + } + /** Builds a string description * @alpha */ diff --git a/ui/components/src/test/editors/NumericInputEditor.test.tsx b/ui/components/src/test/editors/NumericInputEditor.test.tsx index 214d3f7b468..0d633358660 100644 --- a/ui/components/src/test/editors/NumericInputEditor.test.tsx +++ b/ui/components/src/test/editors/NumericInputEditor.test.tsx @@ -152,6 +152,27 @@ describe("", () => { expect(spyOnCommit.calledOnce).to.be.true; }); + it("calls onCommit on increment click", async () => { + const propertyRecord = TestUtils.createNumericProperty("Test", 123, StandardEditorNames.NumericInput); + const spyOnCommit = sinon.spy(); + function handleCommit(_commit: PropertyUpdatedArgs): void { + spyOnCommit(); + } + const wrapper = render( { }} />); + const inputNode = wrapper.container.querySelector("input"); + expect(inputNode).not.to.be.null; + + const input = wrapper.container.querySelector("input") as HTMLInputElement; + const incrementor = wrapper.container.querySelectorAll(".core-number-input-button"); + expect(incrementor.length).to.eq(2); + fireEvent.click(incrementor[0]); + + await TestUtils.flushAsyncOperations(); + expect(spyOnCommit.calledOnce).to.be.true; + + expect(input.value).to.eq("124"); + }); + class MineDataController extends DataControllerBase { public async validateValue(_newValue: PropertyValue, _record: PropertyRecord): Promise { return { encounteredError: true, errorMessage: { priority: OutputMessagePriority.Error, briefMessage: "Test"} }; diff --git a/ui/components/src/ui-components/editors/NumericInputEditor.tsx b/ui/components/src/ui-components/editors/NumericInputEditor.tsx index b7d76e03883..d5cecd03f8d 100644 --- a/ui/components/src/ui-components/editors/NumericInputEditor.tsx +++ b/ui/components/src/ui-components/editors/NumericInputEditor.tsx @@ -37,6 +37,7 @@ interface NumericInputEditorState { export class NumericInputEditor extends React.PureComponent implements TypeEditor { private _isMounted = false; private _inputElement: React.RefObject = React.createRef(); + public hasFocus = false; // hot used since containerHandlesEnter is false /** @internal */ public readonly state: Readonly = { @@ -64,9 +65,16 @@ export class NumericInputEditor extends React.PureComponent => { + // istanbul ignore else + if (this.props.propertyRecord && this.props.onCommit) { + const propertyValue = await this.getPropertyValue(); + // istanbul ignore else + if (propertyValue !== undefined) { + this.props.onCommit({ propertyRecord: this.props.propertyRecord, newValue: propertyValue }); + } + } + }; private _updateValue = (value: number | undefined, _stringValue: string): void => { const newValue = value !== undefined ? value : /* istanbul ignore next */ 0; @@ -75,6 +83,8 @@ export class NumericInputEditor extends React.PureComponent{ + await this._handleCommit (); }); }; @@ -178,6 +188,10 @@ export class NumericInputPropertyEditor extends PropertyEditorBase { public get reactNode(): React.ReactNode { return ; } + // istanbul ignore next + public get containerHandlesEnter(): boolean { // let input editor process enter key + return false; + } } PropertyEditorManager.registerEditor(StandardTypeNames.Number, NumericInputPropertyEditor, StandardEditorNames.NumericInput); From 4dc481fb35e3fb80180fd8ba6603601e8ec34b26 Mon Sep 17 00:00:00 2001 From: Caleb Shafer <31107829+calebmshafer@users.noreply.github.com> Date: Thu, 25 Mar 2021 10:26:34 -0400 Subject: [PATCH 06/50] Drop deprecated ldclient-js package (#1033) * Drop deprecated ldclient-js package --- common/api/imodeljs-frontend.api.md | 7 -- ...-deprecated-ldclient_2021-03-25-03-12.json | 11 +++ core/frontend/package.json | 3 +- core/frontend/src/FeatureToggleClient.ts | 74 ------------------- core/frontend/src/FrontendLoggerCategory.ts | 3 - core/frontend/src/IModelApp.ts | 12 --- 6 files changed, 12 insertions(+), 98 deletions(-) create mode 100644 common/changes/@bentley/imodeljs-frontend/remove-deprecated-ldclient_2021-03-25-03-12.json delete mode 100644 core/frontend/src/FeatureToggleClient.ts diff --git a/common/api/imodeljs-frontend.api.md b/common/api/imodeljs-frontend.api.md index 271e02e9f6c..402e87dea1d 100644 --- a/common/api/imodeljs-frontend.api.md +++ b/common/api/imodeljs-frontend.api.md @@ -146,8 +146,6 @@ import { IpcAppChannel } from '@bentley/imodeljs-common'; import { IpcAppFunctions } from '@bentley/imodeljs-common'; import { IpcListener } from '@bentley/imodeljs-common'; import { IpcSocketFrontend } from '@bentley/imodeljs-common'; -import { LDClient } from 'ldclient-js'; -import { LDFlagValue } from 'ldclient-js'; import { LightSettings } from '@bentley/imodeljs-common'; import { LinePixels } from '@bentley/imodeljs-common'; import { LocalBriefcaseProps } from '@bentley/imodeljs-common'; @@ -3388,7 +3386,6 @@ export interface FrameRenderData { export enum FrontendLoggerCategory { Authorization = "imodeljs-frontend.Authorization", EventSource = "imodeljs-frontend.EventSource", - FeatureToggle = "imodeljs-frontend.FeatureToggles", // @alpha FeatureTracking = "imodeljs-frontend.FeatureTracking", FrontendRequestContext = "imodeljs-frontend.FrontendRequestContext", @@ -4322,8 +4319,6 @@ export class IModelApp { static createRenderSys(opts?: RenderSystem.Options): RenderSystem; // @beta static get extensionAdmin(): ExtensionAdmin; - // @internal - static get featureToggles(): FeatureToggleClient; // @alpha static formatElementToolTip(msg: string[]): HTMLElement; // @internal (undocumented) @@ -4402,8 +4397,6 @@ export interface IModelAppOptions { authorizationClient?: FrontendAuthorizationClient; // @beta extensionAdmin?: ExtensionAdmin; - // @internal - featureToggles?: FeatureToggleClient; i18n?: I18N | I18NOptions; imodelClient?: IModelClient; // @internal (undocumented) diff --git a/common/changes/@bentley/imodeljs-frontend/remove-deprecated-ldclient_2021-03-25-03-12.json b/common/changes/@bentley/imodeljs-frontend/remove-deprecated-ldclient_2021-03-25-03-12.json new file mode 100644 index 00000000000..38699ba4c6e --- /dev/null +++ b/common/changes/@bentley/imodeljs-frontend/remove-deprecated-ldclient_2021-03-25-03-12.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-frontend", + "comment": "Drop deprecated ldclient-js dependency", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-frontend", + "email": "31107829+calebmshafer@users.noreply.github.com" +} \ No newline at end of file diff --git a/core/frontend/package.json b/core/frontend/package.json index b906aad56ee..77cc6e0f88f 100644 --- a/core/frontend/package.json +++ b/core/frontend/package.json @@ -105,7 +105,6 @@ "@bentley/usage-logging-client": "2.15.0-dev.7", "fuse.js": "^3.3.0", "js-base64": "^2.4.5", - "ldclient-js": "^2.6.0", "oidc-client": "^1.9.1", "semver": "^5.5.0", "xml-js": "~1.6.11", @@ -120,4 +119,4 @@ ], "extends": "plugin:@bentley/imodeljs-recommended" } -} +} \ No newline at end of file diff --git a/core/frontend/src/FeatureToggleClient.ts b/core/frontend/src/FeatureToggleClient.ts deleted file mode 100644 index 21378023360..00000000000 --- a/core/frontend/src/FeatureToggleClient.ts +++ /dev/null @@ -1,74 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Bentley Systems, Incorporated. All rights reserved. -* Licensed under the MIT License. See LICENSE.md in the project root for license terms. -*--------------------------------------------------------------------------------------------*/ -/** @packageDocumentation - * @module Features - */ - -import { initialize, LDClient, LDFlagValue, LDUser } from "ldclient-js"; -import { assert, Config, Guid, Logger } from "@bentley/bentleyjs-core"; -import { AccessToken } from "@bentley/itwin-client"; -import { FrontendLoggerCategory } from "./FrontendLoggerCategory"; - -/** Client-side class for checking and toggling feature flags - * The [[FeatureToggleClient]] includes methods for applications to do the following via Launch Darkly: - * * Set the current user - * * Check to see whether a specific feature flag is enabled - * * Toggle a feature flag - * - * @internal - */ -export class FeatureToggleClient { - /** App-defined options */ - /** App ids for Launch Darkly deployment environments environments */ - /** Direct reference to the Launch Darkly client in the event the app wants to make its own async calls */ - protected _ldClient?: LDClient; - protected _offlineValue: boolean = false; - - protected readonly _loggingCategory = FrontendLoggerCategory.FeatureToggle; - - /** initialize initializes the Launch Darkly client. Must be called by the app to set the proper environment and user id */ - public async initialize(envKey?: string): Promise { - if (!!this._ldClient) - return; - - const imjsEnvKey: string | undefined = Config.App.get("imjs_launch_darkly_key"); - const ldId = envKey === undefined ? imjsEnvKey : envKey; - if (ldId === undefined) - return; - - const ldClient: LDClient = initialize(ldId, { key: Guid.createValue(), anonymous: true }); - await ldClient.waitUntilReady(); - - this._ldClient = ldClient; - } - - /** sets the Launch Darkly user info from the AccessToken */ - public async setUser(accessToken: AccessToken): Promise { - const userInfo = accessToken.getUserInfo(); - assert(userInfo !== undefined, "FeatureToggleClient unable get user id."); - assert(!!this._ldClient, "FeatureToggleClient.initialize must be called first."); - if (userInfo !== undefined) { - const ldUser: LDUser = { key: userInfo.id }; - await this.ldClient.identify(ldUser); - } - Logger.logTrace(this._loggingCategory, "Changed LaunchDarkly Feature Flags user context to current user.", () => ({ userId: userInfo === undefined ? "undefined" : userInfo.id })); - } - - /** Returns true is the flag specified by is enabled */ - public isFeatureEnabled(featureKey: string, defaultValue?: boolean): boolean { - return this.evaluateFeature(featureKey, !!defaultValue ? defaultValue : this._offlineValue) as boolean; - } - - /** Checks the status of the flag specified by featureKey */ - public evaluateFeature(featureKey: string, defaultValue?: LDFlagValue): LDFlagValue { - assert(!!this._ldClient, "FeatureToggleClient.initialize hasn't been called yet."); - const val: LDFlagValue = this.ldClient.variation(featureKey, defaultValue); - Logger.logTrace(this._loggingCategory, "Evaluated feature flag.", () => ({ featureKey, result: val })); - return val; - } - - /** The native LaunchDarkly client if the basic methods do not suffice. */ - public get ldClient(): LDClient { assert(!!this._ldClient, "FeatureToggleClient.initialize hasn't been called yet."); return this._ldClient; } -} diff --git a/core/frontend/src/FrontendLoggerCategory.ts b/core/frontend/src/FrontendLoggerCategory.ts index 7690c40cc7f..55cc73cbd9a 100644 --- a/core/frontend/src/FrontendLoggerCategory.ts +++ b/core/frontend/src/FrontendLoggerCategory.ts @@ -32,9 +32,6 @@ export enum FrontendLoggerCategory { /** The logger category used for NativeApp */ NativeApp = "imodeljs-frontend.NativeApp", - /** The logger category used by feature-flag-related functions */ - FeatureToggle = "imodeljs-frontend.FeatureToggles", - /** * The logger category used by FeatureTrackingManager * @alpha diff --git a/core/frontend/src/IModelApp.ts b/core/frontend/src/IModelApp.ts index df875e431e7..53a42be87ce 100644 --- a/core/frontend/src/IModelApp.ts +++ b/core/frontend/src/IModelApp.ts @@ -30,7 +30,6 @@ import * as drawingViewState from "./DrawingViewState"; import { ElementLocateManager } from "./ElementLocateManager"; import { EntityState } from "./EntityState"; import { ExtensionAdmin } from "./extension/ExtensionAdmin"; -import { FeatureToggleClient } from "./FeatureToggleClient"; import { FrontendLoggerCategory } from "./FrontendLoggerCategory"; import { FrontendRequestContext } from "./FrontendRequestContext"; import * as modelselector from "./ModelSelectorState"; @@ -129,10 +128,6 @@ export interface IModelAppOptions { extensionAdmin?: ExtensionAdmin; /** If present, supplies the [[UiAdmin]] for this session. */ uiAdmin?: UiAdmin; - /** if present, supplies the [[FeatureToggleClient]] for this session - * @internal - */ - featureToggles?: FeatureToggleClient; rpcInterfaces?: RpcInterfaceDefinition[]; } @@ -199,7 +194,6 @@ export class IModelApp { private static _animationRequested = false; private static _animationInterval: BeDuration | undefined = BeDuration.fromSeconds(1); private static _animationIntervalId?: number; - private static _featureToggles: FeatureToggleClient; private static _securityOptions: FrontendSecurityOptions; private static _mapLayerFormatRegistry: MapLayerFormatRegistry; @@ -270,11 +264,6 @@ export class IModelApp { */ public static readonly telemetry: TelemetryManager = new TelemetryManager(); - /** The [[FeatureToggleClient]] for this session - * @internal - */ - public static get featureToggles() { return this._featureToggles; } - /** Map of classFullName to EntityState class */ private static _entityClasses = new Map(); @@ -424,7 +413,6 @@ export class IModelApp { this._extensionAdmin = (opts.extensionAdmin !== undefined) ? opts.extensionAdmin : new ExtensionAdmin({}); this._quantityFormatter = (opts.quantityFormatter !== undefined) ? opts.quantityFormatter : new QuantityFormatter(); this._uiAdmin = (opts.uiAdmin !== undefined) ? opts.uiAdmin : new UiAdmin(); - this._featureToggles = (opts.featureToggles !== undefined) ? opts.featureToggles : new FeatureToggleClient(); this._mapLayerFormatRegistry = new MapLayerFormatRegistry(opts.mapLayerOptions); [ From 21cdd50377bbb3157d3c6869aaa7ce965a76a4cc Mon Sep 17 00:00:00 2001 From: Robert Lukasonok <70327485+roluk@users.noreply.github.com> Date: Thu, 25 Mar 2021 17:47:08 +0200 Subject: [PATCH 07/50] Update immer to ^9.0.1 (#1027) --- common/api/summary/ui-framework.exports.csv | 10 +- common/api/ui-framework.api.md | 20 +- .../update-immer_2021-03-24-15-39.json | 11 + .../update-immer_2021-03-24-15-39.json | 11 + .../update-immer_2021-03-24-15-39.json | 11 + .../update-immer_2021-03-24-15-39.json | 11 + common/config/rush/pnpm-lock.yaml | 1424 ++++++++--------- full-stack-tests/presentation/package.json | 4 +- presentation/components/package.json | 4 +- ui/components/package.json | 4 +- ui/framework/package.json | 4 +- ui/ninezone/package.json | 4 +- 12 files changed, 765 insertions(+), 753 deletions(-) create mode 100644 common/changes/@bentley/presentation-components/update-immer_2021-03-24-15-39.json create mode 100644 common/changes/@bentley/ui-components/update-immer_2021-03-24-15-39.json create mode 100644 common/changes/@bentley/ui-framework/update-immer_2021-03-24-15-39.json create mode 100644 common/changes/@bentley/ui-ninezone/update-immer_2021-03-24-15-39.json diff --git a/common/api/summary/ui-framework.exports.csv b/common/api/summary/ui-framework.exports.csv index 284a74947af..bf61000a9da 100644 --- a/common/api/summary/ui-framework.exports.csv +++ b/common/api/summary/ui-framework.exports.csv @@ -186,7 +186,7 @@ public;ElementTooltipChangedEventArgs alpha;EmphasizeElementsChangedArgs beta;ExpandableSection beta;ExpandableSectionProps -internal;expandWidget: +internal;expandWidget: (base: beta;ExtensibleToolbarProps beta;featureOverridesActiveStateFunc(state: Readonly alpha;FocusToolSettings @@ -457,11 +457,11 @@ beta;SessionStateActionsProps beta;SessionStateActionsUnion = ActionsUnion beta;sessionStateMapDispatchToProps: beta;SessionStateReducer(state: SessionState | undefined, action: SessionStateActionsUnion): DeepReadonly -internal;setPanelSize: +internal;setPanelSize: (base: beta;SettingsModalFrontstage internal;settingsStatusToUiSettingsStatus(status: SettingsStatus): UiSettingsStatus -internal;setWidgetLabel: -internal;setWidgetState: +internal;setWidgetLabel: (base: +internal;setWidgetState: (base: alpha;SheetCard alpha;SheetCardProps alpha;SheetData @@ -469,7 +469,7 @@ alpha;SheetNavigationAid alpha;SheetNavigationAidControl alpha;SheetNavigationProps alpha;SheetsModalFrontstage -internal;showWidget: +internal;showWidget: (base: public;SignIn public;SignInProps public;SignOutModalFrontstage diff --git a/common/api/ui-framework.api.md b/common/api/ui-framework.api.md index c97b89f6a1f..51ecde7a641 100644 --- a/common/api/ui-framework.api.md +++ b/common/api/ui-framework.api.md @@ -1869,7 +1869,7 @@ export interface ExpandableSectionProps extends CommonProps { } // @internal (undocumented) -export const expandWidget: (base: Base, id: string) => Base; +}, id: string) => import("immer/dist/internal").WritableDraft; // @beta export interface ExtensibleToolbarProps { @@ -4659,7 +4659,7 @@ export const sessionStateMapDispatchToProps: { export function SessionStateReducer(state: SessionState | undefined, action: SessionStateActionsUnion): DeepReadonly; // @internal (undocumented) -export const setPanelSize: (base: Base, side: PanelSide, size: number | undefined) => Base; +}, side: PanelSide, size: number | undefined) => import("immer/dist/internal").WritableDraft; // @beta export class SettingsModalFrontstage implements ModalFrontstageInfo { @@ -4797,7 +4797,7 @@ export class SettingsModalFrontstage implements ModalFrontstageInfo { export function settingsStatusToUiSettingsStatus(status: SettingsStatus): UiSettingsStatus; // @internal (undocumented) -export const setWidgetLabel: (base: Base, id: string, label: string) => Base; +}, id: string, label: string) => import("immer/dist/internal").WritableDraft; // @internal (undocumented) -export const setWidgetState: (base: Base, widgetDef: WidgetDef, state: WidgetState_2) => Base; +}, widgetDef: WidgetDef, state: WidgetState_2) => import("immer/dist/internal").WritableDraft; // @alpha export class SheetCard extends React.Component { @@ -5093,7 +5093,7 @@ export class SheetsModalFrontstage implements ModalFrontstageInfo { } // @internal (undocumented) -export const showWidget: (base: Base, id: string) => Base; +}, id: string) => import("immer/dist/internal").WritableDraft; // @public export class SignIn extends React.PureComponent { diff --git a/common/changes/@bentley/presentation-components/update-immer_2021-03-24-15-39.json b/common/changes/@bentley/presentation-components/update-immer_2021-03-24-15-39.json new file mode 100644 index 00000000000..d603aa33bd4 --- /dev/null +++ b/common/changes/@bentley/presentation-components/update-immer_2021-03-24-15-39.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/presentation-components", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/presentation-components", + "email": "70327485+roluk@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/ui-components/update-immer_2021-03-24-15-39.json b/common/changes/@bentley/ui-components/update-immer_2021-03-24-15-39.json new file mode 100644 index 00000000000..8b0919d3a2b --- /dev/null +++ b/common/changes/@bentley/ui-components/update-immer_2021-03-24-15-39.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ui-components", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/ui-components", + "email": "70327485+roluk@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/ui-framework/update-immer_2021-03-24-15-39.json b/common/changes/@bentley/ui-framework/update-immer_2021-03-24-15-39.json new file mode 100644 index 00000000000..61faabf7bcc --- /dev/null +++ b/common/changes/@bentley/ui-framework/update-immer_2021-03-24-15-39.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ui-framework", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/ui-framework", + "email": "70327485+roluk@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/ui-ninezone/update-immer_2021-03-24-15-39.json b/common/changes/@bentley/ui-ninezone/update-immer_2021-03-24-15-39.json new file mode 100644 index 00000000000..84a2c18a816 --- /dev/null +++ b/common/changes/@bentley/ui-ninezone/update-immer_2021-03-24-15-39.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ui-ninezone", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/ui-ninezone", + "email": "70327485+roluk@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index ed3964e67a5..3e251e32625 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -3,13 +3,13 @@ dependencies: '@azure-tools/azcopy-node': 2.1.0 '@azure/storage-blob': 10.4.0 '@babel/core': 7.7.4 - '@bentley/icons-generic': 1.0.34 - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic': 1.0.33 + '@bentley/icons-generic-webfont': 1.0.33 '@bentley/imodeljs-native': 2.15.0 '@bentley/react-scripts': 3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32 '@bentley/units-schema': 1.0.6 '@microsoft/api-extractor': 7.7.3 - '@microsoft/applicationinsights-web': 2.6.0 + '@microsoft/applicationinsights-web': 2.5.11 '@openid/appauth': 1.3.0_debug@2.6.9 '@rush-temp/analytical-backend': 'file:projects/analytical-backend.tgz' '@rush-temp/backend-application-insights-client': 'file:projects/backend-application-insights-client.tgz' @@ -126,7 +126,7 @@ dependencies: '@types/faker': 4.1.12 '@types/file-saver': 2.0.1 '@types/flatbuffers': 1.10.0 - '@types/formidable': 1.2.1 + '@types/formidable': 1.0.32 '@types/fs-extra': 4.0.11 '@types/glob': 5.0.36 '@types/i18next': 8.4.6 @@ -135,7 +135,7 @@ dependencies: '@types/js-base64': 2.3.2 '@types/jsdom': 12.2.4 '@types/json5': 0.0.30 - '@types/jsonwebtoken': 8.5.1 + '@types/jsonwebtoken': 8.5.0 '@types/linkify-it': 2.1.0 '@types/lodash': 4.14.168 '@types/lolex': 2.1.3 @@ -149,10 +149,10 @@ dependencies: '@types/puppeteer': 2.0.1 '@types/qs': 6.9.6 '@types/react': 16.9.43 - '@types/react-autosuggest': 10.1.3 + '@types/react-autosuggest': 10.1.2 '@types/react-beautiful-dnd': 12.1.3 '@types/react-data-grid': 4.0.2 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/react-highlight-words': 0.11.1 '@types/react-redux': 7.1.16 '@types/react-resize-detector': 5.0.0 @@ -200,11 +200,11 @@ dependencies: cache-require-paths: 0.3.0 callable-instance2: 1.0.0 case-sensitive-paths-webpack-plugin: 2.4.0 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 - chai-spies: 1.0.0_chai@4.3.4 - chai-string: 1.5.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 + chai-spies: 1.0.0_chai@4.3.3 + chai-string: 1.5.0_chai@4.3.3 chai-subset: 1.6.0 chalk: 3.0.0 child_process: 1.0.2 @@ -220,10 +220,10 @@ dependencies: deep-assign: 2.0.0 deep-equal: 1.1.1 detect-port: 1.3.0 - dompurify: 2.2.7 + dompurify: 2.2.6 dotenv: 8.2.0 dotenv-expand: 5.1.0 - electron: 11.4.1 + electron: 11.3.0 enzyme: 3.11.0 enzyme-adapter-react-16: 1.15.6_4f82faf5e8cab057bc46d4d95079ec42 enzyme-to-json: 3.6.1_enzyme@3.11.0 @@ -259,7 +259,7 @@ dependencies: i18next-node-fs-backend: 2.1.3 i18next-xhr-backend: 2.0.1 ignore-styles: 5.0.1 - immer: 8.0.1 + immer: 9.0.1 immutable: 3.8.2 inspire-tree: 5.0.2 istanbul-instrumenter-loader: 3.0.1_webpack@4.42.0 @@ -301,12 +301,12 @@ dependencies: postcss-preset-env: 6.7.0 postcss-safe-parser: 4.0.1 puppeteer: 5.3.1 - qs: 6.10.1 + qs: 6.9.6 raf: 3.4.1 raf-schd: 4.0.2 react: 16.14.0 react-autosuggest: 10.1.0_react@16.14.0 - react-beautiful-dnd: 13.1.0_react-dom@16.14.0+react@16.14.0 + react-beautiful-dnd: 13.0.0_react-dom@16.14.0+react@16.14.0 react-compound-slider: 2.5.0_react@16.14.0 react-data-grid: 6.0.1_react-dom@16.14.0+react@16.14.0 react-dev-utils: 11.0.4 @@ -317,7 +317,7 @@ dependencies: react-dom: 16.14.0_react@16.14.0 react-highlight-words: 0.14.0_react@16.14.0 react-markdown: 4.3.1_react@16.14.0 - react-redux: 7.2.3_bbabd8c34ea235719dc50e75b43f85a4 + react-redux: 7.2.2_bbabd8c34ea235719dc50e75b43f85a4 react-resize-detector: 5.2.0_react-dom@16.14.0+react@16.14.0 react-router-dom: 5.2.0_react@16.14.0 react-select: 3.1.0_react-dom@16.14.0+react@16.14.0 @@ -346,7 +346,7 @@ dependencies: serve-handler: 6.1.3 shortid: 2.2.16 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 source-map-loader: 1.1.3_webpack@4.42.0 source-map-support: 0.5.19 spdy: 4.0.2 @@ -495,14 +495,14 @@ packages: dev: false resolution: integrity: sha512-sXOhOu/37Tr8428f32Jwuwga975Xw64pYg1UeUwOBMhkNgtn5vUuNRa3fhmem+I6f8EKoi6hOsYDFlaHeZ52jA== - /@azure/ms-rest-nodeauth/3.0.8: + /@azure/ms-rest-nodeauth/3.0.7: dependencies: '@azure/ms-rest-azure-env': 2.0.0 '@azure/ms-rest-js': 2.2.3 adal-node: 0.1.28 dev: false resolution: - integrity: sha512-HmEkzAUGWxWHrwHysX9vE00cuK2WjxCYvBWV6cbsvm+eSm3VXpkGHPSoCHXyqUQOGqu58LXI4XFVJxFT/s40pA== + integrity: sha512-7Q1MyMB+eqUQy8JO+virSIzAjqR2UbKXE/YQZe+53gC8yakm8WOQ5OzGfPP+eyHqeRs6bQESyw2IC5feLWlT2A== /@azure/storage-blob/10.4.0: dependencies: '@azure/ms-rest-js': 2.2.3 @@ -529,19 +529,19 @@ packages: dev: false resolution: integrity: sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== - /@babel/compat-data/7.13.12: + /@babel/compat-data/7.13.8: dev: false resolution: - integrity: sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ== + integrity: sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog== /@babel/core/7.7.4: dependencies: '@babel/code-frame': 7.12.13 '@babel/generator': 7.13.9 '@babel/helpers': 7.13.10 - '@babel/parser': 7.13.12 + '@babel/parser': 7.13.10 '@babel/template': 7.12.13 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 convert-source-map: 1.7.0 debug: 4.3.1 json5: 2.2.0 @@ -558,12 +558,12 @@ packages: dependencies: '@babel/code-frame': 7.12.13 '@babel/generator': 7.13.9 - '@babel/helper-module-transforms': 7.13.12 + '@babel/helper-module-transforms': 7.13.0 '@babel/helpers': 7.13.10 - '@babel/parser': 7.13.12 + '@babel/parser': 7.13.10 '@babel/template': 7.12.13 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 convert-source-map: 1.7.0 debug: 4.3.1 gensync: 1.0.0-beta.2 @@ -579,7 +579,7 @@ packages: integrity: sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== /@babel/generator/7.13.9: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 jsesc: 2.5.2 source-map: 0.5.7 dev: false @@ -587,20 +587,20 @@ packages: integrity: sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== /@babel/helper-annotate-as-pure/7.12.13: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== /@babel/helper-builder-binary-assignment-operator-visitor/7.12.13: dependencies: '@babel/helper-explode-assignable-expression': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== /@babel/helper-compilation-targets/7.13.10_@babel+core@7.9.0: dependencies: - '@babel/compat-data': 7.13.12 + '@babel/compat-data': 7.13.8 '@babel/core': 7.9.0 '@babel/helper-validator-option': 7.12.17 browserslist: 4.16.3 @@ -610,19 +610,19 @@ packages: '@babel/core': ^7.0.0 resolution: integrity: sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA== - /@babel/helper-create-class-features-plugin/7.13.11_@babel+core@7.9.0: + /@babel/helper-create-class-features-plugin/7.13.10_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 '@babel/helper-function-name': 7.12.13 - '@babel/helper-member-expression-to-functions': 7.13.12 + '@babel/helper-member-expression-to-functions': 7.13.0 '@babel/helper-optimise-call-expression': 7.12.13 - '@babel/helper-replace-supers': 7.13.12 + '@babel/helper-replace-supers': 7.13.0 '@babel/helper-split-export-declaration': 7.12.13 dev: false peerDependencies: '@babel/core': ^7.0.0 resolution: - integrity: sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw== + integrity: sha512-YV7r2YxdTUaw84EwNkyrRke/TJHR/UXGiyvACRqvdVJ2/syV2rQuJNnaRLSuYiop8cMRXOgseTGoJCWX0q2fFg== /@babel/helper-create-regexp-features-plugin/7.12.17_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 @@ -637,7 +637,7 @@ packages: dependencies: '@babel/core': 7.9.0 '@babel/helper-compilation-targets': 7.13.10_@babel+core@7.9.0 - '@babel/helper-module-imports': 7.13.12 + '@babel/helper-module-imports': 7.12.13 '@babel/helper-plugin-utils': 7.13.0 '@babel/traverse': 7.13.0 debug: 4.3.1 @@ -651,7 +651,7 @@ packages: integrity: sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== /@babel/helper-explode-assignable-expression/7.13.0: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== @@ -659,51 +659,52 @@ packages: dependencies: '@babel/helper-get-function-arity': 7.12.13 '@babel/template': 7.12.13 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== /@babel/helper-get-function-arity/7.12.13: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== /@babel/helper-hoist-variables/7.13.0: dependencies: '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g== - /@babel/helper-member-expression-to-functions/7.13.12: + /@babel/helper-member-expression-to-functions/7.13.0: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: - integrity: sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== - /@babel/helper-module-imports/7.13.12: + integrity: sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ== + /@babel/helper-module-imports/7.12.13: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: - integrity: sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== - /@babel/helper-module-transforms/7.13.12: + integrity: sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g== + /@babel/helper-module-transforms/7.13.0: dependencies: - '@babel/helper-module-imports': 7.13.12 - '@babel/helper-replace-supers': 7.13.12 - '@babel/helper-simple-access': 7.13.12 + '@babel/helper-module-imports': 7.12.13 + '@babel/helper-replace-supers': 7.13.0 + '@babel/helper-simple-access': 7.12.13 '@babel/helper-split-export-declaration': 7.12.13 '@babel/helper-validator-identifier': 7.12.11 '@babel/template': 7.12.13 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 + lodash: 4.17.21 dev: false resolution: - integrity: sha512-7zVQqMO3V+K4JOOj40kxiCrMf6xlQAkewBB0eu2b03OO/Q21ZutOzjpfD79A5gtE/2OWi1nv625MrDlGlkbknQ== + integrity: sha512-Ls8/VBwH577+pw7Ku1QkUWIyRRNHpYlts7+qSqBBFCW3I8QteB9DxfcZ5YJpOwH6Ihe/wn8ch7fMGOP1OhEIvw== /@babel/helper-optimise-call-expression/7.12.13: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== @@ -715,34 +716,34 @@ packages: dependencies: '@babel/helper-annotate-as-pure': 7.12.13 '@babel/helper-wrap-function': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== - /@babel/helper-replace-supers/7.13.12: + /@babel/helper-replace-supers/7.13.0: dependencies: - '@babel/helper-member-expression-to-functions': 7.13.12 + '@babel/helper-member-expression-to-functions': 7.13.0 '@babel/helper-optimise-call-expression': 7.12.13 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: - integrity: sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== - /@babel/helper-simple-access/7.13.12: + integrity: sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw== + /@babel/helper-simple-access/7.12.13: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: - integrity: sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== + integrity: sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA== /@babel/helper-skip-transparent-expression-wrappers/7.12.1: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== /@babel/helper-split-export-declaration/7.12.13: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== @@ -759,7 +760,7 @@ packages: '@babel/helper-function-name': 7.12.13 '@babel/template': 7.12.13 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== @@ -767,7 +768,7 @@ packages: dependencies: '@babel/template': 7.12.13 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ== @@ -779,24 +780,13 @@ packages: dev: false resolution: integrity: sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== - /@babel/parser/7.13.12: + /@babel/parser/7.13.10: dev: false engines: node: '>=6.0.0' hasBin: true resolution: - integrity: sha512-4T7Pb244rxH24yR116LAuJ+adxXXnHhZaLJjegJVKSdoNCe4x1eDBaud5YIcQFcqzsaD5BHvJw5BQ0AZapdCRw== - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.13.12_@babel+core@7.9.0: - dependencies: - '@babel/core': 7.9.0 - '@babel/helper-plugin-utils': 7.13.0 - '@babel/helper-skip-transparent-expression-wrappers': 7.12.1 - '@babel/plugin-proposal-optional-chaining': 7.13.12_@babel+core@7.9.0 - dev: false - peerDependencies: - '@babel/core': ^7.13.0 - resolution: - integrity: sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ== + integrity: sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ== /@babel/plugin-proposal-async-generator-functions/7.13.8_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 @@ -811,7 +801,7 @@ packages: /@babel/plugin-proposal-class-properties/7.13.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-create-class-features-plugin': 7.13.11_@babel+core@7.9.0 + '@babel/helper-create-class-features-plugin': 7.13.10_@babel+core@7.9.0 '@babel/helper-plugin-utils': 7.13.0 dev: false peerDependencies: @@ -821,7 +811,7 @@ packages: /@babel/plugin-proposal-class-properties/7.8.3_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-create-class-features-plugin': 7.13.11_@babel+core@7.9.0 + '@babel/helper-create-class-features-plugin': 7.13.10_@babel+core@7.9.0 '@babel/helper-plugin-utils': 7.13.0 dev: false peerDependencies: @@ -831,7 +821,7 @@ packages: /@babel/plugin-proposal-decorators/7.8.3_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-create-class-features-plugin': 7.13.11_@babel+core@7.9.0 + '@babel/helper-create-class-features-plugin': 7.13.10_@babel+core@7.9.0 '@babel/helper-plugin-utils': 7.13.0 '@babel/plugin-syntax-decorators': 7.12.13_@babel+core@7.9.0 dev: false @@ -921,7 +911,7 @@ packages: integrity: sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== /@babel/plugin-proposal-object-rest-spread/7.13.8_@babel+core@7.9.0: dependencies: - '@babel/compat-data': 7.13.12 + '@babel/compat-data': 7.13.8 '@babel/core': 7.9.0 '@babel/helper-compilation-targets': 7.13.10_@babel+core@7.9.0 '@babel/helper-plugin-utils': 7.13.0 @@ -942,7 +932,7 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== - /@babel/plugin-proposal-optional-chaining/7.13.12_@babel+core@7.9.0: + /@babel/plugin-proposal-optional-chaining/7.13.8_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 '@babel/helper-plugin-utils': 7.13.0 @@ -952,7 +942,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 resolution: - integrity: sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== + integrity: sha512-hpbBwbTgd7Cz1QryvwJZRo1U0k1q8uyBmeXOSQUjdg/A2TASkhR/rz7AyqZ/kS8kbpsNA80rOYbxySBJAqmhhQ== /@babel/plugin-proposal-optional-chaining/7.9.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 @@ -966,7 +956,7 @@ packages: /@babel/plugin-proposal-private-methods/7.13.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-create-class-features-plugin': 7.13.11_@babel+core@7.9.0 + '@babel/helper-create-class-features-plugin': 7.13.10_@babel+core@7.9.0 '@babel/helper-plugin-utils': 7.13.0 dev: false peerDependencies: @@ -1141,7 +1131,7 @@ packages: /@babel/plugin-transform-async-to-generator/7.13.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-module-imports': 7.13.12 + '@babel/helper-module-imports': 7.12.13 '@babel/helper-plugin-utils': 7.13.0 '@babel/helper-remap-async-to-generator': 7.13.0 dev: false @@ -1174,7 +1164,7 @@ packages: '@babel/helper-function-name': 7.12.13 '@babel/helper-optimise-call-expression': 7.12.13 '@babel/helper-plugin-utils': 7.13.0 - '@babel/helper-replace-supers': 7.13.12 + '@babel/helper-replace-supers': 7.13.0 '@babel/helper-split-export-declaration': 7.12.13 globals: 11.12.0 dev: false @@ -1279,7 +1269,7 @@ packages: /@babel/plugin-transform-modules-amd/7.13.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-module-transforms': 7.13.12 + '@babel/helper-module-transforms': 7.13.0 '@babel/helper-plugin-utils': 7.13.0 babel-plugin-dynamic-import-node: 2.3.3 dev: false @@ -1290,9 +1280,9 @@ packages: /@babel/plugin-transform-modules-commonjs/7.13.8_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-module-transforms': 7.13.12 + '@babel/helper-module-transforms': 7.13.0 '@babel/helper-plugin-utils': 7.13.0 - '@babel/helper-simple-access': 7.13.12 + '@babel/helper-simple-access': 7.12.13 babel-plugin-dynamic-import-node: 2.3.3 dev: false peerDependencies: @@ -1303,7 +1293,7 @@ packages: dependencies: '@babel/core': 7.9.0 '@babel/helper-hoist-variables': 7.13.0 - '@babel/helper-module-transforms': 7.13.12 + '@babel/helper-module-transforms': 7.13.0 '@babel/helper-plugin-utils': 7.13.0 '@babel/helper-validator-identifier': 7.12.11 babel-plugin-dynamic-import-node: 2.3.3 @@ -1315,7 +1305,7 @@ packages: /@babel/plugin-transform-modules-umd/7.13.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-module-transforms': 7.13.12 + '@babel/helper-module-transforms': 7.13.0 '@babel/helper-plugin-utils': 7.13.0 dev: false peerDependencies: @@ -1344,7 +1334,7 @@ packages: dependencies: '@babel/core': 7.9.0 '@babel/helper-plugin-utils': 7.13.0 - '@babel/helper-replace-supers': 7.13.12 + '@babel/helper-replace-supers': 7.13.0 dev: false peerDependencies: '@babel/core': ^7.0.0-0 @@ -1398,7 +1388,7 @@ packages: /@babel/plugin-transform-react-jsx-development/7.12.17_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/plugin-transform-react-jsx': 7.13.12_@babel+core@7.9.0 + '@babel/plugin-transform-react-jsx': 7.12.17_@babel+core@7.9.0 dev: false peerDependencies: '@babel/core': ^7.0.0-0 @@ -1422,19 +1412,19 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-O5JJi6fyfih0WfDgIJXksSPhGP/G0fQpfxYy87sDc+1sFmsCS6wr3aAn+whbzkhbjtq4VMqLRaSzR6IsshIC0Q== - /@babel/plugin-transform-react-jsx/7.13.12_@babel+core@7.9.0: + /@babel/plugin-transform-react-jsx/7.12.17_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 '@babel/helper-annotate-as-pure': 7.12.13 - '@babel/helper-module-imports': 7.13.12 + '@babel/helper-module-imports': 7.12.13 '@babel/helper-plugin-utils': 7.13.0 '@babel/plugin-syntax-jsx': 7.12.13_@babel+core@7.9.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false peerDependencies: '@babel/core': ^7.0.0-0 resolution: - integrity: sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA== + integrity: sha512-mwaVNcXV+l6qJOuRhpdTEj8sT/Z0owAVWf9QujTZ0d2ye9X/K+MTOTSizcgKOj18PGnTc/7g1I4+cIUjsKhBcw== /@babel/plugin-transform-react-pure-annotations/7.12.1_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 @@ -1466,7 +1456,7 @@ packages: /@babel/plugin-transform-runtime/7.9.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-module-imports': 7.13.12 + '@babel/helper-module-imports': 7.12.13 '@babel/helper-plugin-utils': 7.13.0 resolve: 1.19.0 semver: 5.7.1 @@ -1524,7 +1514,7 @@ packages: /@babel/plugin-transform-typescript/7.13.0_@babel+core@7.9.0: dependencies: '@babel/core': 7.9.0 - '@babel/helper-create-class-features-plugin': 7.13.11_@babel+core@7.9.0 + '@babel/helper-create-class-features-plugin': 7.13.10_@babel+core@7.9.0 '@babel/helper-plugin-utils': 7.13.0 '@babel/plugin-syntax-typescript': 7.12.13_@babel+core@7.9.0 dev: false @@ -1551,14 +1541,13 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== - /@babel/preset-env/7.13.12_@babel+core@7.9.0: + /@babel/preset-env/7.13.10_@babel+core@7.9.0: dependencies: - '@babel/compat-data': 7.13.12 + '@babel/compat-data': 7.13.8 '@babel/core': 7.9.0 '@babel/helper-compilation-targets': 7.13.10_@babel+core@7.9.0 '@babel/helper-plugin-utils': 7.13.0 '@babel/helper-validator-option': 7.12.17 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.13.12_@babel+core@7.9.0 '@babel/plugin-proposal-async-generator-functions': 7.13.8_@babel+core@7.9.0 '@babel/plugin-proposal-class-properties': 7.13.0_@babel+core@7.9.0 '@babel/plugin-proposal-dynamic-import': 7.13.8_@babel+core@7.9.0 @@ -1569,7 +1558,7 @@ packages: '@babel/plugin-proposal-numeric-separator': 7.12.13_@babel+core@7.9.0 '@babel/plugin-proposal-object-rest-spread': 7.13.8_@babel+core@7.9.0 '@babel/plugin-proposal-optional-catch-binding': 7.13.8_@babel+core@7.9.0 - '@babel/plugin-proposal-optional-chaining': 7.13.12_@babel+core@7.9.0 + '@babel/plugin-proposal-optional-chaining': 7.13.8_@babel+core@7.9.0 '@babel/plugin-proposal-private-methods': 7.13.0_@babel+core@7.9.0 '@babel/plugin-proposal-unicode-property-regex': 7.12.13_@babel+core@7.9.0 '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.9.0 @@ -1617,7 +1606,7 @@ packages: '@babel/plugin-transform-unicode-escapes': 7.12.13_@babel+core@7.9.0 '@babel/plugin-transform-unicode-regex': 7.12.13_@babel+core@7.9.0 '@babel/preset-modules': 0.1.4_@babel+core@7.9.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 babel-plugin-polyfill-corejs2: 0.1.10_@babel+core@7.9.0 babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.9.0 babel-plugin-polyfill-regenerator: 0.1.6_@babel+core@7.9.0 @@ -1627,13 +1616,13 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 resolution: - integrity: sha512-JzElc6jk3Ko6zuZgBtjOd01pf9yYDEIH8BcqVuYIuOkzOwDesoa/Nz4gIo4lBG6K861KTV9TvIgmFuT6ytOaAA== + integrity: sha512-nOsTScuoRghRtUsRr/c69d042ysfPHcu+KOB4A9aAO9eJYqrkat+LF8G1yp1HD18QiwixT2CisZTr/0b3YZPXQ== /@babel/preset-env/7.9.0_@babel+core@7.9.0: dependencies: - '@babel/compat-data': 7.13.12 + '@babel/compat-data': 7.13.8 '@babel/core': 7.9.0 '@babel/helper-compilation-targets': 7.13.10_@babel+core@7.9.0 - '@babel/helper-module-imports': 7.13.12 + '@babel/helper-module-imports': 7.12.13 '@babel/helper-plugin-utils': 7.13.0 '@babel/plugin-proposal-async-generator-functions': 7.13.8_@babel+core@7.9.0 '@babel/plugin-proposal-dynamic-import': 7.13.8_@babel+core@7.9.0 @@ -1685,7 +1674,7 @@ packages: '@babel/plugin-transform-typeof-symbol': 7.12.13_@babel+core@7.9.0 '@babel/plugin-transform-unicode-regex': 7.12.13_@babel+core@7.9.0 '@babel/preset-modules': 0.1.4_@babel+core@7.9.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 browserslist: 4.16.3 core-js-compat: 3.9.1 invariant: 2.2.4 @@ -1702,7 +1691,7 @@ packages: '@babel/helper-plugin-utils': 7.13.0 '@babel/plugin-proposal-unicode-property-regex': 7.12.13_@babel+core@7.9.0 '@babel/plugin-transform-dotall-regex': 7.12.13_@babel+core@7.9.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 esutils: 2.0.3 dev: false peerDependencies: @@ -1714,7 +1703,7 @@ packages: '@babel/core': 7.9.0 '@babel/helper-plugin-utils': 7.13.0 '@babel/plugin-transform-react-display-name': 7.12.13_@babel+core@7.9.0 - '@babel/plugin-transform-react-jsx': 7.13.12_@babel+core@7.9.0 + '@babel/plugin-transform-react-jsx': 7.12.17_@babel+core@7.9.0 '@babel/plugin-transform-react-jsx-development': 7.12.17_@babel+core@7.9.0 '@babel/plugin-transform-react-pure-annotations': 7.12.1_@babel+core@7.9.0 dev: false @@ -1727,7 +1716,7 @@ packages: '@babel/core': 7.9.0 '@babel/helper-plugin-utils': 7.13.0 '@babel/plugin-transform-react-display-name': 7.8.3_@babel+core@7.9.0 - '@babel/plugin-transform-react-jsx': 7.13.12_@babel+core@7.9.0 + '@babel/plugin-transform-react-jsx': 7.12.17_@babel+core@7.9.0 '@babel/plugin-transform-react-jsx-development': 7.12.17_@babel+core@7.9.0 '@babel/plugin-transform-react-jsx-self': 7.12.13_@babel+core@7.9.0 '@babel/plugin-transform-react-jsx-source': 7.12.13_@babel+core@7.9.0 @@ -1768,8 +1757,8 @@ packages: /@babel/template/7.12.13: dependencies: '@babel/code-frame': 7.12.13 - '@babel/parser': 7.13.12 - '@babel/types': 7.13.12 + '@babel/parser': 7.13.10 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== @@ -1779,30 +1768,30 @@ packages: '@babel/generator': 7.13.9 '@babel/helper-function-name': 7.12.13 '@babel/helper-split-export-declaration': 7.12.13 - '@babel/parser': 7.13.12 - '@babel/types': 7.13.12 + '@babel/parser': 7.13.10 + '@babel/types': 7.13.0 debug: 4.3.1 globals: 11.12.0 lodash: 4.17.21 dev: false resolution: integrity: sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ== - /@babel/types/7.13.12: + /@babel/types/7.13.0: dependencies: '@babel/helper-validator-identifier': 7.12.11 lodash: 4.17.21 to-fast-properties: 2.0.0 dev: false resolution: - integrity: sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA== - /@bentley/icons-generic-webfont/1.0.34: + integrity: sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA== + /@bentley/icons-generic-webfont/1.0.33: dev: false resolution: - integrity: sha512-5zZgs+himE2vjf39CVlDXMHCFAwSfcoORqJBk3Vji8QVCF8AIX4IX2DO6HlsIAM7szxMNqhz1kd07Xfppro6MA== - /@bentley/icons-generic/1.0.34: + integrity: sha512-pXB74CYoEnUNF+5e3O7RVyFadl+VO9Z+RXqGuta6o0HmYV8gRybtlagCOJF5AnI3C1h++ZY0vsfTthLgTYIatw== + /@bentley/icons-generic/1.0.33: dev: false resolution: - integrity: sha512-IIs1wDcY2oZ8tJ3EZRw0U51M+0ZL3MvwoDYYmhUXaa9/UZqpFoOyLBGaxjirQteWXqTIMm3mFvmC+Nbn1ok4Iw== + integrity: sha512-c3TylvyMeaGKGt4WoUawNIOetIwbVLJoSe3HBn5CtUV7oEpmvz5qbxLuCTvf5ZAGqhQxJLW+FSX7Z0floo4FIQ== /@bentley/imodeljs-native/2.15.0: dev: false requiresBuild: true @@ -1811,7 +1800,7 @@ packages: /@bentley/react-scripts/3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32: dependencies: '@babel/core': 7.9.0 - '@bentley/webpack-tools-core': 2.13.2_webpack@4.42.0 + '@bentley/webpack-tools-core': 2.12.3_webpack@4.42.0 '@svgr/webpack': 4.3.3 '@typescript-eslint/eslint-plugin': 4.11.1_d0bf3c0366a0d1edd9673f55e63a15b1 '@typescript-eslint/parser': 4.11.1_eslint@6.8.0+typescript@4.1.5 @@ -1891,7 +1880,7 @@ packages: dev: false resolution: integrity: sha512-E59wOYMdBDVNDbZ3+FChznM+Twdo+ZHcCa7FRTgnatc7Z4N4yBpyXwh186COgOarBk2uoBtEskvaPqz5RhHIaA== - /@bentley/webpack-tools-core/2.13.2_webpack@4.42.0: + /@bentley/webpack-tools-core/2.12.3_webpack@4.42.0: dependencies: chalk: 3.0.0 file-loader: 4.3.0_webpack@4.42.0 @@ -1908,10 +1897,10 @@ packages: peerDependencies: webpack: 4.42.0 resolution: - integrity: sha512-F2lWJoP4Z/qdQsFDistS0P/gdqLRgH2xrawRQQS/2KeT/oMiTOd0XRjavvhU0hGEfTnNXRstsvin5SzaTYf2Tw== + integrity: sha512-/JcnEEt5xUajeBtHIKJx7PKWQnRZ5mBSP4ihKwRcJCi9RqV7nasmKTLqzQ8lTL4oB3EOMd4Q4HakCJJil1xasA== /@cnakazawa/watch/1.0.4: dependencies: - exec-sh: 0.3.6 + exec-sh: 0.3.4 minimist: 1.2.5 dev: false engines: @@ -2183,7 +2172,7 @@ packages: jest-runtime: 24.9.0 jest-util: 24.9.0 jest-worker: 24.9.0 - node-notifier: 5.4.5 + node-notifier: 5.4.3 slash: 2.0.0 source-map: 0.6.1 string-length: 2.0.0 @@ -2260,7 +2249,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.3 '@types/istanbul-reports': 3.0.0 - '@types/node': 12.20.6 + '@types/node': 10.14.1 '@types/yargs': 15.0.13 chalk: 4.1.0 dev: false @@ -2294,82 +2283,76 @@ packages: hasBin: true resolution: integrity: sha512-bjLnWrowqSFJFO/TO54E8wzoS1TogBJSfd+9DKEu4t8E7DvXgDPj+Tmez8d4f8Wk/kH4sIcBWFsqsLAJJOI5zw== - /@microsoft/applicationinsights-analytics-js/2.6.0: + /@microsoft/applicationinsights-analytics-js/2.5.11: dependencies: - '@microsoft/applicationinsights-common': 2.6.0 - '@microsoft/applicationinsights-core-js': 2.6.0 + '@microsoft/applicationinsights-common': 2.5.11 + '@microsoft/applicationinsights-core-js': 2.5.11 '@microsoft/applicationinsights-shims': 1.0.3 - '@microsoft/dynamicproto-js': 1.1.1 + '@microsoft/dynamicproto-js': 1.1.0 dev: false resolution: - integrity: sha512-l7UnG4hiuQpzb5J6X3wijkS7LGhz8AenxBXQDkmdgWf5tjwWV3jZN4UXz9eEduC9MRldOKZ6OUb3uI2bvIqPVw== - /@microsoft/applicationinsights-channel-js/2.6.0: + integrity: sha512-Ug5p/BOpA5hx3Hhsaw+BPXZ6sKsvYrkqK35M8jKRGS/ZVbrqePy+4C8zBimqJKYX7PLXwLoFl803b8hc1i8KVA== + /@microsoft/applicationinsights-channel-js/2.5.11: dependencies: - '@microsoft/applicationinsights-common': 2.6.0 - '@microsoft/applicationinsights-core-js': 2.6.0 + '@microsoft/applicationinsights-common': 2.5.11 + '@microsoft/applicationinsights-core-js': 2.5.11 '@microsoft/applicationinsights-shims': 1.0.3 - '@microsoft/dynamicproto-js': 1.1.1 + '@microsoft/dynamicproto-js': 1.1.0 dev: false resolution: - integrity: sha512-APxSM6eilHq9TRsrEvqGvKfNFBW/C5EZim1XJlNI9cX22I6LrbrB70clcBwa+ssRQtPg6c+MRPVQBVe5O57+fQ== - /@microsoft/applicationinsights-common/2.6.0: + integrity: sha512-jKQ03ZwJ1/i4kkFTFG5jfv0AxOeS9VyzVdO21nUO7/N07yVMV/l8BRlEIFdfUi6eCv8cQF2cOTtc9NAqPPy3Og== + /@microsoft/applicationinsights-common/2.5.11: dependencies: - '@microsoft/applicationinsights-core-js': 2.6.0 + '@microsoft/applicationinsights-core-js': 2.5.11 '@microsoft/applicationinsights-shims': 1.0.3 - '@microsoft/dynamicproto-js': 1.1.1 dev: false resolution: - integrity: sha512-AqsA9RZKEi0BbzhK3XBNSPx2x4JNRqvg149Jjf0o5UKI2zm3JCzSeXtquTQYD3iwSflqKAn0jLjr1ao+/DbIiA== - /@microsoft/applicationinsights-core-js/2.6.0: + integrity: sha512-laiJ5BeEqOiFltW32JyVHndny4R4QUcgCdl675A+t9YCsVl6y8DUxvSMT9W3AgYFLVGmrIyYSJLL0xnOT97xhg== + /@microsoft/applicationinsights-core-js/2.5.11: dependencies: '@microsoft/applicationinsights-shims': 1.0.3 - '@microsoft/dynamicproto-js': 1.1.1 + '@microsoft/dynamicproto-js': 1.1.0 dev: false resolution: - integrity: sha512-IBayTBEISR2hVkG6aNAYGDQrJzx2JguWEAWpcV00sLT+J4zAY80Pk+CClI35txB7ePk8pu1p8ebq2Z+l1GfJag== - /@microsoft/applicationinsights-dependencies-js/2.6.0: + integrity: sha512-Httm8NiFnb+gwBvMy+RcI1v9M8qu8JqIn6Wht7QnhPwaVBvwYCFLrIfoT0LOjwAGGASmFHueHMSnbboYWmiZjw== + /@microsoft/applicationinsights-dependencies-js/2.5.11: dependencies: - '@microsoft/applicationinsights-common': 2.6.0 - '@microsoft/applicationinsights-core-js': 2.6.0 + '@microsoft/applicationinsights-common': 2.5.11 + '@microsoft/applicationinsights-core-js': 2.5.11 '@microsoft/applicationinsights-shims': 1.0.3 - '@microsoft/dynamicproto-js': 1.1.1 + '@microsoft/dynamicproto-js': 1.1.0 dev: false resolution: - integrity: sha512-b6crj5dG/JXiiuzjSy6+NmpJFlnPQmvG/wxTO5fqzy9zh7GHva7P/KFaWq/ABTuX9aFyd22w1TY73PuiPQ+fRw== - /@microsoft/applicationinsights-properties-js/2.6.0: + integrity: sha512-vye01TID4kpW6MbZIeAUzvNygauJvCu+0TcpwtKVeAoVBKIfnT1cPrI62ynB9e7AbNzm0AJ/Ax+iR0Y6POhEQQ== + /@microsoft/applicationinsights-properties-js/2.5.11: dependencies: - '@microsoft/applicationinsights-common': 2.6.0 - '@microsoft/applicationinsights-core-js': 2.6.0 + '@microsoft/applicationinsights-common': 2.5.11 + '@microsoft/applicationinsights-core-js': 2.5.11 '@microsoft/applicationinsights-shims': 1.0.3 - '@microsoft/dynamicproto-js': 1.1.1 dev: false resolution: - integrity: sha512-LI1CjB6sMU3BVHvP5OcIgeijc89KaSVNCxO0drMWa6eBDBY7IMdh1qg0XC0SsumLIYuxYrkYgDb3o5webqNllA== + integrity: sha512-3RPunopAvfW4BC/yRIwkGDYwvn1aHn8f4TUzkdEnaeRzaGkU++ag5mPi9AhUC0l2gSUA8ex+TLwFJ8cgcDz5Xg== /@microsoft/applicationinsights-shims/1.0.3: dev: false resolution: integrity: sha512-+S17aqEkOYpyBpmclhgwcEplwnxSo5AxYBdRg38GBobI1GKPSpZfnLssLzcjJ6XZCS5tqB5xjyTZs6gHj7ZJWQ== - /@microsoft/applicationinsights-web/2.6.0: - dependencies: - '@microsoft/applicationinsights-analytics-js': 2.6.0 - '@microsoft/applicationinsights-channel-js': 2.6.0 - '@microsoft/applicationinsights-common': 2.6.0 - '@microsoft/applicationinsights-core-js': 2.6.0 - '@microsoft/applicationinsights-dependencies-js': 2.6.0 - '@microsoft/applicationinsights-properties-js': 2.6.0 + /@microsoft/applicationinsights-web/2.5.11: + dependencies: + '@microsoft/applicationinsights-analytics-js': 2.5.11 + '@microsoft/applicationinsights-channel-js': 2.5.11 + '@microsoft/applicationinsights-common': 2.5.11 + '@microsoft/applicationinsights-core-js': 2.5.11 + '@microsoft/applicationinsights-dependencies-js': 2.5.11 + '@microsoft/applicationinsights-properties-js': 2.5.11 '@microsoft/applicationinsights-shims': 1.0.3 - '@microsoft/dynamicproto-js': 1.1.1 + '@microsoft/dynamicproto-js': 1.1.0 dev: false resolution: - integrity: sha512-3TONRtWjAm2fwWmicTTWM8gPJmg81zKiYyfzp7aSF0HiT/0ljArDR8KJgHeiX6ZiwT49xVkUoBxxEXtUEvJVkQ== - /@microsoft/dynamicproto-js/1.1.1: - dependencies: - findup-sync: 4.0.0 - nopt: 5.0.0 - pify: 2.3.0 + integrity: sha512-epwFbaMzibFN12YVRDlt6sBoz9fhjk9CI8y13oGH3B3sKM4mOhdrBRMh7YRhjzVz+3ygFTq9rS9IRu2Ozj7a7A== + /@microsoft/dynamicproto-js/1.1.0: dev: false resolution: - integrity: sha512-SPY1PlXmg4FbJVItVdhDV+zigajPtSI8oZPrsKBEIzAF4FROuwWIq5C+RAF8VJshBqphcvU8Eoh4DrUEZOB31g== + integrity: sha512-pjcr+A6wTQHl/S4b5zQzeDMC6+9ekojCFHQAEYI4a8u9ZjWwbg4jmtO22CWEuRWWN/lBMjay9FKanlODWk5wqQ== /@microsoft/node-core-library/3.18.2: dependencies: '@types/node': 8.10.54 @@ -2586,7 +2569,7 @@ packages: integrity: sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w== /@svgr/hast-util-to-babel-ast/4.3.2: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false engines: node: '>=8' @@ -2617,7 +2600,7 @@ packages: dependencies: '@babel/core': 7.9.0 '@babel/plugin-transform-react-constant-elements': 7.13.10_@babel+core@7.9.0 - '@babel/preset-env': 7.13.12_@babel+core@7.9.0 + '@babel/preset-env': 7.13.10_@babel+core@7.9.0 '@babel/preset-react': 7.12.13_@babel+core@7.9.0 '@svgr/core': 4.3.3 '@svgr/plugin-jsx': 4.3.3 @@ -2713,35 +2696,35 @@ packages: dev: false resolution: integrity: sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg== - /@types/babel__core/7.1.14: + /@types/babel__core/7.1.12: dependencies: - '@babel/parser': 7.13.12 - '@babel/types': 7.13.12 + '@babel/parser': 7.13.10 + '@babel/types': 7.13.0 '@types/babel__generator': 7.6.2 '@types/babel__template': 7.4.0 - '@types/babel__traverse': 7.11.1 + '@types/babel__traverse': 7.11.0 dev: false resolution: - integrity: sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== + integrity: sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ== /@types/babel__generator/7.6.2: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== /@types/babel__template/7.4.0: dependencies: - '@babel/parser': 7.13.12 - '@babel/types': 7.13.12 + '@babel/parser': 7.13.10 + '@babel/types': 7.13.0 dev: false resolution: integrity: sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== - /@types/babel__traverse/7.11.1: + /@types/babel__traverse/7.11.0: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 dev: false resolution: - integrity: sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== + integrity: sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg== /@types/base64-js/1.3.0: dev: false resolution: @@ -2753,20 +2736,20 @@ packages: /@types/body-parser/1.19.0: dependencies: '@types/connect': 3.4.34 - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== /@types/bunyan-seq/0.2.2: dependencies: '@types/bunyan': 1.8.6 - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-UXW9AI3WN7U2SRoVK112yG3L/JOXtLc40Bm1WiFk/nnxh5CHLcAXgwHupOPp7PHc2aWLE5ZAgLHfl4ULn4KeBw== /@types/bunyan/1.8.6: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-YiozPOOsS6bIuz31ilYqR5SlLif4TBWsousN2aCWLi5233nZSX19tFbcQUPdR7xJ8ypPyxkCGNxg0CIV5n9qxQ== @@ -2818,12 +2801,12 @@ packages: dev: false resolution: integrity: sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ== - /@types/cheerio/0.22.28: + /@types/cheerio/0.22.25: dependencies: '@types/node': 10.14.1 dev: false resolution: - integrity: sha512-ehUMGSW5IeDxJjbru4awKYMlKGmo1wSSGUVqXtYwlgmUM8X1a0PZttEIm6yEY7vHsY/hh6iPnklF213G0UColw== + integrity: sha512-Y2kmbk74dSGRI1bBmo67bowDoVxNm9cs+IPZznsFPRuBN6ToK2RCATZipOJsgO0Unbtiy01o0hP2SS+MKdUNvQ== /@types/classnames/2.2.11: dev: false resolution: @@ -2840,7 +2823,7 @@ packages: integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog== /@types/cpx/1.5.1: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-PVFRjClbYw22ckQR1OtjlQpg3ZqbSIIOq+/dbkqsIEYWmpZqL9OXLXTLUEhsYaST+1oNfx5c067aMqoXnAp8+w== @@ -2864,13 +2847,13 @@ packages: integrity: sha512-3JwbEeRVQ3n6+JgBW/hCdkydRk9/vWT+UEglcXEJqLJEcUganDH37zlfLznxPKTZZfDqA9K229l1qN458ubcOQ== /@types/dotenv/6.1.1: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg== /@types/enzyme/3.9.3: dependencies: - '@types/cheerio': 0.22.28 + '@types/cheerio': 0.22.25 '@types/react': 16.9.43 dev: false resolution: @@ -2879,18 +2862,18 @@ packages: dev: false resolution: integrity: sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== - /@types/express-serve-static-core/4.17.19: + /@types/express-serve-static-core/4.17.18: dependencies: '@types/node': 10.14.1 '@types/qs': 6.9.6 '@types/range-parser': 1.2.3 dev: false resolution: - integrity: sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA== + integrity: sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA== /@types/express/4.17.11: dependencies: '@types/body-parser': 1.19.0 - '@types/express-serve-static-core': 4.17.19 + '@types/express-serve-static-core': 4.17.18 '@types/qs': 6.9.6 '@types/serve-static': 1.13.9 dev: false @@ -2908,29 +2891,29 @@ packages: dev: false resolution: integrity: sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA== - /@types/formidable/1.2.1: + /@types/formidable/1.0.32: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: - integrity: sha512-4sVIjd51AADf4YnpsdqNQh7n3ZRLo16w+w6F7zzKjK6dBsQc9Vrq8GQLpHOOWq0V8Fe2bbp2EpihHx57iVgm5Q== + integrity: sha512-jOAB5+GFW+C+2xdvUcpd/CnYg2rD5xCyagJLBJU+9PB4a/DKmsAqS9yZI3j/Q9zwvM7ztPHaAIH1ijzp4cezdQ== /@types/fs-extra/4.0.11: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-iHm/nBVmMR/VJQn/xCSwZ6C/qfm1Tgsh2IrCCinAsF+mlHDGpV+vLR/EA6xezBXpv0/amDOaqxa8f2TVxBQyog== /@types/glob/5.0.36: dependencies: '@types/events': 3.0.0 - '@types/minimatch': 3.0.4 - '@types/node': 12.20.6 + '@types/minimatch': 3.0.3 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg== /@types/glob/7.1.3: dependencies: - '@types/minimatch': 3.0.4 + '@types/minimatch': 3.0.3 '@types/node': 10.14.1 dev: false resolution: @@ -2964,7 +2947,7 @@ packages: integrity: sha512-5KhnWbUIfncsFQvZO2/k0P4qqvWpI8Isd3wa/56zVqORl9db3J+aPFgoeO0FN8oKozaT+s0U9RoQnSlqI5YRhw== /@types/i18next-node-fs-backend/2.1.0: dependencies: - i18next: 20.1.0 + i18next: 20.0.0 dev: false resolution: integrity: sha512-bOOeT89UO/bYLJoQHdN5S3pggj7mMmFfQMBpDdUQOQIQkENGpnTwhNsIM/kjl1NE2HEihjlRZUNVV60Ze86UZA== @@ -3007,7 +2990,7 @@ packages: integrity: sha512-iGjZEnheu9n53fhlU+QLovdKHsdwPJ79iammNM0opTEp18zcJ/nNAIthuMilJoDPNUQHoqRAJdDNI5rxHY4nkA== /@types/jsdom/12.2.4: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 '@types/tough-cookie': 4.0.0 parse5: 4.0.0 dev: false @@ -3025,12 +3008,12 @@ packages: dev: false resolution: integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA== - /@types/jsonwebtoken/8.5.1: + /@types/jsonwebtoken/8.5.0: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: - integrity: sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw== + integrity: sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg== /@types/keyv/3.1.1: dependencies: '@types/node': 10.14.1 @@ -3065,10 +3048,6 @@ packages: dev: false resolution: integrity: sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - /@types/minimatch/3.0.4: - dev: false - resolution: - integrity: sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== /@types/minipass/2.2.0: dependencies: '@types/node': 10.14.1 @@ -3081,7 +3060,7 @@ packages: integrity: sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== /@types/multiparty/0.0.31: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha1-MB/S2wWl1PNAhhPrW5ZSzWELeeI= @@ -3103,10 +3082,10 @@ packages: dev: false resolution: integrity: sha512-Rymt08vh1GaW4vYB6QP61/5m/CFLGnFZP++bJpWbiNxceNa6RBipDmb413jvtSf/R1gg5a/jQVl2jY4XVRscEA== - /@types/node/12.20.6: + /@types/node/12.20.5: dev: false resolution: - integrity: sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA== + integrity: sha512-5Oy7tYZnu3a4pnJ//d4yVvOImExl4Vtwf0D40iKUlU+XlUsyV9iyFWyCFlwy489b72FMAik/EFwRkNLjjOdSPg== /@types/node/8.10.54: dev: false resolution: @@ -3125,7 +3104,7 @@ packages: integrity: sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== /@types/puppeteer/2.0.1: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-G8vEyU83Bios+dzs+DZGpAirDmMqRhfFBJCkFrg+A5+6n5EPPHxwBLImJto3qjh0mrBXbLBCyuahhhtTrAfR5g== @@ -3141,12 +3120,12 @@ packages: dev: false resolution: integrity: sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== - /@types/react-autosuggest/10.1.3: + /@types/react-autosuggest/10.1.2: dependencies: '@types/react': 16.9.43 dev: false resolution: - integrity: sha512-j80cdYhqOEBbG7JWWl//95d+jf2mkL+tod0C6oM3f0tQx+gIRdFRiYOuGkEduQrtTcZR5a2AdYI8LpUTRfhBMw== + integrity: sha512-K23lmXhC3Bbd8y/jm5+wYrw/NAeN4U/wlHTgAEBIwLOyQKFCFYA3ONKte9P21L+RGIXRP8UlzHOSRtmIZw5Nqw== /@types/react-beautiful-dnd/12.1.3: dependencies: '@types/react': 16.9.43 @@ -3159,12 +3138,12 @@ packages: dev: false resolution: integrity: sha512-no7HnLfm5CSLicuLixZjgsfq0myt6+aBxyVCIo9XiJdNLiZUC0uogMa2f4wq+xdTaslYHeyzwsVL6KF0B765Yg== - /@types/react-dom/16.9.12: + /@types/react-dom/16.9.11: dependencies: '@types/react': 16.9.43 dev: false resolution: - integrity: sha512-i7NPZZpPte3jtVOoW+eLB7G/jsX5OM6GqQnH+lC0nq0rqwlK0x8WcMEvYDgFWqWhWMlTltTimzdMax6wYfZssA== + integrity: sha512-3UuR4MoWf5spNgrG6cwsmT9DdRghcR4IDFOzNZ6+wcmacxkFykcb5ji0nNVm9ckBT4BCxvCrJJbM4+EYsEEVIg== /@types/react-highlight-words/0.11.1: dependencies: '@types/react': 16.9.43 @@ -3204,7 +3183,7 @@ packages: /@types/react-select/3.0.26: dependencies: '@types/react': 16.9.43 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/react-transition-group': 4.4.1 dev: false resolution: @@ -3271,7 +3250,7 @@ packages: /@types/rimraf/2.0.4: dependencies: '@types/glob': 7.1.3 - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-8gBudvllD2A/c0CcEX/BivIDorHFt5UI5m46TsNj8DjWCCTTZT74kEe4g+QsY7P/B9WdO98d82zZgXO/RQzu2Q== @@ -3281,7 +3260,7 @@ packages: integrity: sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== /@types/serve-handler/6.1.0: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-F9BpWotLZrQvq1CdE3oCnVmQUb6dWq20HSB/qjF4mG7WkZjPQ6fye8veznMKoBPhFJve4yz9C1NOITdTcoLngQ== @@ -3323,13 +3302,13 @@ packages: integrity: sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== /@types/source-map-support/0.4.2: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-GbGWx39O8NdUHSChdrU0XeigBAgu1Teg3llwE0slSVcH2qISaQT70ftAiH+h4HIt3VIObFU34PSpXIKJuXCybQ== /@types/spdy/3.4.4: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-N9LBlbVRRYq6HgYpPkqQc3a9HJ/iEtVZToW6xlTtJiMhmRJ7jJdV7TaZQJw/Ve/1ePUsQiCTDc4JMuzzag94GA== @@ -3339,14 +3318,14 @@ packages: integrity: sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== /@types/stream-buffers/3.0.3: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-NeFeX7YfFZDYsCfbuaOmFQ0OjSmHreKBpp7MQ4alWQBHeh2USLsj7qyMyn9t82kjqIX516CR/5SRHnARduRtbQ== /@types/superagent/4.1.10: dependencies: '@types/cookiejar': 2.1.2 - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-xAgkb2CMWUMCyVc/3+7iQfOEBE75NvuZeezvmixbUw3nmENf2tCnQkW5yQLTYqvXUQ+R6EXxdqKKbal2zM5V/g== @@ -3363,7 +3342,7 @@ packages: /@types/tar/4.0.4: dependencies: '@types/minipass': 2.2.0 - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-0Xv+xcmkTsOZdIF4yCnd7RkOOyfyqPaqJ7RZFKnwdxfDbkN3eAAE9sHl8zJFqBz4VhxolW9EErbjR1oyH7jK2A== @@ -3399,7 +3378,7 @@ packages: integrity: sha512-WGZCqBZZ0mXN2RxvLHL6/7RCu+OWs28jgQMP04LWfpyJlQUMTR6YU9CNJAKDgbw+EV/u687INXuLUc7FuML/4g== /@types/webpack-sources/0.1.8: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 '@types/source-list-map': 0.1.2 source-map: 0.6.1 dev: false @@ -3408,7 +3387,7 @@ packages: /@types/webpack/4.41.26: dependencies: '@types/anymatch': 1.3.1 - '@types/node': 12.20.6 + '@types/node': 12.20.5 '@types/tapable': 1.0.6 '@types/uglify-js': 3.13.0 '@types/webpack-sources': 0.1.8 @@ -3418,7 +3397,7 @@ packages: integrity: sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA== /@types/ws/6.0.4: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 dev: false resolution: integrity: sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg== @@ -3461,7 +3440,7 @@ packages: debug: 4.3.1 functional-red-black-tree: 1.0.1 regexpp: 3.1.0 - semver: 7.3.5 + semver: 7.3.4 tsutils: 3.17.1_typescript@4.1.5 typescript: 4.1.5 dev: false @@ -3476,16 +3455,16 @@ packages: optional: true resolution: integrity: sha512-fABclAX2QIEDmTMk6Yd7Muv1CzFLwWM4505nETzRHpP3br6jfahD9UUJkhnJ/g2m7lwfz8IlswcwGGPGiq9exw== - /@typescript-eslint/eslint-plugin/4.11.1_96d27755fc43363abf6361149046cfaa: + /@typescript-eslint/eslint-plugin/4.11.1_beaa369e1546dfa313f6b02e7ef7d59a: dependencies: - '@typescript-eslint/experimental-utils': 4.11.1_eslint@7.22.0+typescript@4.1.5 - '@typescript-eslint/parser': 4.11.1_eslint@7.22.0+typescript@4.1.5 + '@typescript-eslint/experimental-utils': 4.11.1_eslint@7.21.0+typescript@4.1.5 + '@typescript-eslint/parser': 4.11.1_eslint@7.21.0+typescript@4.1.5 '@typescript-eslint/scope-manager': 4.11.1 debug: 4.3.1 - eslint: 7.22.0 + eslint: 7.21.0 functional-red-black-tree: 1.0.1 regexpp: 3.1.0 - semver: 7.3.5 + semver: 7.3.4 tsutils: 3.17.1_typescript@4.1.5 typescript: 4.1.5 dev: false @@ -3509,7 +3488,7 @@ packages: eslint: 6.8.0 functional-red-black-tree: 1.0.1 regexpp: 3.1.0 - semver: 7.3.5 + semver: 7.3.4 tsutils: 3.17.1_typescript@4.1.5 typescript: 4.1.5 dev: false @@ -3524,12 +3503,12 @@ packages: optional: true resolution: integrity: sha512-fABclAX2QIEDmTMk6Yd7Muv1CzFLwWM4505nETzRHpP3br6jfahD9UUJkhnJ/g2m7lwfz8IlswcwGGPGiq9exw== - /@typescript-eslint/experimental-utils/3.10.1_eslint@7.22.0+typescript@4.1.5: + /@typescript-eslint/experimental-utils/3.10.1_eslint@7.21.0+typescript@4.1.5: dependencies: '@types/json-schema': 7.0.7 '@typescript-eslint/types': 3.10.1 '@typescript-eslint/typescript-estree': 3.10.1_typescript@4.1.5 - eslint: 7.22.0 + eslint: 7.21.0 eslint-scope: 5.1.1 eslint-utils: 2.1.0 dev: false @@ -3573,13 +3552,13 @@ packages: typescript: '*' resolution: integrity: sha512-mAlWowT4A6h0TC9F+J5pdbEhjNiEMO+kqPKQ4sc3fVieKL71dEqfkKgtcFVSX3cjSBwYwhImaQ/mXQF0oaI38g== - /@typescript-eslint/experimental-utils/4.11.1_eslint@7.22.0+typescript@4.1.5: + /@typescript-eslint/experimental-utils/4.11.1_eslint@7.21.0+typescript@4.1.5: dependencies: '@types/json-schema': 7.0.7 '@typescript-eslint/scope-manager': 4.11.1 '@typescript-eslint/types': 4.11.1 '@typescript-eslint/typescript-estree': 4.11.1_typescript@4.1.5 - eslint: 7.22.0 + eslint: 7.21.0 eslint-scope: 5.1.1 eslint-utils: 2.1.0 typescript: 4.1.5 @@ -3627,13 +3606,13 @@ packages: optional: true resolution: integrity: sha512-BJ3jwPQu1jeynJ5BrjLuGfK/UJu6uwHxJ/di7sanqmUmxzmyIcd3vz58PMR7wpi8k3iWq2Q11KMYgZbUpRoIPw== - /@typescript-eslint/parser/4.11.1_eslint@7.22.0+typescript@4.1.5: + /@typescript-eslint/parser/4.11.1_eslint@7.21.0+typescript@4.1.5: dependencies: '@typescript-eslint/scope-manager': 4.11.1 '@typescript-eslint/types': 4.11.1 '@typescript-eslint/typescript-estree': 4.11.1_typescript@4.1.5 debug: 4.3.1 - eslint: 7.22.0 + eslint: 7.21.0 typescript: 4.1.5 dev: false engines: @@ -3693,7 +3672,7 @@ packages: glob: 7.1.6 is-glob: 4.0.1 lodash: 4.17.21 - semver: 7.3.5 + semver: 7.3.4 tsutils: 3.17.1_typescript@4.1.5 typescript: 4.1.5 dev: false @@ -3711,10 +3690,10 @@ packages: '@typescript-eslint/types': 4.11.1 '@typescript-eslint/visitor-keys': 4.11.1 debug: 4.3.1 - globby: 11.0.3 + globby: 11.0.2 is-glob: 4.0.1 lodash: 4.17.21 - semver: 7.3.5 + semver: 7.3.4 tsutils: 3.17.1_typescript@4.1.5 typescript: 4.1.5 dev: false @@ -3958,9 +3937,9 @@ packages: date-utils: 1.2.21 jws: 3.2.2 request: 2.88.2 - underscore: 1.12.1 + underscore: 1.12.0 uuid: 3.4.0 - xmldom: 0.5.0 + xmldom: 0.1.31 xpath.js: 1.1.0 dev: false engines: @@ -4056,7 +4035,7 @@ packages: dev: false resolution: integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - /ajv/7.2.3: + /ajv/7.2.1: dependencies: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 @@ -4064,7 +4043,7 @@ packages: uri-js: 4.4.1 dev: false resolution: - integrity: sha512-idv5WZvKVXDqKralOImQgPM9v6WOdLNa0IY3B3doOjw/YxRGT8I+allIJ6kd7Uaj+SF1xZUSU+nPM5aDNBVtnw== + integrity: sha512-+nu0HDv7kNSOua9apAVc979qd932rrZeb3WOvoiD31A/p1mIE5/9bN2027pE2rOPYEdS3UHzsvof4hY+lM9/WQ== /almost-equal/1.1.0: dev: false resolution: @@ -4103,14 +4082,14 @@ packages: node: '>=4' resolution: integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - /ansi-escapes/4.3.2: + /ansi-escapes/4.3.1: dependencies: - type-fest: 0.21.3 + type-fest: 0.11.0 dev: false engines: node: '>=8' resolution: - integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + integrity: sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== /ansi-html/0.0.7: dev: false engines: @@ -4469,7 +4448,7 @@ packages: /autoprefixer/8.6.5: dependencies: browserslist: 3.2.8 - caniuse-lite: 1.0.30001204 + caniuse-lite: 1.0.30001197 normalize-range: 0.1.2 num2fraction: 1.2.2 postcss: 6.0.23 @@ -4481,7 +4460,7 @@ packages: /autoprefixer/9.8.6: dependencies: browserslist: 4.16.3 - caniuse-lite: 1.0.30001204 + caniuse-lite: 1.0.30001197 colorette: 1.2.2 normalize-range: 0.1.2 num2fraction: 1.2.2 @@ -4529,7 +4508,7 @@ packages: multistream: 2.1.1 mysql2: 2.2.5 rimraf: 2.7.1 - sequelize: 6.6.2_mysql2@2.2.5+tedious@9.2.3 + sequelize: 6.5.0_mysql2@2.2.5+tedious@9.2.3 tedious: 9.2.3 tslib: 1.14.1 uri-templates: 0.2.0 @@ -4556,9 +4535,9 @@ packages: /babel-eslint/10.1.0_eslint@6.8.0: dependencies: '@babel/code-frame': 7.12.13 - '@babel/parser': 7.13.12 + '@babel/parser': 7.13.10 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 eslint: 6.8.0 eslint-visitor-keys: 1.3.0 resolve: 1.19.0 @@ -4596,7 +4575,7 @@ packages: '@babel/core': 7.9.0 '@jest/transform': 24.9.0 '@jest/types': 24.9.0 - '@types/babel__core': 7.1.14 + '@types/babel__core': 7.1.12 babel-plugin-istanbul: 5.2.0 babel-preset-jest: 24.9.0_@babel+core@7.9.0 chalk: 2.4.2 @@ -4656,7 +4635,7 @@ packages: integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== /babel-plugin-emotion/10.2.2: dependencies: - '@babel/helper-module-imports': 7.13.12 + '@babel/helper-module-imports': 7.12.13 '@emotion/hash': 0.8.0 '@emotion/memoize': 0.7.4 '@emotion/serialize': 0.11.16 @@ -4686,7 +4665,7 @@ packages: integrity: sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== /babel-plugin-jest-hoist/24.9.0: dependencies: - '@types/babel__traverse': 7.11.1 + '@types/babel__traverse': 7.11.0 dev: false engines: node: '>= 6' @@ -4718,7 +4697,7 @@ packages: integrity: sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw== /babel-plugin-polyfill-corejs2/0.1.10_@babel+core@7.9.0: dependencies: - '@babel/compat-data': 7.13.12 + '@babel/compat-data': 7.13.8 '@babel/core': 7.9.0 '@babel/helper-define-polyfill-provider': 0.1.5_@babel+core@7.9.0 semver: 6.3.0 @@ -4848,7 +4827,7 @@ packages: integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== /backbone/1.4.0: dependencies: - underscore: 1.12.1 + underscore: 1.12.0 dev: false resolution: integrity: sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ== @@ -5143,16 +5122,16 @@ packages: integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== /browserslist/3.2.8: dependencies: - caniuse-lite: 1.0.30001204 - electron-to-chromium: 1.3.699 + caniuse-lite: 1.0.30001197 + electron-to-chromium: 1.3.683 dev: false hasBin: true resolution: integrity: sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== /browserslist/4.11.1: dependencies: - caniuse-lite: 1.0.30001204 - electron-to-chromium: 1.3.699 + caniuse-lite: 1.0.30001197 + electron-to-chromium: 1.3.683 node-releases: 1.1.71 pkg-up: 2.0.0 dev: false @@ -5161,8 +5140,8 @@ packages: integrity: sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g== /browserslist/4.14.2: dependencies: - caniuse-lite: 1.0.30001204 - electron-to-chromium: 1.3.699 + caniuse-lite: 1.0.30001197 + electron-to-chromium: 1.3.683 escalade: 3.1.1 node-releases: 1.1.71 dev: false @@ -5173,9 +5152,9 @@ packages: integrity: sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw== /browserslist/4.16.3: dependencies: - caniuse-lite: 1.0.30001204 + caniuse-lite: 1.0.30001197 colorette: 1.2.2 - electron-to-chromium: 1.3.699 + electron-to-chromium: 1.3.683 escalade: 3.1.1 node-releases: 1.1.71 dev: false @@ -5293,7 +5272,7 @@ packages: dev: false resolution: integrity: sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - /cacache/15.0.6: + /cacache/15.0.5: dependencies: '@npmcli/move-file': 1.1.2 chownr: 2.0.0 @@ -5316,7 +5295,7 @@ packages: engines: node: '>= 10' resolution: - integrity: sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== + integrity: sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== /cache-base/1.0.1: dependencies: collection-visit: 1.0.0 @@ -5460,16 +5439,16 @@ packages: /caniuse-api/3.0.0: dependencies: browserslist: 4.16.3 - caniuse-lite: 1.0.30001204 + caniuse-lite: 1.0.30001197 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 dev: false resolution: integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - /caniuse-lite/1.0.30001204: + /caniuse-lite/1.0.30001197: dev: false resolution: - integrity: sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ== + integrity: sha512-8aE+sqBqtXz4G8g35Eg/XEaFr2N7rd/VQ6eABGBmNtcB8cN6qNJhMi6oSFy4UWWZgqgL3filHT8Nha4meu3tsw== /capture-exit/2.0.0: dependencies: rsvp: 4.8.5 @@ -5494,18 +5473,18 @@ packages: dev: false resolution: integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - /chai-as-promised/7.1.1_chai@4.3.4: + /chai-as-promised/7.1.1_chai@4.3.3: dependencies: - chai: 4.3.4 + chai: 4.3.3 check-error: 1.0.2 dev: false peerDependencies: chai: '>= 2.1.2 < 5' resolution: integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - /chai-jest-snapshot/2.0.0_chai@4.3.4: + /chai-jest-snapshot/2.0.0_chai@4.3.3: dependencies: - chai: 4.3.4 + chai: 4.3.3 jest-snapshot: 21.2.1 lodash.values: 4.3.0 dev: false @@ -5513,9 +5492,9 @@ packages: chai: '>=1.9.0' resolution: integrity: sha512-u8jZZjw/0G1t5A8wDfH6K7DAVfMg3g0dsw9wKQURNUyrZX96VojHNrFMmLirq1m0kOvC5icgL/Qh/fu1MZyvUw== - /chai-spies/1.0.0_chai@4.3.4: + /chai-spies/1.0.0_chai@4.3.3: dependencies: - chai: 4.3.4 + chai: 4.3.3 dev: false engines: node: '>= 4.0.0' @@ -5523,9 +5502,9 @@ packages: chai: '*' resolution: integrity: sha512-elF2ZUczBsFoP07qCfMO/zeggs8pqCf3fZGyK5+2X4AndS8jycZYID91ztD9oQ7d/0tnS963dPkd0frQEThDsg== - /chai-string/1.5.0_chai@4.3.4: + /chai-string/1.5.0_chai@4.3.3: dependencies: - chai: 4.3.4 + chai: 4.3.3 dev: false peerDependencies: chai: ^4.1.2 @@ -5537,7 +5516,7 @@ packages: node: '>=4' resolution: integrity: sha1-pdDKFOMpp5WW7XAFi2ZGvWmIz+k= - /chai/4.3.4: + /chai/4.3.3: dependencies: assertion-error: 1.1.0 check-error: 1.0.2 @@ -5549,7 +5528,7 @@ packages: engines: node: '>=4' resolution: - integrity: sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== + integrity: sha512-MPSLOZwxxnA0DhLE84klnGPojWFK5KuhP7/j5dTsxpr2S3XlkqJP5WbyYl1gCTWvG2Z5N+HD4F472WsbEZL6Pw== /chalk/1.1.3: dependencies: ansi-styles: 2.2.1 @@ -5620,7 +5599,7 @@ packages: css-what: 4.0.0 domelementtype: 2.1.0 domhandler: 4.0.0 - domutils: 2.5.0 + domutils: 2.4.4 deprecated: Use cheerio-select instead dev: false resolution: @@ -5706,7 +5685,7 @@ packages: integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== /chrome-launcher/0.10.7: dependencies: - '@types/node': 12.20.6 + '@types/node': 12.20.5 is-wsl: 1.1.0 lighthouse-logger: 1.2.0 mkdirp: 0.5.1 @@ -6263,7 +6242,7 @@ packages: import-fresh: 3.3.0 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 1.10.2 + yaml: 1.10.0 dev: false engines: node: '>=8' @@ -6275,7 +6254,7 @@ packages: import-fresh: 3.3.0 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 1.10.2 + yaml: 1.10.0 dev: false engines: node: '>=10' @@ -6493,7 +6472,7 @@ packages: boolbase: 1.0.0 css-what: 4.0.0 domhandler: 4.0.0 - domutils: 2.5.0 + domutils: 2.4.4 nth-check: 2.0.0 dev: false resolution: @@ -6949,10 +6928,10 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - /detect-node/2.0.5: + /detect-node/2.0.4: dev: false resolution: - integrity: sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== + integrity: sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== /detect-port-alt/1.1.6: dependencies: address: 1.1.2 @@ -7163,10 +7142,10 @@ packages: node: '>= 4' resolution: integrity: sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA== - /dompurify/2.2.7: + /dompurify/2.2.6: dev: false resolution: - integrity: sha512-jdtDffdGNY+C76jvodNTu9jt5yYj59vuTUyx+wXdzcSwAGTYZDAQkQ7Iwx9zcGrA4ixC1syU4H3RZROqRxokxg== + integrity: sha512-7b7ZArhhH0SP6W2R9cqK6RjaU82FZ2UPM7RO8qN1b1wyvC/NY1FNWcX1Pu00fFOAnzEORtwXe4bPaClg6pUybQ== /domready/1.0.8: dev: false resolution: @@ -7178,14 +7157,14 @@ packages: dev: false resolution: integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - /domutils/2.5.0: + /domutils/2.4.4: dependencies: dom-serializer: 1.2.0 domelementtype: 2.1.0 domhandler: 4.0.0 dev: false resolution: - integrity: sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg== + integrity: sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA== /dot-case/3.0.4: dependencies: no-case: 3.0.4 @@ -7265,14 +7244,14 @@ packages: dev: false resolution: integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - /electron-to-chromium/1.3.699: + /electron-to-chromium/1.3.683: dev: false resolution: - integrity: sha512-fjt43CPXdPYwD9ybmKbNeLwZBmCVdLY2J5fGZub7/eMPuiqQznOGNXv/wurnpXIlE7ScHnvG9Zi+H4/i6uMKmw== - /electron/11.4.1: + integrity: sha512-8mFfiAesXdEdE0DhkMKO7W9U6VU/9T3VTWwZ+4g84/YMP4kgwgFtQgUxuu7FUMcvSeKSNhFQNU+WZ68BQTLT5A== + /electron/11.3.0: dependencies: '@electron/get': 1.12.4 - '@types/node': 12.20.6 + '@types/node': 12.20.5 extract-zip: 1.7.0 dev: false engines: @@ -7280,7 +7259,7 @@ packages: hasBin: true requiresBuild: true resolution: - integrity: sha512-FaH15/yN5vSkKk4mieXemEl1AdQ9P+tsBVsgS+uTVa1agnHDcxMxyoPmtme8NsyLCgobVWHIwNtKD1jSADmzXA== + integrity: sha512-MhdS0gok3wZBTscLBbYrOhLaQybCSAfkupazbK1dMP5c+84eVMxJE/QGohiWQkzs0tVFIJsAHyN19YKPbelNrQ== /elliptic/6.5.4: dependencies: bn.js: 4.12.0 @@ -7420,7 +7399,7 @@ packages: integrity: sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q== /enzyme-to-json/3.6.1_enzyme@3.11.0: dependencies: - '@types/cheerio': 0.22.28 + '@types/cheerio': 0.22.25 enzyme: 3.11.0 lodash: 4.17.21 react-is: 16.13.1 @@ -7616,11 +7595,11 @@ packages: dev: false resolution: integrity: sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== - /eslint-import-resolver-typescript/2.0.0_e8c3ce6c9a72ba40b09aaf06432c8600: + /eslint-import-resolver-typescript/2.0.0_681fcbd990de29f26077fe2d18dfb08a: dependencies: debug: 4.3.1 - eslint: 7.22.0 - eslint-plugin-import: 2.20.1_eslint@7.22.0 + eslint: 7.21.0 + eslint-plugin-import: 2.20.1_eslint@7.21.0 is-glob: 4.0.1 resolve: 1.19.0 tiny-glob: 0.2.8 @@ -7676,10 +7655,10 @@ packages: node: '>=4' resolution: integrity: sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== - /eslint-plugin-deprecation/1.1.0_eslint@7.22.0+typescript@4.1.5: + /eslint-plugin-deprecation/1.1.0_eslint@7.21.0+typescript@4.1.5: dependencies: - '@typescript-eslint/experimental-utils': 3.10.1_eslint@7.22.0+typescript@4.1.5 - eslint: 7.22.0 + '@typescript-eslint/experimental-utils': 3.10.1_eslint@7.21.0+typescript@4.1.5 + eslint: 7.21.0 tslib: 1.14.1 tsutils: 3.17.1_typescript@4.1.5 typescript: 4.1.5 @@ -7755,14 +7734,14 @@ packages: eslint: 2.x - 6.x resolution: integrity: sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw== - /eslint-plugin-import/2.20.1_eslint@7.22.0: + /eslint-plugin-import/2.20.1_eslint@7.21.0: dependencies: array-includes: 3.1.3 array.prototype.flat: 1.2.4 contains-path: 0.1.0 debug: 2.6.9 doctrine: 1.5.0 - eslint: 7.22.0 + eslint: 7.21.0 eslint-import-resolver-node: 0.3.4 eslint-module-utils: 2.6.0 has: 1.0.3 @@ -7794,7 +7773,7 @@ packages: jsdoctypeparser: 9.0.0 lodash: 4.17.21 regextras: 0.7.1 - semver: 7.3.5 + semver: 7.3.4 spdx-expression-parse: 3.0.1 dev: false engines: @@ -7803,15 +7782,15 @@ packages: eslint: ^6.0.0 || ^7.0.0 resolution: integrity: sha512-LlRdsSQBSPsI3MvhWoGc+Ev3PfFRBk41wwkmbOgC7KP7WQlbeWPpASF5Vdv17XEZ7J+xvPB3KCMyR//6Dbjnnw== - /eslint-plugin-jsdoc/30.6.2_eslint@7.22.0: + /eslint-plugin-jsdoc/30.6.2_eslint@7.21.0: dependencies: comment-parser: 0.7.6 debug: 4.3.1 - eslint: 7.22.0 + eslint: 7.21.0 jsdoctypeparser: 9.0.0 lodash: 4.17.21 regextras: 0.7.1 - semver: 7.3.5 + semver: 7.3.4 spdx-expression-parse: 3.0.1 dev: false engines: @@ -7859,7 +7838,7 @@ packages: eslint: ^3 || ^4 || ^5 || ^6 || ^7 resolution: integrity: sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== - /eslint-plugin-jsx-a11y/6.4.1_eslint@7.22.0: + /eslint-plugin-jsx-a11y/6.4.1_eslint@7.21.0: dependencies: '@babel/runtime': 7.13.10 aria-query: 4.2.2 @@ -7869,7 +7848,7 @@ packages: axobject-query: 2.2.0 damerau-levenshtein: 1.0.6 emoji-regex: 9.2.2 - eslint: 7.22.0 + eslint: 7.21.0 has: 1.0.3 jsx-ast-utils: 3.2.0 language-tags: 1.0.5 @@ -7886,9 +7865,9 @@ packages: eslint: '>=2.0.0' resolution: integrity: sha512-epsA4g804mRovlOHSbeO1xxW7REGeUjULRME9MJTJDOVscNIA01AkR66TP4cmHDfD+w72EQ9cPhf37MbZiFI2w== - /eslint-plugin-prefer-arrow/1.1.7_eslint@7.22.0: + /eslint-plugin-prefer-arrow/1.1.7_eslint@7.21.0: dependencies: - eslint: 7.22.0 + eslint: 7.21.0 dev: false peerDependencies: eslint: '>=2.0.0' @@ -7912,9 +7891,9 @@ packages: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 resolution: integrity: sha512-EjxTHxjLKIBWFgDJdhKKzLh5q+vjTFrqNZX36uIxWS4OfyXe5DawqPj3U5qeJ1ngLwatjzQnmR0Lz0J0YH3kxw== - /eslint-plugin-react-hooks/3.0.0_eslint@7.22.0: + /eslint-plugin-react-hooks/3.0.0_eslint@7.21.0: dependencies: - eslint: 7.22.0 + eslint: 7.21.0 dev: false engines: node: '>=7' @@ -7965,11 +7944,11 @@ packages: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 resolution: integrity: sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ== - /eslint-plugin-react/7.19.0_eslint@7.22.0: + /eslint-plugin-react/7.19.0_eslint@7.21.0: dependencies: array-includes: 3.1.3 doctrine: 2.1.0 - eslint: 7.22.0 + eslint: 7.21.0 has: 1.0.3 jsx-ast-utils: 2.4.1 object.entries: 1.1.3 @@ -8078,7 +8057,7 @@ packages: hasBin: true resolution: integrity: sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - /eslint/7.22.0: + /eslint/7.21.0: dependencies: '@babel/code-frame': 7.12.11 '@eslint/eslintrc': 0.4.0 @@ -8097,7 +8076,7 @@ packages: file-entry-cache: 6.0.1 functional-red-black-tree: 1.0.1 glob-parent: 5.1.2 - globals: 13.7.0 + globals: 12.4.0 ignore: 4.0.6 import-fresh: 3.3.0 imurmurhash: 0.1.4 @@ -8111,7 +8090,7 @@ packages: optionator: 0.9.1 progress: 2.0.3 regexpp: 3.1.0 - semver: 7.3.5 + semver: 7.3.4 strip-ansi: 6.0.0 strip-json-comments: 3.1.1 table: 6.0.7 @@ -8122,7 +8101,7 @@ packages: node: ^10.12.0 || >=12.0.0 hasBin: true resolution: - integrity: sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg== + integrity: sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg== /espree/6.2.1: dependencies: acorn: 7.4.1 @@ -8235,14 +8214,14 @@ packages: node: '>=0.8.x' resolution: integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - /eventsource/1.1.0: + /eventsource/1.0.7: dependencies: original: 1.0.2 dev: false engines: node: '>=0.12.0' resolution: - integrity: sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg== + integrity: sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== /evp_bytestokey/1.0.3: dependencies: md5.js: 1.3.5 @@ -8250,10 +8229,10 @@ packages: dev: false resolution: integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - /exec-sh/0.3.6: + /exec-sh/0.3.4: dev: false resolution: - integrity: sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== + integrity: sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== /execa/1.0.0: dependencies: cross-spawn: 6.0.5 @@ -8766,17 +8745,6 @@ packages: node: '>= 0.10' resolution: integrity: sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - /findup-sync/4.0.0: - dependencies: - detect-file: 1.0.0 - is-glob: 4.0.1 - micromatch: 4.0.2 - resolve-dir: 1.0.1 - dev: false - engines: - node: '>= 8' - resolution: - integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== /findup/0.1.5: dependencies: colors: 0.6.2 @@ -8898,7 +8866,7 @@ packages: integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= /fork-ts-checker-webpack-plugin/4.1.6: dependencies: - '@babel/code-frame': 7.10.4 + '@babel/code-frame': 7.12.13 chalk: 2.4.2 micromatch: 3.1.10 minimatch: 3.0.4 @@ -9249,7 +9217,7 @@ packages: es6-error: 4.1.1 matcher: 3.0.0 roarr: 2.15.4 - semver: 7.3.5 + semver: 7.3.4 serialize-error: 7.0.1 dev: false engines: @@ -9331,14 +9299,6 @@ packages: node: '>=8' resolution: integrity: sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - /globals/13.7.0: - dependencies: - type-fest: 0.20.2 - dev: false - engines: - node: '>=8' - resolution: - integrity: sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== /globals/9.18.0: dev: false engines: @@ -9371,7 +9331,7 @@ packages: node: '>=10' resolution: integrity: sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== - /globby/11.0.3: + /globby/11.0.2: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 @@ -9383,7 +9343,7 @@ packages: engines: node: '>=10' resolution: - integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== + integrity: sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og== /globby/6.1.0: dependencies: array-union: 1.0.2 @@ -9411,7 +9371,7 @@ packages: decompress-response: 6.0.0 http2-wrapper: 1.0.3 lowercase-keys: 2.0.0 - p-cancelable: 2.1.0 + p-cancelable: 2.0.0 responselike: 2.0.0 dev: false engines: @@ -9474,7 +9434,7 @@ packages: node: '>=0.4.7' hasBin: true optionalDependencies: - uglify-js: 3.13.2 + uglify-js: 3.13.0 resolution: integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== /har-schema/2.0.0: @@ -9806,7 +9766,7 @@ packages: dependencies: domelementtype: 2.1.0 domhandler: 3.3.0 - domutils: 2.5.0 + domutils: 2.4.4 entities: 2.2.0 dev: false resolution: @@ -9815,7 +9775,7 @@ packages: dependencies: domelementtype: 2.1.0 domhandler: 4.0.0 - domutils: 2.5.0 + domutils: 2.4.4 entities: 2.1.0 dev: false resolution: @@ -9971,12 +9931,12 @@ packages: dev: false resolution: integrity: sha1-kP/Z+bxhfzS5oS4DcmD1JERfdoQ= - /i18next/20.1.0: + /i18next/20.0.0: dependencies: '@babel/runtime': 7.13.10 dev: false resolution: - integrity: sha512-sV+ZwTM4Ik4d6wKdwNS/ocKmvXi6DFA/YHMgdQX3i4L5993jnbo1/j1pK/c4+zBOjexer4dt+c5JHsFj4CUoXQ== + integrity: sha512-PtyZadfdqoJz9MBbjXhMVM8IvG3YAGfUhzAu/JyR/xI35bbrxNVMhVs9jMlgSkzveiTm6KlwD2q9mC9co9Zsew== /iconv-lite/0.4.24: dependencies: safer-buffer: 2.1.2 @@ -10048,6 +10008,10 @@ packages: dev: false resolution: integrity: sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== + /immer/9.0.1: + dev: false + resolution: + integrity: sha512-7CCw1DSgr8kKYXTYOI1qMM/f5qxT5vIVMeGLDCDX8CSxsggr1Sjdoha4OhsP0AZ1UvWbyZlILHvLjaynuu02Mg== /immutable/3.8.2: dev: false engines: @@ -10159,7 +10123,7 @@ packages: integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== /inquirer/7.3.3: dependencies: - ansi-escapes: 4.3.2 + ansi-escapes: 4.3.1 chalk: 4.1.0 cli-cursor: 3.1.0 cli-width: 3.0.0 @@ -10697,12 +10661,6 @@ packages: dev: false resolution: integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - /is-unicode-supported/0.1.0: - dev: false - engines: - node: '>=10' - resolution: - integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== /is-whitespace-character/1.0.4: dev: false resolution: @@ -10812,10 +10770,10 @@ packages: /istanbul-lib-instrument/3.3.0: dependencies: '@babel/generator': 7.13.9 - '@babel/parser': 7.13.12 + '@babel/parser': 7.13.10 '@babel/template': 7.12.13 '@babel/traverse': 7.13.0 - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 istanbul-lib-coverage: 2.0.5 semver: 6.3.0 dev: false @@ -11207,7 +11165,7 @@ packages: integrity: sha512-bpaeBnDpdqaRTzN8tWg0DqOTo2DvD3StOemxn67CUd1p1Po+BUpvePAp44jdJ7Pxcjfg+42o4NHw1SxdCA2rvg== /jest-snapshot/24.9.0: dependencies: - '@babel/types': 7.13.12 + '@babel/types': 7.13.0 '@jest/types': 24.9.0 chalk: 2.4.2 expect: 24.9.0 @@ -11259,7 +11217,7 @@ packages: integrity: sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== /jest-watch-typeahead/0.4.2: dependencies: - ansi-escapes: 4.3.2 + ansi-escapes: 4.3.1 chalk: 2.4.2 jest-regex-util: 24.9.0 jest-watcher: 24.9.0 @@ -11848,7 +11806,7 @@ packages: enquirer: 2.3.6 execa: 4.1.0 listr2: 3.4.3_enquirer@2.3.6 - log-symbols: 4.1.0 + log-symbols: 4.0.0 micromatch: 4.0.2 normalize-path: 3.0.0 please-upgrade-node: 3.2.0 @@ -12070,18 +12028,17 @@ packages: dev: false resolution: integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - /log-symbols/4.1.0: + /log-symbols/4.0.0: dependencies: chalk: 4.1.0 - is-unicode-supported: 0.1.0 dev: false engines: node: '>=10' resolution: - integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + integrity: sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== /log-update/4.0.0: dependencies: - ansi-escapes: 4.3.2 + ansi-escapes: 4.3.1 cli-cursor: 3.1.0 slice-ansi: 4.0.0 wrap-ansi: 6.2.0 @@ -13061,7 +13018,7 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - /node-notifier/5.4.5: + /node-notifier/5.4.3: dependencies: growly: 1.3.0 is-wsl: 1.1.0 @@ -13070,7 +13027,7 @@ packages: which: 1.3.1 dev: false resolution: - integrity: sha512-tVbHs7DyTLtzOiN78izLA85zRqB9NvEXkAf014Vx3jtSvn/xBl6bR8ZYifj+dFcFrKI21huSQgJZ6ZtL3B4HfQ== + integrity: sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== /node-releases/1.1.71: dev: false resolution: @@ -13101,15 +13058,6 @@ packages: hasBin: true resolution: integrity: sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= - /nopt/5.0.0: - dependencies: - abbrev: 1.1.1 - dev: false - engines: - node: '>=6' - hasBin: true - resolution: - integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== /normalize-package-data/2.5.0: dependencies: hosted-git-info: 2.8.8 @@ -13562,7 +13510,7 @@ packages: integrity: sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= /p-any/3.0.0: dependencies: - p-cancelable: 2.1.0 + p-cancelable: 2.0.0 p-some: 5.0.0 dev: false engines: @@ -13575,12 +13523,12 @@ packages: node: '>=6' resolution: integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - /p-cancelable/2.1.0: + /p-cancelable/2.0.0: dev: false engines: node: '>=8' resolution: - integrity: sha512-HAZyB3ZodPo+BDpb4/Iu7Jv4P6cSazBz9ZM0ChhEXp70scx834aWCEjQRwgt41UzzejUAPdbqqONfRWTPYrPAQ== + integrity: sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== /p-defer/1.0.0: dev: false engines: @@ -13686,7 +13634,7 @@ packages: /p-some/5.0.0: dependencies: aggregate-error: 3.1.0 - p-cancelable: 2.1.0 + p-cancelable: 2.0.0 dev: false engines: node: '>=10' @@ -14652,17 +14600,17 @@ packages: node: '>=6.0.0' resolution: integrity: sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== - /postcss-prefix-selector/1.9.0: + /postcss-prefix-selector/1.8.0: dependencies: postcss: 7.0.35 dev: false resolution: - integrity: sha512-tTUHUNP+/Qfgg+fvbljUIeLs1ijICWb8+CT3bZM2joE2pkd+EnuBzSfZNHY2RMmozNRp44yEFv+I+6IIiLcoCg== + integrity: sha512-5r3Oj6bl8FsVR6EWZzM/CWpOaJuQ2HIF7QpDtHNH3KX5BmZhy3skzO7jFlJaFh1O4XdM2H2K4pLa/uwZoluTCQ== /postcss-preset-env/6.7.0: dependencies: autoprefixer: 9.8.6 browserslist: 4.16.3 - caniuse-lite: 1.0.30001204 + caniuse-lite: 1.0.30001197 css-blank-pseudo: 0.1.4 css-has-pseudo: 0.10.0 css-prefers-color-scheme: 3.1.1 @@ -14885,25 +14833,25 @@ packages: dev: false resolution: integrity: sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw== - /posthtml-render/1.3.1: + /posthtml-render/1.4.0: dev: false engines: node: '>=10' resolution: - integrity: sha512-eSToKjNLu0FiF76SSGMHjOFXYzAc/CJqi677Sq6hYvcvFCBtD6de/W5l+0IYPf7ypscqAfjCttxvTdMJt5Gj8Q== + integrity: sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw== /posthtml-svg-mode/1.0.3: dependencies: merge-options: 1.0.1 posthtml: 0.9.2 posthtml-parser: 0.2.1 - posthtml-render: 1.3.1 + posthtml-render: 1.4.0 dev: false resolution: integrity: sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ== /posthtml/0.9.2: dependencies: posthtml-parser: 0.2.1 - posthtml-render: 1.3.1 + posthtml-render: 1.4.0 dev: false engines: node: '>=0.10.0' @@ -14981,7 +14929,7 @@ packages: '@jest/types': 26.6.2 ansi-regex: 5.0.0 ansi-styles: 4.3.0 - react-is: 17.0.2 + react-is: 17.0.1 dev: false engines: node: '>= 10' @@ -15159,14 +15107,6 @@ packages: teleport: '>=0.2.0' resolution: integrity: sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - /qs/6.10.1: - dependencies: - side-channel: 1.0.4 - dev: false - engines: - node: '>=0.6' - resolution: - integrity: sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== /qs/6.5.2: dev: false engines: @@ -15179,6 +15119,12 @@ packages: node: '>=0.6' resolution: integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + /qs/6.9.6: + dev: false + engines: + node: '>=0.6' + resolution: + integrity: sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== /query-string/4.3.4: dependencies: object-assign: 4.1.1 @@ -15204,10 +15150,10 @@ packages: dev: false resolution: integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== - /queue-microtask/1.2.3: + /queue-microtask/1.2.2: dev: false resolution: - integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + integrity: sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg== /quick-lru/5.1.1: dev: false engines: @@ -15338,7 +15284,7 @@ packages: react: '>=16.3.0' resolution: integrity: sha512-/azBHmc6z/31s/lBf6irxPf/7eejQdR0IqnZUzjdSibtlS8+Rw/R79pgDAo6Ft5QqCUTyEQ+f0FhL+1olDQ8OA== - /react-beautiful-dnd/13.1.0_react-dom@16.14.0+react@16.14.0: + /react-beautiful-dnd/13.0.0_react-dom@16.14.0+react@16.14.0: dependencies: '@babel/runtime': 7.13.10 css-box-model: 1.2.1 @@ -15346,15 +15292,15 @@ packages: raf-schd: 4.0.2 react: 16.14.0 react-dom: 16.14.0_react@16.14.0 - react-redux: 7.2.3_bbabd8c34ea235719dc50e75b43f85a4 + react-redux: 7.2.2_bbabd8c34ea235719dc50e75b43f85a4 redux: 4.0.5 use-memo-one: 1.1.2_react@16.14.0 dev: false peerDependencies: - react: ^16.8.5 || ^17.0.0 - react-dom: ^16.8.5 || ^17.0.0 + react: ^16.8.5 + react-dom: ^16.8.5 resolution: - integrity: sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA== + integrity: sha512-87It8sN0ineoC3nBW0SbQuTFXM6bUqM62uJGY4BtTf0yzPl8/3+bHMWkgIe0Z6m8e+gJgjWxefGRVfpE3VcdEg== /react-compound-slider/2.5.0_react@16.14.0: dependencies: '@babel/runtime': 7.13.10 @@ -15488,10 +15434,10 @@ packages: dev: false resolution: integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - /react-is/17.0.2: + /react-is/17.0.1: dev: false resolution: - integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + integrity: sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== /react-lifecycles-compat/3.0.4: dev: false resolution: @@ -15512,10 +15458,9 @@ packages: react: ^15.0.0 || ^16.0.0 resolution: integrity: sha512-HQlWFTbDxTtNY6bjgp3C3uv1h2xcjCSi1zAEzfBW9OwJJvENSYiLXWNXN5hHLsoqai7RnZiiHzcnWdXk2Splzw== - /react-redux/7.2.3_bbabd8c34ea235719dc50e75b43f85a4: + /react-redux/7.2.2_bbabd8c34ea235719dc50e75b43f85a4: dependencies: '@babel/runtime': 7.13.10 - '@types/react-redux': 7.1.16 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 prop-types: 15.7.2 @@ -15535,7 +15480,7 @@ packages: react-native: optional: true resolution: - integrity: sha512-ZhAmQ1lrK+Pyi0ZXNMUZuYxYAZd59wFuVDGUt536kSGdD0ya9Q7BfsE95E3TsFLE3kOSFp5m6G5qbatE+Ic1+w== + integrity: sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA== /react-resize-detector/5.2.0_react-dom@16.14.0+react@16.14.0: dependencies: lodash: 4.17.21 @@ -15904,7 +15849,7 @@ packages: regenerate: 1.4.2 regenerate-unicode-properties: 8.2.0 regjsgen: 0.5.2 - regjsparser: 0.6.9 + regjsparser: 0.6.7 unicode-match-property-ecmascript: 1.0.4 unicode-match-property-value-ecmascript: 1.2.0 dev: false @@ -15938,13 +15883,13 @@ packages: dev: false resolution: integrity: sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== - /regjsparser/0.6.9: + /regjsparser/0.6.7: dependencies: jsesc: 0.5.0 dev: false hasBin: true resolution: - integrity: sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== + integrity: sha512-ib77G0uxsA2ovgiYbCVGx4Pv3PSttAx2vIwidqQzbL2U5S4Q+j00HdSAneSBuyVcMvEnTXMjiGgB+DlXozVhpQ== /relateurl/0.2.7: dev: false engines: @@ -16325,7 +16270,7 @@ packages: /roarr/2.15.4: dependencies: boolean: 3.0.2 - detect-node: 2.0.5 + detect-node: 2.0.4 globalthis: 1.0.2 json-stringify-safe: 5.0.1 semver-compare: 1.0.0 @@ -16357,7 +16302,7 @@ packages: integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== /run-parallel/1.2.0: dependencies: - queue-microtask: 1.2.3 + queue-microtask: 1.2.2 dev: false resolution: integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== @@ -16407,7 +16352,7 @@ packages: '@cnakazawa/watch': 1.0.4 anymatch: 2.0.0 capture-exit: 2.0.0 - exec-sh: 0.3.6 + exec-sh: 0.3.4 execa: 1.0.0 fb-watchman: 2.0.1 micromatch: 3.1.10 @@ -16430,7 +16375,7 @@ packages: neo-async: 2.6.2 sass: 1.32.8 schema-utils: 3.0.0 - semver: 7.3.5 + semver: 7.3.4 webpack: 4.42.0_webpack@4.42.0 dev: false engines: @@ -16596,7 +16541,7 @@ packages: hasBin: true resolution: integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - /semver/7.3.5: + /semver/7.3.4: dependencies: lru-cache: 6.0.0 dev: false @@ -16604,7 +16549,7 @@ packages: node: '>=10' hasBin: true resolution: - integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + integrity: sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== /send/0.17.1: dependencies: debug: 2.6.9 @@ -16639,7 +16584,7 @@ packages: node: '>= 10.0.0' resolution: integrity: sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg== - /sequelize/6.6.2_mysql2@2.2.5+tedious@9.2.3: + /sequelize/6.5.0_mysql2@2.2.5+tedious@9.2.3: dependencies: debug: 4.3.1 dottie: 2.0.2 @@ -16649,7 +16594,7 @@ packages: moment-timezone: 0.5.33 mysql2: 2.2.5 retry-as-promised: 3.2.0 - semver: 7.3.5 + semver: 7.3.4 sequelize-pool: 6.1.0 tedious: 9.2.3 toposort-class: 1.0.1 @@ -16680,7 +16625,7 @@ packages: tedious: optional: true resolution: - integrity: sha512-H/zrzmTK+tis9PJaSigkuXI57nKBvNCtPQol0yxCvau1iWLzSOuq8t3tMOVeQ+Ep8QH2HoD9/+FCCIAqzUr/BQ== + integrity: sha512-owBt8fnzVy8E1OvyCyfCdVk7OOLyPVrBCMEf+CvRReC5oCyo+UqeXCtwaex9L6LM9ifZ1i3TG3sFeM5MgLK0CQ== /serialize-error/7.0.1: dependencies: type-fest: 0.13.1 @@ -16871,16 +16816,16 @@ packages: dev: false resolution: integrity: sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - /sinon-chai/3.6.0_chai@4.3.4+sinon@9.2.4: + /sinon-chai/3.5.0_chai@4.3.3+sinon@9.2.4: dependencies: - chai: 4.3.4 + chai: 4.3.3 sinon: 9.2.4 dev: false peerDependencies: chai: ^4.0.0 - sinon: '>=4.0.0 <11.0.0' + sinon: '>=4.0.0 <10.0.0' resolution: - integrity: sha512-bk2h+0xyKnmvazAnc7HE5esttqmCerSMcBtuB2PS2T4tG6x8woXAxZeJaOJWD+8reXHngnXn0RtIbfEW9OTHFg== + integrity: sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg== /sinon/9.2.4: dependencies: '@sinonjs/commons': 1.8.2 @@ -16974,7 +16919,7 @@ packages: /sockjs-client/1.4.0: dependencies: debug: 3.2.7 - eventsource: 1.1.0 + eventsource: 1.0.7 faye-websocket: 0.11.3 inherits: 2.0.4 json3: 3.3.3 @@ -17103,7 +17048,7 @@ packages: /spdy-transport/3.0.0: dependencies: debug: 4.3.1 - detect-node: 2.0.5 + detect-node: 2.0.4 hpack.js: 2.1.6 obuf: 1.1.2 readable-stream: 3.6.0 @@ -17116,7 +17061,7 @@ packages: /spdy-transport/3.0.0_supports-color@6.1.0: dependencies: debug: 4.3.1_supports-color@6.1.0 - detect-node: 2.0.5 + detect-node: 2.0.4 hpack.js: 2.1.6 obuf: 1.1.2 readable-stream: 3.6.0 @@ -17560,7 +17505,7 @@ packages: formidable: 1.2.2 methods: 1.1.2 mime: 1.6.0 - qs: 6.10.1 + qs: 6.9.6 readable-stream: 2.3.7 dev: false engines: @@ -17577,9 +17522,9 @@ packages: formidable: 1.2.2 methods: 1.1.2 mime: 2.5.2 - qs: 6.10.1 + qs: 6.9.6 readable-stream: 3.6.0 - semver: 7.3.5 + semver: 7.3.4 dev: false engines: node: '>= 7.0.0' @@ -17658,7 +17603,7 @@ packages: merge-options: 1.0.1 micromatch: 3.1.0 postcss: 5.2.18 - postcss-prefix-selector: 1.9.0 + postcss-prefix-selector: 1.8.0 posthtml-rename-id: 1.0.12 posthtml-svg-mode: 1.0.3 query-string: 4.3.4 @@ -17743,7 +17688,7 @@ packages: integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== /table/6.0.7: dependencies: - ajv: 7.2.3 + ajv: 7.2.1 lodash: 4.17.21 slice-ansi: 4.0.0 string-width: 4.2.2 @@ -17808,7 +17753,7 @@ packages: integrity: sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== /tedious/9.2.3: dependencies: - '@azure/ms-rest-nodeauth': 3.0.8 + '@azure/ms-rest-nodeauth': 3.0.7 '@js-joda/core': 3.2.0 adal-node: 0.1.28 bl: 3.0.1 @@ -17851,7 +17796,7 @@ packages: integrity: sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== /terser-webpack-plugin/3.0.7_webpack@4.42.0: dependencies: - cacache: 15.0.6 + cacache: 15.0.5 find-cache-dir: 3.3.1 jest-worker: 26.6.2 p-limit: 3.1.0 @@ -18318,25 +18263,19 @@ packages: node: '>=4' resolution: integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - /type-fest/0.13.1: + /type-fest/0.11.0: dev: false engines: - node: '>=10' - optional: true - resolution: - integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - /type-fest/0.20.2: - dev: false - engines: - node: '>=10' + node: '>=8' resolution: - integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - /type-fest/0.21.3: + integrity: sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + /type-fest/0.13.1: dev: false engines: node: '>=10' + optional: true resolution: - integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== /type-fest/0.8.1: dev: false engines: @@ -18375,7 +18314,7 @@ packages: backbone: 1.4.0 jquery: 3.6.0 lunr: 2.3.9 - underscore: 1.12.1 + underscore: 1.12.0 dev: false engines: node: '>= 8' @@ -18384,7 +18323,7 @@ packages: /typedoc-plugin-external-module-name/3.0.0_typedoc@0.16.11: dependencies: lodash: 4.17.21 - semver: 7.3.5 + semver: 7.3.4 typedoc: 0.16.11 dev: false peerDependencies: @@ -18465,14 +18404,14 @@ packages: dev: false resolution: integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - /uglify-js/3.13.2: + /uglify-js/3.13.0: dev: false engines: node: '>=0.8.0' hasBin: true optional: true resolution: - integrity: sha512-SbMu4D2Vo95LMC/MetNaso1194M1htEA+JrqE9Hk+G2DhI+itfS9TRu9ZKeCahLDNa/J3n4MqUJ/fOHMzQpRWw== + integrity: sha512-TWYSWa9T2pPN4DIJYbU9oAjQx+5qdV5RUDxwARg8fmJZrD/V27Zj0JngW5xg1DFz42G0uDYl2XhzF6alSzD62w== /uglify-js/3.4.10: dependencies: commander: 2.19.0 @@ -18513,10 +18452,10 @@ packages: dev: false resolution: integrity: sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== - /underscore/1.12.1: + /underscore/1.12.0: dev: false resolution: - integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== + integrity: sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ== /underscore/1.7.0: dev: false resolution: @@ -19575,6 +19514,13 @@ packages: dev: false resolution: integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + /xmldom/0.1.31: + deprecated: Deprecated due to CVE-2021-21366 resolved in 0.5.0 + dev: false + engines: + node: '>=0.1' + resolution: + integrity: sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== /xmldom/0.5.0: dev: false engines: @@ -19633,12 +19579,12 @@ packages: dev: false resolution: integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - /yaml/1.10.2: + /yaml/1.10.0: dev: false engines: node: '>= 6' resolution: - integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + integrity: sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== /yargonaut/1.1.4: dependencies: chalk: 1.1.3 @@ -19669,12 +19615,12 @@ packages: node: '>=6' resolution: integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - /yargs-parser/20.2.7: + /yargs-parser/20.2.6: dev: false engines: node: '>=10' resolution: - integrity: sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + integrity: sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA== /yargs/13.3.2: dependencies: cliui: 5.0.0 @@ -19716,7 +19662,7 @@ packages: require-directory: 2.1.1 string-width: 4.2.2 y18n: 5.0.5 - yargs-parser: 20.2.7 + yargs-parser: 20.2.6 dev: false engines: node: '>=10' @@ -19759,18 +19705,19 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/semver': 5.5.0 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 semver: 5.7.1 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/analytical-backend' resolution: - integrity: sha512-AZ+HdApRhvlTFYG1AaThqVrKaTGszL2j6b14M/XKcU2rbnigAAtIQ9tpoj8fxmWEbPnLIGBgCzoP/bvAOPAYug== + integrity: sha512-JYKF3hP2dQkVEG7Ck6b6ss1bZf86PNrbsqC+1wyHNYbbWPa7lfoAQ9L97LiIVkJym6ZaoILsRWEPGxiGZ1qiXQ== tarball: 'file:projects/analytical-backend.tgz' version: 0.0.0 'file:projects/backend-application-insights-client.tgz': @@ -19779,7 +19726,7 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 applicationinsights: 1.8.10 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -19790,7 +19737,7 @@ packages: dev: false name: '@rush-temp/backend-application-insights-client' resolution: - integrity: sha512-bfiaBryqKcwM0y4Lo1vM75S+v6Vp63OXvyrdQzNFtWg7Dh3ZFBZOn9i7rwJNQVH6lT4DAMPfSXPFI2Lo1Ic+rQ== + integrity: sha512-0qfV+XYeOUzLb+oFS7tQrXd6QeJi7aEz3pfHpX8TZ9PmRYKkDW37jHnKXlOkixX/Aij0Pv+ylJTyWsVGR0xZ7w== tarball: 'file:projects/backend-application-insights-client.tgz' version: 0.0.0 'file:projects/backend-itwin-client.tgz': @@ -19800,7 +19747,7 @@ packages: '@types/deep-assign': 0.1.1 '@types/fs-extra': 4.0.11 '@types/js-base64': 2.3.2 - '@types/jsonwebtoken': 8.5.1 + '@types/jsonwebtoken': 8.5.0 '@types/mocha': 5.2.7 '@types/nock': 11.1.0 '@types/node': 10.14.1 @@ -19808,7 +19755,7 @@ packages: '@types/sinon': 9.0.11 '@types/stream-buffers': 3.0.3 applicationinsights: 1.8.10 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 deep-assign: 2.0.0 eslint: 6.8.0 @@ -19827,11 +19774,12 @@ packages: sinon: 9.2.4 source-map-support: 0.5.19 stream-buffers: 3.0.2 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/backend-itwin-client' resolution: - integrity: sha512-TnW8tMq8Id7SuhSjAG+Ncbe85Qtiz7qNlfMfsk+SjQjlGQVDpmcq376CIpN/tD4PwMnyoQ/AyoI4jCJNzsxZww== + integrity: sha512-9fwwO2fKGhZVBJYaQ0jJ0heToOSBsLUXvsbKQqOInaTuj7J0G6axql3wlKNNIIMLRu0xDPsF5Lca0d8IBozEmQ== tarball: 'file:projects/backend-itwin-client.tgz' version: 0.0.0 'file:projects/backend-webpack-tools.tgz': @@ -19852,7 +19800,7 @@ packages: dev: false name: '@rush-temp/backend-webpack-tools' resolution: - integrity: sha512-JMX3JHjs9qWxAh83ZK8+sIOzNhVzUbFYDPhQnk4B7C6bnIFNJJ+6TP+bHMdR802nssUADGfE8LHRfmVfUZtB9A== + integrity: sha512-GWvEb9AQh3CVe06Lq5daHGhw0lbZrCoDfKgo62Quzf8lQUaCSNLH2+Q5AiGCxKEwBTPO2BlQOvnHqyI8yBj3QA== tarball: 'file:projects/backend-webpack-tools.tgz' version: 0.0.0 'file:projects/bentleyjs-core.tgz': @@ -19861,24 +19809,25 @@ packages: '@types/chai-as-promised': 7.1.3 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/bentleyjs-core' resolution: - integrity: sha512-G354ZZzX/ffhfBlE4afGLpUbo7GAgY903GT5KY0g92T86pLaBmWsOxTZktQ3HY7WBaNrzlpHbfXDO0jUeSCbQQ== + integrity: sha512-d8unhxOM56m+W42p+xGs3iCQV96dJVtO3/K24rOgQWlymrewLst+S0i5/0nCZltfVNepVuFZeO93scZXGW/wnA== tarball: 'file:projects/bentleyjs-core.tgz' version: 0.0.0 'file:projects/build-tools.tgz': dependencies: '@microsoft/api-extractor': 7.7.3 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 chalk: 3.0.0 cpx: 1.5.0 cross-spawn: 7.0.3 @@ -19907,7 +19856,7 @@ packages: dev: false name: '@rush-temp/build-tools' resolution: - integrity: sha512-PZr3Qx6HF5PkQNaCjrEE3zGM2Io/b3QtxDerbbfO4/gVrYxcNrblA6OYmcfGek2tgZMc+E8G4ZL5f+PuF75zhw== + integrity: sha512-dYKZxERXrnTxxAaSCXh2SzM+mYIRNGOopGECjxcvwhGPqtclcLxmuHAfpofkNJfsRLNLdiKbwC9O4oIUKfp8jQ== tarball: 'file:projects/build-tools.tgz' version: 0.0.0 'file:projects/certa.tgz': @@ -19922,7 +19871,7 @@ packages: '@types/uuid': 7.0.4 '@types/yargs': 12.0.19 detect-port: 1.3.0 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 express: 4.17.1 jsonc-parser: 2.0.3 @@ -19938,7 +19887,7 @@ packages: dev: false name: '@rush-temp/certa' resolution: - integrity: sha512-BJz/ppn5QStlm8yV8cu3DXhlwsgERaCY7S+05QsGSTTvk1ccJabP2+4OTnG9bWV8He6yacwjHzyk6N5jqEj/LA== + integrity: sha512-9aDR2Tc/7oVROojvU8rXMqAXSvKK08kSUtggJtAXieHT76mJM2IUhsjMSbldXmGHnVjJrrJmuo5jxzPiA8xQ3g== tarball: 'file:projects/certa.tgz' version: 0.0.0 'file:projects/config-loader.tgz': @@ -19955,7 +19904,7 @@ packages: dev: false name: '@rush-temp/config-loader' resolution: - integrity: sha512-spfRT6tal19HJ0nhqJ/hwFsAyZCudnG44ZUhqwa307yA2EoZZs6O5D8twvz6IorENqXU+rfm033zLIEYNi1kwg== + integrity: sha512-pSS+5YUd/xUuFk/lrwWJH2ufxSbEeAXJ41qoeMbEZUa3WBaGk1wVDTmsEtDpo+ZkbyxHcoMO7HTVwSeOSeKF/w== tarball: 'file:projects/config-loader.tgz' version: 0.0.0 'file:projects/context-registry-client.tgz': @@ -19964,7 +19913,7 @@ packages: '@types/deep-assign': 0.1.1 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 deep-assign: 2.0.0 eslint: 6.8.0 mocha: 5.2.0 @@ -19976,7 +19925,7 @@ packages: dev: false name: '@rush-temp/context-registry-client' resolution: - integrity: sha512-aC3cjYMZKjj24mtJSxE9wV8Weup674qSJAAwT8v4Ee6+1KtyXnKnAq9tWSvV+08jDYVngYvwfz/p7fAhSISpTg== + integrity: sha512-Lvf+Hy3O+aonQx8Ry9u8jiLZNkPbUIKIK61OvOIThdvbflPReadXaHjR265qSav7PwSFDbYb39y30qzWyB//Qw== tarball: 'file:projects/context-registry-client.tgz' version: 0.0.0 'file:projects/core-full-stack-tests.tgz': @@ -19987,9 +19936,9 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/serve-handler': 6.1.0 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - electron: 11.4.1 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + electron: 11.3.0 eslint: 6.8.0 fs-extra: 8.1.0 glob: 7.1.6 @@ -20005,7 +19954,7 @@ packages: dev: false name: '@rush-temp/core-full-stack-tests' resolution: - integrity: sha512-gzRq3ABgmdgsDeFppty2iGpeS7hduA4N0kUNToCdDznDZEl0mCtK4u+OofSUHTiR/mu10jYjI3luzX+FRC902A== + integrity: sha512-SEyHKq9SUnD1pwBw+uLsh/bTX8bDNIvau9rlCiEQngsd5ZegDB+lUagQ9cEQ6lsakqSly71jg9bAAOKpcMR7Qw== tarball: 'file:projects/core-full-stack-tests.tgz' version: 0.0.0 'file:projects/display-performance-test-app.tgz_sass@1.32.8+webpack-cli@3.3.12': @@ -20019,7 +19968,7 @@ packages: chrome-launcher: 0.10.7 cpx: 1.5.0 cross-env: 5.2.1 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 express: 4.17.1 npm-run-all: 4.1.5 @@ -20035,13 +19984,13 @@ packages: sass: '*' webpack-cli: '*' resolution: - integrity: sha512-uPDWiSomBPV6h9URdY3n0WAmBJOip6A4mKixdlF8qKsMyXGneJNAnMvsP58dwBOEP6fGZuHN8DENBtKhkNl6lg== + integrity: sha512-2Jyyz0Q52tv6SoSWasCLSs2Sm9j13FIKwS40XoZmJmcArUJgcwZJigaXtp/pmnghbztqZBpwqS8iC52tWcQvCg== tarball: 'file:projects/display-performance-test-app.tgz' version: 0.0.0 'file:projects/display-test-app.tgz_webpack-cli@3.3.12': dependencies: - '@bentley/icons-generic': 1.0.34 - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic': 1.0.33 + '@bentley/icons-generic-webfont': 1.0.33 '@bentley/react-scripts': 3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32 '@types/body-parser': 1.19.0 '@types/express': 4.17.11 @@ -20051,7 +20000,7 @@ packages: child_process: 1.0.2 cpx: 1.5.0 cross-env: 5.2.1 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 express: 4.17.1 fs-extra: 8.1.0 @@ -20069,7 +20018,7 @@ packages: peerDependencies: webpack-cli: '*' resolution: - integrity: sha512-lHU4QgL80YUnBrVDIKOTKvHHiYacgfx5/IkuwRfgPUIVU6y0xnLWk3O328A+aFPsryLOt6ucQJs7zrWZAuUGvA== + integrity: sha512-F+PmyJfzI64W9+Q0/aWrrWkDZFs+cqIGZPPEz+Uucj2Kcej+qN6ZgoYp8UO5o+y+FJol0m+KCikDrRkOoOfpbw== tarball: 'file:projects/display-test-app.tgz' version: 0.0.0 'file:projects/ecschema-locaters.tgz': @@ -20081,19 +20030,20 @@ packages: '@types/node': 10.14.1 '@types/sinon': 9.0.11 '@types/xmldom': 0.1.30 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 eslint: 6.8.0 glob: 7.1.6 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 + ts-node: 7.0.1 typescript: 4.1.5 xmldom: 0.5.0 dev: false name: '@rush-temp/ecschema-locaters' resolution: - integrity: sha512-3lKdUOaNdJZaHgTUXCouq2qe/IIsTnsw+2XjauhhhP1h5ZO5FVESeAHOARC8un2Pnt79bwM0TQ2yiiHTF8eZbg== + integrity: sha512-sm0CiWYR8m+zH2ZC743MK2dVLOqMy+tWf/PSI0TJ+56er626uzVX5zuK6cwl++BVuLI4jnpSi0GKclNuiRlgbQ== tarball: 'file:projects/ecschema-locaters.tgz' version: 0.0.0 'file:projects/ecschema-metadata.tgz': @@ -20110,21 +20060,22 @@ packages: '@types/xmldom': 0.1.30 almost-equal: 1.1.0 benchmark: 2.1.4 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 eslint: 6.8.0 i18next-node-fs-backend: 2.1.3 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 sinon: 9.2.4 + ts-node: 7.0.1 typescript: 4.1.5 xmldom: 0.5.0 xmlhttprequest: 1.8.0 dev: false name: '@rush-temp/ecschema-metadata' resolution: - integrity: sha512-Dte6cjTDZc5yIxXodN6ij2NQNm7MR+82f3mau/6+5O1bLM8FYlgFjmhGtQHs+ZW5xogvkoP3SaBi9W+haUoEvg== + integrity: sha512-UARX6cX+CGIQxR0HY4JYpFu7FL1Ab1XDZtjZQzjHdWg4y66e3drpp9SrLCdSiIgtbEQEs6a18ciqcafdWpYgpA== tarball: 'file:projects/ecschema-metadata.tgz' version: 0.0.0 'file:projects/ecschema2ts.tgz': @@ -20135,8 +20086,8 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/xmldom': 0.1.30 - chai: 4.3.4 - chai-string: 1.5.0_chai@4.3.4 + chai: 4.3.3 + chai-string: 1.5.0_chai@4.3.3 chalk: 3.0.0 commander: 2.20.3 cpx: 1.5.0 @@ -20146,19 +20097,20 @@ packages: nyc: 14.1.1 rimraf: 3.0.2 source-map-support: 0.5.19 + ts-node: 7.0.1 typescript: 4.1.5 xmldom: 0.5.0 dev: false name: '@rush-temp/ecschema2ts' resolution: - integrity: sha512-wFuGZbaJShnGvuqQYU6a7/2wUEzs923VvPMSavW5dkLygaYRp8ikLBEPvTlm186pzz9Jivo51GGahnoGhsXauQ== + integrity: sha512-0I3obMNG9WRjABNUU/56k+I6Pup27b0FI23NQ8M+a53/QQhomaymtuhifv/khpV+Yjn4UZSx9heUW4aUizTNRw== tarball: 'file:projects/ecschema2ts.tgz' version: 0.0.0 'file:projects/electron-manager.tgz_debug@2.6.9': dependencies: '@openid/appauth': 1.3.0_debug@2.6.9 '@types/node': 10.14.1 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 open: 7.4.2 rimraf: 3.0.2 @@ -20170,24 +20122,24 @@ packages: peerDependencies: debug: '*' resolution: - integrity: sha512-w/CqYYTTTP0JdP7Rr4F1m2kHApN8me6qZmf5ZkKIpfTbBoENs9lKoTZVLX5hGmxMteX7dQRYls3cl7HtDzjTmw== + integrity: sha512-xc25oHQH5BDVipWd8qtBaqNZmFGKP8kZUPXJzpPOXknfTpncToyRCCg5iCyzGM3G62qvz5SWuMiLZdR3bAPz+w== tarball: 'file:projects/electron-manager.tgz' version: 0.0.0 'file:projects/eslint-plugin.tgz': dependencies: - '@typescript-eslint/eslint-plugin': 4.11.1_96d27755fc43363abf6361149046cfaa - '@typescript-eslint/parser': 4.11.1_eslint@7.22.0+typescript@4.1.5 - eslint: 7.22.0 + '@typescript-eslint/eslint-plugin': 4.11.1_beaa369e1546dfa313f6b02e7ef7d59a + '@typescript-eslint/parser': 4.11.1_eslint@7.21.0+typescript@4.1.5 + eslint: 7.21.0 eslint-import-resolver-node: 0.3.4 - eslint-import-resolver-typescript: 2.0.0_e8c3ce6c9a72ba40b09aaf06432c8600 - eslint-plugin-deprecation: 1.1.0_eslint@7.22.0+typescript@4.1.5 - eslint-plugin-import: 2.20.1_eslint@7.22.0 + eslint-import-resolver-typescript: 2.0.0_681fcbd990de29f26077fe2d18dfb08a + eslint-plugin-deprecation: 1.1.0_eslint@7.21.0+typescript@4.1.5 + eslint-plugin-import: 2.20.1_eslint@7.21.0 eslint-plugin-jam3: 0.2.3 - eslint-plugin-jsdoc: 30.6.2_eslint@7.22.0 - eslint-plugin-jsx-a11y: 6.4.1_eslint@7.22.0 - eslint-plugin-prefer-arrow: 1.1.7_eslint@7.22.0 - eslint-plugin-react: 7.19.0_eslint@7.22.0 - eslint-plugin-react-hooks: 3.0.0_eslint@7.22.0 + eslint-plugin-jsdoc: 30.6.2_eslint@7.21.0 + eslint-plugin-jsx-a11y: 6.4.1_eslint@7.21.0 + eslint-plugin-prefer-arrow: 1.1.7_eslint@7.21.0 + eslint-plugin-react: 7.19.0_eslint@7.21.0 + eslint-plugin-react-hooks: 3.0.0_eslint@7.21.0 require-dir: 1.2.0 typescript: 4.1.5 dev: false @@ -20208,9 +20160,9 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 body-parser: 1.19.0 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 express: 4.17.1 fs-extra: 8.1.0 @@ -20228,7 +20180,7 @@ packages: dev: false name: '@rush-temp/example-code-app' resolution: - integrity: sha512-AlMe5i0L3lYggtI8R8xyTcjEyE99woLOf4JzPLQx/RvLZVtLxkLwtMZnOuEQCu1pO5Y3UotJVRfn+S7CWsR3UQ== + integrity: sha512-m51a+ltCJcTFYGDdrsUHDkhktziOOlYa/37MVY9a15SIcbRqjyLGnrPFmpCj/dqWo2bJvmjG4/0t2KCtwWHVDw== tarball: 'file:projects/example-code-app.tgz' version: 0.0.0 'file:projects/example-code-snippets.tgz': @@ -20243,9 +20195,9 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 body-parser: 1.19.0 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 express: 4.17.1 fs-extra: 8.1.0 @@ -20262,7 +20214,7 @@ packages: dev: false name: '@rush-temp/example-code-snippets' resolution: - integrity: sha512-naYm9G2lRjoqe0SEE8fWQqlM2+XeYAIokUgyU3gWkRPeQBxL4WzHfLMLE4TfPLjX4N3U5+RxM6iumc7hupAnzQ== + integrity: sha512-z8opgyUqisr6XA1pNh/CWBXy1KqoV8eWuw6Cc0et0A30ALtSKcU8mNTdbqKFfjPqA9mwUzjzQXhSseLBdm0d3g== tarball: 'file:projects/example-code-snippets.tgz' version: 0.0.0 'file:projects/export-gltf.tgz': @@ -20276,7 +20228,7 @@ packages: dev: false name: '@rush-temp/export-gltf' resolution: - integrity: sha512-AF9lDC0DRQ7Lscl6DTxr7vYpFzXSv588I9Zyct8yRYbHQYO/TSwijhJpc4d11xQ5oCwxA78PCLLTari0gZNmeg== + integrity: sha512-+NFtnjVSyfMDE7IQXN5TyEDMiZf8TIxvdJEMgaMRYEEdfNBBC6WwGZX7PKlqBq4L74NY063teNq6y5eW+pq1yw== tarball: 'file:projects/export-gltf.tgz' version: 0.0.0 'file:projects/export-obj.tgz': @@ -20290,7 +20242,7 @@ packages: dev: false name: '@rush-temp/export-obj' resolution: - integrity: sha512-jhLEM9COIQS72uokbNlzoKeMzUa+dD09XtDcrovqISS1bMsGyQLI1eFc8/dLY+qAuuaPtFerR1GfLCZgj4KcrQ== + integrity: sha512-fTuPk5b35sePTPWpAkx4ZbBQQWWBRp4zuEjoPlSStBdV+CcNx2JGR3T93j70QldFMOfvlnkkVzl3B9D/7p5c4A== tarball: 'file:projects/export-obj.tgz' version: 0.0.0 'file:projects/express-server.tgz': @@ -20302,7 +20254,7 @@ packages: '@types/node': 10.14.1 '@types/sinon': 9.0.11 '@types/supertest': 2.0.10 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 express: 4.17.1 mocha: 5.2.0 @@ -20315,7 +20267,7 @@ packages: dev: false name: '@rush-temp/express-server' resolution: - integrity: sha512-IFKVKRtATZCv5rfe80XdJVETE+ERfMNS1xeVS8HyqXxcwK0Xi474KL+onAY6cs10J7TnffMGFTVuzAFAbKFDjA== + integrity: sha512-y05y3LTFTZ0g7sflnUFK97V904DlKdcTEvYKWtLPC+F+GenS2Ofg5WQdH6rgrVYYpq8Jw1iB11ZYihDXN+6sGg== tarball: 'file:projects/express-server.tgz' version: 0.0.0 'file:projects/extension-cli.tgz': @@ -20327,8 +20279,8 @@ packages: '@types/semver': 5.5.0 '@types/tar': 4.0.4 '@types/yargs': 12.0.19 - chai: 4.3.4 - electron: 11.4.1 + chai: 4.3.3 + electron: 11.3.0 eslint: 6.8.0 fast-sha256: 1.3.0 mocha: 5.2.0 @@ -20340,7 +20292,7 @@ packages: dev: false name: '@rush-temp/extension-cli' resolution: - integrity: sha512-Avb2HvF+/KEAOZddbaX5wM52WQHN31skw6iWu4pmA/cHEoMAh+IoI8gVv0yTwl18K+6Vtnf8N7D1+tWuCO0l5w== + integrity: sha512-ilufAR0fYF3X2W9hi7XV1FHr+oJrfmcExewfkAlYCUPzQ20hAZcpFABY5cCRAHX8gXj8i2UANuyd5ndvKuIYUg== tarball: 'file:projects/extension-cli.tgz' version: 0.0.0 'file:projects/extension-client.tgz': @@ -20348,7 +20300,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -20359,7 +20311,7 @@ packages: dev: false name: '@rush-temp/extension-client' resolution: - integrity: sha512-sqOZQQYNlGzAiELS0gmgsPLTqLjtRSTPpOpBfONEIXUSxad1azPWrKDbzzBUI44gyZjiSEoTs6sV7SLbmQo4Uw== + integrity: sha512-RrVUHX2FS7ENhZ0T3V8fNqc3nLwHHcDt1cGC6ElsGmsKHt/REkI8n6CVgdo59aXSW8w1WjP+njWjqUleOW41lg== tarball: 'file:projects/extension-client.tgz' version: 0.0.0 'file:projects/extension-webpack-tools.tgz': @@ -20405,16 +20357,16 @@ packages: dev: false name: '@rush-temp/extension-webpack-tools' resolution: - integrity: sha512-H2XQrEaIJA6NITpyQY0Qo+2BSre2mG227w1gwd649rWiVEH7TJwmk8KsfUR/Ca0vGUrsgmJZHRFJsocLHpi/8A== + integrity: sha512-xqf0bNShi3E+17Uig5fiig5JBiFtcBODBZW/N22XgXZjiwx5kx+cZey5YgZTbI8PWuaeJMCJPP2+4hMVSxVLxA== tarball: 'file:projects/extension-webpack-tools.tgz' version: 0.0.0 'file:projects/frontend-application-insights-client.tgz': dependencies: - '@microsoft/applicationinsights-web': 2.6.0 + '@microsoft/applicationinsights-web': 2.5.11 '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -20425,7 +20377,7 @@ packages: dev: false name: '@rush-temp/frontend-application-insights-client' resolution: - integrity: sha512-kVEsmb9d0pIpp8hSJjCLyoy23lRQJJ1yk1hkA6mpZzCfO8I6SZ/e2XhK/R6H5blPGAQXRWNQPeFJraV7JUrvUg== + integrity: sha512-dPcvoY7bXNm6QUIGmn7MG6s0eaKyzfKAPJqYUQeK3wdQ+x/OIQ1A4VneeUFOFgmkm4RVJhMUyClbGJNuafdljg== tarball: 'file:projects/frontend-application-insights-client.tgz' version: 0.0.0 'file:projects/frontend-authorization-client.tgz': @@ -20438,7 +20390,7 @@ packages: dev: false name: '@rush-temp/frontend-authorization-client' resolution: - integrity: sha512-gvD7rP7L/tr6LXuv242jD61zIFY6uR2LLo62OVgok9Jg+HaaXuFVr9CayfdKz9mxJOpCCzq7klfy+X1aL9H1hg== + integrity: sha512-9pMwjFLazfSAYQo4e6vbMHlB4y5p0W9l6caXp7YEv42rXJNHeL4Kkf3d4lygqrczzmNnow3dBf00zA43pLupoQ== tarball: 'file:projects/frontend-authorization-client.tgz' version: 0.0.0 'file:projects/frontend-devtools.tgz': @@ -20453,7 +20405,7 @@ packages: dev: false name: '@rush-temp/frontend-devtools' resolution: - integrity: sha512-v3lpcrA9U6Wm641kRW9G+hPylqzyClMvo6x3sBInbEMsOEK9Bk+NrxNl3yZDWpdnWggWp1OlecwJAIY26DJohg== + integrity: sha512-OPn6f+y14stq3sG7sc3vBHv4W+kdSYfLqTlDIWZCXjhF9o12FSwuSrlfkJdxs6xjfRWt6BhJQKFELNZUulpooA== tarball: 'file:projects/frontend-devtools.tgz' version: 0.0.0 'file:projects/geometry-core.tgz': @@ -20462,7 +20414,7 @@ packages: '@types/flatbuffers': 1.10.0 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 debug: 2.6.9 eslint: 6.8.0 flatbuffers: 1.12.0 @@ -20470,11 +20422,12 @@ packages: nyc: 14.1.1 rimraf: 3.0.2 semver: 5.7.1 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/geometry-core' resolution: - integrity: sha512-lrgDLwLfNJSXOUAk+1piK+B6bOEesGvOBMOU7Sb8U7RDAmKZJvKOgRY/HAU7b1mGIeVvKk/nXkbGWxooTaPE7g== + integrity: sha512-0rf4dGs30CkhZcem8yQRmayyiBSk+xm3/8ezForTwMQJnaALOHCFy+kMpjLrtYxPI5TNKuDdDcsC4YYD2x5kBQ== tarball: 'file:projects/geometry-core.tgz' version: 0.0.0 'file:projects/geonames-extension.tgz_webpack@4.42.0': @@ -20491,7 +20444,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-Upzni1XTjOaoIKF4Up15xpw/+NPVhAQaFI4wIfb2mv02g82zdz9IpQMw0sHnEXZym543KFJgHrgX5Z/scp/dZQ== + integrity: sha512-/5AjYzf2asfIsRWbxeESY9GF8N/LFIFqN18CA8zGevBdQfUWWXtf6+629+dVG8thv+IjVOSwyXAl7nlRvIjYHQ== tarball: 'file:projects/geonames-extension.tgz' version: 0.0.0 'file:projects/hypermodeling-frontend.tgz': @@ -20499,7 +20452,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 eslint: 6.8.0 glob: 7.1.6 @@ -20512,7 +20465,7 @@ packages: dev: false name: '@rush-temp/hypermodeling-frontend' resolution: - integrity: sha512-fewmwWeEKyWUy7RPp/cM5USHw+NACL4MxuqPO6bdEVdt2dbDcBa4XnUxqBzIguGZnsX7+jMyrC9hcTMCvv3OXw== + integrity: sha512-9C8WKQcG18whaR5N8FMZMAY3BQXqFAkkjyItVo1yC0WZWzho+v+XoTy0Y7t5BHSHka7bBmTzayqkAOnkbWmd2w== tarball: 'file:projects/hypermodeling-frontend.tgz' version: 0.0.0 'file:projects/imjs-importer.tgz': @@ -20521,7 +20474,7 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/yargs': 12.0.19 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 rimraf: 3.0.2 @@ -20530,7 +20483,7 @@ packages: dev: false name: '@rush-temp/imjs-importer' resolution: - integrity: sha512-76vQ3+VAqAHOl98DDiX8SYoKx0x3LS+B2s9PTo9JC83JTsKSh7av3/e9lbVnclc5BgsEZK7pKKLlzYgcYHObKw== + integrity: sha512-1wuhx1Sv9iqUqxOaJ2YlEN2XK7daaskLNa9NYHr8fhoBWr0AHSKrXfLRWceoY2rA6Vmj+msHDk4Tdf6NRzws+A== tarball: 'file:projects/imjs-importer.tgz' version: 0.0.0 'file:projects/imodel-bridge.tgz': @@ -20539,7 +20492,7 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/object-hash': 1.3.4 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 eslint: 6.8.0 mocha: 5.2.0 @@ -20550,7 +20503,7 @@ packages: dev: false name: '@rush-temp/imodel-bridge' resolution: - integrity: sha512-qlE0RTROFqRqLfLLG0S1lHTY/OH6DEBLPpTaMLdphS0wNNVXBolQWsSJlzpNaprk7j3+oY5XoHrLCHl2oosaLQ== + integrity: sha512-Ju1EMwZQe/NJ8K9Ee4SXx68KjGNLG7HGW2YbJpHNPCgj/IfYBxmVQQYgwg819cnV64YMJ9FfMrlYKAOuoonRwQ== tarball: 'file:projects/imodel-bridge.tgz' version: 0.0.0 'file:projects/imodel-from-geojson.tgz_request@2.88.2': @@ -20572,7 +20525,7 @@ packages: peerDependencies: request: '*' resolution: - integrity: sha512-lUi4kfgdbZD61rfhtxGjSLMlvz0fpnaH5pY+ZlKsHITV5uDL4Ib43PnWxJHqlGfdHxLdeebt3JxZso+5jEfm3A== + integrity: sha512-RWHXoXZmP1qUPW4rNdW/xvNsrGsy018ayWll7Ve4Lr9JS1B8Hspo6oFVIiYvuXFVsBIJw0ocnslwVTLJKg22OQ== tarball: 'file:projects/imodel-from-geojson.tgz' version: 0.0.0 'file:projects/imodel-from-orbitgt-pointcloud.tgz': @@ -20591,7 +20544,7 @@ packages: dev: false name: '@rush-temp/imodel-from-orbitgt-pointcloud' resolution: - integrity: sha512-exQBkFsSgC3czvN2J4BixPqxMof1I7qcAl4J4VS6kHv/Bk9uVoYZDgNH7h4g62Vd3eqWNdYt8AtnnEnNKrx/xg== + integrity: sha512-8dVNtwqp187yBWFlTbKt3yOtAD07sz3mxm8jGUImGnvqWDHs70UOKrGnQCvGQWqx7NP4KTJ3CcS2LPnQZy42rA== tarball: 'file:projects/imodel-from-orbitgt-pointcloud.tgz' version: 0.0.0 'file:projects/imodel-from-reality-model.tgz': @@ -20611,7 +20564,7 @@ packages: dev: false name: '@rush-temp/imodel-from-reality-model' resolution: - integrity: sha512-JA1Mr37DGm1iWQAaNlrR6z+uFWVevgLGAZt3yMaO3BgIVynr+VPMkxd+SlUHISaoYUpnkDbPtSq4k3ga/qJXPw== + integrity: sha512-bB1lvNtBJJPqPz1Shv5kNfcGFPu6W+QEOk5qZyRglXEUwi/PRP0cE5G6VbT6caT6VMSjIsX6vrY02j3cXAmF6w== tarball: 'file:projects/imodel-from-reality-model.tgz' version: 0.0.0 'file:projects/imodel-transformer.tgz_request@2.88.2': @@ -20636,7 +20589,7 @@ packages: peerDependencies: request: '*' resolution: - integrity: sha512-9OKCIJ+VM4xUQNsxNzNHxf2z5MQtrhtDsky3JLxik253gJjX+MRpiIV0ZXQZF8IOmi3a7AQpwGQKhQsHAmmiQQ== + integrity: sha512-MkCIXCq4dsQsyxwK4DIifJXMCkC0fu9TfjjNZ8lz2UvUkFTVjrqWyzee0iKS+bXqQ9Pg8/GL8na7gG/HTH6+wA== tarball: 'file:projects/imodel-transformer.tgz' version: 0.0.0 'file:projects/imodelhub-client-tests.tgz': @@ -20647,7 +20600,7 @@ packages: '@types/js-base64': 2.3.2 '@types/mocha': 5.2.7 '@types/nock': 11.1.0 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 deep-assign: 2.0.0 eslint: 6.8.0 @@ -20661,7 +20614,7 @@ packages: dev: false name: '@rush-temp/imodelhub-client-tests' resolution: - integrity: sha512-SZ5Efp2pPhxfE4L6+Dpxer5hl6ZCc4OT4tpzVtFcyvlQXTPygnr3a6VhqKeLOo83UT9G1Gis8CXaH5siZBSRvg== + integrity: sha512-oj/XDByUvt3WKoUl9/IWA14iXv14UxfVpyhLmTSW8KQD1W6fI3UvBmdYo6XYi8C+eawPrYNEVW0aah29YQyHig== tarball: 'file:projects/imodelhub-client-tests.tgz' version: 0.0.0 'file:projects/imodelhub-client.tgz': @@ -20677,17 +20630,18 @@ packages: dev: false name: '@rush-temp/imodelhub-client' resolution: - integrity: sha512-3akXxsG06PyED9r2WXtfFZZsSVDkHAG6R1eY+jkEnllX/lq2yYKKN6xKY2GRtbOhOLhQspw/EzmPaedklr1yBA== + integrity: sha512-pSOYQNHfU29y8WkaE7HdaOxTk66Z2U1WaBd8uiFeKabxDtxEPOGtu2iPYZtRe2+8x3ndz43fIRyoEUQtnE0XVA== tarball: 'file:projects/imodelhub-client.tgz' version: 0.0.0 'file:projects/imodeljs-backend.tgz_debug@2.6.9': dependencies: '@azure/storage-blob': 10.4.0 '@bentley/imodeljs-native': 2.15.0 + '@openid/appauth': 1.3.0_debug@2.6.9 '@types/chai': 4.2.15 '@types/chai-as-promised': 7.1.3 '@types/deep-assign': 0.1.1 - '@types/formidable': 1.2.1 + '@types/formidable': 1.0.32 '@types/fs-extra': 4.0.11 '@types/glob': 5.0.36 '@types/js-base64': 2.3.2 @@ -20699,8 +20653,8 @@ packages: '@types/sinon': 9.0.11 '@types/ws': 6.0.4 azurite: 3.11.0_debug@2.6.9 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 cpx: 1.5.0 deep-assign: 2.0.0 eslint: 6.8.0 @@ -20715,13 +20669,16 @@ packages: npm-run-all: 4.1.5 null-loader: 0.1.1 nyc: 14.1.1 + open: 7.4.2 openid-client: 3.15.10 rimraf: 3.0.2 semver: 5.7.1 sinon: 9.2.4 source-map-loader: 1.1.3_webpack@4.42.0 source-map-support: 0.5.19 + ts-node: 7.0.1 typescript: 4.1.5 + username: 5.1.0 webpack: 4.42.0_webpack@4.42.0 ws: 7.4.4 dev: false @@ -20730,7 +20687,7 @@ packages: peerDependencies: debug: '*' resolution: - integrity: sha512-jKhJbVzdiYauKYa2O+HR6kiqEh3//u724jyyVzDfvI/5ui181/FnlkiQVm+9JfTtINiU0dh/3YPpbXTLcLDQUA== + integrity: sha512-rBWgPJgTTRynDZ5Vh3VS7E8amZCciT6QSCyRCDnTaVOx3b2UFiCEQ3B7vyQe6oAsNLgbS6LBi8V0eh0tYswr8w== tarball: 'file:projects/imodeljs-backend.tgz' version: 0.0.0 'file:projects/imodeljs-common.tgz': @@ -20742,7 +20699,7 @@ packages: '@types/node': 10.14.1 '@types/semver': 5.5.0 '@ungap/url-search-params': 0.1.4 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 flatbuffers: 1.12.0 js-base64: 2.6.4 @@ -20750,11 +20707,12 @@ packages: nyc: 14.1.1 rimraf: 3.0.2 semver: 5.7.1 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/imodeljs-common' resolution: - integrity: sha512-mKI/NfOtTzEoa1spsJBFGIY4hT4Z0SV+Is9mrR/QNKJFWZSE3KA3QdJfcnFuTOrP2aGNHs13GUCxRmrL7x6o2A== + integrity: sha512-xDmhdISqmB4DXCIt6P4hSVJSEvcYTFh5LQ22dlOMJwjcYTgWH20eKNFOFogN/AwZ4qa4U1fXX8R0V0uuFEcf2g== tarball: 'file:projects/imodeljs-common.tgz' version: 0.0.0 'file:projects/imodeljs-editor-backend.tgz_webpack@4.42.0': @@ -20765,10 +20723,10 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/semver': 5.5.0 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 cpx: 1.5.0 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -20776,6 +20734,7 @@ packages: sinon: 9.2.4 source-map-loader: 1.1.3_webpack@4.42.0 source-map-support: 0.5.19 + ts-node: 7.0.1 typescript: 4.1.5 dev: false id: 'file:projects/imodeljs-editor-backend.tgz' @@ -20783,7 +20742,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-roLZy7xFLfo7GsR8cldWaryz/2aGDYGHfB1RfNQByjAPBru8T4S8QlIgnyCpHCFWilsd0rK1JtNSQyo9E7I9eQ== + integrity: sha512-Bdqfci0c3aDqow1bfQ2b7NZ/wK92ACGJiYj0tiIlBqQAVQFtC++r9ombyhExvPqVF+Y/XtmOhp4pPc6nfzWMmA== tarball: 'file:projects/imodeljs-editor-backend.tgz' version: 0.0.0 'file:projects/imodeljs-editor-common.tgz': @@ -20792,15 +20751,16 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/semver': 5.5.0 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 rimraf: 3.0.2 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/imodeljs-editor-common' resolution: - integrity: sha512-vCHLfi+bT4sKAcUkBIUoaSDP8QdDnwoB0wR9c2QgnNliYJjF7/YT3+cTCwCY9wvFjnPpAYbiKjiqMrAO7hi8qQ== + integrity: sha512-bI9aRDlddJ9Rj3j41/m6LkyHTh/wOB59521GGFjJnCjYnpzt1leJEsTx+u7fnMPFLQJQPLqYb/m+MqqkWA0crA== tarball: 'file:projects/imodeljs-editor-common.tgz' version: 0.0.0 'file:projects/imodeljs-editor-frontend.tgz_webpack@4.42.0': @@ -20809,9 +20769,9 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/semver': 5.5.0 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 glob: 7.1.6 mocha: 5.2.0 @@ -20825,7 +20785,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-51I+/7ICDzCNJ9U71TcLZNQ92u29koV+PGlovk8Iv/MR1GbN0GQovPyrId122YWCkGqHlT8/srPMW7scMcxoZw== + integrity: sha512-5feE2MEmK2SLRZEV9gh2Jl4x0iW7UW5u2E5JsAaskc8lbQts0BTys2IPIplSIUYnYiotrLMW1tjffWVI3a8H2g== tarball: 'file:projects/imodeljs-editor-frontend.tgz' version: 0.0.0 'file:projects/imodeljs-frontend.tgz': @@ -20838,8 +20798,8 @@ packages: '@types/node': 10.14.1 '@types/semver': 5.5.0 '@types/sinon': 9.0.11 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 cpx: 1.5.0 eslint: 6.8.0 fuse.js: 3.6.1 @@ -20860,7 +20820,7 @@ packages: dev: false name: '@rush-temp/imodeljs-frontend' resolution: - integrity: sha512-khuDsyXUykSSm7+HYgGvUXfX3Vk0jCmRZDOuQO0VR2+ytZRDAzEIC05wwtJtfoYLIyBNk1W/Mylqr7xVjkKjlQ== + integrity: sha512-LIYUxtEaXRhDfIoiItqNCnqmEFexjk0h+3kGdoJGVSPHDUyscAPUSOU5kh6Iq/pmL/ZCnpReKBsi1CCr9VkDhA== tarball: 'file:projects/imodeljs-frontend.tgz' version: 0.0.0 'file:projects/imodeljs-i18n.tgz': @@ -20877,7 +20837,7 @@ packages: dev: false name: '@rush-temp/imodeljs-i18n' resolution: - integrity: sha512-cr8AcWQBIqftGg8hasp+kdGZtu8su91eZacWyzGu3eDlBoa1WBA59OCd0uVkblL/0J9vhNa4LUntpHv/1FrhIQ== + integrity: sha512-ND8lOuWzQ1oIIDMYEsEucm7aRcBrEuorGdOFyaW9PIo7PzLDttyVviCPA7EgX2DQm0gxcjEJQz5IaPFzjEcARQ== tarball: 'file:projects/imodeljs-i18n.tgz' version: 0.0.0 'file:projects/imodeljs-markup.tgz': @@ -20886,7 +20846,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 eslint: 6.8.0 glob: 7.1.6 @@ -20899,7 +20859,7 @@ packages: dev: false name: '@rush-temp/imodeljs-markup' resolution: - integrity: sha512-cnkfu5OGt/v8Cx8vbKmAj+wEE1neKNRine4lrtjxFNB8iJe7SzeFIfgJ0uUUXU8u3w3Pb6KCTrbA/A6em/8JOg== + integrity: sha512-oYX+tzEy5i+Ns53FE3vVLpZ16+XOLaBe5zyHbPkAaRMsbfBpf+4yE8IVQmJ4yxT7ZjfqLB9GiT7Ixj1OH5oH6Q== tarball: 'file:projects/imodeljs-markup.tgz' version: 0.0.0 'file:projects/imodeljs-quantity.tgz': @@ -20910,18 +20870,19 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/sinon': 9.0.11 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 sinon: 9.2.4 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/imodeljs-quantity' resolution: - integrity: sha512-rr+HLywUNOLJC09Nwn/1VHib/uhPzmsZ0M3IOoSZYm+xlkY+d7my7sur1U5w1VH0b7poXsRwfNAhJAI37e6pBA== + integrity: sha512-0hqMfumx9ftuS2kNytRcsQ1y4rSiZPXPyb8LUbGEgE7UIYgQfkB3EkHeFwsX/YgwSZWjSmXtagQ5kF9BNSMtwQ== tarball: 'file:projects/imodeljs-quantity.tgz' version: 0.0.0 'file:projects/internal-tools.tgz': @@ -20950,7 +20911,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-ynG/2JpVB1css8TkMe7tcvA5NOfqjx3OuwQkt3A1CbCu0PvLLPO0nbq2cK4WtNTa+xbiRx6Lrq50rfaNRKE62A== + integrity: sha512-xgppsygXcTLJWS33HBGmEqsA8GeWKPSLMdik4sT415Iaf+XY8pvgixpD0jOo8G/1uvh47I0nV+4samwV3ohIrQ== tarball: 'file:projects/iot-demo.tgz' version: 0.0.0 'file:projects/itwin-client.tgz': @@ -20964,17 +20925,18 @@ packages: '@types/qs': 6.9.6 '@types/superagent': 4.1.10 '@types/xmldom': 0.1.30 - chai: 4.3.4 + chai: 4.3.3 deep-assign: 2.0.0 eslint: 6.8.0 js-base64: 2.6.4 mocha: 5.2.0 nock: 12.0.3 nyc: 14.1.1 - qs: 6.10.1 + qs: 6.9.6 rimraf: 3.0.2 source-map-loader: 1.1.3_webpack@4.42.0 superagent: 5.3.1 + ts-node: 7.0.1 typescript: 4.1.5 webpack: 4.42.0_webpack@4.42.0 xmldom: 0.5.0 @@ -20982,7 +20944,7 @@ packages: dev: false name: '@rush-temp/itwin-client' resolution: - integrity: sha512-tzeDWnk50+c057AD0HL/zBawsdW6vh2AGJiWkGOQ86JGXmplhRu3Rxs4FuDZfzs8bDu6ZmPkcEd6igcvRxmrXw== + integrity: sha512-i/xHlW3doZIOJQEUV9EVBkdyoA6+yi/5S39GItEVQroZCSO4ewagLqbBzoz5DmbtwsjC5fYBwEWDubx1hL5psg== tarball: 'file:projects/itwin-client.tgz' version: 0.0.0 'file:projects/linear-referencing-backend.tgz': @@ -20991,17 +20953,18 @@ packages: '@types/fs-extra': 4.0.11 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/linear-referencing-backend' resolution: - integrity: sha512-ZQPEuyxpJR4vpTZizC6OiyoS9ABGtG5YBIXuxSiLPbU9ZxYGdOrcBuBRlWz78DOa8zNR3h9K8yHgMFV3DmjJXQ== + integrity: sha512-TxtygPWPvQ1vev3q7KmMcDbUr/LE/ThvlMjXviemcUCYoVDB8Y805zLU8Z6oKYGqhxT8sBd1f2YFfCBFVHulog== tarball: 'file:projects/linear-referencing-backend.tgz' version: 0.0.0 'file:projects/linear-referencing-common.tgz': @@ -21009,17 +20972,18 @@ packages: '@types/chai': 4.2.15 '@types/fs-extra': 4.0.11 '@types/mocha': 5.2.7 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/linear-referencing-common' resolution: - integrity: sha512-Ppgd52lBFZhA8k4yZSLGvMe9FFXEQPKhBVgS5OemLxtXle2rYGHPIrHwvxpLHdDm1zHaKpnFUeCGX1KxdFUMZw== + integrity: sha512-3P4RbGl4gkoOVjpEw3D+eL6LURyowaMUjGBHzqOlwuKG2LnBUuwWfk5mzE9qAW5bxKg+NUZByOMst3vHWY+7Vw== tarball: 'file:projects/linear-referencing-common.tgz' version: 0.0.0 'file:projects/logger-config.tgz': @@ -21037,7 +21001,7 @@ packages: dev: false name: '@rush-temp/logger-config' resolution: - integrity: sha512-yp55y9bUyIZPa3qN3ynGuuoTD9D+x8eKTWyi7gHpi1/cHcCDEwGPOLT38nv/usiVNiMmAiy9F7/JrnNMEUF3xw== + integrity: sha512-GIzgU4neJoCjET5PfXQSpRUDYNyaJQq4wrqIrVUmv1g08HqpGma42mFpgw/thdG2JCJSpE3DDbA8ZsL716rg+w== tarball: 'file:projects/logger-config.tgz' version: 0.0.0 'file:projects/map-layers.tgz_123a069461c022655d11fe624d233491': @@ -21055,10 +21019,10 @@ packages: '@types/react-select': 3.0.26 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 - chai-spies: 1.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 + chai-spies: 1.0.0_chai@4.3.3 classnames: 2.2.6 cpx: 1.5.0 enzyme: 3.11.0 @@ -21070,13 +21034,13 @@ packages: mocha: 5.2.0 nyc: 14.1.1 react: 16.14.0 - react-beautiful-dnd: 13.1.0_react-dom@16.14.0+react@16.14.0 + react-beautiful-dnd: 13.0.0_react-dom@16.14.0+react@16.14.0 react-compound-slider: 2.5.0_react@16.14.0 react-dom: 16.14.0_react@16.14.0 react-select: 3.1.0_react-dom@16.14.0+react@16.14.0 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 typescript: 4.1.5 xmlhttprequest: 1.8.0 dev: false @@ -21087,7 +21051,7 @@ packages: sass: '*' webpack-cli: '*' resolution: - integrity: sha512-AROWH8ThdAXlqcCLGP8qFNDMcudv462aZJGwFCIFzAELWNH5ZyRglxyRVpmZv/+NfoUWejXj73zPOZ4fyoJ6ww== + integrity: sha512-TyYoPSgKQkhNv3yzHsV5bLWySscl4YgOQbTAKwCqNte5+Cba5qSAYmdhSUn8Fga79T+bWCsROL+iHp+zGLbfig== tarball: 'file:projects/map-layers.tgz' version: 0.0.0 'file:projects/mobile-manager.tgz': @@ -21098,8 +21062,8 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/ws': 6.0.4 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 cpx: 1.5.0 eslint: 6.8.0 js-base64: 2.6.4 @@ -21111,7 +21075,7 @@ packages: dev: false name: '@rush-temp/mobile-manager' resolution: - integrity: sha512-/q9PA3hYrQEI4EyehIEV6huM2GrQnGnsYIqb7KSh4MOILce2CFIwPsUFiqfLBjylfSHqKokyrYSNGmOLmewx2g== + integrity: sha512-/U8pQG77XOdTk0BNJB0mXIOSRRevnISxWBBjROfcXtpf9ourzX3GV6v0hZvv2e2EzkWN+sbK0oGgsGKlKjiw+g== tarball: 'file:projects/mobile-manager.tgz' version: 0.0.0 'file:projects/native-app-full-stack-tests.tgz': @@ -21121,8 +21085,8 @@ packages: '@types/mocha': 5.2.7 '@types/nock': 11.1.0 '@types/node': 10.14.1 - chai: 4.3.4 - electron: 11.4.1 + chai: 4.3.3 + electron: 11.3.0 eslint: 6.8.0 fs-extra: 8.1.0 glob: 7.1.6 @@ -21137,16 +21101,16 @@ packages: dev: false name: '@rush-temp/native-app-full-stack-tests' resolution: - integrity: sha512-A7laf2XNohCNHGDqW7yJ3+oBeKSNxJupmVXbZT42EO8fakZRbn1c6OtbWG5hEebCpZdlXg5NCvoFnqr5E2ifAw== + integrity: sha512-7YpNxuIgINqBkiWasnjRlm9UoWC2KbXLtr1049vipSGGOx/PmJbY4FSpO54jkp9GQu9jGLL6sJSzFJI8kkuOAg== tarball: 'file:projects/native-app-full-stack-tests.tgz' version: 0.0.0 'file:projects/ninezone-test-app.tgz_sass@1.32.8+webpack-cli@3.3.12': dependencies: - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic-webfont': 1.0.33 '@bentley/react-scripts': 3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32 '@types/classnames': 2.2.11 '@types/react': 16.9.43 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/react-router-dom': 5.1.7 classnames: 2.2.6 highlight.js: 10.6.0 @@ -21163,7 +21127,7 @@ packages: sass: '*' webpack-cli: '*' resolution: - integrity: sha512-wX20ue+oJrO7JIV+8jLvOtOx1qMEIls/Tn3vmDmILATz/6NrnuUVR/Sbuad5ISpQ49OFL2el25NpGbP/PX0tjg== + integrity: sha512-gWj848NoKQXhxj0jUHwLbvIO2zYYJPFLkkY0lSBK5IWG308P8Tr6GDyfsYqetiwDT0qGxq7WDfa45D6awB3LvQ== tarball: 'file:projects/ninezone-test-app.tgz' version: 0.0.0 'file:projects/oidc-signin-tool.tgz': @@ -21173,8 +21137,8 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/puppeteer': 2.0.1 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -21185,7 +21149,7 @@ packages: dev: false name: '@rush-temp/oidc-signin-tool' resolution: - integrity: sha512-Fst/FcPk9jLeH0Vx4VFqQgz6m3J6G67kuR4J6/IGb5p8kEjuRjgdLp1aEZES4A/brhuZBiR2unXmFVxJjtrnPg== + integrity: sha512-eAcU+m5f1qjOZIRyXvrwJMf92b0k1VydQWdC8jcbFiLzGLVAjd+ksXUtkWw1dPikuDkvtA3vKtp24uKIqk86hA== tarball: 'file:projects/oidc-signin-tool.tgz' version: 0.0.0 'file:projects/orbitgt-core.tgz': @@ -21193,7 +21157,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 debug: 2.6.9 eslint: 6.8.0 @@ -21201,11 +21165,12 @@ packages: nyc: 14.1.1 rimraf: 3.0.2 semver: 5.7.1 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/orbitgt-core' resolution: - integrity: sha512-1s5mhlQ0BbFvhUe/3jyD6mgHfaHCZnWLIvPEW8+S9pfJJ74+02+82F5qcA4nVpGrDQkETA9DSnMWeqOJd3a/cA== + integrity: sha512-zxPI0y90YQqnXve1Lf2aHMVQ4Vk7YgeUVO+Ztbsh/x9P5JZrcJDWtrWzHPTJHVwl8sPgdVFKpzN5tpk6Q3n7yQ== tarball: 'file:projects/orbitgt-core.tgz' version: 0.0.0 'file:projects/perf-tools.tgz': @@ -21218,7 +21183,7 @@ packages: dev: false name: '@rush-temp/perf-tools' resolution: - integrity: sha512-XWQJhbF2vEdIbapDRcT6nCF94/odQIOj2NhkMfeNZYrACV5SYXI/rIEPzbzIQlFQeYuNMHg/l/lpgSMhRuJ5Og== + integrity: sha512-eOfkzPJEVTpV+jeQ5AZ/mXFPjF/xXL6QggzwzCZp5okB3tsUYM0OMdrYGvGEo8CwKFKXDD9hupbC4MLCmhzhRg== tarball: 'file:projects/perf-tools.tgz' version: 0.0.0 'file:projects/physical-material-backend.tgz': @@ -21227,17 +21192,18 @@ packages: '@types/fs-extra': 4.0.11 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 cpx: 1.5.0 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 rimraf: 3.0.2 + ts-node: 7.0.1 typescript: 4.1.5 dev: false name: '@rush-temp/physical-material-backend' resolution: - integrity: sha512-cwSS2R8ecACOSE7T5z3B2yO9+5jDf3aNpdbfXLT8UFyQvl/cigf4ScUO/DLnSxoJca1prZ6udhQ477xcfOapaw== + integrity: sha512-UV10WvrtbBTSA6IVmkCXYTjoEcPlrgu5eLVl+LptNgJ/9JsZa5QysOI9K77PXrcXrLbPWQLLEGQiOBHi2RvRqg== tarball: 'file:projects/physical-material-backend.tgz' version: 0.0.0 'file:projects/presentation-backend.tgz': @@ -21254,9 +21220,9 @@ packages: '@types/object-hash': 1.3.4 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 chai-subset: 1.6.0 cpx: 1.5.0 cross-env: 5.2.1 @@ -21269,13 +21235,13 @@ packages: object-hash: 1.3.1 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 typemoq: 2.1.0 typescript: 4.1.5 dev: false name: '@rush-temp/presentation-backend' resolution: - integrity: sha512-vUrJ/xtuvx7lwPUToISVBlIyrClvlxaAUE7ppSAKEdRxfXoOWYWUnh+dLgS9XooCe/ZtAZ/138cHt5Cs+Txq2Q== + integrity: sha512-dSy6YoG6izDd35l/7RFDj6j5EvI0e76bajMGfXoYxSBlueYTSBcvXH1tKIX5gnkEImjxXN9UIGr2Ze42eeKqSA== tarball: 'file:projects/presentation-backend.tgz' version: 0.0.0 'file:projects/presentation-common.tgz': @@ -21289,9 +21255,9 @@ packages: '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 '@types/source-map-support': 0.4.2 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 cpx: 1.5.0 cross-env: 5.2.1 deep-equal: 1.1.1 @@ -21302,7 +21268,7 @@ packages: nyc: 14.1.1 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 typemoq: 2.1.0 typescript: 4.1.5 typescript-json-schema: 0.43.0 @@ -21310,7 +21276,7 @@ packages: dev: false name: '@rush-temp/presentation-common' resolution: - integrity: sha512-Uel5ahki/5m9F3jVrpzcuBKYokggFapv5H9TUHZSvTkuRI5ynFduyMT+vvehmG6aXI3/4oyq5JmLMYd2Pa1cFQ== + integrity: sha512-L/7agwBlYqwq7HqxQpkaEMucS/ctJgAeEAJLhhO+wfclsW1ccMInchWHHGu2qBbMqCeh4qkpmdF+ZEGqKC8lfA== tarball: 'file:projects/presentation-common.tgz' version: 0.0.0 'file:projects/presentation-components.tgz_jsdom@11.12.0': @@ -21326,13 +21292,13 @@ packages: '@types/lodash': 4.14.168 '@types/mocha': 5.2.7 '@types/react': 16.9.43 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 '@types/testing-library__react-hooks': 3.4.1 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 chai-subset: 1.6.0 cpx: 1.5.0 cross-env: 5.2.1 @@ -21342,7 +21308,7 @@ packages: eslint: 6.8.0 faker: 4.1.0 ignore-styles: 5.0.1 - immer: 8.0.1 + immer: 9.0.1 jsdom-global: 3.0.2_jsdom@11.12.0 lodash: 4.17.21 micro-memoize: 4.0.9 @@ -21354,7 +21320,7 @@ packages: rimraf: 3.0.2 rxjs: 6.6.6 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 typemoq: 2.1.0 typescript: 4.1.5 xmlhttprequest: 1.8.0 @@ -21364,7 +21330,7 @@ packages: peerDependencies: jsdom: '*' resolution: - integrity: sha512-Ew7LiUDVjzpZKCqawIYTNkbj5l5gESpNWe3O4HEAAqRnCrWylZXiEsr+lQPtkd4qjQJYQeGTaEH+567U4IYp+w== + integrity: sha512-2ZiAnH8NGwCoSmkyaSeFlYj+k1LCpidGKDxvV/skDo5wiw6Iqo14rkr9+ue476mzUzcFZY/vBePDQgJ57RYwCw== tarball: 'file:projects/presentation-components.tgz' version: 0.0.0 'file:projects/presentation-frontend.tgz_jsdom@11.12.0': @@ -21379,9 +21345,9 @@ packages: '@types/node': 10.14.1 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 cpx: 1.5.0 cross-env: 5.2.1 deep-equal: 1.1.1 @@ -21393,7 +21359,7 @@ packages: nyc: 14.1.1 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 typemoq: 2.1.0 typescript: 4.1.5 xmlhttprequest: 1.8.0 @@ -21403,7 +21369,7 @@ packages: peerDependencies: jsdom: '*' resolution: - integrity: sha512-8F3JNyZqZF/kYo4HsIOXyBJfpfUSxbTwByxIOWiiuMfzJnVkXPgU1N9fWd43BXCY3ad055cRrfPe9Z5m1bP75Q== + integrity: sha512-CdLaXlXA6R6oFBXrLhoxzgCyxG1c+/9V3+5ncDaGpqXwkgVs4AEKsnH6kjdWrbeF7DenjNcWZI6ZbpJZLa/vYw== tarball: 'file:projects/presentation-frontend.tgz' version: 0.0.0 'file:projects/presentation-full-stack-tests.tgz_jsdom@11.12.0': @@ -21419,15 +21385,15 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/react': 16.9.43 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/rimraf': 2.0.4 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 '@types/testing-library__react-hooks': 3.4.1 cache-require-paths: 0.3.0 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 chai-subset: 1.6.0 cpx: 1.5.0 cross-env: 5.2.1 @@ -21435,7 +21401,7 @@ packages: eslint: 6.8.0 faker: 4.1.0 ignore-styles: 5.0.1 - immer: 8.0.1 + immer: 9.0.1 jsdom-global: 3.0.2_jsdom@11.12.0 mocha: 5.2.0 react: 16.14.0 @@ -21443,7 +21409,8 @@ packages: react-test-renderer: 16.14.0_react@16.14.0 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 + ts-node: 7.0.1 typemoq: 2.1.0 typescript: 4.1.5 xmlhttprequest: 1.8.0 @@ -21453,21 +21420,21 @@ packages: peerDependencies: jsdom: '*' resolution: - integrity: sha512-UNJ6/lr/d8A/8c1fJNv8fgksm9gCnAymizEeY7wS/od4Dildh95l/BHT+tKLTiUk2gEu9iVZg6t9FAhlNdI4EA== + integrity: sha512-oMnIXb9/6JehpxUGaLqqkCDgK+ufBNvAqtql6Dq/ySl6+YnJulPqCH8U5veG+Kfj4Tl1p4WTgtimnxWUW/Hj0w== tarball: 'file:projects/presentation-full-stack-tests.tgz' version: 0.0.0 'file:projects/presentation-test-app.tgz_webpack-cli@3.3.12': dependencies: - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic-webfont': 1.0.33 '@bentley/react-scripts': 3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32 '@types/bunyan': 1.8.6 '@types/react': 16.9.43 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/react-select': 3.0.26 autoprefixer: 8.6.5 cpx: 1.5.0 cross-env: 5.2.1 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 npm-run-all: 4.1.5 postcss-flexbugs-fixes: 4.1.0 @@ -21486,7 +21453,7 @@ packages: peerDependencies: webpack-cli: '*' resolution: - integrity: sha512-koE1mc6Bh9m+YdpTEdmFfq/lLY8ZORF3NUGMA9iixzaLsd8AhMiaS2f9x516pYrdEny5Wugtn5m3T/2t5RLPFg== + integrity: sha512-aX8T8Av4zy+9OwXeH1xcvCpapgv50GHNXe9ion8VNO7ujMmi0BbyWJlgYY/n/GT9LdHXNbWBngQi4gXJKePl2Q== tarball: 'file:projects/presentation-test-app.tgz' version: 0.0.0 'file:projects/presentation-testing.tgz_jsdom@11.12.0': @@ -21498,9 +21465,9 @@ packages: '@types/mocha': 5.2.7 '@types/rimraf': 2.0.4 '@types/sinon': 9.0.11 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 cpx: 1.5.0 cross-env: 5.2.1 eslint: 6.8.0 @@ -21519,7 +21486,7 @@ packages: peerDependencies: jsdom: '*' resolution: - integrity: sha512-NvStnoOY8WttWoioeuGMEYkCM9Bkpblr//m9aVDs2Yuv1HMM1Zknwne3WDbsyg5F+iM3UAoe8dVv6XpPD1ZRtQ== + integrity: sha512-oeDAy9QGPnnRPEuUeC0ySx82ghUYt+bekeIxipLR9M6jv5UEtuUtAKeyBTzyBXNGKGK4naEyUOpufl9hO/DLJA== tarball: 'file:projects/presentation-testing.tgz' version: 0.0.0 'file:projects/product-settings-client.tgz': @@ -21527,7 +21494,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -21538,7 +21505,7 @@ packages: dev: false name: '@rush-temp/product-settings-client' resolution: - integrity: sha512-R90klofEMUEsQ/Q18fSw9H2U64PsW0NW9p7jpsXzCaksnvQQjGLEK7gLp1ea8817ZlAwdP4uBstgBn/TvAbddw== + integrity: sha512-Nqzl/bHRjvEuq9lOD2WV5niMNxOZxx8sHdMGd8d3wBf+Qpo8wuWAniE33gRJvSKw6jqAzeFPy6prgwJpCptBVw== tarball: 'file:projects/product-settings-client.tgz' version: 0.0.0 'file:projects/projectshare-client.tgz': @@ -21546,7 +21513,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -21557,7 +21524,7 @@ packages: dev: false name: '@rush-temp/projectshare-client' resolution: - integrity: sha512-xTPXCdjLjV+tCI/luyw1eQ30PE1II87SXx1bIFjEzBwuEY/5ZwLQwHdBIa5H18kBlW+cK7n7P+Ae/vH/HT8J0g== + integrity: sha512-zbbSTguzP4890RvlbqVRAe5xDprys3RtF9s03MmyU8xXS8QjXRLhOe7JknekXCL/n69P7cMDK2ISM8EjrN+weA== tarball: 'file:projects/projectshare-client.tgz' version: 0.0.0 'file:projects/rbac-client.tgz': @@ -21565,7 +21532,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -21576,7 +21543,7 @@ packages: dev: false name: '@rush-temp/rbac-client' resolution: - integrity: sha512-kazS/OrFDj4nwGvfuRzml32UKZn6fz31MW2DRt6LhEFHUlvBmPG5hr7lORjdDWhIETfdCohUwQHHGVzszyYy3A== + integrity: sha512-eD33qbczStdHNKqfCGDwytWIagz6np+fttr/2pOKZwqafdXraw42tZ9F+6bIaaqOKRzhzx7cbrFlzLkhzgM5Vw== tarball: 'file:projects/rbac-client.tgz' version: 0.0.0 'file:projects/reality-data-client.tgz': @@ -21584,7 +21551,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -21595,7 +21562,7 @@ packages: dev: false name: '@rush-temp/reality-data-client' resolution: - integrity: sha512-TFhQyGo5RZ9Lf1zJ2UcjD6oiQflyakn8RjrlkLRg0W/Vh2oAhStFEOf7b1DzAW4/fhs8J4fGbHvsLc35UR77FQ== + integrity: sha512-c6iNqNuVCD5TpyMbuvWMCMvjSbbTuvGdwvOaZF7y9vcfSs925VMVHBirGAfHzfk1a4Rl7uUheHOVLLe8gm4tzw== tarball: 'file:projects/reality-data-client.tgz' version: 0.0.0 'file:projects/rpc-full-stack-tests.tgz': @@ -21606,8 +21573,8 @@ packages: '@types/node': 10.14.1 '@types/semver': 5.5.0 '@types/spdy': 3.4.4 - chai: 4.3.4 - electron: 11.4.1 + chai: 4.3.3 + electron: 11.3.0 eslint: 6.8.0 express: 4.17.1 glob: 7.1.6 @@ -21621,7 +21588,7 @@ packages: dev: false name: '@rush-temp/rpc-full-stack-tests' resolution: - integrity: sha512-IEkGaW3A4RDw+++DL5/QI5N8FnjteFXkE/oBE8RqRD+RfWKmZMaKHIieUK4Qn8S3aLPFKazRkvAehqlhhFxP8Q== + integrity: sha512-TQ86J/2Y6dwWrsAdR06qSP4wpyN3P81noL3O8QNox99M4ehn3ewtuU6oALPsMgwMvdoTnmeKKzovnqRCMqRpaw== tarball: 'file:projects/rpc-full-stack-tests.tgz' version: 0.0.0 'file:projects/rpcinterface-full-stack-tests.tgz': @@ -21632,8 +21599,8 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/puppeteer': 2.0.1 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 cpx: 1.5.0 dotenv: 8.2.0 dotenv-expand: 5.1.0 @@ -21651,7 +21618,7 @@ packages: dev: false name: '@rush-temp/rpcinterface-full-stack-tests' resolution: - integrity: sha512-vkWYqmpriM4NRPKIRjZDex8/AAhu2XMC3vLrbN++Ty2EyEUKJ9sIU4F3xnkJu0FX9FeEBeFO2zdL/gDezzbtmA== + integrity: sha512-ga3xLev7ZaPPc/T80mgQEVqPrp0yrJjvGfTyQYlQQPcSkOYro9DzCCpRJslVCSzcBn0EV9E2zTCNEyf31PTZGQ== tarball: 'file:projects/rpcinterface-full-stack-tests.tgz' version: 0.0.0 'file:projects/telemetry-client.tgz': @@ -21659,7 +21626,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -21670,7 +21637,7 @@ packages: dev: false name: '@rush-temp/telemetry-client' resolution: - integrity: sha512-jyiIqZ8PJHafmPmFCnHNKQEH+PjXuepRwU8Q4IomPaiQABYAgJvoTEllnk6YGrpN6BrfBnP9wR9uaj3N+dQHCQ== + integrity: sha512-U0jMFFb2Z9W0drOoQj4IF40UMdU0yL63GiDRsQi4/pQd8aw/rYKhooAJrqVuy86NhGyaIjPkygqBN7Dad/apCQ== tarball: 'file:projects/telemetry-client.tgz' version: 0.0.0 'file:projects/test-apps-analysis-importer.tgz': @@ -21689,7 +21656,7 @@ packages: dev: false name: '@rush-temp/test-apps-analysis-importer' resolution: - integrity: sha512-EVX3o+GAg8XIsi41NqGzbahtF3qZvj476N8NLZbQ6Rgp89PRxmIyqM0q3zJ5ewQIKDhgawyTVVaj8RUR2uvBhQ== + integrity: sha512-VvWMcHH/1VLWpk16dWExHob6bd/7/p/+RDIn3a2esZZalV3F0ETV6/AALe2xgdT55PGvV3k+9G+HJJkocUCz5A== tarball: 'file:projects/test-apps-analysis-importer.tgz' version: 0.0.0 'file:projects/test-apps-synchro-schedule-importer.tgz': @@ -21707,12 +21674,12 @@ packages: dev: false name: '@rush-temp/test-apps-synchro-schedule-importer' resolution: - integrity: sha512-hzGBltGootas0CNpdICDTlmQaVKhYMO5HUo72HVELa73wULiB8gjvqXMe5gMLQB1LGwlhW+N7KEdIsB/F9QiMQ== + integrity: sha512-G0XXEVyrd5y/Q2vDIFd34h905kyGxaP/WoUPDM1PmavHzQSyAzBPiXgfC59RvGjTO0S0KPyk1hzKfYVUtUUDQQ== tarball: 'file:projects/test-apps-synchro-schedule-importer.tgz' version: 0.0.0 'file:projects/ui-abstract.tgz': dependencies: - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic-webfont': 1.0.33 '@types/chai': 4.2.15 '@types/chai-as-promised': 7.1.3 '@types/chai-jest-snapshot': 1.3.6 @@ -21721,10 +21688,10 @@ packages: '@types/node': 10.14.1 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 - chai-spies: 1.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 + chai-spies: 1.0.0_chai@4.3.3 cpx: 1.5.0 eslint: 6.8.0 ignore-styles: 5.0.1 @@ -21735,7 +21702,7 @@ packages: raf: 3.4.1 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 ts-node: 7.0.1 tsconfig-paths: 3.9.0 typescript: 4.1.5 @@ -21743,12 +21710,12 @@ packages: dev: false name: '@rush-temp/ui-abstract' resolution: - integrity: sha512-tFKCJxc3tM6vaTO7FI092gHUDK6iZdrJMwkbvdsPYVP6VWQ9GzTLAKZzmwuWDTwZNQRLEfFw2WpNh2TVcIK30w== + integrity: sha512-TUvYLbUzIxYg7MoKaSI2hrK2JK8QNvV9yKL6hUIrAoZmUCksiRo5UFNeFEueUmBfAXKXe7HqdIvGT5Xwvg3fog== tarball: 'file:projects/ui-abstract.tgz' version: 0.0.0 'file:projects/ui-components.tgz': dependencies: - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic-webfont': 1.0.33 '@testing-library/react': 8.0.9_react-dom@16.14.0+react@16.14.0 '@testing-library/react-hooks': 3.7.0_98e0eb37a9f7280a1c5a6c886619f5b4 '@types/chai': 4.2.15 @@ -21764,7 +21731,7 @@ packages: '@types/mocha': 5.2.7 '@types/react': 16.9.43 '@types/react-data-grid': 4.0.2 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/react-highlight-words': 0.11.1 '@types/react-resize-detector': 5.0.0 '@types/react-select': 3.0.26 @@ -21776,11 +21743,11 @@ packages: '@types/sinon-chai': 3.2.5 '@types/testing-library__react-hooks': 3.4.1 callable-instance2: 1.0.0 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 - chai-spies: 1.0.0_chai@4.3.4 - chai-string: 1.5.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 + chai-spies: 1.0.0_chai@4.3.3 + chai-string: 1.5.0_chai@4.3.3 classnames: 2.2.6 cpx: 1.5.0 enzyme: 3.11.0 @@ -21790,7 +21757,7 @@ packages: eventemitter2: 5.0.1 faker: 4.1.0 ignore-styles: 5.0.1 - immer: 8.0.1 + immer: 9.0.1 immutable: 3.8.2 inspire-tree: 5.0.2 jsdom: 11.12.0 @@ -21820,7 +21787,7 @@ packages: rxjs: 6.6.6 shortid: 2.2.16 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 ts-key-enum: 2.0.7 ts-node: 7.0.1 tsconfig-paths: 3.9.0 @@ -21830,12 +21797,12 @@ packages: dev: false name: '@rush-temp/ui-components' resolution: - integrity: sha512-h/shUM+Kf6koztCFezdO6jFtolETdWV/Ck4KkZ+9Fv/b/UW9c1/2FgiCYSdbKlZwTk5W2TC9RwC3821dce2WyQ== + integrity: sha512-sYt8/W10+vbqLhaFTdYliRC3KrlSMHAuVkZVvtfYb5biOAOX1PIorKccfwLnLVfBPMEj1oz4hl6ACTfRVMK9Qw== tarball: 'file:projects/ui-components.tgz' version: 0.0.0 'file:projects/ui-core.tgz_2f645c1465aea7f802b6a9a8594dc28f': dependencies: - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic-webfont': 1.0.33 '@bentley/react-scripts': 3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32 '@testing-library/react': 8.0.9_react-dom@16.14.0+react@16.14.0 '@testing-library/react-hooks': 3.7.0_98e0eb37a9f7280a1c5a6c886619f5b4 @@ -21850,19 +21817,19 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/react': 16.9.43 - '@types/react-autosuggest': 10.1.3 - '@types/react-dom': 16.9.12 + '@types/react-autosuggest': 10.1.2 + '@types/react-dom': 16.9.11 '@types/react-select': 3.0.26 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 '@types/testing-library__react-hooks': 3.4.1 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 - chai-spies: 1.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 + chai-spies: 1.0.0_chai@4.3.3 classnames: 2.2.6 cpx: 1.5.0 - dompurify: 2.2.7 + dompurify: 2.2.6 enzyme: 3.11.0 enzyme-adapter-react-16: 1.15.6_4f82faf5e8cab057bc46d4d95079ec42 enzyme-to-json: 3.6.1_enzyme@3.11.0 @@ -21883,7 +21850,7 @@ packages: resize-observer-polyfill: 1.5.1 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 svg-sprite-loader: 4.2.1_webpack@4.42.0 ts-node: 7.0.1 tsconfig-paths: 3.9.0 @@ -21898,13 +21865,13 @@ packages: webpack: '*' webpack-cli: '*' resolution: - integrity: sha512-z+MxeQ12v/1P1fZFoaL+oeMgdAUshB9tD78uQw/xYh0fNayKNn5eqX3A87GQ2S+tGDGwkPZE6kgaCAobNjZR/A== + integrity: sha512-wxt26nlxbmDPQjF4KkhwjOUnGl8ltMIm18b7kOKbUtBy26XBm9amQ6CKd2KJBCl0O7SwVemSzxVbTizG85MK7Q== tarball: 'file:projects/ui-core.tgz' version: 0.0.0 'file:projects/ui-framework.tgz_2f645c1465aea7f802b6a9a8594dc28f': dependencies: - '@bentley/icons-generic': 1.0.34 - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic': 1.0.33 + '@bentley/icons-generic-webfont': 1.0.33 '@bentley/react-scripts': 3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32 '@testing-library/react': 8.0.9_react-dom@16.14.0+react@16.14.0 '@testing-library/react-hooks': 3.7.0_98e0eb37a9f7280a1c5a6c886619f5b4 @@ -21919,17 +21886,17 @@ packages: '@types/mocha': 5.2.7 '@types/node': 10.14.1 '@types/react': 16.9.43 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/react-redux': 7.1.16 '@types/react-resize-detector': 5.0.0 '@types/rimraf': 2.0.4 '@types/sinon': 9.0.11 '@types/sinon-chai': 3.2.5 '@types/testing-library__react-hooks': 3.4.1 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 - chai-spies: 1.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 + chai-spies: 1.0.0_chai@4.3.3 classnames: 2.2.6 cpx: 1.5.0 enzyme: 3.11.0 @@ -21938,7 +21905,7 @@ packages: eslint: 6.8.0 faker: 4.1.0 ignore-styles: 5.0.1 - immer: 8.0.1 + immer: 9.0.1 jsdom: 11.12.0 jsdom-global: 3.0.2_jsdom@11.12.0 lodash: 4.17.21 @@ -21949,7 +21916,7 @@ packages: react-dnd: 11.1.3_react-dom@16.14.0+react@16.14.0 react-dnd-html5-backend: 11.1.3 react-dom: 16.14.0_react@16.14.0 - react-redux: 7.2.3_bbabd8c34ea235719dc50e75b43f85a4 + react-redux: 7.2.2_bbabd8c34ea235719dc50e75b43f85a4 react-resize-detector: 5.2.0_react-dom@16.14.0+react@16.14.0 react-split-pane: 0.1.92_react-dom@16.14.0+react@16.14.0 react-test-renderer: 16.14.0_react@16.14.0 @@ -21957,7 +21924,7 @@ packages: rimraf: 3.0.2 rxjs: 6.6.6 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 svg-sprite-loader: 4.2.1_webpack@4.42.0 ts-node: 7.0.1 tsconfig-paths: 3.9.0 @@ -21972,7 +21939,7 @@ packages: webpack: '*' webpack-cli: '*' resolution: - integrity: sha512-NK/JKuiwvygLCf2hHmg/2mQFyPXZiP7EKr5+SFi2ojtB2WjErvKEZW4+ZynHMIBYBFxISaPtWXyKOJy88YgDHw== + integrity: sha512-+tN2kAjZ4sc2d8Ue4OsryxJ1Rsse2vlSMBpZuzJV3VkxTd98NEyNe0m676/J1pLox9xFHAx+hrbUTe8+5T512A== tarball: 'file:projects/ui-framework.tgz' version: 0.0.0 'file:projects/ui-ninezone.tgz_react-test-renderer@16.14.0': @@ -21987,14 +21954,14 @@ packages: '@types/enzyme': 3.9.3 '@types/mocha': 5.2.7 '@types/react': 16.9.43 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/sinon': 9.0.11 '@types/testing-library__react-hooks': 3.4.1 '@types/uuid': 7.0.4 - chai: 4.3.4 - chai-as-promised: 7.1.1_chai@4.3.4 - chai-jest-snapshot: 2.0.0_chai@4.3.4 - chai-spies: 1.0.0_chai@4.3.4 + chai: 4.3.3 + chai-as-promised: 7.1.1_chai@4.3.3 + chai-jest-snapshot: 2.0.0_chai@4.3.3 + chai-spies: 1.0.0_chai@4.3.3 classnames: 2.2.6 cpx: 1.5.0 enzyme: 3.11.0 @@ -22002,7 +21969,7 @@ packages: enzyme-to-json: 3.6.1_enzyme@3.11.0 eslint: 6.8.0 ignore-styles: 5.0.1 - immer: 8.0.1 + immer: 9.0.1 jsdom: 11.12.0 jsdom-global: 3.0.2_jsdom@11.12.0 mocha: 5.2.0 @@ -22012,7 +21979,7 @@ packages: react-dom: 16.14.0_react@16.14.0 rimraf: 3.0.2 sinon: 9.2.4 - sinon-chai: 3.6.0_chai@4.3.4+sinon@9.2.4 + sinon-chai: 3.5.0_chai@4.3.3+sinon@9.2.4 ts-node: 7.0.1 typemoq: 2.1.0 typescript: 4.1.5 @@ -22023,21 +21990,21 @@ packages: peerDependencies: react-test-renderer: '*' resolution: - integrity: sha512-IjQ5ht1NuvjXn5zxFiwBZD+9f1heVtm0VMBf4V30Bl46jHfBpNDabezxoPzJC6fxPC+j3mF7KI9Huo6/4o4DQQ== + integrity: sha512-vJBu4aqzFSL3hqxdKLTlYOajeGCk46tDSvUdmUaPE4s8oiXriiYn63luPtyojjsd4P+3LIT3TsnBU6d/MdU/9A== tarball: 'file:projects/ui-ninezone.tgz' version: 0.0.0 'file:projects/ui-test-app.tgz_webpack-cli@3.3.12': dependencies: '@axe-core/react': 4.1.1 - '@bentley/icons-generic': 1.0.34 - '@bentley/icons-generic-webfont': 1.0.34 + '@bentley/icons-generic': 1.0.33 + '@bentley/icons-generic-webfont': 1.0.33 '@bentley/react-scripts': 3.4.9_50a9a52775dfbe3fbd64ccf8e2a3fa32 '@types/classnames': 2.2.11 '@types/lorem-ipsum': 1.0.2 '@types/node': 10.14.1 '@types/react': 16.9.43 '@types/react-beautiful-dnd': 12.1.3 - '@types/react-dom': 16.9.12 + '@types/react-dom': 16.9.11 '@types/react-redux': 7.1.16 '@types/react-select': 3.0.26 '@types/semver': 5.5.0 @@ -22046,7 +22013,7 @@ packages: cross-env: 5.2.1 dotenv: 8.2.0 dotenv-expand: 5.1.0 - electron: 11.4.1 + electron: 11.3.0 eslint: 6.8.0 fs-extra: 8.1.0 lorem-ipsum: 2.0.3 @@ -22054,10 +22021,10 @@ packages: mobx-react: 5.4.4_mobx@5.15.7+react@16.14.0 npm-run-all: 4.1.5 react: 16.14.0 - react-beautiful-dnd: 13.1.0_react-dom@16.14.0+react@16.14.0 + react-beautiful-dnd: 13.0.0_react-dom@16.14.0+react@16.14.0 react-compound-slider: 2.5.0_react@16.14.0 react-dom: 16.14.0_react@16.14.0 - react-redux: 7.2.3_bbabd8c34ea235719dc50e75b43f85a4 + react-redux: 7.2.2_bbabd8c34ea235719dc50e75b43f85a4 react-select: 3.1.0_react-dom@16.14.0+react@16.14.0 redux: 4.0.5 rimraf: 3.0.2 @@ -22071,7 +22038,7 @@ packages: peerDependencies: webpack-cli: '*' resolution: - integrity: sha512-tlqwKM749iI6BFF26Xi7P4NnJUQmfWqcsrClNYkUp9UghZYFkabGppKaftd1zSTyFmkVkGgdeKEL0+kq7ujpnA== + integrity: sha512-BaZ/rgI/4ZkK2uChyvgw54gFHdlS3e+HidrSlYVmFN1nIm6vc0iF79QxWzqnekmSE+yxmWIeSDhb01VWe9P+Kw== tarball: 'file:projects/ui-test-app.tgz' version: 0.0.0 'file:projects/ui-test-extension.tgz_webpack@4.42.0': @@ -22095,7 +22062,7 @@ packages: peerDependencies: webpack: '*' resolution: - integrity: sha512-geimJNnYWZaLFTReKASFzk6W+SCCmn6OoqGtST2sDMjmgKe3vuf8Q7p0dvNyaU+rvTqYHmNit/yTZ7AePjymJA== + integrity: sha512-XMcnyrieGThpN+Vx2ksFZ/gilIBxMYX+YXt3We0hocqu6zx7xtyOi6RPZfVweLHIqjLxH0CkpjVPcq7tbAkC3g== tarball: 'file:projects/ui-test-extension.tgz' version: 0.0.0 'file:projects/usage-logging-client.tgz': @@ -22103,7 +22070,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 mocha: 5.2.0 nyc: 14.1.1 @@ -22114,7 +22081,7 @@ packages: dev: false name: '@rush-temp/usage-logging-client' resolution: - integrity: sha512-HlBqYbJ/aink9KVkyUSefNLC91spX/coXnmoP+iciBCiRJ8patMTCQA6Fod5JxlX6JapiWJglceO3Rj7usQvKQ== + integrity: sha512-+CfNLrcqPrUVgBXNdb8lHq8xeT50bQEOLD7qnNo7qU0OMzFsZNtZIMq0GQ0eohz6Ia5xpX7qQQcVzYvZR4XWtQ== tarball: 'file:projects/usage-logging-client.tgz' version: 0.0.0 'file:projects/webgl-compatibility.tgz': @@ -22122,7 +22089,7 @@ packages: '@types/chai': 4.2.15 '@types/mocha': 5.2.7 '@types/node': 10.14.1 - chai: 4.3.4 + chai: 4.3.3 eslint: 6.8.0 glob: 7.1.6 mocha: 5.2.0 @@ -22133,7 +22100,7 @@ packages: dev: false name: '@rush-temp/webgl-compatibility' resolution: - integrity: sha512-hqQkveP2sf4XGHPBupmwcix/f0ZPlRdsN1bz5OuUYBRLb9JlkcxErsEZs3ytwEe3gbGDQiw0idBKBUJnwbXJLA== + integrity: sha512-5lDyJi8KtopEBvczBqtzrepHM4Wj34iHAlxaPQit9hdputz2Jv1xaGP4OUdHzKe6jo1wmNRsP3mW3cqRzSnlWw== tarball: 'file:projects/webgl-compatibility.tgz' version: 0.0.0 'file:projects/webpack-tools-core.tgz': @@ -22161,9 +22128,10 @@ packages: dev: false name: '@rush-temp/webpack-tools-core' resolution: - integrity: sha512-qjK/WLrhbCoOmujIGNoh0n5AFS3Itd+or1LTvVdjfmoIrgeFpbIZdO9qGggc3wjDnzq12F/wGY6nz8OKsG4HCg== + integrity: sha512-u0PwjfZhFhQPgSTAByrRFmJHHep/tr+HfUFSWZFirL0WJZZestYFYoTpFO4m2yT2jRH8qatjokzkOC7iifPBCA== tarball: 'file:projects/webpack-tools-core.tgz' version: 0.0.0 +registry: '' specifiers: '@axe-core/react': ^4.1.1 '@azure-tools/azcopy-node': ^2.0.0 @@ -22425,7 +22393,7 @@ specifiers: i18next-node-fs-backend: ^2.1.3 i18next-xhr-backend: ^2.0.1 ignore-styles: ^5.0.1 - immer: 8.0.1 + immer: ^9.0.1 immutable: ^3.8.2 inspire-tree: ^5.0.1 istanbul-instrumenter-loader: ^3.0.1 diff --git a/full-stack-tests/presentation/package.json b/full-stack-tests/presentation/package.json index b55a452989f..3011f89ddfc 100644 --- a/full-stack-tests/presentation/package.json +++ b/full-stack-tests/presentation/package.json @@ -59,7 +59,7 @@ "cpx": "^1.5.0", "deep-equal": "^1", "faker": "^4.1.0", - "immer": "8.0.1", + "immer": "^9.0.1", "mocha": "^5.2.0", "react": "^16.8.0", "react-dom": "^16.8.0", @@ -91,4 +91,4 @@ ], "extends": "plugin:@bentley/imodeljs-recommended" } -} +} \ No newline at end of file diff --git a/presentation/components/package.json b/presentation/components/package.json index 5ad1570eb72..83c50e69578 100644 --- a/presentation/components/package.json +++ b/presentation/components/package.json @@ -98,7 +98,7 @@ "eslint": "^6.8.0", "faker": "^4.1.0", "ignore-styles": "^5.0.1", - "immer": "8.0.1", + "immer": "^9.0.1", "jsdom-global": "3.0.2", "mocha": "^5.2.0", "nyc": "^14.0.0", @@ -135,4 +135,4 @@ ], "extends": "plugin:@bentley/ui" } -} +} \ No newline at end of file diff --git a/ui/components/package.json b/ui/components/package.json index 1db63d4d585..a772a9d5f08 100644 --- a/ui/components/package.json +++ b/ui/components/package.json @@ -124,7 +124,7 @@ "callable-instance2": "1.0.0", "classnames": "^2.2.5", "eventemitter2": "^5.0.1", - "immer": "8.0.1", + "immer": "^9.0.1", "immutable": "^3.8.2", "inspire-tree": "^5.0.1", "linkify-it": "~2.2.0", @@ -166,4 +166,4 @@ "plugin:@bentley/jsdoc" ] } -} +} \ No newline at end of file diff --git a/ui/framework/package.json b/ui/framework/package.json index 5aa5e80da94..855a40c1944 100644 --- a/ui/framework/package.json +++ b/ui/framework/package.json @@ -142,7 +142,7 @@ "@bentley/icons-generic-webfont": "^1.0.15", "@bentley/presentation-components": "2.15.0-dev.7", "classnames": "^2.2.5", - "immer": "8.0.1", + "immer": "^9.0.1", "lodash": "^4.17.10", "react-dnd": "^11.1.3", "react-dnd-html5-backend": "^11.1.3", @@ -174,4 +174,4 @@ "plugin:@bentley/jsdoc" ] } -} +} \ No newline at end of file diff --git a/ui/ninezone/package.json b/ui/ninezone/package.json index 38ffc7dda95..1178b95aac8 100644 --- a/ui/ninezone/package.json +++ b/ui/ninezone/package.json @@ -91,7 +91,7 @@ ], "dependencies": { "classnames": "^2.2.5", - "immer": "8.0.1", + "immer": "^9.0.1", "uuid": "^7.0.3" }, "nyc": { @@ -118,4 +118,4 @@ "plugin:@bentley/jsdoc" ] } -} +} \ No newline at end of file From 9f9bde1ac237289be6454131ce4e57d4aa44a095 Mon Sep 17 00:00:00 2001 From: bsteinbk <65047615+bsteinbk@users.noreply.github.com> Date: Thu, 25 Mar 2021 13:27:30 -0400 Subject: [PATCH 08/50] Fix color picker hue slider (#1040) * fix hue display in DR by removing webkit prefix. Adjust max slider value. * rush change Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../ui-components/fixHueSlider_2021-03-25-16-15.json | 11 +++++++++++ ui/components/src/ui-components/color/HueSlider.scss | 3 --- ui/components/src/ui-components/color/HueSlider.tsx | 8 ++++---- 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 common/changes/@bentley/ui-components/fixHueSlider_2021-03-25-16-15.json diff --git a/common/changes/@bentley/ui-components/fixHueSlider_2021-03-25-16-15.json b/common/changes/@bentley/ui-components/fixHueSlider_2021-03-25-16-15.json new file mode 100644 index 00000000000..34f114dadbb --- /dev/null +++ b/common/changes/@bentley/ui-components/fixHueSlider_2021-03-25-16-15.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ui-components", + "comment": "Fix color picker hue display in DR by removing webkit prefix. Adjust max slider value.", + "type": "none" + } + ], + "packageName": "@bentley/ui-components", + "email": "65047615+bsteinbk@users.noreply.github.com" +} \ No newline at end of file diff --git a/ui/components/src/ui-components/color/HueSlider.scss b/ui/components/src/ui-components/color/HueSlider.scss index 358804e95dd..d9e92c85ddd 100644 --- a/ui/components/src/ui-components/color/HueSlider.scss +++ b/ui/components/src/ui-components/color/HueSlider.scss @@ -28,7 +28,6 @@ height: 100%; border-radius: 1em; background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); - background: -webkit-linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); } .components-hue-pointer { @@ -52,8 +51,6 @@ border-radius: 1em; background: linear-gradient(to top, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); - background: -webkit-linear-gradient(to top, #f00 0%, #ff0 17%, - #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); } .components-hue-pointer { diff --git a/ui/components/src/ui-components/color/HueSlider.tsx b/ui/components/src/ui-components/color/HueSlider.tsx index aa306920c5a..937cd6b839a 100644 --- a/ui/components/src/ui-components/color/HueSlider.tsx +++ b/ui/components/src/ui-components/color/HueSlider.tsx @@ -17,10 +17,10 @@ import { SpecialKey } from "@bentley/ui-abstract"; // hue is a value from 0 to 360 function calculateHue(currentPos: number, high: number, isVertical: boolean) { // istanbul ignore next - if (currentPos < 0) { - return 359; - } else if (currentPos > high) { - return 0; + if (currentPos <= 0) { + return isVertical?359:0; + } else if (currentPos >= high) { + return isVertical?0:359; } else { let percent = ((currentPos * 100) / high); if (isVertical) From 347425254048056c7f5baeb4e94e1d12b7b71102 Mon Sep 17 00:00:00 2001 From: Bill Goehrig <33036725+wgoehrig@users.noreply.github.com> Date: Thu, 25 Mar 2021 14:02:20 -0400 Subject: [PATCH 09/50] Fallback to use V1 checkpoints when a V2 checkpoint contains invalid dbGuid (#1042) * Clarify misleading log messages in RpcBriefcaseUtility.open * Update SnapshotDb.openCheckpointV2 to throw when mismatched dbGuids are detected. * rush change. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- common/api/imodeljs-backend.api.md | 1 + .../fix-v2-guidmismatch_2021-03-25-16-33.json | 11 ++++++ core/backend/src/CheckpointManager.ts | 35 +++++++++++------ core/backend/src/IModelDb.ts | 6 +++ .../src/rpc-impl/RpcBriefcaseUtility.ts | 13 ++++++- .../src/test/standalone/IModel.test.ts | 38 +++++++++++++++++++ .../src/frontend/hub/IModelConnection.test.ts | 2 +- 7 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 common/changes/@bentley/imodeljs-backend/fix-v2-guidmismatch_2021-03-25-16-33.json diff --git a/common/api/imodeljs-backend.api.md b/common/api/imodeljs-backend.api.md index 20bc9425951..9b56f0419eb 100644 --- a/common/api/imodeljs-backend.api.md +++ b/common/api/imodeljs-backend.api.md @@ -690,6 +690,7 @@ export class CheckpointManager { // (undocumented) static readonly onDownload: BeEvent<(job: DownloadJob) => void>; static tryOpenLocalFile(request: DownloadRequest): SnapshotDb | undefined; + static validateCheckpointGuids(checkpoint: CheckpointProps, nativeDb: IModelJsNative.DgnDb): void; // (undocumented) static verifyCheckpoint(checkpoint: CheckpointProps, fileName: string): boolean; } diff --git a/common/changes/@bentley/imodeljs-backend/fix-v2-guidmismatch_2021-03-25-16-33.json b/common/changes/@bentley/imodeljs-backend/fix-v2-guidmismatch_2021-03-25-16-33.json new file mode 100644 index 00000000000..a3b433e34e8 --- /dev/null +++ b/common/changes/@bentley/imodeljs-backend/fix-v2-guidmismatch_2021-03-25-16-33.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-backend", + "comment": "", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-backend", + "email": "33036725+wgoehrig@users.noreply.github.com" +} \ No newline at end of file diff --git a/core/backend/src/CheckpointManager.ts b/core/backend/src/CheckpointManager.ts index 443cc7d7fcd..52881b59c88 100644 --- a/core/backend/src/CheckpointManager.ts +++ b/core/backend/src/CheckpointManager.ts @@ -14,7 +14,7 @@ import { } from "@bentley/bentleyjs-core"; import { CheckpointQuery, CheckpointV2Query } from "@bentley/imodelhub-client"; import { BriefcaseIdValue, DownloadBriefcaseStatus, IModelError } from "@bentley/imodeljs-common"; -import { BlobDaemon, BlobDaemonCommandArg } from "@bentley/imodeljs-native"; +import { BlobDaemon, BlobDaemonCommandArg, IModelJsNative } from "@bentley/imodeljs-native"; import { AuthorizedClientRequestContext, ProgressCallback, UserCancelledError } from "@bentley/itwin-client"; import { BackendLoggerCategory } from "./BackendLoggerCategory"; import { BriefcaseManager } from "./BriefcaseManager"; @@ -271,17 +271,7 @@ export class V1CheckpointManager { if (dbChangeSetId !== checkpoint.mergedChangeSetId) throw new IModelError(IModelStatus.ValidationFailed, "ParentChangeSetId of the checkpoint was not correctly setup", Logger.logError, loggerCategory, () => ({ ...traceInfo, ...checkpoint, dbChangeSetId })); - const dbGuid = Guid.normalize(nativeDb.getDbGuid()); - if (dbGuid !== Guid.normalize(requestedCkp.iModelId)) { - Logger.logWarning(loggerCategory, "iModelId is not properly setup in the checkpoint. Updated checkpoint to the correct iModelId.", () => ({ ...traceInfo, ...checkpoint, dbGuid })); - nativeDb.setDbGuid(Guid.normalize(requestedCkp.iModelId)); - // Required to reset the ChangeSetId because setDbGuid clears the value. - nativeDb.saveLocalValue("ParentChangeSetId", dbChangeSetId); - } - - const dbContextGuid = Guid.normalize(nativeDb.queryProjectGuid()); - if (dbContextGuid !== Guid.normalize(requestedCkp.contextId)) - throw new IModelError(IModelStatus.ValidationFailed, "ContextId was not properly setup in the checkpoint", Logger.logError, loggerCategory, () => ({ ...traceInfo, dbContextGuid })); + CheckpointManager.validateCheckpointGuids(requestedCkp, nativeDb); // Apply change sets if necessary if (dbChangeSetId !== requestedCkp.changeSetId) { @@ -344,6 +334,27 @@ export class CheckpointManager { return V1CheckpointManager.downloadCheckpoint(request); } + /** checks a file's dbGuid & contextId for consistency, and updates the dbGuid when possible */ + public static validateCheckpointGuids(checkpoint: CheckpointProps, nativeDb: IModelJsNative.DgnDb) { + const traceInfo = { contextId: checkpoint.contextId, iModelId: checkpoint.iModelId }; + + const dbChangeSetId = nativeDb.getParentChangeSetId(); + const dbGuid = Guid.normalize(nativeDb.getDbGuid()); + if (dbGuid !== Guid.normalize(checkpoint.iModelId)) { + if (nativeDb.isReadonly()) + throw new IModelError(IModelStatus.ValidationFailed, "iModelId is not properly setup in the checkpoint", Logger.logError, loggerCategory, () => ({ ...traceInfo, dbGuid })); + + Logger.logWarning(loggerCategory, "iModelId is not properly setup in the checkpoint. Updated checkpoint to the correct iModelId.", () => ({ ...traceInfo, dbGuid })); + nativeDb.setDbGuid(Guid.normalize(checkpoint.iModelId)); + // Required to reset the ChangeSetId because setDbGuid clears the value. + nativeDb.saveLocalValue("ParentChangeSetId", dbChangeSetId); + } + + const dbContextGuid = Guid.normalize(nativeDb.queryProjectGuid()); + if (dbContextGuid !== Guid.normalize(checkpoint.contextId)) + throw new IModelError(IModelStatus.ValidationFailed, "ContextId was not properly setup in the checkpoint", Logger.logError, loggerCategory, () => ({ ...traceInfo, dbContextGuid })); + } + /** @returns true if the file is the checkpoint requested */ public static verifyCheckpoint(checkpoint: CheckpointProps, fileName: string): boolean { if (!IModelJsFs.existsSync(fileName)) diff --git a/core/backend/src/IModelDb.ts b/core/backend/src/IModelDb.ts index aa5669bc821..cd949c38084 100644 --- a/core/backend/src/IModelDb.ts +++ b/core/backend/src/IModelDb.ts @@ -2605,6 +2605,12 @@ export class SnapshotDb extends IModelDb { const filePath = await V2CheckpointManager.attach(checkpoint); const snapshot = SnapshotDb.openFile(filePath, { lazyBlockCache: true, key: CheckpointManager.getKey(checkpoint) }); snapshot._contextId = checkpoint.contextId; + try { + CheckpointManager.validateCheckpointGuids(checkpoint, snapshot.nativeDb); + } catch (err) { + snapshot.close(); + throw err; + } return snapshot; } diff --git a/core/backend/src/rpc-impl/RpcBriefcaseUtility.ts b/core/backend/src/rpc-impl/RpcBriefcaseUtility.ts index 81b751a43b9..d642b378f9f 100644 --- a/core/backend/src/rpc-impl/RpcBriefcaseUtility.ts +++ b/core/backend/src/rpc-impl/RpcBriefcaseUtility.ts @@ -12,7 +12,7 @@ import { BriefcaseProps, IModelConnectionProps, IModelError, IModelRpcOpenProps, import { AuthorizedClientRequestContext } from "@bentley/itwin-client"; import { BackendLoggerCategory } from "../BackendLoggerCategory"; import { BriefcaseManager } from "../BriefcaseManager"; -import { CheckpointProps, V1CheckpointManager } from "../CheckpointManager"; +import { CheckpointManager, CheckpointProps, V1CheckpointManager } from "../CheckpointManager"; import { BriefcaseDb, IModelDb, SnapshotDb } from "../IModelDb"; import { IModelHost } from "../IModelHost"; import { IModelJsFs } from "../IModelJsFs"; @@ -127,12 +127,21 @@ export class RpcBriefcaseUtility { // opening a checkpoint, readonly. let db: SnapshotDb | void; + // first check if it's already open + db = SnapshotDb.tryFindByKey(CheckpointManager.getKey(checkpoint)); + if (db) { + Logger.logTrace(loggerCategory, "Checkpoint was already open", () => ({ ...tokenProps })); + return db; + } + try { - // first try V2 checkpoint + // now try V2 checkpoint db = await SnapshotDb.openCheckpointV2(checkpoint); requestContext.enter(); Logger.logTrace(loggerCategory, "using V2 checkpoint briefcase", () => ({ ...tokenProps })); } catch (e) { + Logger.logTrace(loggerCategory, "unable to open V2 checkpoint - falling back to V1 checkpoint", () => ({ ...tokenProps })); + // this isn't a v2 checkpoint. Set up a race between the specified timeout period and the open. Throw an RpcPendingResponse exception if the timeout happens first. const request = { checkpoint, diff --git a/core/backend/src/test/standalone/IModel.test.ts b/core/backend/src/test/standalone/IModel.test.ts index 1e232b9988a..fbee8f81da3 100644 --- a/core/backend/src/test/standalone/IModel.test.ts +++ b/core/backend/src/test/standalone/IModel.test.ts @@ -1709,6 +1709,7 @@ describe("iModel", () => { const iModelId = snapshot.getGuid(); const contextId = Guid.createValue(); const changeSetId = generateChangeSetId(); + snapshot.nativeDb.saveProjectGuid(Guid.normalize(contextId)); snapshot.nativeDb.saveLocalValue("ParentChangeSetId", changeSetId); // even fake checkpoints need a changeSetId! snapshot.saveChanges(); snapshot.close(); @@ -1755,6 +1756,43 @@ describe("iModel", () => { checkpoint.close(); }); + it("should throw for invalid dbGuid in v2 checkpoint", async () => { + const dbPath = IModelTestUtils.prepareOutputFile("IModel", "TestCheckpoint.bim"); + const snapshot = SnapshotDb.createEmpty(dbPath, { rootSubject: { name: "test" } }); + const iModelId = Guid.createValue(); // This is wrong - it should be `snapshot.getGuid()`! + const contextId = Guid.createValue(); + const changeSetId = generateChangeSetId(); + snapshot.nativeDb.saveProjectGuid(Guid.normalize(contextId)); + snapshot.nativeDb.saveLocalValue("ParentChangeSetId", changeSetId); + snapshot.saveChanges(); + snapshot.close(); + + // Mock iModelHub + const mockCheckpointV2: CheckpointV2 = { + wsgId: "INVALID", + ecId: "INVALID", + changeSetId, + containerAccessKeyAccount: "testAccount", + containerAccessKeyContainer: `imodelblocks-${iModelId}`, + containerAccessKeySAS: "testSAS", + containerAccessKeyDbName: "testDb", + }; + const checkpointsV2Handler = IModelHost.iModelClient.checkpointsV2; + sinon.stub(checkpointsV2Handler, "get").callsFake(async () => [mockCheckpointV2]); + sinon.stub(IModelHost.iModelClient, "checkpointsV2").get(() => checkpointsV2Handler); + + // Mock blockcacheVFS daemon + sinon.stub(BlobDaemon, "getDbFileName").callsFake(() => dbPath); + const daemonSuccessResult = { result: DbResult.BE_SQLITE_OK, errMsg: "" }; + sinon.stub(BlobDaemon, "command").callsFake(async () => daemonSuccessResult); + + process.env.BLOCKCACHE_DIR = "/foo/"; + const ctx = ClientRequestContext.current as AuthorizedClientRequestContext; + + const error = await getIModelError(SnapshotDb.openCheckpointV2({ requestContext: ctx, contextId, iModelId, changeSetId })); + expectIModelError(IModelStatus.ValidationFailed, error); + }); + it("should throw when opening checkpoint without blockcache dir env", async () => { process.env.BLOCKCACHE_DIR = ""; const ctx = ClientRequestContext.current as AuthorizedClientRequestContext; diff --git a/full-stack-tests/core/src/frontend/hub/IModelConnection.test.ts b/full-stack-tests/core/src/frontend/hub/IModelConnection.test.ts index dcdf75a3bbc..13368c7220b 100644 --- a/full-stack-tests/core/src/frontend/hub/IModelConnection.test.ts +++ b/full-stack-tests/core/src/frontend/hub/IModelConnection.test.ts @@ -150,7 +150,7 @@ describe("IModelConnection (#integration)", () => { assert.isNotNull(noVersionsIModel3); }); - it("should send a usage log everytime an iModel is opened", async () => { + it.skip("should send a usage log everytime an iModel is opened", async () => { const projectId = await TestUtility.getTestProjectId("iModelJsIntegrationTest"); const iModelId = await TestUtility.getTestIModelId(projectId, "ReadOnlyTest"); From ef34c10563a41dfed6cb69a06316bc5a5ddcc118 Mon Sep 17 00:00:00 2001 From: MarcNeely <36053767+MarcNeely@users.noreply.github.com> Date: Thu, 25 Mar 2021 14:37:23 -0500 Subject: [PATCH 10/50] Z scaling (#937) * modify model transform keyin to take scaling * test * fix instancing * Compare forceNoInstancing * restore deleted property. * Remove unnecessary invalidateScene and requestRedraw calls. * Cleanup & make work nicer with Z offset * fix rgb axes in measure distance tool * Remove debug * lint & typo * Modify tessellation for nonuniform scaling * rush change * extract-api * Replace use of System.instance with IModelApp.rSys * move scaleFactor calc to TileDrawArgs constructor Co-authored-by: Paul Connelly <22944042+pmconne@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- common/api/imodeljs-frontend.api.md | 29 +++--- .../z-scaling_2021-03-22-21-25.json | 11 +++ core/frontend/src/AccuSnap.ts | 21 +++- core/frontend/src/ViewState.ts | 22 +++++ core/frontend/src/Viewport.ts | 14 ++- core/frontend/src/render/RenderSystem.ts | 3 + .../src/render/webgl/BranchUniforms.ts | 12 +++ core/frontend/src/render/webgl/System.ts | 1 + core/frontend/src/render/webgl/glsl/Vertex.ts | 20 +++- core/frontend/src/tile/PrimaryTileTree.ts | 42 ++++++-- core/frontend/src/tile/Tile.ts | 2 +- core/frontend/src/tile/TileDrawArgs.ts | 34 ++++++- core/frontend/src/tools/MeasureTool.ts | 96 ++++++++++++++----- core/frontend/src/tools/ViewTool.ts | 10 +- .../public/locales/en/SVTTools.json | 3 + .../display-test-app/src/frontend/App.ts | 2 + .../src/frontend/DisplayScale.ts | 81 ++++++++++++++++ 17 files changed, 344 insertions(+), 59 deletions(-) create mode 100644 common/changes/@bentley/imodeljs-frontend/z-scaling_2021-03-22-21-25.json create mode 100644 test-apps/display-test-app/src/frontend/DisplayScale.ts diff --git a/common/api/imodeljs-frontend.api.md b/common/api/imodeljs-frontend.api.md index 402e87dea1d..a53ac3c19f6 100644 --- a/common/api/imodeljs-frontend.api.md +++ b/common/api/imodeljs-frontend.api.md @@ -5930,15 +5930,7 @@ export class MeasureAreaTool extends MeasureElementTool { // @alpha (undocumented) export class MeasureDistanceTool extends PrimitiveTool { // (undocumented) - protected readonly _acceptedSegments: { - distance: number; - slope: number; - start: Point3d; - end: Point3d; - delta: Vector3d; - refAxes: Matrix3d; - marker: MeasureMarker; - }[]; + protected readonly _acceptedSegments: Segment[]; // (undocumented) protected acceptNewSegments(): Promise; // (undocumented) @@ -5952,7 +5944,7 @@ export class MeasureDistanceTool extends PrimitiveTool { // (undocumented) protected displayDelta(context: DecorateContext, seg: any): void; // (undocumented) - protected displayDynamicDistance(context: DecorateContext, points: Point3d[]): void; + protected displayDynamicDistance(context: DecorateContext, points: Point3d[], adjustedPoints: Point3d[]): void; // (undocumented) getDecorationGeometry(_hit: HitDetail): GeometryStreamProps | undefined; // (undocumented) @@ -5968,12 +5960,11 @@ export class MeasureDistanceTool extends PrimitiveTool { // (undocumented) isValidLocation(_ev: BeButtonEvent, _isButtonEvent: boolean): boolean; // (undocumented) + protected _lastMotionAdjustedPt?: Point3d; + // (undocumented) protected _lastMotionPt?: Point3d; // (undocumented) - protected readonly _locationData: { - point: Point3d; - refAxes: Matrix3d; - }[]; + protected readonly _locationData: Location[]; // (undocumented) onDataButtonDown(ev: BeButtonEvent): Promise; // (undocumented) @@ -8114,6 +8105,8 @@ export abstract class RenderSystem implements IDisposable { get supportsInstancing(): boolean; // @internal (undocumented) get supportsLogZBuffer(): boolean; + // @internal (undocumented) + get supportsNonuniformScaledInstancing(): boolean; } // @public @@ -8509,6 +8502,8 @@ export class ScreenViewport extends Viewport { source: DepthPointSource; sourceId?: string; }; + // @internal (undocumented) + picker: ElementPicker; pickNearestVisibleGeometry(pickPoint: Point3d, radius?: number, allowNonLocatable?: boolean, out?: Point3d): Point3d | undefined; // @internal static removeAllChildren(el: HTMLDivElement): void; @@ -10199,6 +10194,8 @@ export class TileDrawArgs { // @internal (undocumented) parentsAndChildrenExclusive: boolean; // @internal (undocumented) + readonly pixelSizeScaleFactor: number; + // @internal (undocumented) planarClassifier?: RenderPlanarClassifier; // @internal processSelectedTiles(_tiles: Tile[]): void; @@ -12675,6 +12672,10 @@ export abstract class ViewState extends ElementState { // (undocumented) toJSON(): ViewDefinitionProps; toProps(): ViewStateProps; + // @internal (undocumented) + transformNormalByModelDisplayTransform(modelId: string | undefined, normal: Vector3d): void; + // @internal (undocumented) + transformPointByModelDisplayTransform(modelId: string | undefined, pnt: Point3d, inverse: boolean): void; // (undocumented) protected _updateMaxGlobalScopeFactor(): void; get viewFlags(): ViewFlags; diff --git a/common/changes/@bentley/imodeljs-frontend/z-scaling_2021-03-22-21-25.json b/common/changes/@bentley/imodeljs-frontend/z-scaling_2021-03-22-21-25.json new file mode 100644 index 00000000000..7b035fe06de --- /dev/null +++ b/common/changes/@bentley/imodeljs-frontend/z-scaling_2021-03-22-21-25.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-frontend", + "comment": "Added capability to scale the model display transform nonuniformly and have still Accusnap properly.", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-frontend", + "email": "36053767+MarcNeely@users.noreply.github.com" +} \ No newline at end of file diff --git a/core/frontend/src/AccuSnap.ts b/core/frontend/src/AccuSnap.ts index 677492c0a21..9d0fc560881 100644 --- a/core/frontend/src/AccuSnap.ts +++ b/core/frontend/src/AccuSnap.ts @@ -705,28 +705,39 @@ export class AccuSnap implements Decorator { }; // If this hit is from a plan projection model, apply the model's elevation to the snap point for display. + // Likewise, if it is a hit on a model with a display transform, apply the model's transform to the snap point. let snapPoint = result.snapPoint!; const elevation = undefined !== thisHit.modelId ? thisHit.viewport.view.getModelElevation(thisHit.modelId) : 0; - if (0 !== elevation) { + if (0 !== elevation || undefined !== thisHit.viewport.view.modelDisplayTransformProvider) { const adjustedSnapPoint = Point3d.fromJSON(snapPoint); + thisHit.viewport.view.transformPointByModelDisplayTransform(thisHit.modelId, adjustedSnapPoint, false); adjustedSnapPoint.z += elevation; snapPoint = adjustedSnapPoint; } const snap = new SnapDetail(thisHit, result.snapMode, result.heat, snapPoint); - // Apply model's elevation to curve for display. + // Apply model's elevation and display transform to curve for display. let transform; - if (0 !== elevation) + if (undefined !== thisHit.modelId && undefined !== thisHit.viewport.view.modelDisplayTransformProvider) { + transform = thisHit.viewport.view.getModelDisplayTransform(thisHit.modelId, Transform.createIdentity()); + if (0 !== elevation) + transform.origin.set(0, 0, elevation); + } else if (0 !== elevation) { transform = Transform.createTranslationXYZ(0, 0, elevation); + } snap.setCurvePrimitive(parseCurve(result.curve), transform, result.geomType); if (undefined !== result.parentGeomType) snap.parentGeomType = result.parentGeomType; - if (undefined !== result.hitPoint) + if (undefined !== result.hitPoint) { snap.hitPoint.setFromJSON(result.hitPoint); // Update hitPoint from readPixels with exact point location corrected to surface/edge geometry... - if (undefined !== result.normal) + thisHit.viewport.view.transformPointByModelDisplayTransform(thisHit.modelId, snap.hitPoint, false); + } + if (undefined !== result.normal) { snap.normal = Vector3d.fromJSON(result.normal); + thisHit.viewport.view.transformNormalByModelDisplayTransform(thisHit.modelId, snap.normal); + } if (SnapMode.Intersection !== snap.snapMode) return snap; diff --git a/core/frontend/src/ViewState.ts b/core/frontend/src/ViewState.ts index 2d83e0ec530..817a39eda82 100644 --- a/core/frontend/src/ViewState.ts +++ b/core/frontend/src/ViewState.ts @@ -1034,6 +1034,28 @@ export abstract class ViewState extends ElementState { return this.modelDisplayTransformProvider ? this.modelDisplayTransformProvider.getModelDisplayTransform(modelId, baseTransform) : baseTransform; } + /** @internal */ + public transformPointByModelDisplayTransform(modelId: string | undefined, pnt: Point3d, inverse: boolean): void { + if (undefined !== modelId && undefined !== this.modelDisplayTransformProvider) { + const transform = this.modelDisplayTransformProvider.getModelDisplayTransform(modelId, Transform.createIdentity()); + const newPnt = inverse ? transform.multiplyInversePoint3d(pnt) : transform.multiplyPoint3d(pnt); + if (undefined !== newPnt) + pnt.set(newPnt.x, newPnt.y, newPnt.z); + } + } + + /** @internal */ + public transformNormalByModelDisplayTransform(modelId: string | undefined, normal: Vector3d): void { + if (undefined !== modelId && undefined !== this.modelDisplayTransformProvider) { + const transform = this.modelDisplayTransformProvider.getModelDisplayTransform(modelId, Transform.createIdentity()); + const newVec = transform.matrix.multiplyInverse(normal); + if (undefined !== newVec) { + newVec.normalizeInPlace(); + normal.set(newVec.x, newVec.y, newVec.z); + } + } + } + /** Invoked when this view becomes the view displayed by the specified [[Viewport]]. * A ViewState can be attached to at most **one** Viewport. * @note If you override this method you **must** call `super.attachToViewport`. diff --git a/core/frontend/src/Viewport.ts b/core/frontend/src/Viewport.ts index fe50f05e06b..1d5c7c93148 100644 --- a/core/frontend/src/Viewport.ts +++ b/core/frontend/src/Viewport.ts @@ -2366,9 +2366,12 @@ export abstract class Viewport implements IDisposable { this.npcToWorld(npc, npc); // If this is a plan projection model, invert the elevation applied to its display transform. + // Likewise, if it is a hit on a model with a display transform, reverse the display transform. const modelId = pixels.getPixel(x, y).featureTable?.modelId; - if (undefined !== modelId) + if (undefined !== modelId) { npc.z -= this.view.getModelElevation(modelId); + this.view.transformPointByModelDisplayTransform(modelId, npc, true); + } } return npc; @@ -2765,6 +2768,9 @@ export class ScreenViewport extends Viewport { return result; } + /** @internal */ + public picker = new ElementPicker(); // Picker used in pickDepthPoint below so it hangs around and can be querried later. + /** Find a point on geometry visible in this Viewport, within a radius of supplied pick point. * If no geometry is selected, return the point projected to the most appropriate reference plane. * @param pickPoint Point to search about, in world coordinates @@ -2781,14 +2787,14 @@ export class ScreenViewport extends Viewport { if (undefined === radius) radius = this.pixelsFromInches(ToolSettings.viewToolPickRadiusInches); - const picker = new ElementPicker(); + this.picker.empty(); const locateOpts = new LocateOptions(); locateOpts.allowNonLocatable = (undefined === options || !options.excludeNonLocatable); locateOpts.allowDecorations = (undefined === options || !options.excludeDecorations); locateOpts.allowExternalIModels = (undefined === options || !options.excludeExternalIModels); - if (0 !== picker.doPick(this, pickPoint, radius, locateOpts)) { - const hitDetail = picker.getHit(0)!; + if (0 !== this.picker.doPick(this, pickPoint, radius, locateOpts)) { + const hitDetail = this.picker.getHit(0)!; const hitPoint = hitDetail.getPoint(); if (hitDetail.isModelHit) return { plane: Plane3dByOriginAndUnitNormal.create(hitPoint, this.view.getUpVector(hitPoint))!, source: DepthPointSource.Model, sourceId: hitDetail.sourceId }; diff --git a/core/frontend/src/render/RenderSystem.ts b/core/frontend/src/render/RenderSystem.ts index b031c411893..a3f3ec17230 100644 --- a/core/frontend/src/render/RenderSystem.ts +++ b/core/frontend/src/render/RenderSystem.ts @@ -191,6 +191,9 @@ export abstract class RenderSystem implements IDisposable { /** @internal */ public get supportsInstancing(): boolean { return true; } + /** @internal */ + public get supportsNonuniformScaledInstancing(): boolean { return true; } + /** @internal */ public get dpiAwareLOD(): boolean { return true === this.options.dpiAwareLOD; } diff --git a/core/frontend/src/render/webgl/BranchUniforms.ts b/core/frontend/src/render/webgl/BranchUniforms.ts index 4c574969c17..19685637803 100644 --- a/core/frontend/src/render/webgl/BranchUniforms.ts +++ b/core/frontend/src/render/webgl/BranchUniforms.ts @@ -61,6 +61,7 @@ export class BranchUniforms { private readonly _mvp32 = new Matrix4(); private readonly _m32 = new Matrix4(); private readonly _v32 = new Matrix3(); + private readonly _mvn32 = new Matrix3(); // Working state private readonly _scratchTransform = Transform.createIdentity(); @@ -169,6 +170,11 @@ export class BranchUniforms { uniform.setMatrix3(this._v32); } + public bindModelViewNTransform(uniform: UniformHandle, geom: CachedGeometry, isViewCoords: boolean) { + if (this.update(uniform, geom, isViewCoords)) + uniform.setMatrix3(this._mvn32); + } + private update(uniform: UniformHandle, geometry: CachedGeometry, isViewCoords: boolean): boolean { const uniforms = this._target.uniforms[isViewCoords ? "viewRect" : "frustum"]; if (!sync(uniforms, this)) @@ -230,6 +236,12 @@ export class BranchUniforms { Matrix4d.createTransform(mv, this._mv); this._mv32.initFromTransform(mv); + const inv = this._mv.createInverse(); + if (undefined !== inv) { + const invTr = inv.cloneTransposed(); + this._mvn32.initFromMatrix3d(invTr.matrixPart()); + } + // Don't bother computing mvp for instanced geometry - it's not used. if (!this._isInstanced) { uniforms.projectionMatrix.multiplyMatrixMatrix(this._mv, this._mvp); diff --git a/core/frontend/src/render/webgl/System.ts b/core/frontend/src/render/webgl/System.ts index 1804469f7ca..3b4c2e2688a 100644 --- a/core/frontend/src/render/webgl/System.ts +++ b/core/frontend/src/render/webgl/System.ts @@ -391,6 +391,7 @@ export class System extends RenderSystem implements RenderSystemDebugControl, Re public get maxTextureSize(): number { return this.capabilities.maxTextureSize; } public get supportsInstancing(): boolean { return this.capabilities.supportsInstancing; } + public get supportsNonuniformScaledInstancing(): boolean { return this.capabilities.isWebGL2; } public get isWebGL2(): boolean { return this.capabilities.isWebGL2; } public get isMobile(): boolean { return this.capabilities.isMobile; } diff --git a/core/frontend/src/render/webgl/glsl/Vertex.ts b/core/frontend/src/render/webgl/glsl/Vertex.ts index 48d059704a7..63d6c14ff80 100644 --- a/core/frontend/src/render/webgl/glsl/Vertex.ts +++ b/core/frontend/src/render/webgl/glsl/Vertex.ts @@ -12,6 +12,7 @@ import { UniformHandle } from "../UniformHandle"; import { Matrix4 } from "../Matrix"; import { RenderPass, TextureUnit } from "../RenderFlags"; import { VariableType, VertexShaderBuilder } from "../ShaderBuilder"; +import { System } from "../System"; import { decodeUint16, decodeUint24 } from "./Decode"; import { addInstanceOverrides } from "./Instancing"; import { addLookupTable } from "./LookupTable"; @@ -113,7 +114,13 @@ export function addModelViewMatrix(vert: VertexShaderBuilder): void { } const computeNormalMatrix = ` - g_nmx = mat3(MAT_MV); + g_nmx = mat3(u_modelViewN); + g_nmx[0][0] *= u_frustumScale.x; + g_nmx[1][1] *= u_frustumScale.y; +`; + +const computeNormalMatrix2 = ` + g_nmx = transpose(inverse(mat3(MAT_MV))); g_nmx[0][0] *= u_frustumScale.x; g_nmx[1][1] *= u_frustumScale.y; `; @@ -128,7 +135,16 @@ export function addNormalMatrix(vert: VertexShaderBuilder) { }); }); - vert.addInitializer(computeNormalMatrix); + if (System.instance.capabilities.isWebGL2) + vert.addInitializer(computeNormalMatrix2); + else { + vert.addUniform("u_modelViewN", VariableType.Mat3, (prog) => { + prog.addGraphicUniform("u_modelViewN", (uniform, params) => { + params.target.uniforms.branch.bindModelViewNTransform(uniform, params.geometry, false); + }); + }); + vert.addInitializer(computeNormalMatrix); + } } const scratchLutParams = new Float32Array(4); diff --git a/core/frontend/src/tile/PrimaryTileTree.ts b/core/frontend/src/tile/PrimaryTileTree.ts index a705f83ded5..5e912ea0c4a 100644 --- a/core/frontend/src/tile/PrimaryTileTree.ts +++ b/core/frontend/src/tile/PrimaryTileTree.ts @@ -6,11 +6,10 @@ * @module Tiles */ -import { assert, compareStrings, Id64String } from "@bentley/bentleyjs-core"; -import { Range3d, StringifiedClipVector, Transform } from "@bentley/geometry-core"; +import { assert, compareBooleans, compareStrings, Id64String } from "@bentley/bentleyjs-core"; +import { Geometry, Range3d, StringifiedClipVector, Transform } from "@bentley/geometry-core"; import { - BatchType, compareIModelTileTreeIds, FeatureAppearance, FeatureAppearanceProvider, HiddenLine, iModelTileTreeIdToString, PrimaryTileTreeId, - ViewFlagOverrides, + BatchType, compareIModelTileTreeIds, FeatureAppearance, FeatureAppearanceProvider, HiddenLine, iModelTileTreeIdToString, PrimaryTileTreeId, ViewFlagOverrides, } from "@bentley/imodeljs-common"; import { IModelApp } from "../IModelApp"; import { IModelConnection } from "../IModelConnection"; @@ -20,7 +19,7 @@ import { RenderClipVolume } from "../render/RenderClipVolume"; import { RenderScheduleState } from "../RenderScheduleState"; import { SpatialViewState } from "../SpatialViewState"; import { SceneContext } from "../ViewContext"; -import { ViewState, ViewState3d } from "../ViewState"; +import { ModelDisplayTransformProvider, ViewState, ViewState3d } from "../ViewState"; import { IModelTileTree, IModelTileTreeParams, iModelTileTreeParamsFromJSON, TileDrawArgs, TileGraphicType, TileTree, TileTreeOwner, TileTreeReference, TileTreeSupplier, @@ -31,6 +30,7 @@ interface PrimaryTreeId { readonly modelId: Id64String; readonly is3d: boolean; readonly isPlanProjection: boolean; + readonly forceNoInstancing: boolean; } class PlanProjectionTileTree extends IModelTileTree { @@ -57,6 +57,8 @@ class PrimaryTreeSupplier implements TileTreeSupplier { let cmp = compareStrings(lhs.modelId, rhs.modelId); if (0 === cmp) { cmp = compareIModelTileTreeIds(lhs.treeId, rhs.treeId); + if (0 === cmp) + cmp = compareBooleans(lhs.forceNoInstancing, rhs.forceNoInstancing); } return cmp; @@ -69,7 +71,7 @@ class PrimaryTreeSupplier implements TileTreeSupplier { const options = { edgesRequired: treeId.edgesRequired, - allowInstancing: undefined === treeId.animationId && !treeId.enforceDisplayPriority && !treeId.sectionCut, + allowInstancing: undefined === treeId.animationId && !treeId.enforceDisplayPriority && !treeId.sectionCut && !id.forceNoInstancing, is3d: id.is3d, batchType: BatchType.Primary, }; @@ -126,6 +128,7 @@ class PrimaryTreeReference extends TileTreeReference { private _owner: TileTreeOwner; private readonly _sectionClip?: StringifiedClipVector; private readonly _sectionCutAppearanceProvider?: FeatureAppearanceProvider; + private _forceNoInstancing: boolean; public constructor(view: ViewState, model: GeometricModelState, planProjection: boolean, transformNodeId?: number, sectionClip?: StringifiedClipVector) { super(); @@ -143,16 +146,36 @@ class PrimaryTreeReference extends TileTreeReference { }); } + this._forceNoInstancing = false; + if (!IModelApp.renderSystem.supportsNonuniformScaledInstancing) { + this.checkForceNoInstancing(view.modelDisplayTransformProvider); + view.onModelDisplayTransformProviderChanged.addListener((provider: ModelDisplayTransformProvider | undefined) => this.checkForceNoInstancing(provider)); + } + this._id = { modelId: model.id, is3d: model.is3d, treeId: this.createTreeId(view, model.id, transformNodeId), isPlanProjection: planProjection, + forceNoInstancing: this._forceNoInstancing, }; this._owner = primaryTreeSupplier.getOwner(this._id, model.iModel); } + private checkForceNoInstancing(provider: ModelDisplayTransformProvider | undefined) { + this._forceNoInstancing = false; + // If this model has a display transform with a non-uniform scale then instancing needs to be forced off when using WebGL1. + if (undefined !== provider) { + const tf = provider.getModelDisplayTransform(this.model.id, Transform.createIdentity()); + const sx = tf.matrix.getColumn(0).magnitudeSquared(); + const sy = tf.matrix.getColumn(1).magnitudeSquared(); + const sz = tf.matrix.getColumn(2).magnitudeSquared(); + if (Math.abs(sx - sy) > Geometry.smallMetricDistance || Math.abs(sx - sz) > Geometry.smallMetricDistance) + this._forceNoInstancing = true; + } + } + protected getViewFlagOverrides(_tree: TileTree) { return this._viewFlagOverrides; } @@ -191,12 +214,13 @@ class PrimaryTreeReference extends TileTreeReference { public get treeOwner(): TileTreeOwner { const newId = this.createTreeId(this.view, this._id.modelId, this._id.treeId.animationTransformNodeId); - if (0 !== compareIModelTileTreeIds(newId, this._id.treeId)) { + if (0 !== compareIModelTileTreeIds(newId, this._id.treeId) || this._forceNoInstancing !== this._id.forceNoInstancing) { this._id = { modelId: this._id.modelId, is3d: this._id.is3d, treeId: newId, isPlanProjection: this._id.isPlanProjection, + forceNoInstancing: this._forceNoInstancing, }; this._owner = primaryTreeSupplier.getOwner(this._id, this.model.iModel); @@ -358,14 +382,14 @@ class MaskTreeReference extends TileTreeReference { public constructor(model: GeometricModelState) { super(); this.model = model; - this._id = { modelId: model.id, is3d: model.is3d, treeId: this.createTreeId(), isPlanProjection: false }; + this._id = { modelId: model.id, is3d: model.is3d, treeId: this.createTreeId(), isPlanProjection: false, forceNoInstancing: false }; this._owner = primaryTreeSupplier.getOwner(this._id, model.iModel); } public get treeOwner(): TileTreeOwner { const newId = this.createTreeId(); if (0 !== compareIModelTileTreeIds(newId, this._id.treeId)) { - this._id = { modelId: this._id.modelId, is3d: this._id.is3d, treeId: newId, isPlanProjection: false }; + this._id = { modelId: this._id.modelId, is3d: this._id.is3d, treeId: newId, isPlanProjection: false, forceNoInstancing: false }; this._owner = primaryTreeSupplier.getOwner(this._id, this.model.iModel); } diff --git a/core/frontend/src/tile/Tile.ts b/core/frontend/src/tile/Tile.ts index b11b35e7f11..17dbc1cd485 100644 --- a/core/frontend/src/tile/Tile.ts +++ b/core/frontend/src/tile/Tile.ts @@ -418,7 +418,7 @@ export abstract class Tile { return TileVisibility.Visible; } - const pixelSize = args.getPixelSize(this); + const pixelSize = args.getPixelSize(this) * args.pixelSizeScaleFactor; const maxSize = this.maximumSize * args.tileSizeModifier; return pixelSize > maxSize ? TileVisibility.TooCoarse : TileVisibility.Visible; diff --git a/core/frontend/src/tile/TileDrawArgs.ts b/core/frontend/src/tile/TileDrawArgs.ts index d03857bf076..e5919d478ec 100644 --- a/core/frontend/src/tile/TileDrawArgs.ts +++ b/core/frontend/src/tile/TileDrawArgs.ts @@ -7,7 +7,7 @@ */ import { BeTimePoint } from "@bentley/bentleyjs-core"; -import { ClipVector, Map4d, Matrix4d, Point3d, Point4d, Range1d, Range3d, Transform, Vector3d } from "@bentley/geometry-core"; +import { ClipVector, Geometry, Map4d, Matrix4d, Point3d, Point4d, Range1d, Range3d, Transform, Vector3d } from "@bentley/geometry-core"; import { FeatureAppearanceProvider, FrustumPlanes, HiddenLine, ViewFlagOverrides } from "@bentley/imodeljs-common"; import { FeatureSymbology } from "../render/FeatureSymbology"; import { GraphicBranch } from "../render/GraphicBranch"; @@ -88,6 +88,8 @@ export class TileDrawArgs { public get symbologyOverrides(): FeatureSymbology.Overrides | undefined { return this.graphics.symbologyOverrides; } /** If defined, tiles will be culled if they do not intersect the clip vector. */ public intersectionClip?: ClipVector; + /** @internal */ + public readonly pixelSizeScaleFactor; /** Compute the size in pixels of the specified tile at the point on its bounding sphere closest to the camera. */ public getPixelSize(tile: Tile): number { @@ -192,6 +194,34 @@ export class TileDrawArgs { return this.viewingSpace.worldToViewMap; } + private computePixelSizeScaleFactor(): number { + // Check to see if a model display transform with non-uniform scaling is being used. + const tf = this.context.viewport.view.getModelDisplayTransform(this.tree.modelId, Transform.createIdentity()); + const scale = []; + scale[0] = tf.matrix.getColumn(0).magnitude(); + scale[1] = tf.matrix.getColumn(1).magnitude(); + scale[2] = tf.matrix.getColumn(2).magnitude(); + if (Math.abs(scale[0] - scale[1]) <= Geometry.smallMetricDistance && Math.abs(scale[0] - scale[2]) <= Geometry.smallMetricDistance) + return 1; + // If the component with the largest scale is not the same as the component with the largest tile range use it to adjust the pixel size. + const rangeDiag = this.tree.range.diagonal(); + let maxS = 0; + let maxR = 0; + if (scale[0] > scale[1]) { + maxS = (scale[0] > scale[2] ? 0 : 2); + } else { + maxS = (scale[1] > scale[2] ? 1 : 2); + } + if (rangeDiag.x > rangeDiag.y) { + maxR = (rangeDiag.x > rangeDiag.z ? 0 : 2); + } else { + maxR = (rangeDiag.y > rangeDiag.z ? 1 : 2); + } + if (maxS !== maxR) + return scale[maxS]; + return 1; + } + /** Constructor */ public constructor(params: TileDrawArgParams) { const { location, tree, context, now, viewFlagOverrides, clipVolume, parentsAndChildrenExclusive, symbologyOverrides } = params; @@ -222,6 +252,8 @@ export class TileDrawArgs { this.parentsAndChildrenExclusive = parentsAndChildrenExclusive; if (context.viewport.view.isCameraEnabled()) this._nearFrontCenter = context.viewport.getFrustum(CoordSystem.World).frontCenter; + + this.pixelSizeScaleFactor = this.computePixelSizeScaleFactor(); } /** A multiplier applied to a [[Tile]]'s `maximumSize` property to adjust level of detail. diff --git a/core/frontend/src/tools/MeasureTool.ts b/core/frontend/src/tools/MeasureTool.ts index c42649d6792..4e5d7adf36b 100644 --- a/core/frontend/src/tools/MeasureTool.ts +++ b/core/frontend/src/tools/MeasureTool.ts @@ -116,16 +116,53 @@ class MeasureMarker extends Marker { } } +/** @internal */ +interface Location { point: Point3d, adjustedPoint: Point3d, refAxes: Matrix3d } +/** @internal */ +interface Segment { distance: number, slope: number, start: Point3d, end: Point3d, delta: Vector3d, adjustedStart: Point3d, adjustedEnd: Point3d, adjustedDelta: Vector3d, refAxes: Matrix3d, marker: MeasureMarker } + +/** @internal */ +function adjustPoint(ev: BeButtonEvent, segments?: Array, locations?: Array): Point3d { + // If the point was from a hit we must transform it by the model display tyransform of what got hit. + if (undefined === ev.viewport || undefined === ev.viewport.view.modelDisplayTransformProvider) + return ev.point; + if (undefined !== IModelApp.accuSnap.currHit && undefined !== IModelApp.accuSnap.currHit.modelId) { + if ("0" !== IModelApp.accuSnap.currHit.modelId) { + const newPoint = ev.point.clone(); + ev.viewport.view.transformPointByModelDisplayTransform(IModelApp.accuSnap.currHit.modelId, newPoint, true); + return newPoint; + } else { + // Must have snapped to a decoration, so look through previous any segments & locations for a match to get an adjusted point. + if (undefined !== segments) { + for (const seg of segments) { + if (seg.start.isExactEqual(ev.point)) + return seg.adjustedStart.clone(); + if (seg.end.isExactEqual(ev.point)) + return seg.adjustedEnd.clone(); + } + } + if (undefined !== locations) { + for (const loc of locations) { + if (loc.point.isExactEqual(ev.point)) + return loc.adjustedPoint.clone(); + } + } + } + } + return ev.point; +} + /** @alpha */ export class MeasureDistanceTool extends PrimitiveTool { public static toolId = "Measure.Distance"; public static iconSpec = "icon-measure-distance"; - protected readonly _locationData = new Array<{ point: Point3d, refAxes: Matrix3d }>(); - protected readonly _acceptedSegments = new Array<{ distance: number, slope: number, start: Point3d, end: Point3d, delta: Vector3d, refAxes: Matrix3d, marker: MeasureMarker }>(); + protected readonly _locationData = new Array(); + protected readonly _acceptedSegments = new Array(); protected _totalDistance: number = 0.0; protected _totalDistanceMarker?: MeasureLabel; protected _snapGeomId?: string; protected _lastMotionPt?: Point3d; + protected _lastMotionAdjustedPt?: Point3d; protected allowView(vp: Viewport) { return vp.view.isSpatialView() || vp.view.isDrawingView(); } public isCompatibleViewport(vp: Viewport | undefined, isSelectedViewChange: boolean): boolean { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && this.allowView(vp)); } @@ -200,10 +237,10 @@ export class MeasureDistanceTool extends PrimitiveTool { return (undefined === geomData ? undefined : [geomData]); } - protected displayDynamicDistance(context: DecorateContext, points: Point3d[]): void { + protected displayDynamicDistance(context: DecorateContext, points: Point3d[], adjustedPoints: Point3d[]): void { let totalDistance = 0.0; - for (let i = 0; i < points.length - 1; i++) - totalDistance += points[i].distance(points[i + 1]); + for (let i = 0; i < adjustedPoints.length - 1; i++) + totalDistance += adjustedPoints[i].distance(adjustedPoints[i + 1]); if (0.0 === totalDistance) return; @@ -265,11 +302,15 @@ export class MeasureDistanceTool extends PrimitiveTool { if (!this.isCompatibleViewport(context.viewport, false)) return; - if (!isSuspended && this._locationData.length > 0 && undefined !== this._lastMotionPt) { + if (!isSuspended && this._locationData.length > 0 && undefined !== this._lastMotionPt && undefined !== this._lastMotionAdjustedPt) { const tmpPoints: Point3d[] = []; - for (const loc of this._locationData) + const tmpAdjustedPoints: Point3d[] = []; + for (const loc of this._locationData) { tmpPoints.push(loc.point); // Deep copy not necessary... + tmpAdjustedPoints.push(loc.adjustedPoint); + } tmpPoints.push(this._lastMotionPt); + tmpAdjustedPoints.push(this._lastMotionAdjustedPt); const builderDynVis = context.createGraphicBuilder(GraphicType.WorldDecoration); const colorDynVis = context.viewport.hilite.color; @@ -286,7 +327,7 @@ export class MeasureDistanceTool extends PrimitiveTool { builderDynHid.addLineString(tmpPoints); context.addDecorationFromBuilder(builderDynHid); - this.displayDynamicDistance(context, tmpPoints); + this.displayDynamicDistance(context, tmpPoints, tmpAdjustedPoints); } if (this._acceptedSegments.length > 0) { @@ -334,10 +375,15 @@ export class MeasureDistanceTool extends PrimitiveTool { public async onMouseMotion(ev: BeButtonEvent): Promise { if (this._locationData.length > 0 && undefined !== ev.viewport) { - if (undefined !== this._lastMotionPt) - this._lastMotionPt.setFrom(ev.point); - else - this._lastMotionPt = ev.point.clone(); + const point = ev.point; + const adjustedPoint = adjustPoint(ev, this._acceptedSegments, this._locationData); + if (undefined !== this._lastMotionPt) { + this._lastMotionPt.setFrom(point); + this._lastMotionAdjustedPt?.setFrom(adjustedPoint); + } else { + this._lastMotionPt = point.clone(); + this._lastMotionAdjustedPt = adjustedPoint; + } ev.viewport.invalidateDecorations(); } } @@ -431,7 +477,7 @@ export class MeasureDistanceTool extends PrimitiveTool { } protected async updateSelectedMarkerToolTip(seg: any, ev: BeButtonEvent, reopenToolTip: boolean): Promise { - seg.marker.title = await this.getMarkerToolTip(seg.distance, seg.slope, seg.start, seg.end, seg.marker.isSelected ? seg.delta : undefined); + seg.marker.title = await this.getMarkerToolTip(seg.distance, seg.slope, seg.adjustedStart, seg.adjustedEnd, seg.marker.isSelected ? seg.adjustedDelta : undefined); if (!reopenToolTip || undefined === ev.viewport || !IModelApp.notifications.isToolTipOpen) return; IModelApp.notifications.clearToolTip(); @@ -441,17 +487,21 @@ export class MeasureDistanceTool extends PrimitiveTool { protected async acceptNewSegments(): Promise { if (this._locationData.length > 1) { for (let i = 0; i <= this._locationData.length - 2; i++) { + const adjustedStart = this._locationData[i].adjustedPoint; + const adjustedEnd = this._locationData[i + 1].adjustedPoint; + const distance = adjustedStart.distance(adjustedEnd); + const xyDist = adjustedStart.distanceXY(adjustedEnd); + const zDist = adjustedEnd.z - adjustedStart.z; + const slope = (0.0 === xyDist ? Math.PI : Math.atan(zDist / xyDist)); + const adjustedDelta = Vector3d.createStartEnd(adjustedStart, adjustedEnd); + const refAxes = this._locationData[i].refAxes; + refAxes.multiplyTransposeVectorInPlace(adjustedDelta); const start = this._locationData[i].point; const end = this._locationData[i + 1].point; - const distance = start.distance(end); - const xyDist = start.distanceXY(end); - const zDist = end.z - start.z; - const slope = (0.0 === xyDist ? Math.PI : Math.atan(zDist / xyDist)); const delta = Vector3d.createStartEnd(start, end); - const refAxes = this._locationData[i].refAxes; refAxes.multiplyTransposeVectorInPlace(delta); - const toolTip = await this.getMarkerToolTip(distance, slope, start, end); + const toolTip = await this.getMarkerToolTip(distance, slope, adjustedStart, adjustedEnd); const marker = new MeasureMarker((this._acceptedSegments.length + 1).toString(), toolTip, start.interpolate(0.5, end), Point2d.create(25, 25)); const segMarkerButtonFunc = (ev: BeButtonEvent) => { @@ -481,7 +531,7 @@ export class MeasureDistanceTool extends PrimitiveTool { }; marker.onMouseButton = segMarkerButtonFunc; // eslint-disable-line @typescript-eslint/unbound-method - this._acceptedSegments.push({ distance, slope, start, end, delta, refAxes, marker }); + this._acceptedSegments.push({ distance, slope, start, end, delta, adjustedStart, adjustedEnd, adjustedDelta, refAxes, marker }); } } this._locationData.length = 0; @@ -497,6 +547,7 @@ export class MeasureDistanceTool extends PrimitiveTool { public async onDataButtonDown(ev: BeButtonEvent): Promise { const point = ev.point.clone(); + const adjustedPoint = adjustPoint(ev, this._acceptedSegments, this._locationData); const refAxes = this.getReferenceAxes(ev.viewport); const zDir = refAxes.columnZ(); const normal = refAxes.columnZ(); @@ -532,7 +583,7 @@ export class MeasureDistanceTool extends PrimitiveTool { } } - this._locationData.push({ point, refAxes }); + this._locationData.push({ point, adjustedPoint, refAxes }); if (this._locationData.length > 1 && !ev.isControlKey) await this.acceptNewSegments(); @@ -677,7 +728,8 @@ export class MeasureLocationTool extends PrimitiveTool { public async onDataButtonDown(ev: BeButtonEvent): Promise { const point = ev.point.clone(); - const toolTip = await this.getMarkerToolTip(point); + const adjustedPoint = adjustPoint(ev); + const toolTip = await this.getMarkerToolTip(adjustedPoint); const marker = new MeasureMarker((this._acceptedLocations.length + 1).toString(), toolTip, point, Point2d.create(25, 25)); this._acceptedLocations.push(marker); diff --git a/core/frontend/src/tools/ViewTool.ts b/core/frontend/src/tools/ViewTool.ts index b9483dc5511..e39ca848d4f 100644 --- a/core/frontend/src/tools/ViewTool.ts +++ b/core/frontend/src/tools/ViewTool.ts @@ -1245,8 +1245,16 @@ class ViewRotate extends HandleWithInertia { plane.getNormalRef().setFrom(vp.view.getZVector()); return true; } - if (super.adjustDepthPoint(isValid, vp, plane, source)) + if (super.adjustDepthPoint(isValid, vp, plane, source)) { + if (DepthPointSource.Geometry === source && vp instanceof ScreenViewport) { + // If we had hit something we might need to undo the model display transform of the hit. + const hitDetail = vp.picker.getHit(0); + if (undefined !== hitDetail && undefined !== hitDetail.modelId) { + vp.view.transformPointByModelDisplayTransform(hitDetail.modelId, plane.getOriginRef(), false); + } + } return true; + } plane.getOriginRef().setFrom(this.viewTool.targetCenterWorld); return false; } diff --git a/test-apps/display-test-app/public/locales/en/SVTTools.json b/test-apps/display-test-app/public/locales/en/SVTTools.json index 274fec0a9ee..1c914766250 100644 --- a/test-apps/display-test-app/public/locales/en/SVTTools.json +++ b/test-apps/display-test-app/public/locales/en/SVTTools.json @@ -106,6 +106,9 @@ "ApplyModelTransform": { "keyin": "dta model transform" }, + "ApplyModelDisplayScale": { + "keyin": "dta model scale" + }, "EditingSession": { "keyin": "dta edit" }, diff --git a/test-apps/display-test-app/src/frontend/App.ts b/test-apps/display-test-app/src/frontend/App.ts index 5c421e21eed..1567258aeb2 100644 --- a/test-apps/display-test-app/src/frontend/App.ts +++ b/test-apps/display-test-app/src/frontend/App.ts @@ -38,6 +38,7 @@ import { import { TimePointComparisonTool } from "./TimePointComparison"; import { UiManager } from "./UiManager"; import { MarkupTool, ModelClipTool, SaveImageTool, ZoomToSelectedElementsTool } from "./Viewer"; +import { ApplyModelDisplayScaleTool } from "./DisplayScale"; class DisplayTestAppAccuSnap extends AccuSnap { private readonly _activeSnaps: SnapMode[] = [SnapMode.NearestKeypoint]; @@ -210,6 +211,7 @@ export class DisplayTestApp { const svtToolNamespace = IModelApp.i18n.registerNamespace("SVTTools"); [ + ApplyModelDisplayScaleTool, ApplyModelTransformTool, CloneViewportTool, CloseIModelTool, diff --git a/test-apps/display-test-app/src/frontend/DisplayScale.ts b/test-apps/display-test-app/src/frontend/DisplayScale.ts new file mode 100644 index 00000000000..427deda4c4f --- /dev/null +++ b/test-apps/display-test-app/src/frontend/DisplayScale.ts @@ -0,0 +1,81 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Bentley Systems, Incorporated. All rights reserved. +* See LICENSE.md in the project root for license terms and full copyright notice. +*--------------------------------------------------------------------------------------------*/ + +import { Matrix3d, Point3d, Transform } from "@bentley/geometry-core"; +import { IModelApp, ModelDisplayTransformProvider, Tool } from "@bentley/imodeljs-frontend"; +import { parseArgs } from "@bentley/frontend-devtools"; + +class DisplayScaleTransformProvider implements ModelDisplayTransformProvider { + public constructor(private readonly _models: Set, private readonly _scaleTransform: Transform) { } + + public getModelDisplayTransform(modelId: string, baseTransform: Transform): Transform { + if (!this._models.has(modelId)) + return baseTransform; + + // Apply scale as last part of model to world transform. + return this._scaleTransform.multiplyTransformTransform(baseTransform); + } + + public get transform(): Transform { return this._scaleTransform.clone(); } +} + +/** Apply a display transform to all currently displayed models. */ +export class ApplyModelDisplayScaleTool extends Tool { + public static toolId = "ApplyModelDisplayScale"; + public static get minArgs() { return 0; } + public static get maxArgs() { return 3; } + + public run(scale: Point3d): boolean { + const vp = IModelApp.viewManager.selectedView; + if (!vp) + return false; + + const f = vp.getWorldFrustum(); + // If there was already a transform then we need to undo it for the frustum. + if (undefined !== vp.view.modelDisplayTransformProvider && vp.view.modelDisplayTransformProvider instanceof DisplayScaleTransformProvider) { + const t = vp.view.modelDisplayTransformProvider.transform; + const sx = t.matrix.getColumn(0).magnitude(); + const sy = t.matrix.getColumn(1).magnitude(); + const sz = t.matrix.getColumn(2).magnitude(); + const inverseMax = 1.0 / Math.max(sx, sy, sz); + const scaleFrustumInvTf = Transform.createRefs(Point3d.createZero(), Matrix3d.createScale(inverseMax, inverseMax, inverseMax)); + f.multiply(scaleFrustumInvTf); + } + + let scl; + let maxScale = 1.0; + if (scale.isAlmostEqual(Point3d.create(1.0, 1.0, 1.0))) { + if (undefined !== vp.view.modelDisplayTransformProvider) { + vp.view.modelDisplayTransformProvider = undefined; + } else { + return false; + } + scl = Matrix3d.createIdentity(); + } else { + scl = Matrix3d.createScale(scale.x, scale.y, scale.z); + maxScale = Math.max(scale.y, scale.y, scale.z); + } + + const models = new Set(); + vp.view.forEachModel((model) => models.add(model.id)); + + const sclTf = Transform.createRefs(Point3d.createZero(), scl); + const tp = new DisplayScaleTransformProvider(models, sclTf); + vp.setModelDisplayTransformProvider(tp); + + // Scale frustum uniformly using the largest of the scale values. + const scaleFrustumTf = Transform.createRefs(Point3d.createZero(), Matrix3d.createScale(maxScale, maxScale, maxScale)); + f.multiply(scaleFrustumTf); + vp.setupViewFromFrustum(f); + + return true; + } + + public parseAndRun(...input: string[]): boolean { + const args = parseArgs(input); + const scale = new Point3d(args.getFloat("x") ?? 1.0, args.getFloat("y") ?? 1.0, args.getFloat("z") ?? 1.0); + return this.run(scale); + } +} From 9beb4bfce205d3937f3300310da257a7bd5ed27e Mon Sep 17 00:00:00 2001 From: bbastings <65233531+bbastings@users.noreply.github.com> Date: Thu, 25 Mar 2021 17:20:03 -0400 Subject: [PATCH 11/50] Add an option to use the virtual cursor to help with element locate w/touch input. (#1038) * Add an option to use the virtual cursor to help with element locate w/touch input. * Not sure what happened to ToolSettings.enableVirtualCursorForLocate... * re-run extract-api * Put back the beta tag... Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- common/api/imodeljs-frontend.api.md | 6 +- ...al-cursor-for-locate_2021-03-25-15-39.json | 11 +++ core/frontend/src/AccuSnap.ts | 20 ++++- core/frontend/src/tools/SelectTool.ts | 3 +- core/frontend/src/tools/ToolAdmin.ts | 10 ++- core/frontend/src/tools/ToolAssistance.ts | 2 +- core/frontend/src/tools/ToolSettings.ts | 2 + test-apps/display-test-app/README.md | 11 ++- .../public/locales/en/SVTTools.json | 3 + .../display-test-app/src/frontend/App.ts | 2 + .../display-test-app/src/frontend/Grid.ts | 86 +++++++++++++++++++ 11 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 common/changes/@bentley/imodeljs-frontend/virtual-cursor-for-locate_2021-03-25-15-39.json create mode 100644 test-apps/display-test-app/src/frontend/Grid.ts diff --git a/common/api/imodeljs-frontend.api.md b/common/api/imodeljs-frontend.api.md index a53ac3c19f6..5cc08dd61f8 100644 --- a/common/api/imodeljs-frontend.api.md +++ b/common/api/imodeljs-frontend.api.md @@ -941,7 +941,9 @@ export class AccuSnap implements Decorator { readonly toolState: AccuSnap.ToolState; // @internal (undocumented) touchCursor?: TouchCursor; - } + // @internal (undocumented) + get wantVirtualCursor(): boolean; +} // @public (undocumented) export namespace AccuSnap { @@ -10852,6 +10854,8 @@ export class ToolSettings { static doubleClickTimeout: BeDuration; static doubleClickToleranceInches: number; static doubleTapTimeout: BeDuration; + // @beta + static enableVirtualCursorForLocate: boolean; static preserveWorldUp: boolean; static scrollSpeed: number; static startDragDelay: BeDuration; diff --git a/common/changes/@bentley/imodeljs-frontend/virtual-cursor-for-locate_2021-03-25-15-39.json b/common/changes/@bentley/imodeljs-frontend/virtual-cursor-for-locate_2021-03-25-15-39.json new file mode 100644 index 00000000000..9c0b09f7dd7 --- /dev/null +++ b/common/changes/@bentley/imodeljs-frontend/virtual-cursor-for-locate_2021-03-25-15-39.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/imodeljs-frontend", + "comment": "Add an option to use the virtual cursor to help with element locate w/touch input.", + "type": "none" + } + ], + "packageName": "@bentley/imodeljs-frontend", + "email": "65233531+bbastings@users.noreply.github.com" +} \ No newline at end of file diff --git a/core/frontend/src/AccuSnap.ts b/core/frontend/src/AccuSnap.ts index 9d0fc560881..914edf2d465 100644 --- a/core/frontend/src/AccuSnap.ts +++ b/core/frontend/src/AccuSnap.ts @@ -15,6 +15,7 @@ import { IModelApp } from "./IModelApp"; import { CanvasDecoration } from "./render/CanvasDecoration"; import { IconSprites, Sprite, SpriteLocation } from "./Sprites"; import { BeButton, BeButtonEvent, BeTouchEvent, InputSource } from "./tools/Tool"; +import { ToolSettings } from "./tools/ToolSettings"; import { DecorateContext } from "./ViewContext"; import { Decorator } from "./ViewManager"; import { ScreenViewport, Viewport } from "./Viewport"; @@ -125,6 +126,8 @@ export class TouchCursor implements CanvasDecoration { } public doTouchEnd(ev: BeTouchEvent): void { + if (this._isDragging && undefined !== ev.viewport) + IModelApp.toolAdmin.currentInputState.fromPoint(ev.viewport, this._offsetPosition, InputSource.Touch); // Current location should reflect virtual cursor offset... this._isSelected = this._isDragging = false; if (undefined !== ev.viewport) ev.viewport.invalidateDecorations(); @@ -566,7 +569,7 @@ export class AccuSnap implements Decorator { this.toolState.enabled = yesNo; if (!yesNo) { this.clear(); - if (undefined !== this.touchCursor) { + if (undefined !== this.touchCursor && !this.wantVirtualCursor) { this.touchCursor = undefined; IModelApp.viewManager.invalidateDecorationsAllViews(); } @@ -954,11 +957,16 @@ export class AccuSnap implements Decorator { /** @internal */ public onTouchMoveStart(ev: BeTouchEvent, startEv: BeTouchEvent): boolean { return (undefined !== this.touchCursor) ? this.touchCursor.doTouchMoveStart(ev, startEv) : false; } + /** @internal */ + public get wantVirtualCursor(): boolean { + return this._doSnapping || (this.isLocateEnabled && ToolSettings.enableVirtualCursorForLocate); + } + /** @internal */ public async onTouchTap(ev: BeTouchEvent): Promise { if (undefined !== this.touchCursor) return this.touchCursor.doTouchTap(ev); - if (!this._doSnapping) + if (!this.wantVirtualCursor) return false; this.touchCursor = TouchCursor.createFromTouchTap(ev); if (undefined === this.touchCursor) @@ -1018,7 +1026,13 @@ export class AccuSnap implements Decorator { /** Enable locating elements. * @public */ - public enableLocate(yesNo: boolean) { this.toolState.locate = yesNo; } + public enableLocate(yesNo: boolean) { + this.toolState.locate = yesNo; + if (!yesNo && undefined !== this.touchCursor && !this.wantVirtualCursor) { + this.touchCursor = undefined; + IModelApp.viewManager.invalidateDecorationsAllViews(); + } + } /** Called whenever a new [[Tool]] is started. * @internal diff --git a/core/frontend/src/tools/SelectTool.ts b/core/frontend/src/tools/SelectTool.ts index 865378952a3..5cccb5d2183 100644 --- a/core/frontend/src/tools/SelectTool.ts +++ b/core/frontend/src/tools/SelectTool.ts @@ -190,7 +190,8 @@ export class SelectionTool extends PrimitiveTool { sections.push(ToolAssistance.createSection(mousePickInstructions, ToolAssistance.inputsLabel)); const touchPickInstructions: ToolAssistanceInstruction[] = []; - touchPickInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.OneTouchTap, CoreTools.translate("ElementSet.Inputs.AcceptElement"), false, ToolAssistanceInputMethod.Touch)); + if (!ToolAssistance.createTouchCursorInstructions(touchPickInstructions)) + touchPickInstructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.OneTouchTap, CoreTools.translate("ElementSet.Inputs.AcceptElement"), false, ToolAssistanceInputMethod.Touch)); sections.push(ToolAssistance.createSection(touchPickInstructions, ToolAssistance.inputsLabel)); break; case SelectionMethod.Line: diff --git a/core/frontend/src/tools/ToolAdmin.ts b/core/frontend/src/tools/ToolAdmin.ts index 6e6a2c411cd..924b2da3ea2 100644 --- a/core/frontend/src/tools/ToolAdmin.ts +++ b/core/frontend/src/tools/ToolAdmin.ts @@ -1573,7 +1573,15 @@ export class ToolAdmin { viewport.drawLocateCursor(context, ev.viewPoint, viewport.pixelsFromInches(IModelApp.locateManager.apertureInches), this.isLocateCircleOn, hit); } - public get isLocateCircleOn(): boolean { return this.toolState.locateCircleOn && this.currentInputState.inputSource === InputSource.Mouse && this._canvasDecoration === undefined; } + public get isLocateCircleOn(): boolean { + if (!this.toolState.locateCircleOn || undefined !== this._canvasDecoration) + return false; + + if (InputSource.Mouse === this.currentInputState.inputSource) + return true; + + return (InputSource.Touch === this.currentInputState.inputSource && undefined !== IModelApp.accuSnap.touchCursor); + } /** @internal */ public beginDynamics(): void { diff --git a/core/frontend/src/tools/ToolAssistance.ts b/core/frontend/src/tools/ToolAssistance.ts index acaab32a77a..c8516476833 100644 --- a/core/frontend/src/tools/ToolAssistance.ts +++ b/core/frontend/src/tools/ToolAssistance.ts @@ -262,7 +262,7 @@ export class ToolAssistance { */ public static createTouchCursorInstructions(instructions: ToolAssistanceInstruction[]): boolean { const accuSnap = IModelApp.accuSnap; - if (accuSnap.isSnapEnabled && accuSnap.isSnapEnabledByUser && undefined === accuSnap.touchCursor) { + if (undefined === accuSnap.touchCursor && accuSnap.wantVirtualCursor) { instructions.push(ToolAssistance.createInstruction(ToolAssistanceImage.OneTouchTap, this.translateTouch("Activate"), false, ToolAssistanceInputMethod.Touch)); return true; } else if (undefined !== accuSnap.touchCursor) { diff --git a/core/frontend/src/tools/ToolSettings.ts b/core/frontend/src/tools/ToolSettings.ts index 8fd42bedbf3..8aa6512c258 100644 --- a/core/frontend/src/tools/ToolSettings.ts +++ b/core/frontend/src/tools/ToolSettings.ts @@ -19,6 +19,8 @@ export class ToolSettings { public static doubleClickTimeout = BeDuration.fromMilliseconds(500); /** Number of screen inches of movement allowed between clicks to still qualify as a double-click. */ public static doubleClickToleranceInches = 0.05; + /** @beta Use virtual cursor to help with locating elements using touch input. By default it's only enabled for snapping. */ + public static enableVirtualCursorForLocate = false; /** If true, view rotation tool keeps the up vector (worldZ) aligned with screenY. */ public static preserveWorldUp = true; /** Delay with a touch on the surface before a move operation begins. */ diff --git a/test-apps/display-test-app/README.md b/test-apps/display-test-app/README.md index aeec97319f7..fb497775e63 100644 --- a/test-apps/display-test-app/README.md +++ b/test-apps/display-test-app/README.md @@ -201,6 +201,11 @@ display-test-app has access to all key-ins defined in the imodeljs-frontend and * `background=`: Preserve background color when drawing as a raster image. * **dta aspect skew decorator** *apply=0|1* - Toggle a decorator that draws a simple bspline curve based on the project extents, for testing the effect of aspect ratio skew on the curve stroke tolerance. Use in conjunction with `fdt aspect skew` to adjust the skew. If `apply` is 0, then the skew will have no effect on the curve's level of detail; otherwise a higher aspect ratio skew should produce higher-resolution curve graphics. * **dta classifyclip selected** *inside* - Color code elements from the current selection set based on their containment with the current view clip. Inside - Green, Outside - Red, Overlap - Blue. Specify optional inside arg to only determine inside or outside, not overlap. Disable clip in the view settings to select elements outside clip, use clip tool panel EDIT button to redisplay clip decoration after processing selection. Use key-in again without a clip or selection set to clear the color override. +* **dta grid settings** - Change the grid settings for the selected viewport. + * `spacing=number` Specify x and y grid reference line spacing in meters. + * `ratio=number` Specify y spacing as current x * ratio. + * `gridsPerRef=number` Specify number of grid lines to display per reference line. + * `orientation=0|1|2|3|4` Value for GridOrientationType. * **dta model transform** - Apply a display transform to all models currently displayed in the selected viewport. Origin is specified like `x=1 y=2 z=3`; pitch and roll as `p=45 r=90` in degrees. Any argument can be omitted. Omitting all arguments clears the display transform. Snapping intentionally does not take the display transform into account. ## Editing @@ -217,9 +222,7 @@ Using an editing session is optional, but outside of a session, the viewport's g ### Editing key-ins +display-test-app has access to all key-ins defined in the imodeljs-editor-frontend package. It also provides the following additional key-ins. + * `dta edit` - begin a new editing session, or end the current editing session. The title of the window or browser tab will update to reflect the current state: "[R/W]" indicating no current editing session, or "[EDIT]" indicating an active editing session. -* `dta delete elements` - delete all elements currently in the selection set. -* `dta move elements` - start moving elements. If no elements are currently in the selection set, you will be prompted to select one. First data point defines the start point; second defines the end point and moves the element(s) by the delta between the two points. * `dta place line string` - start placing a line string. Each data point defines another point in the string; a reset (right mouse button) finishes. The element is placed into the first spatial model and spatial category in the viewport's model and category selectors. -* `dta undo` - undo the most recent change. -* `dta redo` - redo the most recently-undone change. diff --git a/test-apps/display-test-app/public/locales/en/SVTTools.json b/test-apps/display-test-app/public/locales/en/SVTTools.json index 1c914766250..0a57c0e67e0 100644 --- a/test-apps/display-test-app/public/locales/en/SVTTools.json +++ b/test-apps/display-test-app/public/locales/en/SVTTools.json @@ -10,6 +10,9 @@ "keyin": "dta classifyclip selected" } }, + "GridSettings": { + "keyin": "dta grid settings" + }, "Markup": { "keyin": "dta markup", "TestSelect": { diff --git a/test-apps/display-test-app/src/frontend/App.ts b/test-apps/display-test-app/src/frontend/App.ts index 1567258aeb2..62e603e0dd7 100644 --- a/test-apps/display-test-app/src/frontend/App.ts +++ b/test-apps/display-test-app/src/frontend/App.ts @@ -25,6 +25,7 @@ import { DrawingAidTestTool } from "./DrawingAidTestTool"; import { EditingSessionTool, PlaceLineStringTool } from "./EditingTools"; import { FenceClassifySelectedTool } from "./Fence"; import { RecordFpsTool } from "./FpsMonitor"; +import { ChangeGridSettingsTool } from "./Grid"; import { IncidentMarkerDemoTool } from "./IncidentMarkerDemo"; import { MarkupSelectTestTool } from "./MarkupSelectTestTool"; import { Notifications } from "./Notifications"; @@ -213,6 +214,7 @@ export class DisplayTestApp { [ ApplyModelDisplayScaleTool, ApplyModelTransformTool, + ChangeGridSettingsTool, CloneViewportTool, CloseIModelTool, CloseWindowTool, diff --git a/test-apps/display-test-app/src/frontend/Grid.ts b/test-apps/display-test-app/src/frontend/Grid.ts new file mode 100644 index 00000000000..f99365bd5d9 --- /dev/null +++ b/test-apps/display-test-app/src/frontend/Grid.ts @@ -0,0 +1,86 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Bentley Systems, Incorporated. All rights reserved. +* See LICENSE.md in the project root for license terms and full copyright notice. +*--------------------------------------------------------------------------------------------*/ + +import { parseArgs } from "@bentley/frontend-devtools"; +import { GridOrientationType } from "@bentley/imodeljs-common"; +import { IModelApp, Tool } from "@bentley/imodeljs-frontend"; + +/** Change grid settings for testing. */ +export class ChangeGridSettingsTool extends Tool { + public static toolId = "GridSettings"; + public static get minArgs() { return 0; } + public static get maxArgs() { return 4; } + + public run(spacing?: number, ratio?: number, gridsPerRef?: number, orientation?: GridOrientationType): boolean { + const vp = IModelApp.viewManager.selectedView; + if (undefined === vp) + return false; + + if (undefined !== spacing) + vp.view.details.gridSpacing = { x: spacing, y: spacing }; + + if (undefined !== ratio) + vp.view.details.gridSpacing = { x: vp.view.details.gridSpacing.x, y: vp.view.details.gridSpacing.x * ratio }; + + if (undefined !== gridsPerRef) + vp.view.details.gridsPerRef = gridsPerRef; + + if (undefined !== orientation) + vp.view.details.gridOrientation = orientation; + + vp.invalidateScene(); // Needed to clear cached grid decoration... + return true; + } + + /** The keyin accepts the following arguments: + * - `spacing=number` Specify x and y grid reference line spacing in meters. + * - `ratio=number` Specify y spacing as current x * ratio. + * - `gridsPerRef=number` Specify number of grid lines to display per reference line. + * - `orientation=0|1|2|3|4` Value for GridOrientationType. + */ + public parseAndRun(...inputArgs: string[]): boolean { + let spacing; + let ratio; + let gridsPerRef; + let orientation; + const args = parseArgs(inputArgs); + + const spacingArg = args.getFloat("s"); + if (undefined !== spacingArg) + spacing = spacingArg; + + const ratioArg = args.getFloat("r"); + if (undefined !== ratioArg) + ratio = ratioArg; + + const gridsPerRefArg = args.getInteger("g"); + if (undefined !== gridsPerRefArg) + gridsPerRef = gridsPerRefArg; + + const orientationArg = args.getInteger("o"); + if (undefined !== orientationArg) { + switch (orientationArg) { + case 0: + orientation = GridOrientationType.View; + break; + case 1: + orientation = GridOrientationType.WorldXY; + break; + case 2: + orientation = GridOrientationType.WorldYZ; + break; + case 3: + orientation = GridOrientationType.WorldXZ; + break; + case 4: + orientation = GridOrientationType.AuxCoord; + break; + } + } + + this.run(spacing, ratio, gridsPerRef, orientation); + return true; + } +} From c22d782e154c17e90cf4ba95ff3f161a5f7efda4 Mon Sep 17 00:00:00 2001 From: bsteinbk <65047615+bsteinbk@users.noreply.github.com> Date: Thu, 25 Mar 2021 21:19:54 -0400 Subject: [PATCH 12/50] Add settings page to set UI Settings (#984) * UI Settings Pages sets colorTheme, autoHideUi, useProximityOpacity, snapWidgetOpacity, dragInteraction, frameworkVersion, widgetOpacity. * Renamed IModelAppUiSettings to UserSettingStorage * Added LocalSettingsStorage and deprecated LocalUiSettings * Added SessionSettingsStorage and deprecate SessionUiSettings * Added UiSettingsStorage interface and aliased UiSettings to it to maintain compatibility * Renamed SettingsProvider to SettingsTabsProvider * Added support for registering classes that implement UserSettingsProvider so they are called when UiSettingStorage is set so they can load their default from the storage location. * Move AppUiSettings from ui-test-app to ui-framework * Renamed QuantityFormatSettingsPanel to QuantityFormatSettingsPage * updated index.html in ui-test-app to add overflow: hidden to avoid scroll bars during login processing. * Updated SignIn component to avoid button moving during sign-in processing. * clean-up Electron sign-in and update index.html to prevent scrollbar during log-in --- common/api/summary/ui-core.exports.csv | 9 +- common/api/summary/ui-framework.exports.csv | 17 +- common/api/ui-components.api.md | 3 + common/api/ui-core.api.md | 73 +- common/api/ui-framework.api.md | 141 +- .../addUiSettingsPage_2021-03-24-14-51.json | 11 + .../addUiSettingsPage_2021-03-24-14-51.json | 11 + .../addUiSettingsPage_2021-03-24-14-51.json | 11 + docs/changehistory/NextVersion.md | 32 +- docs/learning/ui/core/Settings.md | 10 +- docs/learning/ui/framework/Backstage.md | 2 +- docs/learning/ui/framework/UiSettings.md | 131 + docs/learning/ui/framework/index.md | 1 + test-apps/ui-test-app/public/index.html | 61 +- .../public/locales/en/SampleApp.json | 20 +- .../ui-test-app/src/frontend/AppUiSettings.ts | 64 - .../appui/backstage/AppBackstageComposer.tsx | 8 +- .../frontend/appui/frontstages/Settings.scss | 1 - .../frontend/appui/frontstages/Settings.tsx | 150 +- .../ComponentExamplesProvider.tsx | 10 +- ...ovider.tsx => AppSettingsTabsProvider.tsx} | 20 +- test-apps/ui-test-app/src/frontend/index.tsx | 102 +- .../src/test/color/ColorPickerButton.test.tsx | 5 + .../src/test/table/component/Table.test.tsx | 6 +- .../ui-components/color/ColorPickerButton.tsx | 5 - .../datepicker/DatePickerPopupButton.tsx | 16 +- .../src/ui-components/oidc/SignIn.scss | 8 +- .../src/ui-components/oidc/SignIn.tsx | 8 +- .../quantityformat/FormatPanel.tsx | 8 +- .../quantityformat/FormatSample.tsx | 14 +- .../ui-components/table/component/Table.tsx | 23 +- .../test/settings/SettingsManager.test.tsx | 4 +- .../test/uisettings/LocalUiSettings.test.ts | 15 +- .../test/uisettings/SessionUiSettings.test.ts | 14 +- ui/core/src/test/uisettings/UiSetting.test.ts | 31 +- ui/core/src/ui-core.ts | 6 +- ui/core/src/ui-core/listbox/Listbox.tsx | 13 +- .../src/ui-core/settings/SettingsManager.tsx | 14 +- ui/core/src/ui-core/tabs/tabs.scss | 5 +- ...lUiSettings.ts => LocalSettingsStorage.ts} | 16 +- ...iSettings.ts => SessionSettingsStorage.ts} | 13 +- ui/core/src/ui-core/uisettings/UiSetting.ts | 31 +- .../{UiSettings.ts => UiSettingsStorage.ts} | 11 +- .../public/locales/en/UiFramework.json | 23 + ui/framework/src/test/UiFramework.test.ts | 397 ++- .../test/accudraw/FrameworkAccuDraw.test.ts | 354 ++- .../frontstage/ModalSettingsStage.test.tsx | 4 +- .../src/test/popup/KeyinPalettePanel.test.tsx | 40 +- .../src/test/redux/StateManager.test.ts | 36 +- .../src/test/settings/QuantityFormat.test.tsx | 2 +- .../src/test/settings/UiSettingsPage.test.tsx | 183 ++ .../ToolAssistanceField.test.tsx | 10 +- .../src/test/uisettings/AppUiSettings.test.ts | 66 + ...gs.test.ts => UserSettingsStorage.test.ts} | 16 +- .../src/test/utils/UiShowHideManager.test.tsx | 345 +- .../test/widget-panels/Frontstage.test.snap | 522 +++ .../test/widget-panels/Frontstage.test.tsx | 2791 ++++++++--------- .../test/widgets/NavigationWidget.test.snap | 84 + .../test/widgets/NavigationWidget.test.tsx | 237 +- .../test/widgets/ToolWidgetComposer.test.snap | 35 + .../test/widgets/ToolWidgetComposer.test.tsx | 70 +- ui/framework/src/ui-framework.ts | 4 +- ui/framework/src/ui-framework/UiFramework.ts | 109 +- .../accudraw/AccuDrawFieldContainer.tsx | 8 +- .../accudraw/FrameworkAccuDraw.ts | 20 +- .../src/ui-framework/configurableui/state.ts | 41 +- .../ui-framework/popup/KeyinPalettePanel.tsx | 18 +- .../quantityformatting/QuantityFormat.tsx | 4 +- .../quantityformatting/UnitSystemSelector.tsx | 8 +- .../settings/ui/UiSettingsPage.scss | 67 + .../settings/ui/UiSettingsPage.tsx | 208 ++ .../stagepanels/StagePanelDef.tsx | 1 + .../toolassistance/ToolAssistanceField.tsx | 20 +- .../syncui/SyncUiEventDispatcher.ts | 1 + .../ui-framework/uisettings/AppUiSettings.ts | 108 + ...ppUiSettings.ts => UserSettingsStorage.ts} | 12 +- .../ui-framework/uisettings/useUiSettings.tsx | 18 +- .../ui-framework/utils/UiShowHideManager.ts | 68 +- .../ui-framework/widget-panels/Frontstage.tsx | 22 +- 79 files changed, 4410 insertions(+), 2696 deletions(-) create mode 100644 common/changes/@bentley/ui-components/addUiSettingsPage_2021-03-24-14-51.json create mode 100644 common/changes/@bentley/ui-core/addUiSettingsPage_2021-03-24-14-51.json create mode 100644 common/changes/@bentley/ui-framework/addUiSettingsPage_2021-03-24-14-51.json create mode 100644 docs/learning/ui/framework/UiSettings.md delete mode 100644 test-apps/ui-test-app/src/frontend/AppUiSettings.ts rename test-apps/ui-test-app/src/frontend/appui/uiproviders/{AppSettingsProvider.tsx => AppSettingsTabsProvider.tsx} (58%) rename ui/core/src/ui-core/uisettings/{LocalUiSettings.ts => LocalSettingsStorage.ts} (76%) rename ui/core/src/ui-core/uisettings/{SessionUiSettings.ts => SessionSettingsStorage.ts} (80%) rename ui/core/src/ui-core/uisettings/{UiSettings.ts => UiSettingsStorage.ts} (80%) create mode 100644 ui/framework/src/test/settings/UiSettingsPage.test.tsx create mode 100644 ui/framework/src/test/uisettings/AppUiSettings.test.ts rename ui/framework/src/test/uisettings/{IModelAppUiSettings.test.ts => UserSettingsStorage.test.ts} (92%) create mode 100644 ui/framework/src/ui-framework/settings/ui/UiSettingsPage.scss create mode 100644 ui/framework/src/ui-framework/settings/ui/UiSettingsPage.tsx create mode 100644 ui/framework/src/ui-framework/uisettings/AppUiSettings.ts rename ui/framework/src/ui-framework/uisettings/{IModelAppUiSettings.ts => UserSettingsStorage.ts} (89%) diff --git a/common/api/summary/ui-core.exports.csv b/common/api/summary/ui-core.exports.csv index b44df36f757..5f93596d1ba 100644 --- a/common/api/summary/ui-core.exports.csv +++ b/common/api/summary/ui-core.exports.csv @@ -155,6 +155,7 @@ public;LoadingSpinner public;LoadingSpinnerProps public;LoadingStatus public;LoadingStatusProps +public;LocalSettingsStorage beta;LocalUiSettings public;MainTabsProps internal;mergeRefs @@ -225,14 +226,15 @@ public;SearchBoxProps public;Select: (props: SelectProps) => JSX.Element | null public;SelectOption public;SelectProps +public;SessionSettingsStorage beta;SessionUiSettings beta;SettingsContainer: ({ tabs, onSettingsTabSelected, currentSettingsTab, settingsManager, showHeader }: SettingsContainerProps) => JSX.Element beta;SettingsContainerProps beta;SettingsManager -beta;SettingsProvider beta;SettingsProvidersChangedEvent beta;SettingsProvidersChangedEventArgs beta;SettingsTabEntry +beta;SettingsTabsProvider internal;shallowDiffers: (a: internal;Size public;SizeProps @@ -289,10 +291,11 @@ public;TreeNodeProps public;TreeProps public;UiCore public;UiEvent -beta;UiSetting -public;UiSettings +public;UiSetting +public;UiSettings = UiSettingsStorage public;UiSettingsResult public;UiSettingsStatus +public;UiSettingsStorage public;UnderlinedButton(props: UnderlinedButtonProps): JSX.Element public;UnderlinedButtonProps public;useDisposable diff --git a/common/api/summary/ui-framework.exports.csv b/common/api/summary/ui-framework.exports.csv index bf61000a9da..0c183f3c0ee 100644 --- a/common/api/summary/ui-framework.exports.csv +++ b/common/api/summary/ui-framework.exports.csv @@ -37,6 +37,7 @@ public;AnyItemDef = GroupItemDef | CommandItemDef | ToolItemDef | ActionButtonIt public;AnyWidgetProps = WidgetProps | ToolWidgetProps | NavigationWidgetProps internal;appendWidgets(state: NineZoneState, widgetDefs: ReadonlyArray public;AppNotificationManager +beta;AppUiSettings beta;areNoFeatureOverridesActive(): boolean public;Backstage beta;BackstageActionItem @@ -110,7 +111,7 @@ public;ConfigurableUiControlConstructor = new (info: ConfigurableCreateInfo, opt public;ConfigurableUiControlType public;ConfigurableUiElement public;ConfigurableUiManager -public;ConfigurableUiReducer(state: ConfigurableUiState | undefined, _action: ConfigurableUiActionsUnion): ConfigurableUiState +public;ConfigurableUiReducer(state: ConfigurableUiState | undefined, action: ConfigurableUiActionsUnion): ConfigurableUiState public;ConfigurableUiState beta;connectIModelConnection: (mapStateToProps?: any, mapDispatchToProps?: any) => import("react-redux").InferableComponentEnhancerWithProps beta;connectIModelConnectionAndViewState: (mapStateToProps?: any, mapDispatchToProps?: any) => import("react-redux").InferableComponentEnhancerWithProps @@ -245,6 +246,7 @@ beta;getQuantityFormatsSettingsManagerEntry(itemPriority: number, opts?: Partial beta;getSelectionContextSyncEventIds(): string[] internal;getStableWidgetProps(widgetProps: WidgetProps, stableId: string): WidgetProps internal;getStagePanelType: (location: StagePanelLocation_2) => StagePanelType +beta;getUiSettingsManagerEntry(itemPriority: number, allowSettingUiFrameworkVersion?: boolean): SettingsTabEntry internal;getWidgetId(side: PanelSide, key: StagePanelZoneDefKeys): WidgetIdTypes public;GroupButton(props: GroupButtonProps): JSX.Element internal;GroupButtonItem(props: GroupButtonProps_2): JSX.Element @@ -274,6 +276,7 @@ beta;IModelViewportControl beta;IModelViewportControlOptions internal;INACTIVITY_TIME_DEFAULT = 3500 beta;Indicator +beta;InitialAppUiSettings internal;initializeNineZoneState(frontstageDef: FrontstageDef): NineZoneState internal;initializePanel(nineZone: NineZoneState, frontstageDef: FrontstageDef, panelSide: PanelSide): NineZoneState alpha;InputEditorCommitHandler @@ -416,7 +419,7 @@ internal;ProjectScope internal;ProjectServices public;PromptField: import("react-redux").ConnectedComponent public;PropsHelper -beta;QuantityFormatSettingsPanel({ initialQuantityType, availableUnitSystems }: QuantityFormatterSettingsOptions): JSX.Element +beta;QuantityFormatSettingsPage({ initialQuantityType, availableUnitSystems }: QuantityFormatterSettingsOptions): JSX.Element beta;QuantityFormatterSettingsOptions alpha;ReactContent public;ReactMessage = ReactMessage_2 @@ -600,9 +603,11 @@ public;UiFramework internal;UiIntervalEvent internal;UiIntervalEventArgs internal;UiSettingsContext: React.Context -alpha;UiSettingsProvider(props: UiSettingsProviderProps): JSX.Element -alpha;UiSettingsProviderProps +beta;UiSettingsPage({ allowSettingUiFrameworkVersion }: +beta;UiSettingsProvider(props: UiSettingsProviderProps): JSX.Element +beta;UiSettingsProviderProps public;UiShowHideManager +internal;UiShowHideSettingsProvider public;UiVisibilityChangedEvent public;UiVisibilityEventArgs internal;useActiveFrontstageDef(): FrontstageDef | undefined @@ -626,6 +631,8 @@ internal;useNineZoneDispatch(frontstageDef: FrontstageDef): NineZoneDispatch internal;useNineZoneState(frontstageDef: FrontstageDef): NineZoneState | undefined public;UserProfileBackstageItem public;UserProfileBackstageItemProps +beta;UserSettingsProvider +public;UserSettingsStorage internal;useSavedFrontstageState(frontstageDef: FrontstageDef): void internal;useSaveFrontstageSettings(frontstageDef: FrontstageDef): void internal;useStatusBarEntry(): DockedStatusBarEntryContextArg @@ -633,7 +640,7 @@ internal;useSyncDefinitions(frontstageDef: FrontstageDef): void internal;useToolSettingsNode(): React.ReactNode beta;useUiItemsProviderStatusBarItems: (manager: StatusBarItemsManager_2) => readonly CommonStatusBarItem[] beta;useUiItemsProviderToolbarItems: (manager: ToolbarItemsManager, toolbarUsage: ToolbarUsage, toolbarOrientation: ToolbarOrientation) => readonly CommonToolbarItem[] -internal;useUiSettingsContext(): UiSettings +beta;useUiSettingsStorageContext(): UiSettingsStorage internal;useUiVisibility(): boolean internal;useUpdateNineZoneSize(frontstageDef: FrontstageDef): void alpha;useVisibilityTreeFiltering: (nodeLoader: AbstractTreeNodeLoaderWithProvider diff --git a/common/api/ui-components.api.md b/common/api/ui-components.api.md index c69e4342ecd..a07d25fa7bf 100644 --- a/common/api/ui-components.api.md +++ b/common/api/ui-components.api.md @@ -73,6 +73,7 @@ import { TimeDisplay } from '@bentley/ui-abstract'; import { TimeFormat } from '@bentley/ui-core'; import { UiEvent } from '@bentley/ui-core'; import { UiSettings } from '@bentley/ui-core'; +import { UiSettingsStorage } from '@bentley/ui-core'; import { UnitProps } from '@bentley/imodeljs-quantity'; import { UnitsProvider } from '@bentley/imodeljs-quantity'; import { Vector3d } from '@bentley/geometry-core'; @@ -4527,9 +4528,11 @@ export interface TableProps extends CommonProps { scrollToRow?: number; selectionMode?: SelectionMode; settingsIdentifier?: string; + settingsStorage?: UiSettingsStorage; showHideColumns?: boolean; stripedRows?: boolean; tableSelectionTarget?: TableSelectionTarget; + // @deprecated uiSettings?: UiSettings; } diff --git a/common/api/ui-core.api.md b/common/api/ui-core.api.md index 7cfad92565f..6420e016e9f 100644 --- a/common/api/ui-core.api.md +++ b/common/api/ui-core.api.md @@ -1247,8 +1247,8 @@ export interface LoadingStatusProps extends CommonProps { percent: number; } -// @beta -export class LocalUiSettings implements UiSettings { +// @public +export class LocalSettingsStorage implements UiSettingsStorage { constructor(w?: Window); // (undocumented) deleteSetting(settingNamespace: string, settingName: string): Promise; @@ -1260,6 +1260,11 @@ export class LocalUiSettings implements UiSettings { w: Window; } +// @beta @deprecated +export class LocalUiSettings extends LocalSettingsStorage { + constructor(w?: Window); +} + // @public export interface MainTabsProps extends TabsProps { mainClassName: string; @@ -1886,8 +1891,8 @@ export interface SelectProps extends React.SelectHTMLAttributes; @@ -1899,6 +1904,11 @@ export class SessionUiSettings implements UiSettings { w: Window; } +// @beta @deprecated +export class SessionUiSettings extends SessionSettingsStorage { + constructor(w?: Window); +} + // @beta export const SettingsContainer: ({ tabs, onSettingsTabSelected, currentSettingsTab, settingsManager, showHeader }: SettingsContainerProps) => JSX.Element; @@ -1920,7 +1930,7 @@ export interface SettingsContainerProps { export class SettingsManager { activateSettingsTab(settingsTabId: string): void; // (undocumented) - addSettingsProvider(settingsProvider: SettingsProvider): void; + addSettingsProvider(settingsProvider: SettingsTabsProvider): void; closeSettingsContainer(closeFunc: (args: any) => void, closeFuncArgs?: any): void; getSettingEntries(stageId: string, stageUsage: string): Array; // @internal @@ -1931,19 +1941,12 @@ export class SettingsManager { readonly onProcessSettingsTabActivation: ProcessSettingsTabActivationEvent; readonly onSettingsProvidersChanged: SettingsProvidersChangedEvent; // (undocumented) - get providers(): ReadonlyArray; - set providers(p: ReadonlyArray); + get providers(): ReadonlyArray; + set providers(p: ReadonlyArray); // (undocumented) removeSettingsProvider(providerId: string): boolean; } -// @beta -export interface SettingsProvider { - // (undocumented) - getSettingEntries(stageId: string, stageUsage: string): ReadonlyArray | undefined; - readonly id: string; -} - // @beta export class SettingsProvidersChangedEvent extends BeUiEvent { } @@ -1951,7 +1954,7 @@ export class SettingsProvidersChangedEvent extends BeUiEvent; + readonly providers: ReadonlyArray; } // @beta @@ -1967,6 +1970,13 @@ export interface SettingsTabEntry { readonly tooltip?: string | JSX.Element; } +// @beta +export interface SettingsTabsProvider { + // (undocumented) + getSettingEntries(stageId: string, stageUsage: string): ReadonlyArray | undefined; + readonly id: string; +} + // @internal export const shallowDiffers: (a: { [key: string]: any; @@ -2477,17 +2487,19 @@ export class UiCore { export class UiEvent extends BeUiEvent { } -// @beta +// @public export class UiSetting { - constructor(settingNamespace: string, settingName: string, getValue: () => T, applyValue?: ((v: T) => void) | undefined); + constructor(settingNamespace: string, settingName: string, getValue: () => T, applyValue?: ((v: T) => void) | undefined, defaultValue?: T | undefined); // (undocumented) applyValue?: ((v: T) => void) | undefined; - deleteSetting(uiSettings: UiSettings): Promise; - getSetting(uiSettings: UiSettings): Promise; - getSettingAndApplyValue(uiSettings: UiSettings): Promise; + // (undocumented) + defaultValue?: T | undefined; + deleteSetting(storage: UiSettingsStorage): Promise; + getSetting(storage: UiSettingsStorage): Promise; + getSettingAndApplyValue(storage: UiSettingsStorage): Promise; // (undocumented) getValue: () => T; - saveSetting(uiSettings: UiSettings): Promise; + saveSetting(storage: UiSettingsStorage): Promise; // (undocumented) settingName: string; // (undocumented) @@ -2495,14 +2507,7 @@ export class UiSetting { } // @public -export interface UiSettings { - // (undocumented) - deleteSetting(settingNamespace: string, settingName: string): Promise; - // (undocumented) - getSetting(settingNamespace: string, settingName: string): Promise; - // (undocumented) - saveSetting(settingNamespace: string, settingName: string, setting: any): Promise; -} +export type UiSettings = UiSettingsStorage; // @public export interface UiSettingsResult { @@ -2526,6 +2531,16 @@ export enum UiSettingsStatus { UnknownError = 2 } +// @public +export interface UiSettingsStorage { + // (undocumented) + deleteSetting(settingNamespace: string, settingName: string): Promise; + // (undocumented) + getSetting(settingNamespace: string, settingName: string): Promise; + // (undocumented) + saveSetting(settingNamespace: string, settingName: string, setting: any): Promise; +} + // @public export function UnderlinedButton(props: UnderlinedButtonProps): JSX.Element; diff --git a/common/api/ui-framework.api.md b/common/api/ui-framework.api.md index 51ecde7a641..9bdfd155140 100644 --- a/common/api/ui-framework.api.md +++ b/common/api/ui-framework.api.md @@ -164,9 +164,11 @@ import { UiAdmin } from '@bentley/ui-abstract'; import { UiDataProvider } from '@bentley/ui-abstract'; import { UiEvent } from '@bentley/ui-core'; import { UiLayoutDataProvider } from '@bentley/ui-abstract'; +import { UiSetting } from '@bentley/ui-core'; import { UiSettings } from '@bentley/ui-core'; import { UiSettingsResult } from '@bentley/ui-core'; import { UiSettingsStatus } from '@bentley/ui-core'; +import { UiSettingsStorage } from '@bentley/ui-core'; import { UnifiedSelectionTreeEventHandler } from '@bentley/presentation-components'; import { UnifiedSelectionTreeEventHandlerParams } from '@bentley/presentation-components'; import { UnitSystemKey } from '@bentley/imodeljs-frontend'; @@ -486,6 +488,25 @@ export class AppNotificationManager extends NotificationManager { updatePointerMessage(displayPoint: XAndY, relativePosition: RelativePosition): void; } +// @beta +export class AppUiSettings implements UserSettingsProvider { + constructor(defaults: Partial); + // (undocumented) + apply(storage: UiSettingsStorage): Promise; + // (undocumented) + colorTheme: UiSetting; + // (undocumented) + dragInteraction: UiSetting; + // (undocumented) + frameworkVersion: UiSetting; + // (undocumented) + loadUserSettings(storage: UiSettingsStorage): Promise; + // (undocumented) + readonly providerId = "AppUiSettingsProvider"; + // (undocumented) + widgetOpacity: UiSetting; +} + // @beta export function areNoFeatureOverridesActive(): boolean; @@ -1014,6 +1035,10 @@ export class ConfigurableCreateInfo { // @public export enum ConfigurableUiActionId { + // (undocumented) + SetDragInteraction = "configurableui:set-drag-interaction", + // (undocumented) + SetFrameworkVersion = "configurableui:set-framework-version", // (undocumented) SetSnapMode = "configurableui:set_snapmode", // (undocumented) @@ -1030,6 +1055,8 @@ export const ConfigurableUiActions: { setTheme: (theme: string) => import("../redux/redux-ts").ActionWithPayload; setToolPrompt: (toolPrompt: string) => import("../redux/redux-ts").ActionWithPayload; setWidgetOpacity: (opacity: number) => import("../redux/redux-ts").ActionWithPayload; + setDragInteraction: (dragInteraction: boolean) => import("../redux/redux-ts").ActionWithPayload; + setFrameworkVersion: (frameworkVersion: string) => import("../redux/redux-ts").ActionWithPayload; }; // @public @@ -1120,10 +1147,12 @@ export class ConfigurableUiManager { } // @public -export function ConfigurableUiReducer(state: ConfigurableUiState | undefined, _action: ConfigurableUiActionsUnion): ConfigurableUiState; +export function ConfigurableUiReducer(state: ConfigurableUiState | undefined, action: ConfigurableUiActionsUnion): ConfigurableUiState; // @public export interface ConfigurableUiState { + // (undocumented) + frameworkVersion: string; // (undocumented) snapMode: number; // (undocumented) @@ -1131,6 +1160,8 @@ export interface ConfigurableUiState { // (undocumented) toolPrompt: string; // (undocumented) + useDragInteraction: boolean; + // (undocumented) widgetOpacity: number; } @@ -2016,7 +2047,7 @@ export interface FooterModeFieldProps extends StatusFieldProps { } // @internal (undocumented) -export class FrameworkAccuDraw extends AccuDraw { +export class FrameworkAccuDraw extends AccuDraw implements UserSettingsProvider { constructor(); static get displayNotifications(): boolean; static set displayNotifications(v: boolean); @@ -2032,6 +2063,8 @@ export class FrameworkAccuDraw extends AccuDraw { static readonly isSideRotationConditional: ConditionalBooleanValue; static readonly isTopRotationConditional: ConditionalBooleanValue; static readonly isViewRotationConditional: ConditionalBooleanValue; + // (undocumented) + loadUserSettings(storage: UiSettings): Promise; static readonly onAccuDrawUiSettingsChangedEvent: AccuDrawUiSettingsChangedEvent; // (undocumented) onCompassModeChange(): void; @@ -2043,6 +2076,8 @@ export class FrameworkAccuDraw extends AccuDraw { // (undocumented) onRotationModeChange(): void; // (undocumented) + readonly providerId = "FrameworkAccuDraw"; + // (undocumented) setFocusItem(index: ItemField): void; // (undocumented) static translateFromItemField(item: ItemField): AccuDrawField; @@ -2056,7 +2091,7 @@ export class FrameworkAccuDraw extends AccuDraw { export const FrameworkReducer: (state: import("./redux-ts").CombinedReducerState<{ configurableUiState: typeof ConfigurableUiReducer; sessionState: typeof SessionStateReducer; -}>, action: import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject>> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject>> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject>>) => import("./redux-ts").CombinedReducerState<{ +}>, action: import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject>> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject>> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject> | import("./redux-ts").DeepReadonlyObject>>) => import("./redux-ts").CombinedReducerState<{ configurableUiState: typeof ConfigurableUiReducer; sessionState: typeof SessionStateReducer; }>; @@ -2723,6 +2758,9 @@ export function getStableWidgetProps(widgetProps: WidgetProps, stableId: string) // @internal (undocumented) export const getStagePanelType: (location: StagePanelLocation_2) => StagePanelType; +// @beta +export function getUiSettingsManagerEntry(itemPriority: number, allowSettingUiFrameworkVersion?: boolean): SettingsTabEntry; + // @internal (undocumented) export function getWidgetId(side: PanelSide, key: StagePanelZoneDefKeys): WidgetIdTypes; @@ -2908,14 +2946,8 @@ export interface HTMLElementPopupProps extends PopupPropsBase { relativePosition: RelativePosition; } -// @beta -export class IModelAppUiSettings implements UiSettings { - // (undocumented) - deleteSetting(namespace: string, name: string): Promise; - // (undocumented) - getSetting(namespace: string, name: string): Promise; - // (undocumented) - saveSetting(namespace: string, name: string, setting: any): Promise; +// @beta @deprecated +export class IModelAppUiSettings extends UserSettingsStorage { } // @beta @@ -3038,6 +3070,18 @@ export class Indicator extends React.Component { render(): JSX.Element; } +// @beta +export interface InitialAppUiSettings { + // (undocumented) + colorTheme: string; + // (undocumented) + dragInteraction: boolean; + // (undocumented) + frameworkVersion: string; + // (undocumented) + widgetOpacity: number; +} + // @internal (undocumented) export function initializeNineZoneState(frontstageDef: FrontstageDef): NineZoneState; @@ -4328,7 +4372,7 @@ export class PropsHelper { } // @beta -export function QuantityFormatSettingsPanel({ initialQuantityType, availableUnitSystems }: QuantityFormatterSettingsOptions): JSX.Element; +export function QuantityFormatSettingsPage({ initialQuantityType, availableUnitSystems }: QuantityFormatterSettingsOptions): JSX.Element; // @beta export interface QuantityFormatterSettingsOptions { @@ -5762,6 +5806,8 @@ export enum SyncUiEventId { NavigationAidActivated = "navigationaidactivated", SelectionSetChanged = "selectionsetchanged", SettingsProvidersChanged = "settingsproviderschanged", + // (undocumented) + ShowHideManagerSettingChange = "show-hide-setting-change", TaskActivated = "taskactivated", ToolActivated = "toolactivated", UiSettingsChanged = "uisettingschanged", @@ -5939,7 +5985,7 @@ export class ToolAssistanceField extends React.Component; // @internal (undocumented) - static contextType: React.Context; + static contextType: React.Context; // @internal (undocumented) static readonly defaultProps: ToolAssistanceFieldDefaultProps; // @internal (undocumented) @@ -5957,7 +6003,7 @@ export interface ToolAssistanceFieldProps extends StatusFieldProps { defaultPromptAtCursor: boolean; fadeOutCursorPrompt: boolean; includePromptAtCursor: boolean; - uiSettings?: UiSettings; + uiSettings?: UiSettingsStorage; } // @internal @@ -6375,7 +6421,7 @@ export class UiFramework { // (undocumented) static getIsUiVisible(): boolean; // @beta (undocumented) - static getUiSettings(): UiSettings; + static getUiSettingsStorage(): UiSettingsStorage; // @beta (undocumented) static getUserInfo(): UserInfo | undefined; // (undocumented) @@ -6409,6 +6455,8 @@ export class UiFramework { }): Promise; // @internal (undocumented) static get projectServices(): ProjectServices; + // @alpha + static registerUserSettingsProvider(entry: UserSettingsProvider): boolean; // (undocumented) static setAccudrawSnapMode(snapMode: SnapMode): void; // (undocumented) @@ -6432,7 +6480,11 @@ export class UiFramework { // @beta static get settingsManager(): SettingsManager; // @beta (undocumented) - static setUiSettings(uiSettings: UiSettings, immediateSync?: boolean): void; + static setUiSettingsStorage(storage: UiSettingsStorage, immediateSync?: boolean): Promise; + // (undocumented) + static setUiVersion(version: string): void; + // (undocumented) + static setUseDragInteraction(useDragInteraction: boolean): void; // @beta (undocumented) static setUserInfo(userInfo: UserInfo | undefined, immediateSync?: boolean): void; // (undocumented) @@ -6443,6 +6495,8 @@ export class UiFramework { static translate(key: string | string[]): string; // @beta static get uiVersion(): string; + // (undocumented) + static get useDragInteraction(): boolean; // @alpha (undocumented) static get widgetManager(): WidgetManager; } @@ -6458,17 +6512,22 @@ export interface UiIntervalEventArgs { } // @internal (undocumented) -export const UiSettingsContext: React.Context; +export const UiSettingsContext: React.Context; -// @alpha +// @beta +export function UiSettingsPage({ allowSettingUiFrameworkVersion }: { + allowSettingUiFrameworkVersion: boolean; +}): JSX.Element; + +// @beta export function UiSettingsProvider(props: UiSettingsProviderProps): JSX.Element; -// @alpha +// @beta export interface UiSettingsProviderProps { // (undocumented) children?: React.ReactNode; // (undocumented) - uiSettings: UiSettings; + settingsStorage: UiSettingsStorage; } // @public @@ -6482,6 +6541,12 @@ export class UiShowHideManager { static set inactivityTime(time: number); static get isUiVisible(): boolean; static set isUiVisible(visible: boolean); + // @internal (undocumented) + static setAutoHideUi(value: boolean): void; + // @internal (undocumented) + static setSnapWidgetOpacity(value: boolean): void; + // @internal (undocumented) + static setUseProximityOpacity(value: boolean): void; static get showHideFooter(): boolean; static set showHideFooter(showHide: boolean); static get showHidePanels(): boolean; @@ -6494,6 +6559,22 @@ export class UiShowHideManager { static set useProximityOpacity(value: boolean); } +// @internal +export class UiShowHideSettingsProvider implements UserSettingsProvider { + // (undocumented) + static initialize(): void; + // (undocumented) + loadUserSettings(storage: UiSettings): Promise; + // (undocumented) + readonly providerId = "UiShowHideSettingsProvider"; + // (undocumented) + static storeAutoHideUi(v: boolean, storage?: UiSettings): Promise; + // (undocumented) + static storeSnapWidgetOpacity(v: boolean, storage?: UiSettings): Promise; + // (undocumented) + static storeUseProximityOpacity(v: boolean, storage?: UiSettings): Promise; + } + // @public export class UiVisibilityChangedEvent extends UiEvent { } @@ -6575,6 +6656,22 @@ export interface UserProfileBackstageItemProps extends CommonProps { userInfo: UserInfo; } +// @beta +export interface UserSettingsProvider { + loadUserSettings(storage: UiSettingsStorage): Promise; + providerId: string; +} + +// @public +export class UserSettingsStorage implements UiSettingsStorage { + // (undocumented) + deleteSetting(namespace: string, name: string): Promise; + // (undocumented) + getSetting(namespace: string, name: string): Promise; + // (undocumented) + saveSetting(namespace: string, name: string, setting: any): Promise; +} + // @internal (undocumented) export function useSavedFrontstageState(frontstageDef: FrontstageDef): void; @@ -6596,8 +6693,8 @@ export const useUiItemsProviderStatusBarItems: (manager: StatusBarItemsManager_2 // @beta export const useUiItemsProviderToolbarItems: (manager: ToolbarItemsManager, toolbarUsage: ToolbarUsage, toolbarOrientation: ToolbarOrientation) => readonly CommonToolbarItem[]; -// @internal (undocumented) -export function useUiSettingsContext(): UiSettings; +// @beta (undocumented) +export function useUiSettingsStorageContext(): UiSettingsStorage; // @internal (undocumented) export function useUiVisibility(): boolean; diff --git a/common/changes/@bentley/ui-components/addUiSettingsPage_2021-03-24-14-51.json b/common/changes/@bentley/ui-components/addUiSettingsPage_2021-03-24-14-51.json new file mode 100644 index 00000000000..d38006110ce --- /dev/null +++ b/common/changes/@bentley/ui-components/addUiSettingsPage_2021-03-24-14-51.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ui-components", + "comment": "Update to use UiSettingsStorage.", + "type": "none" + } + ], + "packageName": "@bentley/ui-components", + "email": "65047615+bsteinbk@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/ui-core/addUiSettingsPage_2021-03-24-14-51.json b/common/changes/@bentley/ui-core/addUiSettingsPage_2021-03-24-14-51.json new file mode 100644 index 00000000000..d39f2cf1051 --- /dev/null +++ b/common/changes/@bentley/ui-core/addUiSettingsPage_2021-03-24-14-51.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ui-core", + "comment": "Add more descriptive UiSettingsStorage, LocalSettingsStorage, and SessionSettingsStorage and deprecate badly name beta classes.", + "type": "none" + } + ], + "packageName": "@bentley/ui-core", + "email": "65047615+bsteinbk@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@bentley/ui-framework/addUiSettingsPage_2021-03-24-14-51.json b/common/changes/@bentley/ui-framework/addUiSettingsPage_2021-03-24-14-51.json new file mode 100644 index 00000000000..1d417cc5433 --- /dev/null +++ b/common/changes/@bentley/ui-framework/addUiSettingsPage_2021-03-24-14-51.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@bentley/ui-framework", + "comment": "Add UiSettingsPage, AppUiSettings, and ability to register UserSettingsProvider to provide default settings from UsSettingsStorage.", + "type": "none" + } + ], + "packageName": "@bentley/ui-framework", + "email": "65047615+bsteinbk@users.noreply.github.com" +} \ No newline at end of file diff --git a/docs/changehistory/NextVersion.md b/docs/changehistory/NextVersion.md index c9d1525de2e..2f297d742cc 100644 --- a/docs/changehistory/NextVersion.md +++ b/docs/changehistory/NextVersion.md @@ -13,29 +13,39 @@ publish: false ## New settings UI features -### Add Settings Page to set Quantity Formatting Overrides +### Add Settings Tabs and Pages to UI -The [QuantityFormatSettingsPanel]($ui-framework) component has been added to the @bentley/ui-framework package to provide the UI to set both the [PresentationUnitSystem]($presentation-common) and formatting overrides in the [QuantityFormatter]($frontend). This panel can be used in the new [SettingsContainer]($ui-core) UI component. The function `getQuantityFormatsSettingsManagerEntry` will return a [SettingsTabEntry]($ui-core) for use by the [SettingsManager]($ui-core). Below is an example of registering the `QuantityFormatSettingsPanel` with the `SettingsManager`. +#### Quantity Formatting Settings + +The [QuantityFormatSettingsPage]($ui-framework) component has been added to provide the UI to set both the [PresentationUnitSystem]($presentation-common) and formatting overrides in the [QuantityFormatter]($frontend). This component can be used in the new [SettingsContainer]($ui-core) UI component. The function `getQuantityFormatsSettingsManagerEntry` will return a [SettingsTabEntry]($ui-core) for use by the [SettingsManager]($ui-core). + +#### User Interface Settings + +The [UiSettingsPage]($ui-framework) component has been to provide the UI to set general UI settings that effect the look and feel of the App UI user interface. This component can be used in the new [SettingsContainer]($ui-core) UI component. The function `getUiSettingsManagerEntry` will return a [SettingsTabEntry]($ui-core) for use by the [SettingsManager]($ui-core). + +#### Registering Settings + +Below is an example of registering the `QuantityFormatSettingsPage` with the `SettingsManager`. ```ts // Sample settings provider that dynamically adds settings into the setting stage -export class AppSettingsProvider implements SettingsProvider { - public readonly id = "AppSettingsProvider"; +export class AppSettingsTabsProvider implements SettingsTabsProvider { + public readonly id = "AppSettingsTabsProvider"; public getSettingEntries(_stageId: string, _stageUsage: string): ReadonlyArray | undefined { return [ getQuantityFormatsSettingsManagerEntry(10, {availableUnitSystems:new Set(["metric","imperial","usSurvey"])}), + getUiSettingsManagerEntry(30, true), ]; } public static initializeAppSettingProvider() { - UiFramework.settingsManager.addSettingsProvider(new AppSettingsProvider()); + UiFramework.settingsManager.addSettingsProvider(new AppSettingsTabsProvider()); } } - ``` -The `QuantityFormatSettingsPanel` is marked as alpha in this release and is subject to minor modifications in future releases. +The `QuantityFormatSettingsPage` is marked as alpha in this release and is subject to minor modifications in future releases. ## @bentley/imodeljs-quantity package @@ -59,6 +69,14 @@ The class [NativeApp]($frontend) has been promoted from @alpha to @beta. `Native ## Breaking Api Changes +### @bentley/ui-core package + +The beta class `SettingsProvider` was renamed to `SettingsTabsProvider`. + +### @bentley/ui-framework package + +The beta class `QuantityFormatSettingsPanel` was renamed to `QuantityFormatSettingsPage`. + ### @bentley/imodeljs-quantity package #### UnitProps property name change diff --git a/docs/learning/ui/core/Settings.md b/docs/learning/ui/core/Settings.md index 684aa2bf204..cf08ec5466c 100644 --- a/docs/learning/ui/core/Settings.md +++ b/docs/learning/ui/core/Settings.md @@ -1,20 +1,20 @@ # Settings -The [SettingsManager]($ui-core) allows the registration of [SettingsProvider]($ui-core) classes to provide the settings to display with the [SettingsContainer]($ui-core) component. In an application that employs App UI, the [SettingsModalFrontstage]($ui-framework) frontstage will display the SettingsContainer and its entries. +The [SettingsManager]($ui-core) allows the registration of [SettingsTabsProvider]($ui-core) classes to provide the settings to display with the [SettingsContainer]($ui-core) component. In an application that employs App UI, the [SettingsModalFrontstage]($ui-framework) frontstage will display the SettingsContainer and its entries. ## SettingsTabEntry -Registered [SettingsProvider]($ui-core) instance will implement the method `getSettingEntries` to return an array of [SettingsProvider]($ui-core) items. Each SettingsTabEntry will populate a Tab entry in the [SettingsContainer]($ui-core) component. The `tabId` property is a string and must be unique across all registered SettingsProviders. A common practice is to prefix the tabId with the package name to ensure uniqueness. The `page` property holds the React.Element that will be used to construct the component to edit settings for this entry. It is the `page's` responsibility to persist and retrieve persisted settings. If the `page` contains multiple properties that must be saved together the SettingsTabEntry can set the `pageWillHandleCloseRequest` property to `true`. The `page's` control should then register to be notified when the setting container is closing or when the active SettingsEnty is changing so that any unsaved data can be saved. Two React hooks are provided to assist: `settingsManager.onProcessSettingsTabActivation` and `settingsManager.onProcessSettingsContainerClose`. +Registered [SettingsTabsProvider]($ui-core) instance will implement the method `getSettingEntries` to return an array of [SettingsTabsProvider]($ui-core) items. Each SettingsTabEntry will populate a Tab entry in the [SettingsContainer]($ui-core) component. The `tabId` property is a string and must be unique across all registered SettingsProviders. A common practice is to prefix the tabId with the package name to ensure uniqueness. The `page` property holds the React.Element that will be used to construct the component to edit settings for this entry. It is the `page's` responsibility to persist and retrieve persisted settings. If the `page` contains multiple properties that must be saved together the SettingsTabEntry can set the `pageWillHandleCloseRequest` property to `true`. The `page's` control should then register to be notified when the setting container is closing or when the active SettingsEnty is changing so that any unsaved data can be saved. Two React hooks are provided to assist: `settingsManager.onProcessSettingsTabActivation` and `settingsManager.onProcessSettingsContainerClose`. ## Example -### Example SettingsProvider +### Example SettingsTabsProvider Example below shows a settings provide that provides two settings pages. The first one depicts a page that has properties that cannot be saved immediately as individual properties are changed. It must be treated as a modal where once all values are define a save button is used the save the changes. The second settings page handles settings that can be immediately saved when changed and does not require any special processing when the page is closed. ```tsx // Sample UI items provider that dynamically adds ui items -export class ExampleSettingsProvider implements SettingsProvider { +export class ExampleSettingsProvider implements SettingsTabsProvider { public readonly id = "myApp:ExampleSettingsProvider"; public getSettingEntries(stageId: string, stageUsage: string): ReadonlyArray | undefined { @@ -145,6 +145,6 @@ function SaveFormatModalDialog({ persistChangesFunc, persistChangesFuncArg, onDi ## API Reference - [SettingsManager]($ui-core) -- [SettingsProvider]($ui-core) +- [SettingsTabsProvider]($ui-core) - [SettingsContainer]($ui-core) - [SettingsTabEntry]($ui-core) diff --git a/docs/learning/ui/framework/Backstage.md b/docs/learning/ui/framework/Backstage.md index a39d300915a..72865192c15 100644 --- a/docs/learning/ui/framework/Backstage.md +++ b/docs/learning/ui/framework/Backstage.md @@ -24,7 +24,7 @@ export function AppBackstageComposer() { } ``` -Note: the static method `SettingsModalFrontstage.getBackstageActionItem` used above, will create an entry for a `Settings` stage. This stage will display [SettingsTabEntry]($ui-core) items from [SettingsProvider]($ui-core) classes registered with the [SettingsManager]($ui-core). The `SettingsManager` instance is referenced by property `UiFramework.settingsManager`. +Note: the static method `SettingsModalFrontstage.getBackstageActionItem` used above, will create an entry for a `Settings` stage. This stage will display [SettingsTabEntry]($ui-core) items from [SettingsTabsProvider]($ui-core) classes registered with the [SettingsManager]($ui-core). The `SettingsManager` instance is referenced by property `UiFramework.settingsManager`. See additional info in [Backstage](../../../learning/ui/abstract/Backstage.md). diff --git a/docs/learning/ui/framework/UiSettings.md b/docs/learning/ui/framework/UiSettings.md new file mode 100644 index 00000000000..cea021f318a --- /dev/null +++ b/docs/learning/ui/framework/UiSettings.md @@ -0,0 +1,131 @@ +# UI Settings + +'UI Settings' refers to settings that define the state of different parts of the UI. Settings like if the UI is displayed in "dark" or "light" theme, size and location of column sizes or panel sizes. + +## Settings Storage + +Settings that are set up to be stored between "session" need to be stored and retrieved from some storage location. There are two provided storage locations that will serve that purpose. [LocalSettingsStorage]($ui-core) will use browser localStorage. [UserSettingsStorage]($ui-framework) will use the Product Settings Service available through IModelApp.settings. Please note that UserSettingsStorage requires the user to be logged-in to have access to this storage. + +If an application wants to store settings only for the current session [SessionSettingsStorage]($ui-core) is available. + +An application can choose to create and register their own class that implements the [UiSettingsStorage](ui-core) interface, if a custom storage location is desired for UI Settings. + +### Defining which storage to use + +Typically in the index.tsx file of an IModelApp that uses `App UI` user interface the code will set the storage location once the user has signed in. + +```ts + public static getUiSettingsStorage(): UiSettingsStorage { + const authorized = !!IModelApp.authorizationClient && IModelApp.authorizationClient.isAuthorized; + if (!authorized) { + return MyIModelApp._localUiSettingsStorage; // instance of LocalSettingsStorage + } + return MyIModelApp._UserUiSettingsStorage; // instance of UserSettingsStorage + } +``` + +The component [UiSettingsProvider]($ui-framework) can be added into the component tree to provide the storage object via React context. See hook [useUiSettingsStorageContext]($ui-framework). Below is an example of how to wrap the [ConfigurableUiContent]($ui-framework) element so that the context is available to all App UI components. + +```tsx + + } + /> + +``` + +## UserSettingsProvider + +The [UserSettingsProvider]($ui-framework) interface can be implemented by classes that want to restore their saved settings when the method [UiFramework.setUiSettingsStorage]($ui-framework) is called to set the UiSettingsStorage. A `UserSettingsProvider` class must be registered by calling [UiFramework.registerUserSettingsProvider] and supplying the implementing class instance. The `UserSettingsProvider` interface only requires that the provider define a unique `providerId` that is used to ensure the provider is only registered once. It must also implement the method `loadUserSettings(storage: UiSettingsStorage)` to asynchronously load its settings from [UiSettingsStorage](ui-core). + +### AppUiSettings + +The [AppUiSettings]($ui-framework) class, which implements the UserSettingsProvider interface, can be instantiated by the IModelApp and registered as an UserSettingsProvider. This is left up to the application so each one can provide default values for the settings maintained by the `AppUiSettings` class. Below is an excerpt from application startup code that shows the registration of `AppUiSettings`. + +```ts + public static async initialize() { + await UiFramework.initialize(undefined); + + // initialize Presentation + await Presentation.initialize({ + activeLocale: IModelApp.i18n.languageList()[0], + }); + Presentation.selection.scopes.activeScope = "top-assembly"; + + // other initialization calls not shown in this example excerpt + + // app specific call to register setting pages to display + AppSettingsTabsProvider.initializeAppSettingProvider(); + + // Create and register the AppUiSettings instance to provide default for ui settings in Redux store + const lastTheme = (window.localStorage&&window.localStorage.getItem("uifw:defaultTheme"))??SYSTEM_PREFERRED_COLOR_THEME; + const defaults = { + colorTheme: lastTheme ?? SYSTEM_PREFERRED_COLOR_THEME, + dragInteraction: false, + frameworkVersion: "2", + widgetOpacity: 0.8, + }; + + // initialize any settings providers that may need to have defaults set by iModelApp + UiFramework.registerUserSettingsProvider(new AppUiSettings(defaults)); + + // go ahead and initialize settings before login or in case login is by-passed + await UiFramework.setUiSettingsStorage(SampleAppIModelApp.getUiSettingsStorage()); + } +``` + +## Settings Components + +### Quantity Formatting Settings + + The [QuantityFormatSettingsPage]($ui-framework) component provides the UI to set both the [PresentationUnitSystem]($presentation-common) and formatting overrides in the [QuantityFormatter]($frontend). This component can be used in the new [SettingsContainer]($ui-core) UI component. The function `getQuantityFormatsSettingsManagerEntry` will return a [SettingsTabEntry]($ui-core) for use by the [SettingsManager]($ui-core). + +### User Interface Settings + + The [UiSettingsPage]($ui-framework) component provides the UI to set general UI settings that effect the look and feel of the App UI user interface. This component can be used in the new [SettingsContainer]($ui-core) UI component. The function `getUiSettingsManagerEntry` will return a [SettingsTabEntry]($ui-core) for use by the [SettingsManager]($ui-core). + +### Settings stage + +UI and Quantity Settings as well as other settings can be present to the user for editing using the stage [SettingsModalFrontstage]($ui-framework). This stage will display all [SettingsTabEntry]($ui-core) entries that are provided via [SettingsTabsProvider]($ui-core) classes. `SettingsTabsProvider` classes can be registered with the [SettingsManager]($ui-core) by the host application, package, or extension loaded into an IModelApp using the App UI user interface. The steps to add a settings stage include. + +#### Adding a backstage item + +The [SettingsModalFrontstage.getBackstageActionItem] method can be used to get a [BackstageActionItem]($ui-abstract) that is used to construct the backstage. Below is an example of how to set up a backstage menu component that will display the 'Settings' entry if `SettingsTabEntry` items are provided. + +```tsx +export function AppBackstageComposerComponent({ userInfo }: AppBackstageComposerProps) { + const [backstageItems] = React.useState(() => { + return [ + BackstageItemUtilities.createStageLauncher(ViewsFrontstage.stageId, 100, 10, IModelApp.i18n.translate("SampleApp:backstage.viewIModel"), + IModelApp.i18n.translate("SampleApp:backstage.iModelStage"), `svg:${stageIconSvg}`), + SettingsModalFrontstage.getBackstageActionItem (100, 20), + ]; + }); + + return ( + } + /> + ); +} +``` + +#### Defining a SettingsTabsProvider + +Below is an example [SettingsTabsProvider]($ui-core) class that adds two settings pages, one for Units Formatting and the other for UI Settings. In the `AppUiSettings` example above the call to the static method [AppSettingsTabsProvider.initializeAppSettingProvider] is called to add this provider with the SettingsManager instance held by UiFramework. + +```tsx +export class AppSettingsTabsProvider implements SettingsTabsProvider { + public readonly id = "AppSettingsTabsProvider"; + + public getSettingEntries(_stageId: string, _stageUsage: string): ReadonlyArray | undefined { + return [ + getQuantityFormatsSettingsManagerEntry(10, {availableUnitSystems:new Set(["metric","imperial","usSurvey"])}), + getUiSettingsManagerEntry(20), + ]; + } + + public static initializeAppSettingProvider() { + UiFramework.settingsManager.addSettingsProvider(new AppSettingsTabsProvider()); + } +``` diff --git a/docs/learning/ui/framework/index.md b/docs/learning/ui/framework/index.md index 40901b37752..a09344455b8 100644 --- a/docs/learning/ui/framework/index.md +++ b/docs/learning/ui/framework/index.md @@ -20,6 +20,7 @@ There are numerous React components and TypeScript classes in the `@bentley/ui-f - [Dialogs](./Dialogs.md) - [Workflows and Tasks](./TasksWorkflows.md) - [KeyboardShortcut]($ui-framework:KeyboardShortcut) - A keystroke or combination of keystrokes used to launch a command or tool. +- [UI Settings](./UiSettings.md) ## Other Topics diff --git a/test-apps/ui-test-app/public/index.html b/test-apps/ui-test-app/public/index.html index 5f41f564266..5f41375c29e 100644 --- a/test-apps/ui-test-app/public/index.html +++ b/test-apps/ui-test-app/public/index.html @@ -1,49 +1,50 @@ - - - - - - - - iModel.js UI Test App - - - + - - + + - - -
- - + \ No newline at end of file diff --git a/test-apps/ui-test-app/public/locales/en/SampleApp.json b/test-apps/ui-test-app/public/locales/en/SampleApp.json index 8a9b3ddb7bf..5a5a7a5b4cf 100644 --- a/test-apps/ui-test-app/public/locales/en/SampleApp.json +++ b/test-apps/ui-test-app/public/locales/en/SampleApp.json @@ -28,26 +28,8 @@ "loading": "Loading..." }, "settingsStage": { - "settings": "Settings", - "light": "Light", - "dark": "Dark", - "systemPreferred": "System preferred", - "themeTitle": "Theme", - "themeDescription": "Toggle the theme between light and dark", - "autoHideTitle": "Auto-Hide UI", - "autoHideDescription": "Toggle the auto-hide of UI after inactivity", - "dragInteractionTitle": "Drag Interaction", - "dragInteractionDescription": "Toggle the toolbar interaction between click and drag", - "newUiTitle": "Use 2.0 Ui", - "newUiDescription": "Use new 2.0 UI layout", - "useProximityOpacityTitle": "Change Toolbar Opacity", - "useProximityOpacityDescription": "Change the toolbar opacity as the mouse gets closer or farther away", - "snapWidgetOpacityTitle": "Snap Widget Opacity", - "snapWidgetOpacityDescription": "Immediately change the toolbar opacity when the mouse gets close", "accuDrawNotificationsTitle": "Display AccuDraw Notifications", - "accuDrawNotificationsDescription": "Display toast notifications when AccuDraw status changes", - "widgetOpacityTitle": "Widget Opacity", - "widgetOpacityDescription": "Opacity when mouse is not hovering for 2.0 floating widgets and all 1.0 widgets" + "accuDrawNotificationsDescription": "Display toast notifications when AccuDraw status changes" }, "QuantityFormatModalFrontstage": { "QuantityFormatStage": "Quantity Format Overrides" diff --git a/test-apps/ui-test-app/src/frontend/AppUiSettings.ts b/test-apps/ui-test-app/src/frontend/AppUiSettings.ts deleted file mode 100644 index b74d712ac4b..00000000000 --- a/test-apps/ui-test-app/src/frontend/AppUiSettings.ts +++ /dev/null @@ -1,64 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Bentley Systems, Incorporated. All rights reserved. -* See LICENSE.md in the project root for license terms and full copyright notice. -*--------------------------------------------------------------------------------------------*/ -import { UiSetting, UiSettings } from "@bentley/ui-core"; -import { FrameworkAccuDraw, UiFramework, UiShowHideManager } from "@bentley/ui-framework"; -import { SampleAppIModelApp, SampleAppUiActionId } from "."; - -export class AppUiSettings { - private static _settingNamespace = "AppUiSettings"; - private _settings: Array> = []; - - public colorTheme: UiSetting; - public autoHideUi: UiSetting; - public useProximityOpacity: UiSetting; - public snapWidgetOpacity: UiSetting; - public dragInteraction: UiSetting; - public frameworkVersion: UiSetting; - public accuDrawNotifications: UiSetting; - public widgetOpacity: UiSetting; - - constructor() { - this._settings = []; - - this.colorTheme = new UiSetting(AppUiSettings._settingNamespace, "ColorTheme", UiFramework.getColorTheme, UiFramework.setColorTheme); - this._settings.push(this.colorTheme); - - this.autoHideUi = new UiSetting(AppUiSettings._settingNamespace, "AutoHideUi", - () => UiShowHideManager.autoHideUi, (value: boolean) => UiShowHideManager.autoHideUi = value); - this._settings.push(this.autoHideUi); - - this.useProximityOpacity = new UiSetting(AppUiSettings._settingNamespace, "UseProximityOpacity", - () => UiShowHideManager.useProximityOpacity, (value: boolean) => UiShowHideManager.useProximityOpacity = value); - this._settings.push(this.useProximityOpacity); - - this.snapWidgetOpacity = new UiSetting(AppUiSettings._settingNamespace, "SnapWidgetOpacity", - () => UiShowHideManager.snapWidgetOpacity, (value: boolean) => UiShowHideManager.snapWidgetOpacity = value); - this._settings.push(this.snapWidgetOpacity); - - this.dragInteraction = new UiSetting(AppUiSettings._settingNamespace, "DragInteraction", - () => SampleAppIModelApp.store.getState().sampleAppState.dragInteraction, - (value: boolean) => UiFramework.dispatchActionToStore(SampleAppUiActionId.setDragInteraction, value, true)); - this._settings.push(this.dragInteraction); - - this.frameworkVersion = new UiSetting(AppUiSettings._settingNamespace, "FrameworkVersion", - () => SampleAppIModelApp.store.getState().sampleAppState.frameworkVersion, - (value: string) => UiFramework.dispatchActionToStore(SampleAppUiActionId.setFrameworkVersion, value, true)); - this._settings.push(this.frameworkVersion); - - this.accuDrawNotifications = new UiSetting(AppUiSettings._settingNamespace, "AccuDrawNotifications", - () => FrameworkAccuDraw.displayNotifications, (value: boolean) => FrameworkAccuDraw.displayNotifications = value); - this._settings.push(this.accuDrawNotifications); - - this.widgetOpacity = new UiSetting(AppUiSettings._settingNamespace, "WidgetOpacity", - () => UiFramework.getWidgetOpacity(), (value: number) => UiFramework.setWidgetOpacity(value)); - this._settings.push(this.widgetOpacity); - } - - public async apply(uiSettings: UiSettings): Promise { - for (const setting of this._settings) { - await setting.getSettingAndApplyValue(uiSettings); - } - } -} diff --git a/test-apps/ui-test-app/src/frontend/appui/backstage/AppBackstageComposer.tsx b/test-apps/ui-test-app/src/frontend/appui/backstage/AppBackstageComposer.tsx index eb777f3c98c..53d3f7eec34 100644 --- a/test-apps/ui-test-app/src/frontend/appui/backstage/AppBackstageComposer.tsx +++ b/test-apps/ui-test-app/src/frontend/appui/backstage/AppBackstageComposer.tsx @@ -7,7 +7,7 @@ import { connect } from "react-redux"; import { UserInfo } from "@bentley/itwin-client"; import { IModelApp } from "@bentley/imodeljs-frontend"; import { BackstageItemUtilities, BadgeType, ConditionalBooleanValue } from "@bentley/ui-abstract"; -import { BackstageComposer, FrontstageManager, SettingsModalFrontstage, UserProfileBackstageItem } from "@bentley/ui-framework"; +import { BackstageComposer, FrontstageManager, SettingsModalFrontstage, UiFramework, UserProfileBackstageItem } from "@bentley/ui-framework"; import { ComponentExamplesModalFrontstage } from "../frontstages/component-examples/ComponentExamples"; import { LocalFileOpenFrontstage } from "../frontstages/LocalFileStage"; import { RootState, SampleAppIModelApp, SampleAppUiActionId } from "../.."; @@ -33,7 +33,7 @@ interface AppBackstageComposerProps { export function AppBackstageComposerComponent({ userInfo }: AppBackstageComposerProps) { const hiddenCondition3 = new ConditionalBooleanValue(() => SampleAppIModelApp.getTestProperty() === "HIDE", [SampleAppUiActionId.setTestProperty]); const enableCondition = new ConditionalBooleanValue(() => SampleAppIModelApp.getTestProperty() === "HIDE", [SampleAppUiActionId.setTestProperty]); - const notUi2Condition = new ConditionalBooleanValue(() => SampleAppIModelApp.getUiFrameworkProperty() === "1", [SampleAppUiActionId.toggleFrameworkVersion, SampleAppUiActionId.setFrameworkVersion]); + const notUi2Condition = new ConditionalBooleanValue(() => UiFramework.uiVersion === "1", ["configurableui:set-framework-version"]); const imodelIndexHidden = new ConditionalBooleanValue(() => SampleAppIModelApp.isIModelLocal, [SampleAppUiActionId.setIsIModelLocal]); const openLocalFileHidden = new ConditionalBooleanValue(() => SampleAppIModelApp.testAppConfiguration?.snapshotPath === undefined, [SampleAppUiActionId.setIsIModelLocal]); @@ -44,7 +44,7 @@ export function AppBackstageComposerComponent({ userInfo }: AppBackstageComposer BackstageItemUtilities.createStageLauncher("IModelOpen", 300, 10, IModelApp.i18n.translate("SampleApp:backstage.imodelopen"), undefined, "icon-folder-opened"), BackstageItemUtilities.createStageLauncher("IModelIndex", 300, 20, IModelApp.i18n.translate("SampleApp:backstage.imodelindex"), undefined, "icon-placeholder", { isHidden: imodelIndexHidden }), BackstageItemUtilities.createActionItem("SampleApp.open-local-file", 300, 30, async () => LocalFileOpenFrontstage.open(), IModelApp.i18n.translate("SampleApp:backstage:fileSelect"), undefined, "icon-placeholder", { isHidden: openLocalFileHidden }), - SettingsModalFrontstage.getBackstageActionItem (400, 10), + SettingsModalFrontstage.getBackstageActionItem(400, 10), ]; } @@ -58,7 +58,7 @@ export function AppBackstageComposerComponent({ userInfo }: AppBackstageComposer BackstageItemUtilities.createStageLauncher("IModelOpen", 300, 10, IModelApp.i18n.translate("SampleApp:backstage.imodelopen"), undefined, "icon-folder-opened"), BackstageItemUtilities.createStageLauncher("IModelIndex", 300, 20, IModelApp.i18n.translate("SampleApp:backstage.imodelindex"), undefined, "icon-placeholder", { isHidden: imodelIndexHidden }), BackstageItemUtilities.createActionItem("SampleApp.open-local-file", 300, 30, async () => LocalFileOpenFrontstage.open(), IModelApp.i18n.translate("SampleApp:backstage:fileSelect"), undefined, "icon-placeholder", { isHidden: openLocalFileHidden }), - SettingsModalFrontstage.getBackstageActionItem (400, 10), + SettingsModalFrontstage.getBackstageActionItem(400, 10), BackstageItemUtilities.createActionItem("SampleApp.componentExamples", 400, 20, () => FrontstageManager.openModalFrontstage(new ComponentExamplesModalFrontstage()), IModelApp.i18n.translate("SampleApp:backstage.componentExamples"), undefined, "icon-details", { badgeType: BadgeType.New }), ]; }); diff --git a/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.scss b/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.scss index a2a6217ae19..d0784c6cd5c 100644 --- a/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.scss +++ b/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.scss @@ -52,7 +52,6 @@ $settings-rightpanel-width: 220px; > .right-panel { display:flex; - justify-content: center; align-items: center; min-width: $settings-rightpanel-width; padding: 30px 50px 30px 30px; diff --git a/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.tsx b/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.tsx index f1370da3ca6..59a7f0dddc3 100644 --- a/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.tsx +++ b/test-apps/ui-test-app/src/frontend/appui/frontstages/Settings.tsx @@ -8,171 +8,29 @@ import "./Settings.scss"; import * as React from "react"; -import { connect } from "react-redux"; -import { Dispatch } from "redux"; -import { OptionType, Slider, ThemedSelect, ThemedSelectProps, Toggle } from "@bentley/ui-core"; -import { ColorTheme, FrameworkAccuDraw, SyncUiEventDispatcher, SYSTEM_PREFERRED_COLOR_THEME, UiFramework, UiShowHideManager } from "@bentley/ui-framework"; -import { RootState, SampleAppActions, SampleAppIModelApp, SampleAppUiActionId } from "../.."; -interface UiSettingsPageProps { - dragInteraction: boolean; - onToggleDragInteraction: () => void; - frameworkVersion: string; - onToggleFrameworkVersion: () => void; -} - -function isOptionType(value: OptionType | ReadonlyArray): value is OptionType { - if (Array.isArray(value)) - return false; - return true; -} +import { Toggle } from "@bentley/ui-core"; +import { FrameworkAccuDraw, UiFramework } from "@bentley/ui-framework"; /** UiSettingsPage displaying the active settings. */ -class UiSettingsPageComponent extends React.Component { - private _themeTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.themeTitle"); - private _themeDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.themeDescription"); - private _autoHideTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.autoHideTitle"); - private _autoHideDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.autoHideDescription"); - private _dragInteractionTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.dragInteractionTitle"); - private _dragInteractionDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.dragInteractionDescription"); - private _useNewUiTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.newUiTitle"); - private _useNewUiDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.newUiDescription"); - private _useProximityOpacityTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.useProximityOpacityTitle"); - private _useProximityOpacityDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.useProximityOpacityDescription"); - private _snapWidgetOpacityTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.snapWidgetOpacityTitle"); - private _snapWidgetOpacityDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.snapWidgetOpacityDescription"); - private _darkLabel = UiFramework.i18n.translate("SampleApp:settingsStage.dark"); - private _lightLabel = UiFramework.i18n.translate("SampleApp:settingsStage.light"); - private _systemPreferredLabel = UiFramework.i18n.translate("SampleApp:settingsStage.systemPreferred"); +export class AccudrawSettingsPageComponent extends React.Component { private _accuDrawNotificationsTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.accuDrawNotificationsTitle"); private _accuDrawNotificationsDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.accuDrawNotificationsDescription"); - private _widgetOpacityTitle: string = UiFramework.i18n.translate("SampleApp:settingsStage.widgetOpacityTitle"); - private _widgetOpacityDescription: string = UiFramework.i18n.translate("SampleApp:settingsStage.widgetOpacityDescription"); - - private _defaultThemeOption = { label: this._systemPreferredLabel, value: SYSTEM_PREFERRED_COLOR_THEME }; - private _themeOptions: Array = [ - this._defaultThemeOption, - { label: this._lightLabel, value: ColorTheme.Light }, - { label: this._darkLabel, value: ColorTheme.Dark }, - ]; - - private _getDefaultThemeOption() { - const theme = UiFramework.getColorTheme(); - for (const option of this._themeOptions) { - if (option.value === theme) - return option; - } - return this._defaultThemeOption; - } - - private _onThemeChange: ThemedSelectProps["onChange"] = async (value) => { - if (!value) - return; - if (!isOptionType(value)) - return; - - UiFramework.setColorTheme(value.value); - - await SampleAppIModelApp.appUiSettings.colorTheme.saveSetting(SampleAppIModelApp.uiSettings); - }; - - private _onAutoHideChange = async () => { - UiShowHideManager.autoHideUi = !UiShowHideManager.autoHideUi; - - await SampleAppIModelApp.appUiSettings.autoHideUi.saveSetting(SampleAppIModelApp.uiSettings); - }; - - private _onUseProximityOpacityChange = async () => { - UiShowHideManager.useProximityOpacity = !UiShowHideManager.useProximityOpacity; - - await SampleAppIModelApp.appUiSettings.useProximityOpacity.saveSetting(SampleAppIModelApp.uiSettings); - }; - - private _onSnapWidgetOpacityChange = async () => { - UiShowHideManager.snapWidgetOpacity = !UiShowHideManager.snapWidgetOpacity; - - await SampleAppIModelApp.appUiSettings.snapWidgetOpacity.saveSetting(SampleAppIModelApp.uiSettings); - }; private _onAccuDrawNotificationsChange = async () => { FrameworkAccuDraw.displayNotifications = !FrameworkAccuDraw.displayNotifications; - - await SampleAppIModelApp.appUiSettings.accuDrawNotifications.saveSetting(SampleAppIModelApp.uiSettings); - }; - - private _onWidgetOpacityChange = async (values: readonly number[]) => { - if (values.length > 0) { - UiFramework.setWidgetOpacity(values[0]); - await SampleAppIModelApp.appUiSettings.widgetOpacity.saveSetting(SampleAppIModelApp.uiSettings); - } }; public render(): React.ReactNode { return (
- - -
- } - /> - } - /> - } - /> - } - /> - } - /> - } - /> } - /> - v.toFixed(1)} - showTicks showTickLabels getTickCount={() => 10} formatTick={(v: number) => v.toFixed(1)} /> - } + settingUi={} /> ); } } -function mapStateToProps(state: RootState) { - return { dragInteraction: state.sampleAppState.dragInteraction, frameworkVersion: state.sampleAppState.frameworkVersion }; -} - -function mapDispatchToProps(dispatch: Dispatch) { - return { - onToggleDragInteraction: async () => { - dispatch(SampleAppActions.toggleDragInteraction()); - await SampleAppIModelApp.appUiSettings.dragInteraction.saveSetting(SampleAppIModelApp.uiSettings); - }, - onToggleFrameworkVersion: async () => { - dispatch(SampleAppActions.toggleFrameworkVersion()); - SyncUiEventDispatcher.dispatchSyncUiEvent(SampleAppUiActionId.toggleFrameworkVersion); - await SampleAppIModelApp.appUiSettings.frameworkVersion.saveSetting(SampleAppIModelApp.uiSettings); - }, - dispatch, - }; -} - -// eslint-disable-next-line @typescript-eslint/naming-convention -export const ConnectedUiSettingsPage = connect(mapStateToProps, mapDispatchToProps)(UiSettingsPageComponent); - interface SettingsItemProps { title: string; description: string; diff --git a/test-apps/ui-test-app/src/frontend/appui/frontstages/component-examples/ComponentExamplesProvider.tsx b/test-apps/ui-test-app/src/frontend/appui/frontstages/component-examples/ComponentExamplesProvider.tsx index 05967d765a4..c7ba50b2750 100644 --- a/test-apps/ui-test-app/src/frontend/appui/frontstages/component-examples/ComponentExamplesProvider.tsx +++ b/test-apps/ui-test-app/src/frontend/appui/frontstages/component-examples/ComponentExamplesProvider.tsx @@ -24,7 +24,7 @@ import { SearchBox, Select, SettingsContainer, SettingsTabEntry, Slider, SmallText, Spinner, SpinnerSize, SplitButton, Subheading, Textarea, ThemedSelect, Tile, Title, Toggle, ToggleButtonType, UnderlinedButton, VerticalTabs, } from "@bentley/ui-core"; -import { MessageManager, ModalDialogManager, QuantityFormatSettingsPanel, ReactNotifyMessageDetails, UiFramework } from "@bentley/ui-framework"; +import { MessageManager, ModalDialogManager, QuantityFormatSettingsPage, ReactNotifyMessageDetails, UiFramework } from "@bentley/ui-framework"; import { SampleAppIModelApp } from "../../.."; import { ComponentExampleCategory, ComponentExampleProps } from "./ComponentExamples"; import { SampleContextMenu } from "./SampleContextMenu"; @@ -32,17 +32,17 @@ import { SampleExpandableBlock } from "./SampleExpandableBlock"; import { SampleImageCheckBox } from "./SampleImageCheckBox"; import { SamplePopupContextMenu } from "./SamplePopupContextMenu"; import { FormatPopupButton } from "./FormatPopupButton"; -import { ConnectedUiSettingsPage } from "../Settings"; +import { AccudrawSettingsPageComponent } from "../Settings"; function MySettingsPage() { const tabs: SettingsTabEntry[] = [ { itemPriority: 10, tabId: "Quantity", pageWillHandleCloseRequest: true, label: "Quantity", tooltip: "Quantity Format Settings", icon: "icon-measure", - page: , + page: , }, { - itemPriority: 20, tabId: "UI", label: "UI", subLabel: "UI and Accudraw", tooltip: "UI Settings", icon: "icon-paintbrush", - page: , + itemPriority: 20, tabId: "Accudraw", label: "Accudraw", tooltip: "Accudraw Settings", icon: "icon-paintbrush", + page: , }, { itemPriority: 30, tabId: "page3", label: "page3", page:
Page 3
}, { itemPriority: 40, tabId: "page4", label: "page4", subLabel: "disabled page4", isDisabled: true, page:
Page 4
}, diff --git a/test-apps/ui-test-app/src/frontend/appui/uiproviders/AppSettingsProvider.tsx b/test-apps/ui-test-app/src/frontend/appui/uiproviders/AppSettingsTabsProvider.tsx similarity index 58% rename from test-apps/ui-test-app/src/frontend/appui/uiproviders/AppSettingsProvider.tsx rename to test-apps/ui-test-app/src/frontend/appui/uiproviders/AppSettingsTabsProvider.tsx index ed6a44be141..cd3a42bcb52 100644 --- a/test-apps/ui-test-app/src/frontend/appui/uiproviders/AppSettingsProvider.tsx +++ b/test-apps/ui-test-app/src/frontend/appui/uiproviders/AppSettingsTabsProvider.tsx @@ -4,29 +4,29 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; -import { getQuantityFormatsSettingsManagerEntry, UiFramework } from "@bentley/ui-framework"; -import { SettingsProvider, SettingsTabEntry } from "@bentley/ui-core"; -import { ConnectedUiSettingsPage } from "../frontstages/Settings"; +import { getQuantityFormatsSettingsManagerEntry, getUiSettingsManagerEntry, UiFramework } from "@bentley/ui-framework"; +import { SettingsTabEntry, SettingsTabsProvider } from "@bentley/ui-core"; +import { AccudrawSettingsPageComponent } from "../frontstages/Settings"; // Sample settings provider that dynamically adds settings into the setting stage -export class AppSettingsProvider implements SettingsProvider { - public readonly id = "AppSettingsProvider"; +export class AppSettingsTabsProvider implements SettingsTabsProvider { + public readonly id = "AppSettingsTabsProvider"; public getSettingEntries(_stageId: string, _stageUsage: string): ReadonlyArray | undefined { return [ getQuantityFormatsSettingsManagerEntry(10, {availableUnitSystems:new Set(["metric","imperial","usSurvey"])}), { - itemPriority: 20, tabId: "ui-test-app:UI", label: "UI", - page: , + itemPriority: 20, tabId: "ui-test-app:Accudraw", label: "Accudraw", + page: , isDisabled: false, icon: "icon-paintbrush", - subLabel: "UI and Accudraw", - tooltip: "UI and Accudraw Settings", + tooltip: "Accudraw Settings", }, + getUiSettingsManagerEntry(30, true), ]; } public static initializeAppSettingProvider() { - UiFramework.settingsManager.addSettingsProvider(new AppSettingsProvider()); + UiFramework.settingsManager.addSettingsProvider(new AppSettingsTabsProvider()); } } diff --git a/test-apps/ui-test-app/src/frontend/index.tsx b/test-apps/ui-test-app/src/frontend/index.tsx index 01103347773..792b865bd90 100644 --- a/test-apps/ui-test-app/src/frontend/index.tsx +++ b/test-apps/ui-test-app/src/frontend/index.tsx @@ -36,12 +36,12 @@ import { PresentationUnitSystem } from "@bentley/presentation-common"; import { Presentation } from "@bentley/presentation-frontend"; import { getClassName } from "@bentley/ui-abstract"; import { BeDragDropContext } from "@bentley/ui-components"; -import { LocalUiSettings, UiSettings } from "@bentley/ui-core"; +import { LocalSettingsStorage, UiSettings } from "@bentley/ui-core"; import { - ActionsUnion, AppNotificationManager, ConfigurableUiContent, createAction, DeepReadonly, DragDropLayerRenderer, FrameworkAccuDraw, FrameworkReducer, + ActionsUnion, AppNotificationManager, AppUiSettings, ConfigurableUiContent, createAction, DeepReadonly, DragDropLayerRenderer, FrameworkAccuDraw, FrameworkReducer, FrameworkRootState, FrameworkToolAdmin, FrameworkUiAdmin, FrameworkVersion, FrontstageDeactivatedEventArgs, FrontstageDef, FrontstageManager, - IModelAppUiSettings, IModelInfo, ModalFrontstageClosedEventArgs, SafeAreaContext, StateManager, SyncUiEventDispatcher, ThemeManager, - ToolbarDragInteractionContext, UiFramework, UiSettingsProvider, + IModelInfo, ModalFrontstageClosedEventArgs, SafeAreaContext, StateManager, SyncUiEventDispatcher, SYSTEM_PREFERRED_COLOR_THEME, ThemeManager, ToolbarDragInteractionContext, + UiFramework, UiSettingsProvider, UserSettingsStorage, } from "@bentley/ui-framework"; import { SafeAreaInsets } from "@bentley/ui-ninezone"; import { getSupportedRpcs } from "../common/rpcs"; @@ -55,8 +55,7 @@ import { IModelViewportControl } from "./appui/contentviews/IModelViewport"; import { EditFrontstage } from "./appui/frontstages/editing/EditFrontstage"; import { LocalFileOpenFrontstage } from "./appui/frontstages/LocalFileStage"; import { ViewsFrontstage } from "./appui/frontstages/ViewsFrontstage"; -import { AppSettingsProvider } from "./appui/uiproviders/AppSettingsProvider"; -import { AppUiSettings } from "./AppUiSettings"; +import { AppSettingsTabsProvider } from "./appui/uiproviders/AppSettingsTabsProvider"; import { AppViewManager } from "./favorites/AppViewManager"; // Favorite Properties Support import { ElementSelectionListener } from "./favorites/ElementSelectionListener"; // Favorite Properties Support import { AnalysisAnimationTool } from "./tools/AnalysisAnimation"; @@ -73,7 +72,7 @@ import { EditingSessionTool } from "./tools/editing/PrimitiveToolEx"; RpcConfiguration.developmentMode = true; // cSpell:ignore setTestProperty sampleapp uitestapp setisimodellocal projectwise mobx hypermodeling testapp urlps -// cSpell:ignore toggledraginteraction toggleframeworkversion setdraginteraction setframeworkversion +// cSpell:ignore toggledraginteraction toggleframeworkversion set-drag-interaction set-framework-version /** Action Ids used by redux and to send sync UI components. Typically used to refresh visibility or enable state of control. * Use lower case strings to be compatible with SyncUi processing. @@ -82,25 +81,17 @@ export enum SampleAppUiActionId { setTestProperty = "sampleapp:settestproperty", setAnimationViewId = "sampleapp:setAnimationViewId", setIsIModelLocal = "sampleapp:setisimodellocal", - toggleDragInteraction = "sampleapp:toggledraginteraction", - toggleFrameworkVersion = "sampleapp:toggleframeworkversion", - setDragInteraction = "sampleapp:setdraginteraction", - setFrameworkVersion = "sampleapp:setframeworkversion", } export interface SampleAppState { testProperty: string; animationViewId: string; - dragInteraction: boolean; - frameworkVersion: string; isIModelLocal: boolean; } const initialState: SampleAppState = { testProperty: "", animationViewId: "", - dragInteraction: true, - frameworkVersion: "1", isIModelLocal: false, }; @@ -109,10 +100,6 @@ export const SampleAppActions = { setTestProperty: (testProperty: string) => createAction(SampleAppUiActionId.setTestProperty, testProperty), setAnimationViewId: (viewId: string) => createAction(SampleAppUiActionId.setAnimationViewId, viewId), setIsIModelLocal: (isIModelLocal: boolean) => createAction(SampleAppUiActionId.setIsIModelLocal, isIModelLocal), - toggleDragInteraction: () => createAction(SampleAppUiActionId.toggleDragInteraction), - toggleFrameworkVersion: () => createAction(SampleAppUiActionId.toggleFrameworkVersion), - setDragInteraction: (dragInteraction: boolean) => createAction(SampleAppUiActionId.setDragInteraction, dragInteraction), - setFrameworkVersion: (frameworkVersion: string) => createAction(SampleAppUiActionId.setFrameworkVersion, frameworkVersion), }; class SampleAppAccuSnap extends AccuSnap { @@ -147,18 +134,6 @@ function SampleAppReducer(state: SampleAppState = initialState, action: SampleAp case SampleAppUiActionId.setIsIModelLocal: { return { ...state, isIModelLocal: action.payload }; } - case SampleAppUiActionId.toggleDragInteraction: { - return { ...state, dragInteraction: !state.dragInteraction }; - } - case SampleAppUiActionId.toggleFrameworkVersion: { - return { ...state, frameworkVersion: state.frameworkVersion === "1" ? "2" : "1" }; - } - case SampleAppUiActionId.setDragInteraction: { - return { ...state, dragInteraction: action.payload }; - } - case SampleAppUiActionId.setFrameworkVersion: { - return { ...state, frameworkVersion: action.payload }; - } } return state; } @@ -180,7 +155,8 @@ export class SampleAppIModelApp { public static iModelParams: SampleIModelParams | undefined; public static testAppConfiguration: TestAppConfiguration | undefined; private static _appStateManager: StateManager | undefined; - private static _appUiSettings = new AppUiSettings(); + private static _localUiSettings = new LocalSettingsStorage(); + private static _UserUiSettingsStorage = new UserSettingsStorage(); // Favorite Properties Support private static _selectionSetListener = new ElementSelectionListener(true); @@ -189,17 +165,14 @@ export class SampleAppIModelApp { return StateManager.store as Store; } - public static get uiSettings(): UiSettings { - return UiFramework.getUiSettings(); - } - - public static set uiSettings(v: UiSettings) { - UiFramework.setUiSettings(v); - SampleAppIModelApp._appUiSettings.apply(v); // eslint-disable-line @typescript-eslint/no-floating-promises + public static getUiSettingsStorage(): UiSettings { + const authorized = !!IModelApp.authorizationClient && IModelApp.authorizationClient.isAuthorized; + if (SampleAppIModelApp.testAppConfiguration?.useLocalSettings || !authorized) { + return SampleAppIModelApp._localUiSettings; + } + return SampleAppIModelApp._UserUiSettingsStorage; } - public static get appUiSettings(): AppUiSettings { return SampleAppIModelApp._appUiSettings; } - public static async startup(opts: WebViewerAppOpts & NativeAppOpts): Promise { if (ProcessDetector.isElectronAppFrontend) { await ElectronApp.startup(opts); @@ -285,7 +258,23 @@ export class SampleAppIModelApp { // To test map-layer extension comment out the following and ensure ui-test-app\build\imjs_extensions contains map-layers, if not see Readme.md in map-layers package. await MapLayersUI.initialize(false); // if false then add widget in FrontstageDef - AppSettingsProvider.initializeAppSettingProvider(); + AppSettingsTabsProvider.initializeAppSettingProvider(); + + // Create and register the AppUiSettings instance to provide default for ui settings in Redux store + const lastTheme = (window.localStorage&&window.localStorage.getItem("uifw:defaultTheme"))??SYSTEM_PREFERRED_COLOR_THEME; + const defaults = { + colorTheme: lastTheme ?? SYSTEM_PREFERRED_COLOR_THEME, + dragInteraction: false, + frameworkVersion: "2", + widgetOpacity: 0.8, + }; + + // initialize any settings providers that may need to have defaults set by iModelApp + UiFramework.registerUserSettingsProvider(new AppUiSettings(defaults)); + + // go ahead and initialize settings before login or in case login is by-passed + await UiFramework.setUiSettingsStorage(SampleAppIModelApp.getUiSettingsStorage()); + // try starting up event loop if not yet started so key-in palette can be opened IModelApp.startEventLoop(); } @@ -521,7 +510,7 @@ export class SampleAppIModelApp { } public static getUiFrameworkProperty(): string { - return SampleAppIModelApp.store.getState().sampleAppState.frameworkVersion; + return SampleAppIModelApp.store.getState().frameworkState.configurableUiState.frameworkVersion; } public static saveAnimationViewId(value: string, immediateSync = false) { @@ -565,17 +554,17 @@ function AppFrameworkVersionComponent(props: { frameworkVersion: string, childre } function mapDragInteractionStateToProps(state: RootState) { - return { dragInteraction: state.sampleAppState.dragInteraction }; + return { dragInteraction: state.frameworkState.configurableUiState.useDragInteraction }; } function mapFrameworkVersionStateToProps(state: RootState) { - return { frameworkVersion: state.sampleAppState.frameworkVersion }; + return { frameworkVersion: state.frameworkState.configurableUiState.frameworkVersion }; } const AppDragInteraction = connect(mapDragInteractionStateToProps)(AppDragInteractionComponent); const AppFrameworkVersion = connect(mapFrameworkVersionStateToProps)(AppFrameworkVersionComponent); -class SampleAppViewer extends React.Component { +class SampleAppViewer extends React.Component { constructor(props: any) { super(props); @@ -586,7 +575,7 @@ class SampleAppViewer extends React.Component { + private _onUserStateChanged = async (_accessToken: AccessToken | undefined) => { const authorized = !!IModelApp.authorizationClient && IModelApp.authorizationClient.isAuthorized; - this.setState({ authorized, uiSettings: this.getUiSettings(authorized) }); + const uiSettingsStorage = SampleAppIModelApp.getUiSettingsStorage(); + await UiFramework.setUiSettingsStorage(uiSettingsStorage); + this.setState({ authorized, uiSettingsStorage}); this._initializeSignin(authorized); // eslint-disable-line @typescript-eslint/no-floating-promises }; - private getUiSettings(authorized: boolean): UiSettings { - if (SampleAppIModelApp.testAppConfiguration?.useLocalSettings || !authorized) { - SampleAppIModelApp.uiSettings = new LocalUiSettings(); - } else { - SampleAppIModelApp.uiSettings = new IModelAppUiSettings(); - } - - return SampleAppIModelApp.uiSettings; - } - private _handleFrontstageDeactivatedEvent = (args: FrontstageDeactivatedEventArgs): void => { Logger.logInfo(SampleAppIModelApp.loggerCategory(this), `Frontstage exit: id=${args.deactivatedFrontstageDef.id} totalTime=${args.totalTime} engagementTime=${args.engagementTime} idleTime=${args.idleTime}`); }; @@ -643,7 +624,7 @@ class SampleAppViewer extends React.Component {/** UiSettingsProvider is optional. By default LocalUiSettings is used to store UI settings. */} - + } /> @@ -760,7 +741,6 @@ async function main() { IModelApp.telemetry.addClient(applicationInsightsClient); } - // wait for both our i18n namespaces to be read. await SampleAppIModelApp.initialize(); // register new QuantityType diff --git a/ui/components/src/test/color/ColorPickerButton.test.tsx b/ui/components/src/test/color/ColorPickerButton.test.tsx index 713d797ac31..23e67f490a3 100644 --- a/ui/components/src/test/color/ColorPickerButton.test.tsx +++ b/ui/components/src/test/color/ColorPickerButton.test.tsx @@ -80,6 +80,11 @@ describe("", () => { expect(spyOnColorPick).to.be.calledOnce; expect(button.getAttribute("data-value")).to.eq("rgb(255,0,0)"); // red } + + // ensure update prop is handled + const newColorDef = ColorDef.create(ColorByName.green); // green = 0x008000, + renderedComponent.rerender(); + expect(button.getAttribute("data-value")).to.eq("rgb(0,128,0)"); // green }); it("readonly - button press should not open popup", async () => { diff --git a/ui/components/src/test/table/component/Table.test.tsx b/ui/components/src/test/table/component/Table.test.tsx index b438dfe69fc..b58150eebbb 100644 --- a/ui/components/src/test/table/component/Table.test.tsx +++ b/ui/components/src/test/table/component/Table.test.tsx @@ -13,7 +13,7 @@ import * as moq from "typemoq"; import { BeDuration } from "@bentley/bentleyjs-core"; import { PrimitiveValue, PropertyConverterInfo, PropertyDescription, PropertyRecord, PropertyValue, PropertyValueFormat, SpecialKey } from "@bentley/ui-abstract"; -import { HorizontalAlignment, LocalUiSettings } from "@bentley/ui-core"; +import { HorizontalAlignment, LocalSettingsStorage } from "@bentley/ui-core"; import { CellItem, ColumnDescription, PropertyUpdatedArgs, PropertyValueRendererManager, RowItem, SelectionMode, Table, TableDataChangeEvent, @@ -1355,7 +1355,7 @@ describe("Table", () => { reorderableColumns={true} ref={ref} settingsIdentifier="test" - uiSettings={new LocalUiSettings({ localStorage: storageMock() } as Window)} + settingsStorage={new LocalSettingsStorage({ localStorage: storageMock() } as Window)} />); await waitForSpy(onRowsLoaded); table.update(); @@ -1378,7 +1378,7 @@ describe("Table", () => { onRowsLoaded={onRowsLoaded} settingsIdentifier="test" showHideColumns={true} - uiSettings={new LocalUiSettings({ localStorage: storageMock() } as Window)} + settingsStorage={new LocalSettingsStorage({ localStorage: storageMock() } as Window)} />); await waitForSpy(onRowsLoaded); table.update(); diff --git a/ui/components/src/ui-components/color/ColorPickerButton.tsx b/ui/components/src/ui-components/color/ColorPickerButton.tsx index 9ffc1065008..5246671c361 100644 --- a/ui/components/src/ui-components/color/ColorPickerButton.tsx +++ b/ui/components/src/ui-components/color/ColorPickerButton.tsx @@ -63,14 +63,9 @@ const ForwardRefColorPickerButton = React.forwardRef { - // istanbul ignore else - if (initialColor !== initialColorRef.current) { - initialColorRef.current = initialColor; - } setColorDef(initialColor); }, [initialColor]); diff --git a/ui/components/src/ui-components/datepicker/DatePickerPopupButton.tsx b/ui/components/src/ui-components/datepicker/DatePickerPopupButton.tsx index d21bc91716e..64c7417e57f 100644 --- a/ui/components/src/ui-components/datepicker/DatePickerPopupButton.tsx +++ b/ui/components/src/ui-components/datepicker/DatePickerPopupButton.tsx @@ -47,20 +47,12 @@ export function DatePickerPopupButton({ displayEditField, timeDisplay, selected, const timeLabelRef = React.useRef(UiComponents.translate("datepicker.time")); const toolTipLabelRef = React.useRef(UiComponents.translate("datepicker.selectDate")); const toolTipLabel = React.useMemo(() => buttonToolTip ? buttonToolTip : toolTipLabelRef.current, [buttonToolTip]); - const initialDateRef = React.useRef(selected); - // See if new initialDate props have changed since component mounted + // See if props have changed since component mounted React.useEffect(() => { - // istanbul ignore else - if (selected.getTime() !== initialDateRef.current.getTime()) { - const newWorkingDate = new Date(selected.getTime()); - // istanbul ignore else - if (workingDate.getTime() !== newWorkingDate.getTime()) { - setWorkingDate(newWorkingDate); - } - initialDateRef.current = selected; - } - }, [selected, workingDate]); + const newWorkingDate = new Date(selected.getTime()); + setWorkingDate(newWorkingDate); + }, [selected]); const buttonRef = React.useRef(null); const togglePopupDisplay = React.useCallback((event: React.MouseEvent) => { diff --git a/ui/components/src/ui-components/oidc/SignIn.scss b/ui/components/src/ui-components/oidc/SignIn.scss index dd06191c464..b91b7552759 100644 --- a/ui/components/src/ui-components/oidc/SignIn.scss +++ b/ui/components/src/ui-components/oidc/SignIn.scss @@ -54,18 +54,12 @@ $signin-hyperlink-hover-color: $buic-foreground-primary-tone; .components-signin-prompt { margin-top: 3em; text-align: center; + height: 7em; } /* sign in button */ .components-signin-button { @include uicore-buttons-primary-large; - margin-top: auto; - } - - /* signing-in message */ - .components-signingin-message { - margin-top: 3em; - text-align: center; } /* "Register" container */ diff --git a/ui/components/src/ui-components/oidc/SignIn.tsx b/ui/components/src/ui-components/oidc/SignIn.tsx index a71af464164..7e1284710fe 100644 --- a/ui/components/src/ui-components/oidc/SignIn.tsx +++ b/ui/components/src/ui-components/oidc/SignIn.tsx @@ -91,7 +91,10 @@ export class SignIn extends React.PureComponent {
- {this.state.prompt} + {(this.state.isSigningIn && this.props.signingInMessage !== undefined) ? + {this.props.signingInMessage} : + {this.state.prompt} + }
); diff --git a/ui/components/src/ui-components/quantityformat/FormatPanel.tsx b/ui/components/src/ui-components/quantityformat/FormatPanel.tsx index 025d3a1a196..8525aaba3a2 100644 --- a/ui/components/src/ui-components/quantityformat/FormatPanel.tsx +++ b/ui/components/src/ui-components/quantityformat/FormatPanel.tsx @@ -46,15 +46,11 @@ export function FormatPanel(props: FormatPanelProps) { const [formatSpec, setFormatSpec] = React.useState(); const { initialFormat, showSample, initialMagnitude, unitsProvider, persistenceUnit, onFormatChange, provideFormatSpec, enableMinimumProperties } = props; const [formatProps, setFormatProps] = React.useState(initialFormat); - const initialFormatRef = React.useRef(initialFormat); const [showOptions, setShowOptions] = React.useState(false); React.useEffect(() => { - if (initialFormatRef.current !== initialFormat) { - initialFormatRef.current = initialFormat; - setFormatProps(initialFormat); - setFormatSpec(undefined); // this will trigger the new spec to be created in the useEffect hook - } + setFormatProps(initialFormat); + setFormatSpec(undefined); // this will trigger the new spec to be created in the useEffect hook }, [initialFormat]); const handleUserFormatChanges = React.useCallback((newProps: FormatProps) => { diff --git a/ui/components/src/ui-components/quantityformat/FormatSample.tsx b/ui/components/src/ui-components/quantityformat/FormatSample.tsx index e5dc796c616..22ff36de509 100644 --- a/ui/components/src/ui-components/quantityformat/FormatSample.tsx +++ b/ui/components/src/ui-components/quantityformat/FormatSample.tsx @@ -26,16 +26,14 @@ export interface FormatSampleProps extends CommonProps { */ export function FormatSample(props: FormatSampleProps) { const { initialMagnitude, formatSpec, hideLabels } = props; - const initialMagnitudeRef = React.useRef(initialMagnitude ?? 0); - const [magnitude, setMagnitude] = React.useState(initialMagnitudeRef.current); - const [sampleValue, setSampleValue] = React.useState(magnitude.toString()); + const initialValue = initialMagnitude??0; + const [magnitude, setMagnitude] = React.useState(initialValue); + const [sampleValue, setSampleValue] = React.useState(initialValue.toString()); React.useEffect(() => { - if (initialMagnitudeRef.current !== initialMagnitude) { - initialMagnitudeRef.current = initialMagnitude ?? 0; - setMagnitude(initialMagnitudeRef.current); - setSampleValue(initialMagnitudeRef.current.toString()); - } + const value = initialMagnitude ?? 0; + setMagnitude(value); + setSampleValue(value.toString()); }, [initialMagnitude]); const handleOnValueBlur = React.useCallback(() => { diff --git a/ui/components/src/ui-components/table/component/Table.tsx b/ui/components/src/ui-components/table/component/Table.tsx index 6c550fa784d..a6204e7c30d 100644 --- a/ui/components/src/ui-components/table/component/Table.tsx +++ b/ui/components/src/ui-components/table/component/Table.tsx @@ -15,7 +15,8 @@ import ReactResizeDetector from "react-resize-detector"; import { DisposableList, Guid, GuidString } from "@bentley/bentleyjs-core"; import { PropertyValueFormat } from "@bentley/ui-abstract"; import { - CommonProps, Dialog, isNavigationKey, ItemKeyboardNavigator, LocalUiSettings, Orientation, SortDirection, UiSettings, UiSettingsStatus, + CommonProps, Dialog, isNavigationKey, ItemKeyboardNavigator, LocalSettingsStorage, + Orientation, SortDirection, UiSettings, UiSettingsStatus, UiSettingsStorage, } from "@bentley/ui-core"; import { MultiSelectionHandler, OnItemsDeselectedCallback, OnItemsSelectedCallback, SelectionHandler, SingleSelectionHandler, @@ -125,6 +126,9 @@ export interface TableProps extends CommonProps { /** Indicates whether the Table columns are reorderable */ reorderableColumns?: boolean; /** Optional parameter for persistent UI settings. Used for column reordering and show persistency. */ + settingsStorage?: UiSettingsStorage; + /** Optional parameter for persistent UI settings. Used for column reordering and show persistency. + * @deprecated use settingsStorage property */ uiSettings?: UiSettings; /** Identifying string used for persistent state. */ settingsIdentifier?: string; @@ -495,8 +499,9 @@ export class Table extends React.Component { let dataGridColumns = columnDescriptions.map(this._columnDescriptionToReactDataGridColumn); if (this.props.settingsIdentifier) { - const uiSettings: UiSettings = this.props.uiSettings || /* istanbul ignore next */ new LocalUiSettings(); - const reorderResult = await uiSettings.getSetting(this.props.settingsIdentifier, "ColumnReorder"); + // eslint-disable-next-line deprecation/deprecation + const settingsStorage: UiSettingsStorage = this.props.settingsStorage || /* istanbul ignore next */ this.props.uiSettings || /* istanbul ignore next */ new LocalSettingsStorage(); + const reorderResult = await settingsStorage.getSetting(this.props.settingsIdentifier, "ColumnReorder"); // istanbul ignore next if (reorderResult.status === UiSettingsStatus.Success) { const setting = reorderResult.setting as string[]; @@ -504,9 +509,9 @@ export class Table extends React.Component { dataGridColumns = setting.map((key) => dataGridColumns.filter((col) => col.key === key)[0]); } else if (reorderResult.status === UiSettingsStatus.NotFound) { const keys = columnDescriptions.map((col) => col.key); - await uiSettings.saveSetting(this.props.settingsIdentifier, "ColumnReorder", keys); + await settingsStorage.saveSetting(this.props.settingsIdentifier, "ColumnReorder", keys); } - const showhideResult = await uiSettings.getSetting(this.props.settingsIdentifier, "ColumnShowHideHiddenColumns"); + const showhideResult = await settingsStorage.getSetting(this.props.settingsIdentifier, "ColumnShowHideHiddenColumns"); // istanbul ignore next if (showhideResult.status === UiSettingsStatus.Success) { const hiddenColumns = showhideResult.setting as string[]; @@ -1216,9 +1221,9 @@ export class Table extends React.Component { cols.splice(columnTargetIndex, 0, cols.splice(columnSourceIndex, 1)[0]); // istanbul ignore else if (this.props.settingsIdentifier) { - const uiSettings: UiSettings = this.props.uiSettings || /* istanbul ignore next */ new LocalUiSettings(); + const settingsStorage: UiSettingsStorage = this.props.settingsStorage || /* istanbul ignore next */ new LocalSettingsStorage(); const keys = cols.map((col) => col.key); - uiSettings.saveSetting(this.props.settingsIdentifier, "ColumnReorder", keys); // eslint-disable-line @typescript-eslint/no-floating-promises + settingsStorage.saveSetting(this.props.settingsIdentifier, "ColumnReorder", keys); // eslint-disable-line @typescript-eslint/no-floating-promises } this.setState({ columns: [] }, () => { // fix react-data-grid update issues this.setState({ columns: cols }); @@ -1347,8 +1352,8 @@ export class Table extends React.Component { private _handleShowHideChange = (cols: string[]) => { this.setState({ hiddenColumns: cols }); if (this.props.settingsIdentifier) { - const uiSettings: UiSettings = this.props.uiSettings || new LocalUiSettings(); - uiSettings.saveSetting(this.props.settingsIdentifier, "ColumnShowHideHiddenColumns", cols); // eslint-disable-line @typescript-eslint/no-floating-promises + const settingsStorage: UiSettingsStorage = this.props.settingsStorage || new LocalSettingsStorage(); + settingsStorage.saveSetting(this.props.settingsIdentifier, "ColumnShowHideHiddenColumns", cols); // eslint-disable-line @typescript-eslint/no-floating-promises } return true; }; diff --git a/ui/core/src/test/settings/SettingsManager.test.tsx b/ui/core/src/test/settings/SettingsManager.test.tsx index 5529b58e2ad..f61ddbd39d8 100644 --- a/ui/core/src/test/settings/SettingsManager.test.tsx +++ b/ui/core/src/test/settings/SettingsManager.test.tsx @@ -8,7 +8,7 @@ import { render } from "@testing-library/react"; import { expect } from "chai"; import * as sinon from "sinon"; import { SettingsContainer, useSaveBeforeActivatingNewSettingsTab, useSaveBeforeClosingSettingsContainer } from "../../ui-core/settings/SettingsContainer"; -import { SettingsManager, SettingsProvider, SettingsTabEntry } from "../../ui-core/settings/SettingsManager"; +import { SettingsManager, SettingsTabEntry, SettingsTabsProvider } from "../../ui-core/settings/SettingsManager"; function TestModalSettingsPage({ settingsManager, title }: { settingsManager: SettingsManager, title: string }) { @@ -25,7 +25,7 @@ function TestModalSettingsPage({ settingsManager, title }: { settingsManager: Se describe("", () => { const settingsManager = new SettingsManager(); - class TestSettingsProvider implements SettingsProvider { + class TestSettingsProvider implements SettingsTabsProvider { public readonly id = "AppSettingsProvider"; public getSettingEntries(_stageId: string, _stageUsage: string): ReadonlyArray | undefined { diff --git a/ui/core/src/test/uisettings/LocalUiSettings.test.ts b/ui/core/src/test/uisettings/LocalUiSettings.test.ts index cfcaa0c5aa0..5aa792d1ecf 100644 --- a/ui/core/src/test/uisettings/LocalUiSettings.test.ts +++ b/ui/core/src/test/uisettings/LocalUiSettings.test.ts @@ -2,25 +2,30 @@ * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ + import { expect } from "chai"; -import { LocalUiSettings, UiSettingsStatus } from "../../ui-core"; +import { LocalSettingsStorage, LocalUiSettings, UiSettingsStatus } from "../../ui-core"; import { storageMock } from "../TestUtils"; describe("LocalUiSettings", () => { it("default constructor executes successfully", () => { - const initialLocalUiSettings = new LocalUiSettings(); + const initialLocalUiSettings = new LocalUiSettings(); // eslint-disable-line deprecation/deprecation + expect(initialLocalUiSettings).to.not.be.undefined; + }); + it("default LocalSettingsStorage constructor executes successfully", () => { + const initialLocalUiSettings = new LocalSettingsStorage(); // eslint-disable-line deprecation/deprecation expect(initialLocalUiSettings).to.not.be.undefined; }); describe("saveSetting", () => { - const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); + const localUiSettings = new LocalSettingsStorage({ localStorage: storageMock() } as Window); it("Should save setting correctly", async () => { const result = await localUiSettings.saveSetting("Testing", "TestData", { test123: "4567" }); expect(result.status).to.equal(UiSettingsStatus.Success); }); }); describe("getSetting", async () => { - const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); + const localUiSettings = new LocalSettingsStorage({ localStorage: storageMock() } as Window); await localUiSettings.saveSetting("Testing", "TestData", { test123: "4567" }); it("Should load setting correctly", async () => { const result = await localUiSettings.getSetting("Testing", "TestData"); @@ -34,7 +39,7 @@ describe("LocalUiSettings", () => { }); }); describe("deleteSetting", async () => { - const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); + const localUiSettings = new LocalSettingsStorage({ localStorage: storageMock() } as Window); await localUiSettings.saveSetting("Testing", "TestData", { test123: "4567" }); it("Should remove setting correctly", async () => { const result = await localUiSettings.deleteSetting("Testing", "TestData"); diff --git a/ui/core/src/test/uisettings/SessionUiSettings.test.ts b/ui/core/src/test/uisettings/SessionUiSettings.test.ts index df060b1d79e..994bcfc0636 100644 --- a/ui/core/src/test/uisettings/SessionUiSettings.test.ts +++ b/ui/core/src/test/uisettings/SessionUiSettings.test.ts @@ -3,24 +3,28 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { expect } from "chai"; -import { SessionUiSettings, UiSettingsStatus } from "../../ui-core"; +import { SessionSettingsStorage, SessionUiSettings, UiSettingsStatus } from "../../ui-core"; import { storageMock } from "../TestUtils"; describe("SessionUiSettings", () => { it("default constructor executes successfully", () => { - const initialSessionUiSettings = new SessionUiSettings(); + const initialSessionUiSettings = new SessionUiSettings(); // eslint-disable-line deprecation/deprecation + expect(initialSessionUiSettings).to.not.be.undefined; + }); + it("default SessionSettingsStorage constructor executes successfully", () => { + const initialSessionUiSettings = new SessionSettingsStorage(); // eslint-disable-line deprecation/deprecation expect(initialSessionUiSettings).to.not.be.undefined; }); describe("saveSetting", () => { - const sessionSettings = new SessionUiSettings({ sessionStorage: storageMock() } as Window); + const sessionSettings = new SessionSettingsStorage({ sessionStorage: storageMock() } as Window); it("Should save setting correctly", async () => { const result = await sessionSettings.saveSetting("Testing", "TestData", { test123: "4567" }); expect(result.status).to.equal(UiSettingsStatus.Success); }); }); describe("getSetting", async () => { - const sessionSettings = new SessionUiSettings({ sessionStorage: storageMock() } as Window); + const sessionSettings = new SessionSettingsStorage({ sessionStorage: storageMock() } as Window); await sessionSettings.saveSetting("Testing", "TestData", { test123: "4567" }); it("Should load setting correctly", async () => { @@ -35,7 +39,7 @@ describe("SessionUiSettings", () => { }); }); describe("deleteSetting", async () => { - const sessionSettings = new SessionUiSettings({ sessionStorage: storageMock() } as Window); + const sessionSettings = new SessionSettingsStorage({ sessionStorage: storageMock() } as Window); await sessionSettings.saveSetting("Testing", "TestData", { test123: "4567" }); it("Should remove setting correctly", async () => { diff --git a/ui/core/src/test/uisettings/UiSetting.test.ts b/ui/core/src/test/uisettings/UiSetting.test.ts index 4c75de1dedb..8b3f3f57e76 100644 --- a/ui/core/src/test/uisettings/UiSetting.test.ts +++ b/ui/core/src/test/uisettings/UiSetting.test.ts @@ -3,7 +3,7 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { expect } from "chai"; -import { LocalUiSettings, UiSetting, UiSettingsStatus } from "../../ui-core"; +import { LocalSettingsStorage, LocalUiSettings, UiSetting, UiSettingsStatus } from "../../ui-core"; import { storageMock } from "../TestUtils"; function getBoolean(): boolean { return true; } @@ -20,7 +20,7 @@ describe("UiSetting", () => { }); describe("saveSetting", () => { - const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); + const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); // eslint-disable-line deprecation/deprecation it("Should save setting correctly", async () => { const uiSetting = new UiSetting("Namespace", "Setting", getBoolean); @@ -29,21 +29,8 @@ describe("UiSetting", () => { }); }); - describe("getSetting", async () => { - const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); - const uiSetting = new UiSetting("Namespace", "Setting", getString); - await uiSetting.saveSetting(localUiSettings); - - it("Should load setting correctly", async () => { - const result = await uiSetting.getSetting(localUiSettings); - expect(result.status).to.equal(UiSettingsStatus.Success); - expect(result.setting).to.not.be.null; - expect(result.setting).to.equal(getString()); - }); - }); - describe("deleteSetting", async () => { - const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); + const localUiSettings = new LocalSettingsStorage({ localStorage: storageMock() } as Window); const uiSetting = new UiSetting("Namespace", "Setting", getString); await uiSetting.saveSetting(localUiSettings); @@ -62,7 +49,7 @@ describe("UiSetting", () => { let value = 100; function applyNumber(v: number) { value = v; } - const localUiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); + const localUiSettings = new LocalSettingsStorage({ localStorage: storageMock() } as Window); const uiSetting = new UiSetting("Namespace", "Setting", getNumber, applyNumber); await uiSetting.saveSetting(localUiSettings); @@ -79,6 +66,16 @@ describe("UiSetting", () => { expect(result.status).to.eq(UiSettingsStatus.Uninitialized); }); + it("Should use default value if no applyValue", async () => { + const defaultValue = 999; + // make sure testing with a new key not yet in mock storage + const uiSetting2 = new UiSetting("Namespace", "TEST-XYZ", getNumber, applyNumber, defaultValue); + const result = await uiSetting2.getSettingAndApplyValue(localUiSettings); + expect(result.status).to.eq(UiSettingsStatus.Success); + expect(result.setting).to.eq(defaultValue); + expect(value).to.eq(defaultValue); + }); + it("Should return NotFound if not saved", async () => { const uiSetting3 = new UiSetting("Namespace", "XYZ", getNumber, applyNumber); const result = await uiSetting3.getSettingAndApplyValue(localUiSettings); diff --git a/ui/core/src/ui-core.ts b/ui/core/src/ui-core.ts index ac65bc3ac51..0e165c9bbf4 100644 --- a/ui/core/src/ui-core.ts +++ b/ui/core/src/ui-core.ts @@ -153,9 +153,9 @@ export { Tree, TreeProps } from "./ui-core/tree/Tree"; export { TreeNodePlaceholder, TreeNodePlaceholderProps } from "./ui-core/tree/Placeholder"; export * from "./ui-core/uisettings/UiSetting"; -export * from "./ui-core/uisettings/UiSettings"; -export * from "./ui-core/uisettings/LocalUiSettings"; -export * from "./ui-core/uisettings/SessionUiSettings"; +export * from "./ui-core/uisettings/UiSettingsStorage"; +export * from "./ui-core/uisettings/LocalSettingsStorage"; +export * from "./ui-core/uisettings/SessionSettingsStorage"; export * from "./ui-core/utils/IconHelper"; export * from "./ui-core/utils/Point"; diff --git a/ui/core/src/ui-core/listbox/Listbox.tsx b/ui/core/src/ui-core/listbox/Listbox.tsx index 9f7d87fa26e..3d584d2e1e4 100644 --- a/ui/core/src/ui-core/listbox/Listbox.tsx +++ b/ui/core/src/ui-core/listbox/Listbox.tsx @@ -115,21 +115,16 @@ function processKeyboardNavigation(optionValues: ListboxItemProps[], itemIndex: export function Listbox(props: ListboxProps) { const { ariaLabel, ariaLabelledBy, id, children, selectedValue, className, onListboxValueChange, onKeyPress, ...otherProps } = props; const listRef = React.useRef(null); - const [listId] = React.useState(id ?? Guid.createValue()); + const [listId] = React.useState(()=>{return id ?? Guid.createValue();}); const optionValues = React.useMemo(() => getOptionValueArray(children), [children]); const classes = React.useMemo(() => classnames("core-listbox", className), [className]); const [currentValue, setCurrentValue] = React.useState(selectedValue); const [focusValue, setFocusValue] = React.useState(currentValue); - const initialSelectedValueRef = React.useRef(selectedValue); React.useEffect(() => { - // istanbul ignore else - if (initialSelectedValueRef.current !== selectedValue) { - initialSelectedValueRef.current = selectedValue; - setCurrentValue(selectedValue); - setFocusValue(selectedValue); - } - }, [currentValue, selectedValue]); + setCurrentValue(selectedValue); + setFocusValue(selectedValue); + }, [selectedValue]); const scrollTopRef = React.useRef(0); const handleValueChange = React.useCallback((newValue: ListboxValue, isControlOrCommandPressed?: boolean) => { diff --git a/ui/core/src/ui-core/settings/SettingsManager.tsx b/ui/core/src/ui-core/settings/SettingsManager.tsx index 62e199993cb..704bf1fdefd 100644 --- a/ui/core/src/ui-core/settings/SettingsManager.tsx +++ b/ui/core/src/ui-core/settings/SettingsManager.tsx @@ -33,7 +33,7 @@ export interface SettingsTabEntry { readonly isDisabled?: boolean | ConditionalBooleanValue; } -/** Event class for [[this.onSettingsProvidersChanged]] which is emitted when a new SettingsProvider is added or removed. +/** Event class for [[this.onSettingsProvidersChanged]] which is emitted when a new SettingsTabsProvider is added or removed. * @beta */ export class SettingsProvidersChangedEvent extends BeUiEvent { } @@ -42,7 +42,7 @@ export class SettingsProvidersChangedEvent extends BeUiEvent; + readonly providers: ReadonlyArray; } /** Event class for [[this.onProcessSettingsTabActivation]] which is emitted when a new Tab needs to be activated. This allows the current @@ -94,7 +94,7 @@ export interface ActivateSettingsTabEventArgs { * classes that implement this interface need to be registered with the [[SettingsManager]]. * @beta */ -export interface SettingsProvider { +export interface SettingsTabsProvider { /** Id of provider, used to remove registration. */ readonly id: string; getSettingEntries(stageId: string, stageUsage: string): ReadonlyArray | undefined; @@ -104,7 +104,7 @@ export interface SettingsProvider { * @beta */ export class SettingsManager { - private _providers: ReadonlyArray = []; + private _providers: ReadonlyArray = []; /** Event raised when SettingsProviders are changed. */ @@ -131,8 +131,8 @@ export class SettingsManager { public readonly onCloseSettingsContainer = new CloseSettingsContainerEvent(); /** @beta */ - public get providers(): ReadonlyArray { return this._providers; } - public set providers(p: ReadonlyArray) { + public get providers(): ReadonlyArray { return this._providers; } + public set providers(p: ReadonlyArray) { this._providers = p; this.onSettingsProvidersChanged.emit({ providers: p }); } @@ -151,7 +151,7 @@ export class SettingsManager { this.onCloseSettingsContainer.emit({ closeFunc, closeFuncArgs }); } - public addSettingsProvider(settingsProvider: SettingsProvider): void { + public addSettingsProvider(settingsProvider: SettingsTabsProvider): void { const foundProvider = this._providers.find((p) => p.id === settingsProvider.id); if (!foundProvider) { const updatedProviders = [ diff --git a/ui/core/src/ui-core/tabs/tabs.scss b/ui/core/src/ui-core/tabs/tabs.scss index fd2f9e2b937..a5b5abc2d53 100644 --- a/ui/core/src/ui-core/tabs/tabs.scss +++ b/ui/core/src/ui-core/tabs/tabs.scss @@ -46,7 +46,10 @@ } .uicore-tabs-icon { - width: ( $uicore-icons-small + 10px ); + width: ( $uicore-icons-small + 12px ); + height: ( $uicore-icons-small + 12px ); + display: flex; + align-items: center; } } diff --git a/ui/core/src/ui-core/uisettings/LocalUiSettings.ts b/ui/core/src/ui-core/uisettings/LocalSettingsStorage.ts similarity index 76% rename from ui/core/src/ui-core/uisettings/LocalUiSettings.ts rename to ui/core/src/ui-core/uisettings/LocalSettingsStorage.ts index 584599f1af7..e82a8212358 100644 --- a/ui/core/src/ui-core/uisettings/LocalUiSettings.ts +++ b/ui/core/src/ui-core/uisettings/LocalSettingsStorage.ts @@ -6,13 +6,13 @@ * @module UiSettings */ -import { UiSettings, UiSettingsResult, UiSettingsStatus } from "./UiSettings"; +import { UiSettingsResult, UiSettingsStatus, UiSettingsStorage } from "./UiSettingsStorage"; /** - * Implementation of [[UiSettings]] using Window.localStorage. - * @beta + * Implementation of [[UiSettingsStorage]] using Window.localStorage. + * @public */ -export class LocalUiSettings implements UiSettings { +export class LocalSettingsStorage implements UiSettingsStorage { constructor(public w: Window = window) { } @@ -38,3 +38,11 @@ export class LocalUiSettings implements UiSettings { return { status: UiSettingsStatus.Success }; } } + +/** Alias for [[LocalSettingsStorage]] + * @beta @deprecated use LocalSettingsStorage + */ +export class LocalUiSettings extends LocalSettingsStorage { + constructor(w: Window = window) { super (w);} +} + diff --git a/ui/core/src/ui-core/uisettings/SessionUiSettings.ts b/ui/core/src/ui-core/uisettings/SessionSettingsStorage.ts similarity index 80% rename from ui/core/src/ui-core/uisettings/SessionUiSettings.ts rename to ui/core/src/ui-core/uisettings/SessionSettingsStorage.ts index 018ba446b2a..c98dbc38757 100644 --- a/ui/core/src/ui-core/uisettings/SessionUiSettings.ts +++ b/ui/core/src/ui-core/uisettings/SessionSettingsStorage.ts @@ -6,13 +6,13 @@ * @module UiSettings */ -import { UiSettings, UiSettingsResult, UiSettingsStatus } from "./UiSettings"; +import { UiSettingsResult, UiSettingsStatus, UiSettingsStorage } from "./UiSettingsStorage"; /** * Implementation of [[UiSettings]] using Window.sessionStorage. - * @beta + * @public */ -export class SessionUiSettings implements UiSettings { +export class SessionSettingsStorage implements UiSettingsStorage { constructor(public w: Window = window) { } @@ -38,3 +38,10 @@ export class SessionUiSettings implements UiSettings { return { status: UiSettingsStatus.Success }; } } + +/** Alias for [[SessionSettingsStorage]] + * @beta @deprecated use SessionSettingsStorage + */ +export class SessionUiSettings extends SessionSettingsStorage { + constructor(w: Window = window) { super (w);} +} diff --git a/ui/core/src/ui-core/uisettings/UiSetting.ts b/ui/core/src/ui-core/uisettings/UiSetting.ts index 0d73740f490..c699da52f4e 100644 --- a/ui/core/src/ui-core/uisettings/UiSetting.ts +++ b/ui/core/src/ui-core/uisettings/UiSetting.ts @@ -6,10 +6,10 @@ * @module UiSettings */ -import { UiSettings, UiSettingsResult, UiSettingsStatus } from "./UiSettings"; +import { UiSettingsResult, UiSettingsStatus, UiSettingsStorage } from "./UiSettingsStorage"; /** A Ui Setting with namespace and setting name. - * @beta + * @public */ export class UiSetting { /** Constructor @@ -17,31 +17,36 @@ export class UiSetting { * @param settingName Name for the setting, passed to UiSettings. * @param getValue Function for getting the value from the application. * @param applyValue Function for applying the setting value to the application. + * @param defaultValue Optional default value if not already stored. */ - public constructor(public settingNamespace: string, public settingName: string, public getValue: () => T, public applyValue?: (v: T) => void) { + public constructor(public settingNamespace: string, public settingName: string, public getValue: () => T, public applyValue?: (v: T) => void, public defaultValue?: T) { } - /** Gets the setting from UiSettings */ - public async getSetting(uiSettings: UiSettings): Promise { - return uiSettings.getSetting(this.settingNamespace, this.settingName); + /** Gets the setting from [[UiSettingsStorage]] */ + public async getSetting(storage: UiSettingsStorage): Promise { + return storage.getSetting(this.settingNamespace, this.settingName); } /** Saves the setting value from the `getValue` function to UiSettings */ - public async saveSetting(uiSettings: UiSettings): Promise { - return uiSettings.saveSetting(this.settingNamespace, this.settingName, this.getValue()); + public async saveSetting(storage: UiSettingsStorage): Promise { + return storage.saveSetting(this.settingNamespace, this.settingName, this.getValue()); } /** Deletes the setting from UiSettings */ - public async deleteSetting(uiSettings: UiSettings): Promise { - return uiSettings.deleteSetting(this.settingNamespace, this.settingName); + public async deleteSetting(storage: UiSettingsStorage): Promise { + return storage.deleteSetting(this.settingNamespace, this.settingName); } /** Gets the setting from UiSettings and applies the value using the `applyValue` function */ - public async getSettingAndApplyValue(uiSettings: UiSettings): Promise { + public async getSettingAndApplyValue(storage: UiSettingsStorage): Promise { if (this.applyValue) { - const result = await this.getSetting(uiSettings); - if (result !== undefined && result.status === UiSettingsStatus.Success) { + const result = await this.getSetting(storage); + if (result.status === UiSettingsStatus.Success) { this.applyValue(result.setting); + } else if (undefined !== this.defaultValue) { + this.applyValue(this.defaultValue); + result.setting = this.defaultValue; + result.status = UiSettingsStatus.Success; } return result; } diff --git a/ui/core/src/ui-core/uisettings/UiSettings.ts b/ui/core/src/ui-core/uisettings/UiSettingsStorage.ts similarity index 80% rename from ui/core/src/ui-core/uisettings/UiSettings.ts rename to ui/core/src/ui-core/uisettings/UiSettingsStorage.ts index 76d912005c6..bddb86cae00 100644 --- a/ui/core/src/ui-core/uisettings/UiSettings.ts +++ b/ui/core/src/ui-core/uisettings/UiSettingsStorage.ts @@ -9,13 +9,18 @@ /** Interface for getting, saving and deleting settings. * @public */ -export interface UiSettings { +export interface UiSettingsStorage { getSetting(settingNamespace: string, settingName: string): Promise; saveSetting(settingNamespace: string, settingName: string, setting: any): Promise; deleteSetting(settingNamespace: string, settingName: string): Promise; } -/** Enum for [[UiSettings]] status. +/** Alias for [[UiSettingsStorage]] + * @public + */ +export type UiSettings = UiSettingsStorage; + +/** Enum for [[UiSettingsStorage]] status. * @public */ export enum UiSettingsStatus { @@ -26,7 +31,7 @@ export enum UiSettingsStatus { AuthorizationError = 4, } -/** Interface for [[UiSettings]] result. +/** Interface for result of accessing setting in [[UiSettingsStorage]]. * @public */ export interface UiSettingsResult { diff --git a/ui/framework/public/locales/en/UiFramework.json b/ui/framework/public/locales/en/UiFramework.json index 75262a3e64e..949a4a3bdca 100644 --- a/ui/framework/public/locales/en/UiFramework.json +++ b/ui/framework/public/locales/en/UiFramework.json @@ -143,6 +143,29 @@ "formatSectionLabel": "Quantity Formats", "setButtonLabel": "Set", "clearButtonLabel": "Clear" + }, + "uiSettingsPage": { + "label": "UI Settings", + "tooltip": "UI Settings", + "light": "Light", + "dark": "Dark", + "systemPreferred": "System preferred", + "themeTitle": "Theme", + "themeDescription": "Toggle the theme between light and dark", + "autoHideTitle": "Auto-Hide UI", + "autoHideDescription": "Toggle the auto-hide of UI after inactivity", + "dragInteractionTitle": "Toolbar Group Buttons show child action item", + "dragInteractionDescription": "Requires long press to open pop-up panel. Single click executes displayed action.", + "newUiTitle": "Use 2.0 Ui", + "newUiDescription": "Use new 2.0 UI layout", + "useProximityOpacityTitle": "Change Toolbar Opacity", + "useProximityOpacityDescription": "Change the toolbar opacity as the mouse gets closer or farther away", + "snapWidgetOpacityTitle": "Snap Toolbar Opacity", + "snapWidgetOpacityDescription": "Immediately change the toolbar opacity when the mouse gets close", + "accuDrawNotificationsTitle": "Display AccuDraw Notifications", + "accuDrawNotificationsDescription": "Display toast notifications when AccuDraw status changes", + "widgetOpacityTitle": "Widget Opacity", + "widgetOpacityDescription": "Opacity when mouse is not hovering for 2.0 floating widgets and all 1.0 widgets" } }, "tools": { diff --git a/ui/framework/src/test/UiFramework.test.ts b/ui/framework/src/test/UiFramework.test.ts index 03e655f0fbd..898697e992d 100644 --- a/ui/framework/src/test/UiFramework.test.ts +++ b/ui/framework/src/test/UiFramework.test.ts @@ -2,6 +2,8 @@ * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ +// cSpell:ignore typemoq, tabid + import { expect } from "chai"; import * as moq from "typemoq"; import * as sinon from "sinon"; @@ -9,231 +11,284 @@ import { Id64String, Logger } from "@bentley/bentleyjs-core"; import { IModelApp, IModelConnection, MockRender, ViewState } from "@bentley/imodeljs-frontend"; import { Presentation } from "@bentley/presentation-frontend"; import { initialize as initializePresentationTesting, terminate as terminatePresentationTesting } from "@bentley/presentation-testing"; -import { ColorTheme, CursorMenuData, SettingsModalFrontstage, UiFramework } from "../ui-framework"; +import { ColorTheme, CursorMenuData, SettingsModalFrontstage, UiFramework, UserSettingsProvider } from "../ui-framework"; import { DefaultIModelServices } from "../ui-framework/clientservices/DefaultIModelServices"; import { DefaultProjectServices } from "../ui-framework/clientservices/DefaultProjectServices"; -import TestUtils, { mockUserInfo } from "./TestUtils"; -import { UiSettings } from "@bentley/ui-core"; +import TestUtils, { mockUserInfo, storageMock } from "./TestUtils"; +import { LocalSettingsStorage, UiSettingsStorage } from "@bentley/ui-core"; import { OpenSettingsTool } from "../ui-framework/tools/OpenSettingsTool"; -describe("UiFramework", () => { +describe("UiFramework localStorage Wrapper", () => { - beforeEach(() => { - TestUtils.terminateUiFramework(); - }); + const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; + const localStorageMock = storageMock(); - afterEach(() => { - TestUtils.terminateUiFramework(); + before(async () => { + Object.defineProperty(window, "localStorage", { + get: () => localStorageMock, + }); }); - it("store should throw Error without initialize", () => { - expect(() => UiFramework.store).to.throw(Error); + after(() => { + Object.defineProperty(window, "localStorage", localStorageToRestore); }); - it("i18n should throw Error without initialize", () => { - expect(() => UiFramework.i18n).to.throw(Error); - }); + describe("UiFramework", () => { - it("i18nNamespace should return UiFramework", () => { - expect(UiFramework.i18nNamespace).to.eq("UiFramework"); - }); + beforeEach(() => { + TestUtils.terminateUiFramework(); + }); - it("packageName should return ui-framework", () => { - expect(UiFramework.packageName).to.eq("ui-framework"); - }); + afterEach(() => { + TestUtils.terminateUiFramework(); + }); - it("translate should return the key (in test environment)", async () => { - await TestUtils.initializeUiFramework(true); - expect(UiFramework.translate("test1.test2")).to.eq("test1.test2"); - }); + it("store should throw Error without initialize", () => { + expect(() => UiFramework.store).to.throw(Error); + }); - it("test OpenSettingsTool", async () => { - await TestUtils.initializeUiFramework(true); + it("i18n should throw Error without initialize", () => { + expect(() => UiFramework.i18n).to.throw(Error); + }); - const spy = sinon.spy(); - const tabName = "page1"; - const handleOpenSetting = (settingsCategory: string)=> { - expect (settingsCategory).to.eql(tabName); - spy(); - }; + it("i18nNamespace should return UiFramework", () => { + expect(UiFramework.i18nNamespace).to.eq("UiFramework"); + }); - const handleOpenSetting2 = (_settingsCategory: string)=> { - spy(); - }; + it("packageName should return ui-framework", () => { + expect(UiFramework.packageName).to.eq("ui-framework"); + }); - const showSettingsStageToRestore = Object.getOwnPropertyDescriptor(SettingsModalFrontstage, "showSettingsStage")!; - Object.defineProperty(SettingsModalFrontstage, "showSettingsStage", { - get: () => handleOpenSetting, + it("translate should return the key (in test environment)", async () => { + await TestUtils.initializeUiFramework(true); + expect(UiFramework.translate("test1.test2")).to.eq("test1.test2"); }); - const tool = new OpenSettingsTool(); - // tabid arg - tool.parseAndRun(tabName); - spy.calledOnce.should.true; - spy.resetHistory(); - // No tabid arg - Object.defineProperty(SettingsModalFrontstage, "showSettingsStage", { - get: () => handleOpenSetting2, + it("test OpenSettingsTool", async () => { + await TestUtils.initializeUiFramework(true); + + const spy = sinon.spy(); + const tabName = "page1"; + const handleOpenSetting = (settingsCategory: string)=> { + expect (settingsCategory).to.eql(tabName); + spy(); + }; + + const handleOpenSetting2 = (_settingsCategory: string)=> { + spy(); + }; + + const showSettingsStageToRestore = Object.getOwnPropertyDescriptor(SettingsModalFrontstage, "showSettingsStage")!; + Object.defineProperty(SettingsModalFrontstage, "showSettingsStage", { + get: () => handleOpenSetting, + }); + const tool = new OpenSettingsTool(); + // tabid arg + tool.parseAndRun(tabName); + spy.calledOnce.should.true; + spy.resetHistory(); + + // No tabid arg + Object.defineProperty(SettingsModalFrontstage, "showSettingsStage", { + get: () => handleOpenSetting2, + }); + tool.parseAndRun(); + spy.calledOnce.should.true; + spy.resetHistory(); + + Object.defineProperty(SettingsModalFrontstage, "showSettingsStage", showSettingsStageToRestore); }); - tool.parseAndRun(); - spy.calledOnce.should.true; - spy.resetHistory(); - Object.defineProperty(SettingsModalFrontstage, "showSettingsStage", showSettingsStageToRestore); - }); + it("loggerCategory should correctly handle null or undefined object", () => { + expect(UiFramework.loggerCategory(null)).to.eq(UiFramework.packageName); + expect(UiFramework.loggerCategory(undefined)).to.eq(UiFramework.packageName); + }); - it("loggerCategory should correctly handle null or undefined object", () => { - expect(UiFramework.loggerCategory(null)).to.eq(UiFramework.packageName); - expect(UiFramework.loggerCategory(undefined)).to.eq(UiFramework.packageName); - }); + it("calling initialize twice should log", async () => { + const spyLogger = sinon.spy(Logger, "logInfo"); + expect(UiFramework.initialized).to.be.false; + await UiFramework.initialize(TestUtils.store, TestUtils.i18n); + expect(UiFramework.initialized).to.be.true; + await UiFramework.initialize(TestUtils.store, TestUtils.i18n); + spyLogger.calledOnce.should.true; + }); - it("calling initialize twice should log", async () => { - const spyLogger = sinon.spy(Logger, "logInfo"); - expect(UiFramework.initialized).to.be.false; - await UiFramework.initialize(TestUtils.store, TestUtils.i18n); - expect(UiFramework.initialized).to.be.true; - await UiFramework.initialize(TestUtils.store, TestUtils.i18n); - spyLogger.calledOnce.should.true; - }); + it("calling initialize without I18N will use IModelApp.i18n", async () => { + await MockRender.App.startup(); - it("calling initialize without I18N will use IModelApp.i18n", async () => { - await MockRender.App.startup(); + await UiFramework.initialize(TestUtils.store); + expect(UiFramework.i18n).to.eq(IModelApp.i18n); - await UiFramework.initialize(TestUtils.store); - expect(UiFramework.i18n).to.eq(IModelApp.i18n); + await MockRender.App.shutdown(); + }); - await MockRender.App.shutdown(); - }); + it("projectServices should throw Error without initialize", () => { + expect(() => UiFramework.projectServices).to.throw(Error); + }); - it("projectServices should throw Error without initialize", () => { - expect(() => UiFramework.projectServices).to.throw(Error); - }); + it("iModelServices should throw Error without initialize", () => { + expect(() => UiFramework.iModelServices).to.throw(Error); + }); - it("iModelServices should throw Error without initialize", () => { - expect(() => UiFramework.iModelServices).to.throw(Error); - }); + it("projectServices & iModelServices should return defaults", async () => { + await TestUtils.initializeUiFramework(true); + expect(UiFramework.projectServices).to.be.instanceOf(DefaultProjectServices); + expect(UiFramework.iModelServices).to.be.instanceOf(DefaultIModelServices); + expect(UiFramework.frameworkStateKey).to.equal("testDifferentFrameworkKey"); + }); - it("projectServices & iModelServices should return defaults", async () => { - await TestUtils.initializeUiFramework(true); - expect(UiFramework.projectServices).to.be.instanceOf(DefaultProjectServices); - expect(UiFramework.iModelServices).to.be.instanceOf(DefaultIModelServices); - expect(UiFramework.frameworkStateKey).to.equal("testDifferentFrameworkKey"); - }); + it("test default frameworkState key", async () => { + await TestUtils.initializeUiFramework(); + expect(UiFramework.projectServices).to.be.instanceOf(DefaultProjectServices); + expect(UiFramework.iModelServices).to.be.instanceOf(DefaultIModelServices); + expect(UiFramework.frameworkStateKey).to.equal("frameworkState"); + TestUtils.terminateUiFramework(); + }); - it("test default frameworkState key", async () => { - await TestUtils.initializeUiFramework(); - expect(UiFramework.projectServices).to.be.instanceOf(DefaultProjectServices); - expect(UiFramework.iModelServices).to.be.instanceOf(DefaultIModelServices); - expect(UiFramework.frameworkStateKey).to.equal("frameworkState"); - TestUtils.terminateUiFramework(); - }); + it("IsUiVisible", async () => { + await TestUtils.initializeUiFramework(); + UiFramework.setIsUiVisible(false); + expect(UiFramework.getIsUiVisible()).to.be.false; + TestUtils.terminateUiFramework(); + }); - it("IsUiVisible", async () => { - await TestUtils.initializeUiFramework(); - UiFramework.setIsUiVisible(false); - expect(UiFramework.getIsUiVisible()).to.be.false; - TestUtils.terminateUiFramework(); - }); + it("ColorTheme", async () => { + await TestUtils.initializeUiFramework(); + UiFramework.setColorTheme(ColorTheme.Dark); + expect(UiFramework.getColorTheme()).to.eq(ColorTheme.Dark); + TestUtils.terminateUiFramework(); + }); - it("ColorTheme", async () => { - await TestUtils.initializeUiFramework(); - UiFramework.setColorTheme(ColorTheme.Dark); - expect(UiFramework.getColorTheme()).to.eq(ColorTheme.Dark); - TestUtils.terminateUiFramework(); - }); + it("test selection scope state data", async () => { + await TestUtils.initializeUiFramework(); + expect(UiFramework.getActiveSelectionScope()).to.equal("element"); + const scopes = UiFramework.getAvailableSelectionScopes(); + expect(scopes.length).to.be.greaterThan(0); - it("test selection scope state data", async () => { - await TestUtils.initializeUiFramework(); - expect(UiFramework.getActiveSelectionScope()).to.equal("element"); - const scopes = UiFramework.getAvailableSelectionScopes(); - expect(scopes.length).to.be.greaterThan(0); + // since "file" is not a valid scope the active scope should still be element + UiFramework.setActiveSelectionScope("file"); + expect(UiFramework.getActiveSelectionScope()).to.equal("element"); + TestUtils.terminateUiFramework(); + }); - // since "file" is not a valid scope the active scope should still be element - UiFramework.setActiveSelectionScope("file"); - expect(UiFramework.getActiveSelectionScope()).to.equal("element"); - TestUtils.terminateUiFramework(); - }); + it("WidgetOpacity", async () => { + await TestUtils.initializeUiFramework(); + const testValue = 0.50; + UiFramework.setWidgetOpacity(testValue); + expect(UiFramework.getWidgetOpacity()).to.eq(testValue); + TestUtils.terminateUiFramework(); + }); - it("WidgetOpacity", async () => { - await TestUtils.initializeUiFramework(); - const testValue = 0.50; - UiFramework.setWidgetOpacity(testValue); - expect(UiFramework.getWidgetOpacity()).to.eq(testValue); - TestUtils.terminateUiFramework(); - }); + it("ActiveIModelId", async () => { + await TestUtils.initializeUiFramework(); + const testValue = "Test"; + UiFramework.setActiveIModelId(testValue); + expect(UiFramework.getActiveIModelId()).to.eq(testValue); + TestUtils.terminateUiFramework(); + }); - it("ActiveIModelId", async () => { - await TestUtils.initializeUiFramework(); - const testValue = "Test"; - UiFramework.setActiveIModelId(testValue); - expect(UiFramework.getActiveIModelId()).to.eq(testValue); - TestUtils.terminateUiFramework(); - }); + class testSettingsProvider implements UserSettingsProvider { + public readonly providerId = "testSettingsProvider"; + public settingsLoaded = false; + public async loadUserSettings(storage: UiSettingsStorage) { + if (storage) + this.settingsLoaded = true; + } + } - it("SessionState setters/getters", async () => { - await TestUtils.initializeUiFramework(); + it("SessionState setters/getters", async () => { + await TestUtils.initializeUiFramework(); + const settingsProvider = new testSettingsProvider(); + UiFramework.registerUserSettingsProvider(settingsProvider); - const userInfo = mockUserInfo(); + const userInfo = mockUserInfo(); - UiFramework.setUserInfo(userInfo); - expect(UiFramework.getUserInfo()!.id).to.eq(userInfo.id); + UiFramework.setUserInfo(userInfo); + expect(UiFramework.getUserInfo()!.id).to.eq(userInfo.id); - UiFramework.setDefaultIModelViewportControlId("DefaultIModelViewportControlId"); - expect(UiFramework.getDefaultIModelViewportControlId()).to.eq("DefaultIModelViewportControlId"); + UiFramework.setDefaultIModelViewportControlId("DefaultIModelViewportControlId"); + expect(UiFramework.getDefaultIModelViewportControlId()).to.eq("DefaultIModelViewportControlId"); - const testViewId: Id64String = "0x12345678"; - UiFramework.setDefaultViewId(testViewId); - expect(UiFramework.getDefaultViewId()).to.eq(testViewId); + const testViewId: Id64String = "0x12345678"; + UiFramework.setDefaultViewId(testViewId); + expect(UiFramework.getDefaultViewId()).to.eq(testViewId); - const imodelMock = moq.Mock.ofType(); - UiFramework.setIModelConnection(imodelMock.object); - expect(UiFramework.getIModelConnection()).to.eq(imodelMock.object); + const imodelMock = moq.Mock.ofType(); + UiFramework.setIModelConnection(imodelMock.object); + expect(UiFramework.getIModelConnection()).to.eq(imodelMock.object); - const uisettingsMock = moq.Mock.ofType(); - UiFramework.setUiSettings(uisettingsMock.object); - expect(UiFramework.getUiSettings()).to.eq(uisettingsMock.object); + expect(settingsProvider.settingsLoaded).to.be.false; - UiFramework.closeCursorMenu(); - expect(UiFramework.getCursorMenuData()).to.be.undefined; + const uisettings = new LocalSettingsStorage(); + await UiFramework.setUiSettingsStorage(uisettings); + expect(UiFramework.getUiSettingsStorage()).to.eq(uisettings); + expect(settingsProvider.settingsLoaded).to.be.true; + settingsProvider.settingsLoaded = false; + // if we try to set storage to same object this should be a noop and the settingsLoaded property should remain false; + await UiFramework.setUiSettingsStorage(uisettings); + expect(settingsProvider.settingsLoaded).to.be.false; - const menuData: CursorMenuData = { items: [], position: { x: 100, y: 100 } }; - UiFramework.openCursorMenu(menuData); - expect(UiFramework.getCursorMenuData()).not.to.be.undefined; + const uiVersion1 = "1"; + UiFramework.setUiVersion (uiVersion1); + expect(UiFramework.uiVersion).to.eql(uiVersion1); - const viewState = moq.Mock.ofType(); - UiFramework.setDefaultViewState(viewState.object); - expect(UiFramework.getDefaultViewState()).not.to.be.undefined; - }); + const uiVersion = "2"; + UiFramework.setUiVersion (uiVersion); + expect(UiFramework.uiVersion).to.eql(uiVersion); + UiFramework.setUiVersion (""); + expect(UiFramework.uiVersion).to.eql(uiVersion); -}); + const useDragInteraction = true; + UiFramework.setUseDragInteraction (useDragInteraction); + expect(UiFramework.useDragInteraction).to.eql(useDragInteraction); -// before we can test setting scope to a valid scope id we must make sure Presentation Manager is initialized. -describe("Requires Presentation", () => { - const shutdownIModelApp = async () => { - if (IModelApp.initialized) - await IModelApp.shutdown(); - }; - - beforeEach(async () => { - await shutdownIModelApp(); - Presentation.terminate(); - await initializePresentationTesting(); - }); + UiFramework.closeCursorMenu(); + expect(UiFramework.getCursorMenuData()).to.be.undefined; - afterEach(async () => { - await terminatePresentationTesting(); - }); + const menuData: CursorMenuData = { items: [], position: { x: 100, y: 100 } }; + UiFramework.openCursorMenu(menuData); + expect(UiFramework.getCursorMenuData()).not.to.be.undefined; - describe("initialize and setActiveSelectionScope", () => { + const viewState = moq.Mock.ofType(); + UiFramework.setDefaultViewState(viewState.object); + expect(UiFramework.getDefaultViewState()).not.to.be.undefined; - it("creates manager instances", async () => { - await TestUtils.initializeUiFramework(); - UiFramework.setActiveSelectionScope("element"); TestUtils.terminateUiFramework(); - Presentation.terminate(); - await shutdownIModelApp(); + // try again when store is not defined + expect(UiFramework.useDragInteraction).to.eql(false); }); + }); + // before we can test setting scope to a valid scope id we must make sure Presentation Manager is initialized. + describe("Requires Presentation", () => { + const shutdownIModelApp = async () => { + if (IModelApp.initialized) + await IModelApp.shutdown(); + }; + + beforeEach(async () => { + await shutdownIModelApp(); + Presentation.terminate(); + await initializePresentationTesting(); + }); + + afterEach(async () => { + await terminatePresentationTesting(); + }); + + describe("initialize and setActiveSelectionScope", () => { + + it("creates manager instances", async () => { + await TestUtils.initializeUiFramework(); + UiFramework.setActiveSelectionScope("element"); + TestUtils.terminateUiFramework(); + + Presentation.terminate(); + await shutdownIModelApp(); + }); + }); + + }); }); diff --git a/ui/framework/src/test/accudraw/FrameworkAccuDraw.test.ts b/ui/framework/src/test/accudraw/FrameworkAccuDraw.test.ts index a730cc199f3..cf75225fa5a 100644 --- a/ui/framework/src/test/accudraw/FrameworkAccuDraw.test.ts +++ b/ui/framework/src/test/accudraw/FrameworkAccuDraw.test.ts @@ -5,179 +5,209 @@ import * as sinon from "sinon"; import { expect } from "chai"; import { BeButtonEvent, CompassMode, CurrentState, IModelApp, IModelAppOptions, ItemField, MockRender, RotationMode } from "@bentley/imodeljs-frontend"; -import TestUtils from "../TestUtils"; +import TestUtils, { storageMock } from "../TestUtils"; import { FrameworkAccuDraw } from "../../ui-framework/accudraw/FrameworkAccuDraw"; import { AccuDrawUiAdmin, ConditionalBooleanValue } from "@bentley/ui-abstract"; import { FrameworkUiAdmin } from "../../ui-framework/uiadmin/FrameworkUiAdmin"; +import { UiFramework } from "../../ui-framework/UiFramework"; // cspell:ignore dont uiadmin -describe("FrameworkAccuDraw", () => { - before(async () => { - await TestUtils.initializeUiFramework(); - - const opts: IModelAppOptions = {}; - opts.accuDraw = new FrameworkAccuDraw(); - opts.uiAdmin = new FrameworkUiAdmin(); - await MockRender.App.startup(opts); - }); - - after(async () => { - await MockRender.App.shutdown(); - TestUtils.terminateUiFramework(); - }); - - it("FrameworkAccuDraw.displayNotifications should set & return correctly", () => { - FrameworkAccuDraw.displayNotifications = false; - expect(FrameworkAccuDraw.displayNotifications).to.be.false; - FrameworkAccuDraw.displayNotifications = true; - expect(FrameworkAccuDraw.displayNotifications).to.be.true; - }); - - it("should call onCompassModeChange & emit onAccuDrawSetModeEvent & set conditionals", () => { - FrameworkAccuDraw.displayNotifications = true; - const spy = sinon.spy(); - const spyMessage = sinon.spy(IModelApp.notifications, "outputMessage"); - const remove = AccuDrawUiAdmin.onAccuDrawSetModeEvent.addListener(spy); - - IModelApp.accuDraw.setCompassMode(CompassMode.Polar); - FrameworkAccuDraw.isPolarModeConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isPolarModeConditional)).to.be.true; - spy.calledOnce.should.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - - IModelApp.accuDraw.setCompassMode(CompassMode.Rectangular); - FrameworkAccuDraw.isRectangularModeConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isRectangularModeConditional)).to.be.true; - spy.calledTwice.should.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - - FrameworkAccuDraw.displayNotifications = false; - IModelApp.accuDraw.setCompassMode(CompassMode.Polar); - spyMessage.called.should.false; - spyMessage.resetHistory(); - - remove(); - }); +describe("FrameworkAccuDraw localStorage Wrapper", () => { - it("should call onFieldLockChange & emit onAccuDrawSetFieldLockEvent", () => { - const spy = sinon.spy(); - const remove = AccuDrawUiAdmin.onAccuDrawSetFieldLockEvent.addListener(spy); - IModelApp.accuDraw.setFieldLock(ItemField.X_Item, true); - spy.calledOnce.should.true; - spy.resetHistory(); - IModelApp.accuDraw.setFieldLock(ItemField.Y_Item, true); - spy.calledOnce.should.true; - spy.resetHistory(); - IModelApp.accuDraw.setFieldLock(ItemField.Z_Item, true); - spy.calledOnce.should.true; - spy.resetHistory(); - IModelApp.accuDraw.setFieldLock(ItemField.ANGLE_Item, true); - spy.calledOnce.should.true; - spy.resetHistory(); - IModelApp.accuDraw.setFieldLock(ItemField.DIST_Item, true); - spy.calledOnce.should.true; - spy.resetHistory(); - remove(); - }); - - it("should set rotation & conditionals correctly & notify", () => { - FrameworkAccuDraw.displayNotifications = true; - const spyMessage = sinon.spy(IModelApp.notifications, "outputMessage"); - - IModelApp.accuDraw.setRotationMode(RotationMode.Top); - FrameworkAccuDraw.isTopRotationConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isTopRotationConditional)).to.be.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - IModelApp.accuDraw.setRotationMode(RotationMode.Front); - FrameworkAccuDraw.isFrontRotationConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isFrontRotationConditional)).to.be.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - IModelApp.accuDraw.setRotationMode(RotationMode.Side); - FrameworkAccuDraw.isSideRotationConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isSideRotationConditional)).to.be.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - IModelApp.accuDraw.setRotationMode(RotationMode.View); - FrameworkAccuDraw.isViewRotationConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isViewRotationConditional)).to.be.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - IModelApp.accuDraw.setRotationMode(RotationMode.ACS); - FrameworkAccuDraw.isACSRotationConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isACSRotationConditional)).to.be.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - IModelApp.accuDraw.setRotationMode(RotationMode.Context); - FrameworkAccuDraw.isContextRotationConditional.refresh(); - expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isContextRotationConditional)).to.be.true; - spyMessage.calledOnce.should.true; - spyMessage.resetHistory(); - - FrameworkAccuDraw.displayNotifications = false; - IModelApp.accuDraw.setRotationMode(RotationMode.Top); - spyMessage.calledOnce.should.false; - spyMessage.resetHistory(); - }); - - it("should call onFieldValueChange & emit onAccuDrawSetFieldValueToUiEvent", () => { - const spy = sinon.spy(); - const remove = AccuDrawUiAdmin.onAccuDrawSetFieldValueToUiEvent.addListener(spy); - IModelApp.accuDraw.setValueByIndex(ItemField.X_Item, 1.0); - IModelApp.accuDraw.onFieldValueChange(ItemField.X_Item); - spy.calledOnce.should.true; - remove(); - }); + const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; + const localStorageMock = storageMock(); - it("should emit onAccuDrawSetFieldFocusEvent", () => { - const spy = sinon.spy(); - const remove = AccuDrawUiAdmin.onAccuDrawSetFieldFocusEvent.addListener(spy); - IModelApp.accuDraw.setFocusItem(ItemField.X_Item); - spy.calledOnce.should.true; - remove(); - }); - - it("should emit onAccuDrawGrabInputFocusEvent", () => { - const spy = sinon.spy(); - const remove = AccuDrawUiAdmin.onAccuDrawGrabInputFocusEvent.addListener(spy); - IModelApp.accuDraw.grabInputFocus(); - spy.calledOnce.should.true; - remove(); + before(async () => { + Object.defineProperty(window, "localStorage", { + get: () => localStorageMock, + }); }); - it("hasInputFocus should return false", () => { - expect(IModelApp.accuDraw.hasInputFocus).to.be.false; + after(() => { + Object.defineProperty(window, "localStorage", localStorageToRestore); }); - it("should emit onAccuDrawSetFieldValueToUiEvent & onAccuDrawSetFieldFocusEvent", () => { - const spyValue = sinon.spy(); - const remove = AccuDrawUiAdmin.onAccuDrawSetFieldValueToUiEvent.addListener(spyValue); - const spyFocus = sinon.spy(); - const removeFocusSpy = AccuDrawUiAdmin.onAccuDrawSetFieldFocusEvent.addListener(spyFocus); - - IModelApp.accuDraw.currentState = CurrentState.Deactivated; - IModelApp.accuDraw.onMotion(new BeButtonEvent()); - spyValue.called.should.false; - spyValue.resetHistory(); - - IModelApp.accuDraw.currentState = CurrentState.Active; - IModelApp.accuDraw.onMotion(new BeButtonEvent()); - spyValue.called.should.true; - spyFocus.called.should.true; - spyValue.resetHistory(); - spyFocus.resetHistory(); - - IModelApp.accuDraw.dontMoveFocus = true; - IModelApp.accuDraw.onMotion(new BeButtonEvent()); - spyValue.called.should.true; - spyFocus.called.should.false; - - remove(); - removeFocusSpy(); + describe("FrameworkAccuDraw", () => { + before(async () => { + await TestUtils.initializeUiFramework(); + + const opts: IModelAppOptions = {}; + opts.accuDraw = new FrameworkAccuDraw(); + opts.uiAdmin = new FrameworkUiAdmin(); + await MockRender.App.startup(opts); + }); + + after(async () => { + await MockRender.App.shutdown(); + TestUtils.terminateUiFramework(); + }); + + it("FrameworkAccuDraw.displayNotifications should set & return correctly", () => { + FrameworkAccuDraw.displayNotifications = false; + expect(FrameworkAccuDraw.displayNotifications).to.be.false; + FrameworkAccuDraw.displayNotifications = true; + expect(FrameworkAccuDraw.displayNotifications).to.be.true; + }); + + it("should call onCompassModeChange & emit onAccuDrawSetModeEvent & set conditionals", () => { + FrameworkAccuDraw.displayNotifications = true; + const spy = sinon.spy(); + const spyMessage = sinon.spy(IModelApp.notifications, "outputMessage"); + const remove = AccuDrawUiAdmin.onAccuDrawSetModeEvent.addListener(spy); + + IModelApp.accuDraw.setCompassMode(CompassMode.Polar); + FrameworkAccuDraw.isPolarModeConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isPolarModeConditional)).to.be.true; + spy.calledOnce.should.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + + IModelApp.accuDraw.setCompassMode(CompassMode.Rectangular); + FrameworkAccuDraw.isRectangularModeConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isRectangularModeConditional)).to.be.true; + spy.calledTwice.should.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + + FrameworkAccuDraw.displayNotifications = false; + IModelApp.accuDraw.setCompassMode(CompassMode.Polar); + spyMessage.called.should.false; + spyMessage.resetHistory(); + + remove(); + }); + + it("should call onFieldLockChange & emit onAccuDrawSetFieldLockEvent", () => { + const spy = sinon.spy(); + const remove = AccuDrawUiAdmin.onAccuDrawSetFieldLockEvent.addListener(spy); + IModelApp.accuDraw.setFieldLock(ItemField.X_Item, true); + spy.calledOnce.should.true; + spy.resetHistory(); + IModelApp.accuDraw.setFieldLock(ItemField.Y_Item, true); + spy.calledOnce.should.true; + spy.resetHistory(); + IModelApp.accuDraw.setFieldLock(ItemField.Z_Item, true); + spy.calledOnce.should.true; + spy.resetHistory(); + IModelApp.accuDraw.setFieldLock(ItemField.ANGLE_Item, true); + spy.calledOnce.should.true; + spy.resetHistory(); + IModelApp.accuDraw.setFieldLock(ItemField.DIST_Item, true); + spy.calledOnce.should.true; + spy.resetHistory(); + remove(); + }); + + it("should set rotation & conditionals correctly & notify", () => { + FrameworkAccuDraw.displayNotifications = true; + const spyMessage = sinon.spy(IModelApp.notifications, "outputMessage"); + + IModelApp.accuDraw.setRotationMode(RotationMode.Top); + FrameworkAccuDraw.isTopRotationConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isTopRotationConditional)).to.be.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + IModelApp.accuDraw.setRotationMode(RotationMode.Front); + FrameworkAccuDraw.isFrontRotationConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isFrontRotationConditional)).to.be.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + IModelApp.accuDraw.setRotationMode(RotationMode.Side); + FrameworkAccuDraw.isSideRotationConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isSideRotationConditional)).to.be.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + IModelApp.accuDraw.setRotationMode(RotationMode.View); + FrameworkAccuDraw.isViewRotationConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isViewRotationConditional)).to.be.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + IModelApp.accuDraw.setRotationMode(RotationMode.ACS); + FrameworkAccuDraw.isACSRotationConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isACSRotationConditional)).to.be.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + IModelApp.accuDraw.setRotationMode(RotationMode.Context); + FrameworkAccuDraw.isContextRotationConditional.refresh(); + expect(ConditionalBooleanValue.getValue(FrameworkAccuDraw.isContextRotationConditional)).to.be.true; + spyMessage.calledOnce.should.true; + spyMessage.resetHistory(); + + FrameworkAccuDraw.displayNotifications = false; + IModelApp.accuDraw.setRotationMode(RotationMode.Top); + spyMessage.calledOnce.should.false; + spyMessage.resetHistory(); + }); + + it("should call onFieldValueChange & emit onAccuDrawSetFieldValueToUiEvent", () => { + const spy = sinon.spy(); + const remove = AccuDrawUiAdmin.onAccuDrawSetFieldValueToUiEvent.addListener(spy); + IModelApp.accuDraw.setValueByIndex(ItemField.X_Item, 1.0); + IModelApp.accuDraw.onFieldValueChange(ItemField.X_Item); + spy.calledOnce.should.true; + remove(); + }); + + it("should emit onAccuDrawSetFieldFocusEvent", () => { + const spy = sinon.spy(); + const remove = AccuDrawUiAdmin.onAccuDrawSetFieldFocusEvent.addListener(spy); + IModelApp.accuDraw.setFocusItem(ItemField.X_Item); + spy.calledOnce.should.true; + remove(); + }); + + it("should emit onAccuDrawGrabInputFocusEvent", () => { + const spy = sinon.spy(); + const remove = AccuDrawUiAdmin.onAccuDrawGrabInputFocusEvent.addListener(spy); + IModelApp.accuDraw.grabInputFocus(); + spy.calledOnce.should.true; + remove(); + }); + + it("hasInputFocus should return false", () => { + expect(IModelApp.accuDraw.hasInputFocus).to.be.false; + }); + + it("should emit onAccuDrawSetFieldValueToUiEvent & onAccuDrawSetFieldFocusEvent", () => { + const spyValue = sinon.spy(); + const remove = AccuDrawUiAdmin.onAccuDrawSetFieldValueToUiEvent.addListener(spyValue); + const spyFocus = sinon.spy(); + const removeFocusSpy = AccuDrawUiAdmin.onAccuDrawSetFieldFocusEvent.addListener(spyFocus); + + IModelApp.accuDraw.currentState = CurrentState.Deactivated; + IModelApp.accuDraw.onMotion(new BeButtonEvent()); + spyValue.called.should.false; + spyValue.resetHistory(); + + IModelApp.accuDraw.currentState = CurrentState.Active; + IModelApp.accuDraw.onMotion(new BeButtonEvent()); + spyValue.called.should.true; + spyFocus.called.should.true; + spyValue.resetHistory(); + spyFocus.resetHistory(); + + IModelApp.accuDraw.dontMoveFocus = true; + IModelApp.accuDraw.onMotion(new BeButtonEvent()); + spyValue.called.should.true; + spyFocus.called.should.false; + + remove(); + removeFocusSpy(); + }); + + it("should save/retrieve displayNotifications to/from user storage", async () => { + FrameworkAccuDraw.displayNotifications = true; + await TestUtils.flushAsyncOperations(); + expect(FrameworkAccuDraw.displayNotifications).to.be.true; + FrameworkAccuDraw.displayNotifications = false; + await TestUtils.flushAsyncOperations(); + expect(FrameworkAccuDraw.displayNotifications).to.be.false; + + const instance = new FrameworkAccuDraw(); + await instance.loadUserSettings (UiFramework.getUiSettingsStorage()); + await TestUtils.flushAsyncOperations(); + expect(FrameworkAccuDraw.displayNotifications).to.be.false; + }); }); - }); diff --git a/ui/framework/src/test/frontstage/ModalSettingsStage.test.tsx b/ui/framework/src/test/frontstage/ModalSettingsStage.test.tsx index 21629aceb64..f9bdb0267d3 100644 --- a/ui/framework/src/test/frontstage/ModalSettingsStage.test.tsx +++ b/ui/framework/src/test/frontstage/ModalSettingsStage.test.tsx @@ -9,7 +9,7 @@ import { render } from "@testing-library/react"; import { CoreTools, FrontstageDef, FrontstageManager, FrontstageProps, ModalFrontstage, ModalFrontstageInfo, SettingsModalFrontstage } from "../../ui-framework"; import TestUtils from "../TestUtils"; import { UiFramework } from "../../ui-framework/UiFramework"; -import { SettingsManager, SettingsProvider, SettingsTabEntry, useSaveBeforeActivatingNewSettingsTab, useSaveBeforeClosingSettingsContainer } from "@bentley/ui-core"; +import { SettingsManager, SettingsTabEntry, SettingsTabsProvider, useSaveBeforeActivatingNewSettingsTab, useSaveBeforeClosingSettingsContainer } from "@bentley/ui-core"; import { IModelApp, MockRender } from "@bentley/imodeljs-frontend"; import { ConditionalBooleanValue } from "@bentley/ui-abstract"; @@ -88,7 +88,7 @@ describe("ModalSettingsStage", () => { expect (ConditionalBooleanValue.getValue(backstageActionItem.isHidden)).to.be.true; }); - class TestSettingsProvider implements SettingsProvider { + class TestSettingsProvider implements SettingsTabsProvider { public readonly id = "AppSettingsProvider"; public getSettingEntries(_stageId: string, _stageUsage: string): ReadonlyArray | undefined { diff --git a/ui/framework/src/test/popup/KeyinPalettePanel.test.tsx b/ui/framework/src/test/popup/KeyinPalettePanel.test.tsx index 2318a6179c4..8116defafa7 100644 --- a/ui/framework/src/test/popup/KeyinPalettePanel.test.tsx +++ b/ui/framework/src/test/popup/KeyinPalettePanel.test.tsx @@ -51,13 +51,13 @@ describe("", () => { }); it("test clearKeyinPaletteHistory", async () => { - const uiSettings = UiFramework.getUiSettings(); - if (uiSettings) { - await uiSettings.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["keyin1", "keyin2"]); - let settingsResult = await uiSettings.getSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY); + const uiSettingsStorage = UiFramework.getUiSettingsStorage(); + if (uiSettingsStorage) { + await uiSettingsStorage.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["keyin1", "keyin2"]); + let settingsResult = await uiSettingsStorage.getSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY); expect(UiSettingsStatus.Success === settingsResult.status); clearKeyinPaletteHistory(); - settingsResult = await uiSettings.getSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY); + settingsResult = await uiSettingsStorage.getSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY); expect(UiSettingsStatus.NotFound === settingsResult.status); } }); @@ -197,9 +197,9 @@ describe("", () => { }); it("Renders and filters out bogus history entry", async () => { - const uiSettings = UiFramework.getUiSettings(); - if (uiSettings) { - await uiSettings.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); + const uiSettingsStorage = UiFramework.getUiSettingsStorage(); + if (uiSettingsStorage) { + await uiSettingsStorage.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); } const keyins: KeyinEntry[] = [{ value: "keyin one" }, { value: "keyin two" }]; const renderedComponent = render(); @@ -212,9 +212,9 @@ describe("", () => { }); it("handles key presses in select input ", async () => { - const uiSettings = UiFramework.getUiSettings(); - if (uiSettings) { - await uiSettings.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); + const uiSettingsStorage = UiFramework.getUiSettingsStorage(); + if (uiSettingsStorage) { + await uiSettingsStorage.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); } const keyins: KeyinEntry[] = [{ value: "keyin one" }, { value: "keyin two" }]; const renderedComponent = render(); @@ -233,9 +233,9 @@ describe("", () => { }); it("handles ctrl+key presses in select input ", async () => { - const uiSettings = UiFramework.getUiSettings(); - if (uiSettings) { - await uiSettings.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); + const uiSettingsStorage = UiFramework.getUiSettingsStorage(); + if (uiSettingsStorage) { + await uiSettingsStorage.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); } const keyins: KeyinEntry[] = [{ value: "keyin one" }, { value: "keyin two" }]; const renderedComponent = render(); @@ -272,9 +272,9 @@ describe("", () => { }); it("Handles listbox click processing", async () => { - const uiSettings = UiFramework.getUiSettings(); - if (uiSettings) { - await uiSettings.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); + const uiSettingsStorage = UiFramework.getUiSettingsStorage(); + if (uiSettingsStorage) { + await uiSettingsStorage.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); } const keyins: KeyinEntry[] = [{ value: "keyin one" }, { value: "keyin two" }]; const renderedComponent = render(); @@ -292,9 +292,9 @@ describe("", () => { }); it("Handles listbox CTRL+click processing", async () => { - const uiSettings = UiFramework.getUiSettings(); - if (uiSettings) { - await uiSettings.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); + const uiSettingsStorage = UiFramework.getUiSettingsStorage(); + if (uiSettingsStorage) { + await uiSettingsStorage.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, ["history1", "history2", "bogus"]); } const keyins: KeyinEntry[] = [{ value: "keyin one" }, { value: "keyin two" }]; const renderedComponent = render(); diff --git a/ui/framework/src/test/redux/StateManager.test.ts b/ui/framework/src/test/redux/StateManager.test.ts index a72958a66f1..80f236db4ef 100644 --- a/ui/framework/src/test/redux/StateManager.test.ts +++ b/ui/framework/src/test/redux/StateManager.test.ts @@ -5,8 +5,10 @@ import { expect } from "chai"; import { UiError } from "@bentley/ui-abstract"; -import { ActionCreatorsObject, ActionsUnion, createAction, FrameworkReducer, ReducerRegistryInstance } from "../../ui-framework"; +import { ActionCreatorsObject, ActionsUnion, createAction, FrameworkReducer, ReducerRegistryInstance, SYSTEM_PREFERRED_COLOR_THEME, WIDGET_OPACITY_DEFAULT } from "../../ui-framework"; import { StateManager } from "../../ui-framework/redux/StateManager"; +import { ConfigurableUiActions, ConfigurableUiReducer, ConfigurableUiState } from "../../ui-framework/configurableui/state"; +import { SnapMode } from "@bentley/imodeljs-frontend"; // Fake state for the host app interface IAppState { @@ -179,3 +181,35 @@ describe("StateManager", () => { }); }); + +describe("ConfigurableUiReducer", () => { + it("should process actions", () => { + // exercise the ConfigurableUiActions + const initialState: ConfigurableUiState = { + snapMode: SnapMode.NearestKeypoint as number, + toolPrompt: "", + theme: SYSTEM_PREFERRED_COLOR_THEME, + widgetOpacity: WIDGET_OPACITY_DEFAULT, + useDragInteraction: false, + frameworkVersion: "2", + }; + + let outState = ConfigurableUiReducer(initialState, ConfigurableUiActions.setDragInteraction(true)); + expect(outState.useDragInteraction).to.be.true; + + outState = ConfigurableUiReducer(initialState, ConfigurableUiActions.setToolPrompt("Hello-From-Tool")); + expect(outState.toolPrompt).to.be.eql("Hello-From-Tool"); + + outState = ConfigurableUiReducer(initialState, ConfigurableUiActions.setTheme("dark")); + expect(outState.theme).to.be.eql("dark"); + + outState = ConfigurableUiReducer(initialState, ConfigurableUiActions.setWidgetOpacity(.75)); + expect(outState.widgetOpacity).to.be.eql(.75); + + outState = ConfigurableUiReducer(initialState, ConfigurableUiActions.setSnapMode(SnapMode.Center)); + expect(outState.snapMode).to.be.eql(SnapMode.Center); + + outState = ConfigurableUiReducer(initialState, ConfigurableUiActions.setFrameworkVersion("1")); + expect(outState.frameworkVersion).to.be.eql("1"); + }); +}); diff --git a/ui/framework/src/test/settings/QuantityFormat.test.tsx b/ui/framework/src/test/settings/QuantityFormat.test.tsx index 38f57cfb2c0..c8397d31863 100644 --- a/ui/framework/src/test/settings/QuantityFormat.test.tsx +++ b/ui/framework/src/test/settings/QuantityFormat.test.tsx @@ -19,7 +19,7 @@ import { ModalDialogRenderer } from "../../ui-framework/dialog/ModalDialogManage import { FormatProps } from "@bentley/imodeljs-quantity"; import { UiFramework } from "../../ui-framework/UiFramework"; -describe("QuantityFormatSettingsPanel", () => { +describe("QuantityFormatSettingsPage", () => { let presentationManagerMock: moq.IMock; const sandbox = sinon.createSandbox(); diff --git a/ui/framework/src/test/settings/UiSettingsPage.test.tsx b/ui/framework/src/test/settings/UiSettingsPage.test.tsx new file mode 100644 index 00000000000..3eccdeafa98 --- /dev/null +++ b/ui/framework/src/test/settings/UiSettingsPage.test.tsx @@ -0,0 +1,183 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Bentley Systems, Incorporated. All rights reserved. +* See LICENSE.md in the project root for license terms and full copyright notice. +*--------------------------------------------------------------------------------------------*/ +import { expect } from "chai"; +import * as React from "react"; +import { fireEvent, render } from "@testing-library/react"; +import { getUiSettingsManagerEntry, UiSettingsPage } from "../../ui-framework/settings/ui/UiSettingsPage"; +import TestUtils, { storageMock } from "../TestUtils"; +import { UiFramework } from "../../ui-framework/UiFramework"; + +describe("UiSettingsPage", () => { + const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; + let localStorageMock = storageMock(); + + beforeEach(async () => { + // create a new mock each run so there are no "stored values" + localStorageMock = storageMock(); + await TestUtils.initializeUiFramework(); + Object.defineProperty(window, "localStorage", { + get: () => localStorageMock, + }); + }); + + afterEach(() => { + TestUtils.terminateUiFramework(); + Object.defineProperty(window, "localStorage", localStorageToRestore); + }); + + function getInputBySpanTitle(titleSpan: HTMLElement) { + const settingsItemDiv = titleSpan.parentElement?.parentElement; + expect(settingsItemDiv).not.to.be.undefined; + return settingsItemDiv!.querySelector("input"); + } + + it("renders using getUiSettingsManagerEntry (V1)", async () => { + const tabEntry = getUiSettingsManagerEntry (10, false); + const wrapper = render(tabEntry.page); + expect(wrapper).not.to.be.undefined; + expect(wrapper.container.querySelectorAll("span.title").length).to.eq(3); + wrapper.unmount(); + }); + + function getSelectBySpanTitle(titleSpan: HTMLElement) { + const settingsItemDiv = titleSpan.parentElement?.parentElement; + expect(settingsItemDiv).not.to.be.undefined; + return settingsItemDiv!.querySelector("select"); + } + + it("renders without version option (V1) set theme", async () => { + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + + const themeSpan = wrapper.getByText("settings.uiSettingsPage.themeTitle"); + const themeSelect = getSelectBySpanTitle (themeSpan); + expect(themeSelect).not.to.be.null; + await TestUtils.flushAsyncOperations(); + fireEvent.change(themeSelect!, { target: {value: "dark"}}); + await TestUtils.flushAsyncOperations(); + expect(themeSelect!.value).to.be.eq("dark"); + fireEvent.change(themeSelect!, { target: {value: "light"}}); + await TestUtils.flushAsyncOperations(); + expect(themeSelect!.value).to.be.eq("light"); + wrapper.unmount(); + }); + + it("renders without version option (V1) set widget opacity", async () => { + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + const handles = wrapper.container.querySelectorAll(".core-slider-handle"); + expect(handles.length).to.eq(1); + fireEvent.mouseDown(handles[0]); + fireEvent.mouseUp(handles[0]); + await TestUtils.flushAsyncOperations(); + // trigger sync event processing + UiFramework.setWidgetOpacity(.5); + await TestUtils.flushAsyncOperations(); + wrapper.unmount(); + }); + + it("renders without version option (V1) toggle auto-hide", async () => { + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + const autoHideSpan = wrapper.getByText("settings.uiSettingsPage.autoHideTitle"); + const checkbox = getInputBySpanTitle (autoHideSpan); + expect(checkbox).not.to.be.null; + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.true; + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.false; + expect(wrapper.container.querySelectorAll("span.title").length).to.eq(3); + wrapper.unmount(); + }); + + it("renders with version option (V1)", async () => { + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + expect(wrapper.container.querySelectorAll("span.title").length).to.eq(4); + + const titleSpan = wrapper.getByText("settings.uiSettingsPage.newUiTitle"); + const checkbox = getInputBySpanTitle (titleSpan); + expect(checkbox).not.to.be.null; + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(wrapper.container.querySelectorAll("span.title").length).to.eq(7); + + wrapper.unmount(); + }); + + it("renders without version option (V2) toggle drag interaction", async () => { + UiFramework.setUiVersion("2"); + await TestUtils.flushAsyncOperations(); + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + + const titleSpan = wrapper.getByText("settings.uiSettingsPage.dragInteractionTitle"); + const checkbox = getInputBySpanTitle (titleSpan); + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.true; + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.false; + wrapper.unmount(); + }); + + it("renders without version option (V2) toggle useProximityOpacity", async () => { + UiFramework.setUiVersion("2"); + await TestUtils.flushAsyncOperations(); + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + + const titleSpan = wrapper.getByText("settings.uiSettingsPage.useProximityOpacityTitle"); + const checkbox = getInputBySpanTitle (titleSpan); + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.false; + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.true; + wrapper.unmount(); + }); + + it("renders without version option (V2) toggle snapWidgetOpacity", async () => { + UiFramework.setUiVersion("2"); + await TestUtils.flushAsyncOperations(); + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + + const titleSpan = wrapper.getByText("settings.uiSettingsPage.snapWidgetOpacityTitle"); + const checkbox = getInputBySpanTitle (titleSpan); + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.true; + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(checkbox?.checked).to.be.false; + wrapper.unmount(); + }); + + it("renders with version option (V2) toggle ui-version", async () => { + UiFramework.setUiVersion("2"); + await TestUtils.flushAsyncOperations(); + const wrapper = render(); + expect(wrapper).not.to.be.undefined; + expect(wrapper.container.querySelectorAll("span.title").length).to.eq(7); + const uiVersionSpan = wrapper.getByText("settings.uiSettingsPage.newUiTitle"); + const checkbox = getInputBySpanTitle (uiVersionSpan); + + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(wrapper.container.querySelectorAll("span.title").length).to.eq(4); + + fireEvent.click(checkbox!); + await TestUtils.flushAsyncOperations(); + expect(wrapper.container.querySelectorAll("span.title").length).to.eq(7); + + wrapper.unmount(); + }); + +}); diff --git a/ui/framework/src/test/statusfields/toolassistance/ToolAssistanceField.test.tsx b/ui/framework/src/test/statusfields/toolassistance/ToolAssistanceField.test.tsx index eb3caf2cf44..611869c45ac 100644 --- a/ui/framework/src/test/statusfields/toolassistance/ToolAssistanceField.test.tsx +++ b/ui/framework/src/test/statusfields/toolassistance/ToolAssistanceField.test.tsx @@ -9,7 +9,7 @@ import * as sinon from "sinon"; import { Logger } from "@bentley/bentleyjs-core"; import { MockRender, ToolAssistance, ToolAssistanceImage, ToolAssistanceInputMethod } from "@bentley/imodeljs-frontend"; import { WidgetState } from "@bentley/ui-abstract"; -import { LocalUiSettings, Toggle } from "@bentley/ui-core"; +import { LocalSettingsStorage, Toggle } from "@bentley/ui-core"; import { FooterPopup, TitleBarButton } from "@bentley/ui-ninezone"; import { AppNotificationManager, ConfigurableCreateInfo, ConfigurableUiControlType, CursorPopupManager, FrontstageManager, StatusBar, StatusBarWidgetControl, @@ -18,11 +18,11 @@ import { import TestUtils, { mount, storageMock } from "../../TestUtils"; describe("ToolAssistanceField", () => { - const uiSettings = new LocalUiSettings({ localStorage: storageMock() } as Window); + const uiSettingsStorage = new LocalSettingsStorage({ localStorage: storageMock() } as Window); before(async () => { - await uiSettings.saveSetting("ToolAssistance", "showPromptAtCursor", true); - await uiSettings.saveSetting("ToolAssistance", "mouseTouchTabIndex", 0); + await uiSettingsStorage.saveSetting("ToolAssistance", "showPromptAtCursor", true); + await uiSettingsStorage.saveSetting("ToolAssistance", "mouseTouchTabIndex", 0); }); class AppStatusBarWidgetControl extends StatusBarWidgetControl { @@ -35,7 +35,7 @@ describe("ToolAssistanceField", () => { <> + uiSettings={uiSettingsStorage} /> ); } diff --git a/ui/framework/src/test/uisettings/AppUiSettings.test.ts b/ui/framework/src/test/uisettings/AppUiSettings.test.ts new file mode 100644 index 00000000000..9bc1e23c932 --- /dev/null +++ b/ui/framework/src/test/uisettings/AppUiSettings.test.ts @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Bentley Systems, Incorporated. All rights reserved. +* See LICENSE.md in the project root for license terms and full copyright notice. +*--------------------------------------------------------------------------------------------*/ +import { expect } from "chai"; +import { storageMock, TestUtils } from "../TestUtils"; +import { UiFramework } from "../../ui-framework/UiFramework"; +import { AppUiSettings } from "../../ui-framework/uisettings/AppUiSettings"; +import { SYSTEM_PREFERRED_COLOR_THEME } from "../../ui-framework/theme/ThemeManager"; + +describe("AppUiSettings", () => { + const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; + let localStorageMock = storageMock(); + + beforeEach(async () => { + // create a new mock each run so there are no "stored values" + localStorageMock = storageMock(); + await TestUtils.initializeUiFramework(); + Object.defineProperty(window, "localStorage", { + get: () => localStorageMock, + }); + }); + + afterEach(() => { + TestUtils.terminateUiFramework(); + Object.defineProperty(window, "localStorage", localStorageToRestore); + }); + + it("should get/set settings", async () => { + + const uiSetting = new AppUiSettings({}); + await uiSetting.loadUserSettings(UiFramework.getUiSettingsStorage()); + const uiVersion = "2"; + const opacity = 0.5; + const colorTheme = "dark"; + const useDragInteraction = true; + UiFramework.setUiVersion (uiVersion); + UiFramework.setWidgetOpacity(opacity); + UiFramework.setUseDragInteraction(true); + UiFramework.setColorTheme(colorTheme); + UiFramework.setUseDragInteraction(useDragInteraction); + await TestUtils.flushAsyncOperations(); + expect(UiFramework.uiVersion).to.eql(uiVersion); + expect(UiFramework.getWidgetOpacity()).to.eql(opacity); + expect(UiFramework.getColorTheme()).to.eql(colorTheme); + expect(UiFramework.useDragInteraction).to.eql(useDragInteraction); + }); + + it("should used default settings", async () => { + const defaults = { + colorTheme: SYSTEM_PREFERRED_COLOR_THEME, + dragInteraction: false, + frameworkVersion: "2", + widgetOpacity: 0.8, + }; + + const uiSetting = new AppUiSettings(defaults); + await uiSetting.loadUserSettings(UiFramework.getUiSettingsStorage()); + await TestUtils.flushAsyncOperations(); + expect(UiFramework.uiVersion).to.eql(defaults.frameworkVersion); + expect(UiFramework.getWidgetOpacity()).to.eql(defaults.widgetOpacity); + expect(UiFramework.getColorTheme()).to.eql(defaults.colorTheme); + expect(UiFramework.useDragInteraction).to.eql(defaults.dragInteraction); + }); + +}); diff --git a/ui/framework/src/test/uisettings/IModelAppUiSettings.test.ts b/ui/framework/src/test/uisettings/UserSettingsStorage.test.ts similarity index 92% rename from ui/framework/src/test/uisettings/IModelAppUiSettings.test.ts rename to ui/framework/src/test/uisettings/UserSettingsStorage.test.ts index f75c609a6e0..1c6eb00937a 100644 --- a/ui/framework/src/test/uisettings/IModelAppUiSettings.test.ts +++ b/ui/framework/src/test/uisettings/UserSettingsStorage.test.ts @@ -7,10 +7,10 @@ import { expect } from "chai"; import { AuthorizedFrontendRequestContext, IModelApp, MockRender } from "@bentley/imodeljs-frontend"; import { SettingsAdmin, SettingsResult, SettingsStatus } from "@bentley/product-settings-client"; import { UiSettingsStatus } from "@bentley/ui-core"; -import { IModelAppUiSettings, settingsStatusToUiSettingsStatus } from "../../ui-framework"; +import { settingsStatusToUiSettingsStatus, UserSettingsStorage } from "../../ui-framework"; import { TestUtils } from "../TestUtils"; -describe("IModelAppUiSettings", () => { +describe("UserSettingsStorage", () => { before(async () => { await TestUtils.initializeUiFramework(); await MockRender.App.startup(); @@ -30,7 +30,7 @@ describe("IModelAppUiSettings", () => { saveUserSetting, })); sinon.stub(IModelApp, "authorizationClient").get(() => ({ hasSignedIn: true })); - const sut = new IModelAppUiSettings(); + const sut = new UserSettingsStorage(); await sut.saveSetting("TESTNAMESPACE", "TESTNAME", "testvalue"); saveUserSetting.calledOnceWithExactly(sinon.match.any, "testvalue", "TESTNAMESPACE", "TESTNAME", true).should.true; }); @@ -41,7 +41,7 @@ describe("IModelAppUiSettings", () => { deleteUserSetting, })); sinon.stub(IModelApp, "authorizationClient").get(() => ({ hasSignedIn: true })); - const sut = new IModelAppUiSettings(); + const sut = new UserSettingsStorage(); await sut.deleteSetting("TESTNAMESPACE", "TESTNAME"); deleteUserSetting.calledOnceWithExactly(sinon.match.any, "TESTNAMESPACE", "TESTNAME", true).should.true; }); @@ -52,7 +52,7 @@ describe("IModelAppUiSettings", () => { getUserSetting, })); sinon.stub(IModelApp, "authorizationClient").get(() => ({ hasSignedIn: true })); - const sut = new IModelAppUiSettings(); + const sut = new UserSettingsStorage(); const settingResult = await sut.getSetting("TESTNAMESPACE", "TESTNAME"); getUserSetting.calledOnceWithExactly(sinon.match.any, "TESTNAMESPACE", "TESTNAME", true).should.true; settingResult.setting.should.eq("testvalue"); @@ -60,21 +60,21 @@ describe("IModelAppUiSettings", () => { it("should fail to save setting", async () => { sinon.stub(IModelApp, "authorizationClient").get(() => ({ hasSignedIn: false })); - const sut = new IModelAppUiSettings(); + const sut = new UserSettingsStorage(); const result = await sut.saveSetting("TESTNAMESPACE", "TESTNAME", "testvalue"); expect(result.status).to.eq(UiSettingsStatus.AuthorizationError); }); it("should fail to delete setting", async () => { sinon.stub(IModelApp, "authorizationClient").get(() => ({ hasSignedIn: false })); - const sut = new IModelAppUiSettings(); + const sut = new UserSettingsStorage(); const result = await sut.deleteSetting("TESTNAMESPACE", "TESTNAME"); expect(result.status).to.eq(UiSettingsStatus.AuthorizationError); }); it("should fail to get setting", async () => { sinon.stub(IModelApp, "authorizationClient").get(() => ({ hasSignedIn: false })); - const sut = new IModelAppUiSettings(); + const sut = new UserSettingsStorage(); const result = await sut.getSetting("TESTNAMESPACE", "TESTNAME"); expect(result.status).to.eq(UiSettingsStatus.AuthorizationError); }); diff --git a/ui/framework/src/test/utils/UiShowHideManager.test.tsx b/ui/framework/src/test/utils/UiShowHideManager.test.tsx index 65918d99681..0e29cab8d11 100644 --- a/ui/framework/src/test/utils/UiShowHideManager.test.tsx +++ b/ui/framework/src/test/utils/UiShowHideManager.test.tsx @@ -9,221 +9,268 @@ import { render } from "@testing-library/react"; import { ConfigurableCreateInfo, ContentControl, ContentGroup, ContentLayout, ContentLayoutDef, FrontstageManager, INACTIVITY_TIME_DEFAULT, UiFramework, UiShowHideManager, + UiShowHideSettingsProvider, } from "../../ui-framework"; import { TestFrontstage } from "../frontstage/FrontstageTestUtils"; -import TestUtils from "../TestUtils"; +import TestUtils, { storageMock } from "../TestUtils"; +import { LocalSettingsStorage } from "@bentley/ui-core"; -describe("UiShowHideManager", () => { +describe("UiShowHideManager localStorage Wrapper", () => { + + const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; + const localStorageMock = storageMock(); before(async () => { - await TestUtils.initializeUiFramework(); + Object.defineProperty(window, "localStorage", { + get: () => localStorageMock, + }); }); after(() => { - TestUtils.terminateUiFramework(); + Object.defineProperty(window, "localStorage", localStorageToRestore); }); - describe("getters and setters", () => { + describe("UiShowHideManager", () => { - it("autoHideUi should return default of false", () => { - expect(UiShowHideManager.autoHideUi).to.be.false; + before(async () => { + await TestUtils.initializeUiFramework(); }); - it("autoHideUi should set & return correct value", () => { - UiShowHideManager.autoHideUi = true; - expect(UiShowHideManager.autoHideUi).to.be.true; - UiShowHideManager.autoHideUi = false; - expect(UiShowHideManager.autoHideUi).to.be.false; + after(() => { + TestUtils.terminateUiFramework(); }); - it("showHidePanels should return default of false", () => { - expect(UiShowHideManager.showHidePanels).to.be.false; - }); + describe("getters and setters", () => { - it("showHidePanels should set & return correct value", () => { - const spyMethod = sinon.spy(); - const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); + it("autoHideUi should return default of false", () => { + expect(UiShowHideManager.autoHideUi).to.be.false; + }); - UiShowHideManager.showHidePanels = true; - expect(UiShowHideManager.showHidePanels).to.be.true; - spyMethod.calledOnce.should.true; + it("autoHideUi should set & return correct value", () => { + UiShowHideManager.autoHideUi = true; + expect(UiShowHideManager.autoHideUi).to.be.true; + UiShowHideManager.autoHideUi = false; + expect(UiShowHideManager.autoHideUi).to.be.false; + }); - UiShowHideManager.showHidePanels = false; - expect(UiShowHideManager.showHidePanels).to.be.false; - spyMethod.calledTwice.should.true; + it("showHidePanels should return default of false", () => { + expect(UiShowHideManager.showHidePanels).to.be.false; + }); - remove(); - }); + it("showHidePanels should set & return correct value", () => { + const spyMethod = sinon.spy(); + const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); - it("showHideFooter should return default of false", () => { - expect(UiShowHideManager.showHideFooter).to.be.false; - }); + UiShowHideManager.showHidePanels = true; + expect(UiShowHideManager.showHidePanels).to.be.true; + spyMethod.calledOnce.should.true; - it("showHideFooter should set & return correct value", () => { - const spyMethod = sinon.spy(); - const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); + UiShowHideManager.showHidePanels = false; + expect(UiShowHideManager.showHidePanels).to.be.false; + spyMethod.calledTwice.should.true; - UiShowHideManager.showHideFooter = true; - expect(UiShowHideManager.showHideFooter).to.be.true; - spyMethod.calledOnce.should.true; + remove(); + }); - UiShowHideManager.showHideFooter = false; - expect(UiShowHideManager.showHideFooter).to.be.false; - spyMethod.calledTwice.should.true; + it("showHideFooter should return default of false", () => { + expect(UiShowHideManager.showHideFooter).to.be.false; + }); - remove(); - }); + it("showHideFooter should set & return correct value", () => { + const spyMethod = sinon.spy(); + const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); - it("useProximityOpacity should return default of true", () => { - expect(UiShowHideManager.useProximityOpacity).to.be.true; - }); + UiShowHideManager.showHideFooter = true; + expect(UiShowHideManager.showHideFooter).to.be.true; + spyMethod.calledOnce.should.true; - it("useProximityOpacity should set & return correct value", () => { - const spyMethod = sinon.spy(); - const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); + UiShowHideManager.showHideFooter = false; + expect(UiShowHideManager.showHideFooter).to.be.false; + spyMethod.calledTwice.should.true; - UiShowHideManager.useProximityOpacity = false; - expect(UiShowHideManager.useProximityOpacity).to.be.false; - spyMethod.calledOnce.should.true; + remove(); + }); - UiShowHideManager.useProximityOpacity = true; - expect(UiShowHideManager.useProximityOpacity).to.be.true; - spyMethod.calledTwice.should.true; + it("useProximityOpacity should return default of true", () => { + expect(UiShowHideManager.useProximityOpacity).to.be.true; + }); - remove(); - }); + it("useProximityOpacity should set & return correct value", () => { + const spyMethod = sinon.spy(); + const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); - it("snapWidgetOpacity should return default of false", () => { - expect(UiShowHideManager.snapWidgetOpacity).to.be.false; - }); + UiShowHideManager.useProximityOpacity = false; + expect(UiShowHideManager.useProximityOpacity).to.be.false; + spyMethod.calledOnce.should.true; - it("snapWidgetOpacity should set & return correct value", () => { - const spyMethod = sinon.spy(); - const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); + UiShowHideManager.useProximityOpacity = true; + expect(UiShowHideManager.useProximityOpacity).to.be.true; + spyMethod.calledTwice.should.true; - UiShowHideManager.snapWidgetOpacity = true; - expect(UiShowHideManager.snapWidgetOpacity).to.be.true; - spyMethod.calledOnce.should.true; + remove(); + }); - UiShowHideManager.snapWidgetOpacity = false; - expect(UiShowHideManager.snapWidgetOpacity).to.be.false; - spyMethod.calledTwice.should.true; + it("snapWidgetOpacity should return default of false", () => { + expect(UiShowHideManager.snapWidgetOpacity).to.be.false; + }); - remove(); - }); + it("snapWidgetOpacity should set & return correct value", () => { + const spyMethod = sinon.spy(); + const remove = UiFramework.onUiVisibilityChanged.addListener(spyMethod); - it("inactivityTime should return default", () => { - expect(UiShowHideManager.inactivityTime).to.eq(INACTIVITY_TIME_DEFAULT); - }); + UiShowHideManager.snapWidgetOpacity = true; + expect(UiShowHideManager.snapWidgetOpacity).to.be.true; + spyMethod.calledOnce.should.true; - it("inactivityTime should set & return correct value", () => { - const testValue = 10000; - UiShowHideManager.inactivityTime = testValue; - expect(UiShowHideManager.inactivityTime).to.eq(testValue); + UiShowHideManager.snapWidgetOpacity = false; + expect(UiShowHideManager.snapWidgetOpacity).to.be.false; + spyMethod.calledTwice.should.true; + + remove(); + }); + + it("inactivityTime should return default", () => { + expect(UiShowHideManager.inactivityTime).to.eq(INACTIVITY_TIME_DEFAULT); + }); + + it("inactivityTime should set & return correct value", () => { + const testValue = 10000; + UiShowHideManager.inactivityTime = testValue; + expect(UiShowHideManager.inactivityTime).to.eq(testValue); + }); }); - }); - describe("Frontstage Activate", () => { + describe("Frontstage Activate", () => { - it("activating Frontstage should show UI", async () => { - UiFramework.setIsUiVisible(false); - expect(UiShowHideManager.isUiVisible).to.eq(false); - UiShowHideManager.autoHideUi = true; + it("activating Frontstage should show UI", async () => { + UiFramework.setIsUiVisible(false); + expect(UiShowHideManager.isUiVisible).to.eq(false); + UiShowHideManager.autoHideUi = true; - const frontstageProvider = new TestFrontstage(); - FrontstageManager.addFrontstageProvider(frontstageProvider); - await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); + const frontstageProvider = new TestFrontstage(); + FrontstageManager.addFrontstageProvider(frontstageProvider); + await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); - await TestUtils.flushAsyncOperations(); - expect(UiShowHideManager.isUiVisible).to.eq(true); + await TestUtils.flushAsyncOperations(); + expect(UiShowHideManager.isUiVisible).to.eq(true); + }); }); - }); - describe("Content Mouse Events", () => { + describe("Content Mouse Events", () => { - class TestContentControl extends ContentControl { - constructor(info: ConfigurableCreateInfo, options: any) { - super(info, options); + class TestContentControl extends ContentControl { + constructor(info: ConfigurableCreateInfo, options: any) { + super(info, options); - this.reactNode =
Test
; + this.reactNode =
Test
; + } } - } - const myContentGroup: ContentGroup = new ContentGroup({ - contents: [{ id: "myContent", classId: TestContentControl }], + const myContentGroup: ContentGroup = new ContentGroup({ + contents: [{ id: "myContent", classId: TestContentControl }], + }); + + const myContentLayout: ContentLayoutDef = new ContentLayoutDef({ + id: "SingleContent", + descriptionKey: "UiFramework:tests.singleContent", + priority: 100, + }); + + it("Mouse move in content view should show the UI then hide after inactivity", () => { + const fakeTimers = sinon.useFakeTimers(); + UiFramework.setIsUiVisible(false); + UiShowHideManager.autoHideUi = true; + UiShowHideManager.inactivityTime = 20; + expect(UiShowHideManager.isUiVisible).to.eq(false); + + const component = render(); + const container = component.getByTestId("single-content-container"); + container.dispatchEvent(new MouseEvent("mousemove", { bubbles: true, cancelable: true, view: window })); + + fakeTimers.tick(0); + expect(UiShowHideManager.isUiVisible).to.eq(true); + + fakeTimers.tick(1000); + fakeTimers.restore(); + expect(UiShowHideManager.isUiVisible).to.eq(false); + }); + + it("Mouse move in content view should do nothing if autoHideUi is off", async () => { + UiFramework.setIsUiVisible(false); + UiShowHideManager.autoHideUi = false; + expect(UiShowHideManager.isUiVisible).to.eq(false); + + const component = render(); + const container = component.getByTestId("single-content-container"); + container.dispatchEvent(new MouseEvent("mousemove", { bubbles: true, cancelable: true, view: window })); + + await TestUtils.flushAsyncOperations(); + expect(UiShowHideManager.isUiVisible).to.eq(false); + }); }); - const myContentLayout: ContentLayoutDef = new ContentLayoutDef({ - id: "SingleContent", - descriptionKey: "UiFramework:tests.singleContent", - priority: 100, - }); + describe("Widget Mouse Events", () => { + it("Mouse enter in widget should show the UI", async () => { + UiFramework.setIsUiVisible(false); + UiShowHideManager.autoHideUi = true; + expect(UiShowHideManager.isUiVisible).to.eq(false); - it("Mouse move in content view should show the UI then hide after inactivity", () => { - const fakeTimers = sinon.useFakeTimers(); - UiFramework.setIsUiVisible(false); - UiShowHideManager.autoHideUi = true; - UiShowHideManager.inactivityTime = 20; - expect(UiShowHideManager.isUiVisible).to.eq(false); + // const component = render(); + // const container = component.getByTestId("single-content-container"); + // container.dispatchEvent(new MouseEvent("mouseenter", { bubbles: true, cancelable: true, view: window })); - const component = render(); - const container = component.getByTestId("single-content-container"); - container.dispatchEvent(new MouseEvent("mousemove", { bubbles: true, cancelable: true, view: window })); + // TEMP + UiShowHideManager.handleWidgetMouseEnter(); - fakeTimers.tick(0); - expect(UiShowHideManager.isUiVisible).to.eq(true); + await TestUtils.flushAsyncOperations(); + expect(UiShowHideManager.isUiVisible).to.eq(true); + }); - fakeTimers.tick(1000); - fakeTimers.restore(); - expect(UiShowHideManager.isUiVisible).to.eq(false); - }); + it("Mouse enter in widget should do nothing if autoHideUi is off", async () => { + UiFramework.setIsUiVisible(false); + UiShowHideManager.autoHideUi = false; + expect(UiShowHideManager.isUiVisible).to.eq(false); - it("Mouse move in content view should do nothing if autoHideUi is off", async () => { - UiFramework.setIsUiVisible(false); - UiShowHideManager.autoHideUi = false; - expect(UiShowHideManager.isUiVisible).to.eq(false); + // const component = render(); + // const container = component.getByTestId("single-content-container"); + // container.dispatchEvent(new MouseEvent("mouseenter", { bubbles: true, cancelable: true, view: window })); - const component = render(); - const container = component.getByTestId("single-content-container"); - container.dispatchEvent(new MouseEvent("mousemove", { bubbles: true, cancelable: true, view: window })); + // TEMP + UiShowHideManager.handleWidgetMouseEnter(); - await TestUtils.flushAsyncOperations(); - expect(UiShowHideManager.isUiVisible).to.eq(false); + await TestUtils.flushAsyncOperations(); + expect(UiShowHideManager.isUiVisible).to.eq(false); + }); }); }); - describe("Widget Mouse Events", () => { - it("Mouse enter in widget should show the UI", async () => { - UiFramework.setIsUiVisible(false); - UiShowHideManager.autoHideUi = true; - expect(UiShowHideManager.isUiVisible).to.eq(false); + describe("UiShowHideSettingsProvider ", () => { - // const component = render(); - // const container = component.getByTestId("single-content-container"); - // container.dispatchEvent(new MouseEvent("mouseenter", { bubbles: true, cancelable: true, view: window })); + it("should get and set defaults", async () => { + const settingsStorage = new LocalSettingsStorage (); + await UiShowHideSettingsProvider.storeAutoHideUi(false, settingsStorage); + await UiShowHideSettingsProvider.storeUseProximityOpacity (false, settingsStorage); + await UiShowHideSettingsProvider.storeSnapWidgetOpacity(false, settingsStorage); + await TestUtils.initializeUiFramework(); - // TEMP - UiShowHideManager.handleWidgetMouseEnter(); + const uiShowHideSettingsProvider = new UiShowHideSettingsProvider (); + await uiShowHideSettingsProvider.loadUserSettings (UiFramework.getUiSettingsStorage()); - await TestUtils.flushAsyncOperations(); - expect(UiShowHideManager.isUiVisible).to.eq(true); - }); + expect(UiShowHideManager.autoHideUi).to.eq(false); + expect(UiShowHideManager.useProximityOpacity).to.eq(false); + expect(UiShowHideManager.snapWidgetOpacity).to.eq(false); - it("Mouse enter in widget should do nothing if autoHideUi is off", async () => { - UiFramework.setIsUiVisible(false); - UiShowHideManager.autoHideUi = false; - expect(UiShowHideManager.isUiVisible).to.eq(false); + UiShowHideManager.setAutoHideUi(true); + UiShowHideManager.setUseProximityOpacity(true); + UiShowHideManager.setSnapWidgetOpacity(true); + expect(UiShowHideManager.autoHideUi).to.eq(true); + expect(UiShowHideManager.useProximityOpacity).to.eq(true); + expect(UiShowHideManager.snapWidgetOpacity).to.eq(true); - // const component = render(); - // const container = component.getByTestId("single-content-container"); - // container.dispatchEvent(new MouseEvent("mouseenter", { bubbles: true, cancelable: true, view: window })); + TestUtils.terminateUiFramework(); - // TEMP - UiShowHideManager.handleWidgetMouseEnter(); - - await TestUtils.flushAsyncOperations(); - expect(UiShowHideManager.isUiVisible).to.eq(false); }); + }); }); diff --git a/ui/framework/src/test/widget-panels/Frontstage.test.snap b/ui/framework/src/test/widget-panels/Frontstage.test.snap index 4f927623ad0..5739ff675a7 100644 --- a/ui/framework/src/test/widget-panels/Frontstage.test.snap +++ b/ui/framework/src/test/widget-panels/Frontstage.test.snap @@ -109,6 +109,528 @@ exports[`ActiveFrontstageDefProvider should render 1`] = ` `; +exports[`Frontstage local storage wrapper ActiveFrontstageDefProvider should render 1`] = ` +
+ } + toolSettingsContent={} + widgetContent={} + > + + +
+`; + +exports[`Frontstage local storage wrapper WidgetPanelsFrontstage should not render w/o frontstage 1`] = `""`; + +exports[`Frontstage local storage wrapper WidgetPanelsFrontstage should render 1`] = ` + +`; + +exports[`Frontstage local storage wrapper WidgetPanelsFrontstage should render modal stage content 1`] = ` + +`; + +exports[`Frontstage local storage wrapper initializeNineZoneState should initialize widgets 1`] = ` +Object { + "draggedTab": undefined, + "floatingWidgets": Object { + "allIds": Array [], + "byId": Object {}, + }, + "panels": Object { + "bottom": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "bottom", + "size": undefined, + "span": true, + "widgets": Array [], + }, + "left": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "left", + "size": undefined, + "widgets": Array [], + }, + "right": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "right", + "size": undefined, + "widgets": Array [], + }, + "top": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "top", + "size": undefined, + "span": true, + "widgets": Array [], + }, + }, + "size": Object { + "height": 0, + "width": 0, + }, + "tabs": Object { + "nz-tool-settings-tab": Object { + "allowedPanelTargets": Array [ + "bottom", + "left", + "right", + ], + "id": "nz-tool-settings-tab", + "label": "Tool Settings", + }, + }, + "toolSettings": Object { + "type": "docked", + }, + "widgets": Object {}, +} +`; + +exports[`Frontstage local storage wrapper packNineZoneState should remove labels 1`] = ` +Object { + "draggedTab": undefined, + "floatingWidgets": Object { + "allIds": Array [ + "w1", + ], + "byId": Object { + "w1": Object { + "bounds": Object { + "bottom": 0, + "left": 0, + "right": 0, + "top": 0, + }, + "home": Object { + "side": "left", + "widgetId": undefined, + "widgetIndex": 0, + }, + "id": "w1", + }, + }, + }, + "panels": Object { + "bottom": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "bottom", + "size": undefined, + "span": true, + "widgets": Array [], + }, + "left": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "left", + "size": undefined, + "widgets": Array [], + }, + "right": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "right", + "size": undefined, + "widgets": Array [], + }, + "top": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "top", + "size": undefined, + "span": true, + "widgets": Array [], + }, + }, + "size": Object { + "height": 0, + "width": 0, + }, + "tabs": Object { + "t1": Object { + "allowedPanelTargets": undefined, + "id": "t1", + "preferredFloatingWidgetSize": undefined, + }, + }, + "toolSettings": Object { + "type": "docked", + }, + "widgets": Object { + "w1": Object { + "activeTabId": "t1", + "id": "w1", + "minimized": false, + "tabs": Array [ + "t1", + ], + }, + }, +} +`; + +exports[`Frontstage local storage wrapper restoreNineZoneState should log error if widgetDef is not found 1`] = ` +Object { + "frontstageId": "", + "tabId": "t1", +} +`; + +exports[`Frontstage local storage wrapper restoreNineZoneState should restore tabs 1`] = ` +Object { + "draggedTab": undefined, + "floatingWidgets": Object { + "allIds": Array [], + "byId": Object {}, + }, + "panels": Object { + "bottom": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "bottom", + "size": undefined, + "span": true, + "widgets": Array [], + }, + "left": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "left", + "size": undefined, + "widgets": Array [], + }, + "right": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "right", + "size": undefined, + "widgets": Array [], + }, + "top": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "top", + "size": undefined, + "span": true, + "widgets": Array [], + }, + }, + "size": Object { + "height": 0, + "width": 0, + }, + "tabs": Object { + "nz-tool-settings-tab": Object { + "allowedPanelTargets": Array [ + "bottom", + "left", + "right", + ], + "id": "nz-tool-settings-tab", + "label": "Tool Settings", + }, + "t1": Object { + "id": "t1", + "label": "Widget", + }, + }, + "toolSettings": Object { + "type": "docked", + }, + "widgets": Object {}, +} +`; + +exports[`Frontstage local storage wrapper useSavedFrontstageState should load saved nineZoneState 1`] = ` +Object { + "draggedTab": undefined, + "floatingWidgets": Object { + "allIds": Array [], + "byId": Object {}, + }, + "panels": Object { + "bottom": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "bottom", + "size": undefined, + "span": true, + "widgets": Array [], + }, + "left": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "left", + "size": undefined, + "widgets": Array [], + }, + "right": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 3, + "minSize": 200, + "pinned": true, + "resizable": true, + "side": "right", + "size": undefined, + "widgets": Array [], + }, + "top": Object { + "collapseOffset": 100, + "collapsed": false, + "maxSize": 600, + "maxWidgetCount": 2, + "minSize": 100, + "pinned": true, + "resizable": true, + "side": "top", + "size": undefined, + "span": true, + "widgets": Array [], + }, + }, + "size": Object { + "height": 0, + "width": 0, + }, + "tabs": Object { + "nz-tool-settings-tab": Object { + "allowedPanelTargets": Array [ + "bottom", + "left", + "right", + ], + "id": "nz-tool-settings-tab", + "label": "Tool Settings", + }, + }, + "toolSettings": Object { + "type": "docked", + }, + "widgets": Object {}, +} +`; + exports[`WidgetPanelsFrontstage should not render w/o frontstage 1`] = `""`; exports[`WidgetPanelsFrontstage should render 1`] = ` diff --git a/ui/framework/src/test/widget-panels/Frontstage.test.tsx b/ui/framework/src/test/widget-panels/Frontstage.test.tsx index ba166367966..9185d6481dc 100644 --- a/ui/framework/src/test/widget-panels/Frontstage.test.tsx +++ b/ui/framework/src/test/widget-panels/Frontstage.test.tsx @@ -337,84 +337,7 @@ export class TestUi2Provider implements UiItemsProvider { } } -describe("WidgetPanelsFrontstage", () => { - it("should render", () => { - const frontstageDef = new FrontstageDef(); - sinon.stub(FrontstageManager, "activeFrontstageDef").get(() => frontstageDef); - const wrapper = shallow(); - wrapper.should.matchSnapshot(); - }); - - it("should render modal stage content", () => { - const modalStageInfo = { - title: "TestModalStage", - content:
Hello World!
, - }; - sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => modalStageInfo); - const frontstageDef = new FrontstageDef(); - const contentGroup = moq.Mock.ofType(); - sinon.stub(FrontstageManager, "activeFrontstageDef").get(() => frontstageDef); - sinon.stub(frontstageDef, "contentGroup").get(() => contentGroup.object); - const wrapper = shallow(); - wrapper.should.matchSnapshot(); - }); - - it("should not render w/o frontstage", () => { - sinon.stub(FrontstageManager, "activeFrontstageDef").get(() => undefined); - const wrapper = shallow(); - wrapper.should.matchSnapshot(); - }); -}); - -describe("ModalFrontstageComposer", () => { - before(async () => { - await TestUtils.initializeUiFramework(); - }); - - after(() => { - TestUtils.terminateUiFramework(); - }); - - it("should render modal stage content when mounted", () => { - const modalStageInfo = { - title: "TestModalStage", - content:
Hello World!
, - }; - mount(); - }); - - it("should add tool activated event listener", () => { - const addListenerSpy = sinon.spy(FrontstageManager.onModalFrontstageChangedEvent, "addListener"); - const removeListenerSpy = sinon.spy(FrontstageManager.onModalFrontstageChangedEvent, "removeListener"); - const sut = renderHook(() => useActiveModalFrontstageInfo()); - sut.unmount(); - addListenerSpy.calledOnce.should.true; - removeListenerSpy.calledOnce.should.true; - }); - - it("should update active modal info", () => { - const modalStageInfo = { - title: "TestModalStage", - content:
Hello World!
, - }; - - sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => undefined); - renderHook(() => useActiveModalFrontstageInfo()); - act(() => { - sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => undefined); - FrontstageManager.onModalFrontstageChangedEvent.emit({ - modalFrontstageCount: 0, - }); - - sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => modalStageInfo); - FrontstageManager.onModalFrontstageChangedEvent.emit({ - modalFrontstageCount: 1, - }); - }); - }); -}); - -describe("ActiveFrontstageDefProvider", () => { +describe("Frontstage local storage wrapper", () => { const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; const localStorageMock = storageMock(); @@ -422,1539 +345,1615 @@ describe("ActiveFrontstageDefProvider", () => { Object.defineProperty(window, "localStorage", { get: () => localStorageMock, }); - - await TestUtils.initializeUiFramework(); }); after(() => { Object.defineProperty(window, "localStorage", localStorageToRestore); - TestUtils.terminateUiFramework(); }); - beforeEach(() => { - sinon.stub(FrontstageManager, "nineZoneSize").set(() => { }); - }); + describe("WidgetPanelsFrontstage", () => { + it("should render", () => { + const frontstageDef = new FrontstageDef(); + sinon.stub(FrontstageManager, "activeFrontstageDef").get(() => frontstageDef); + const wrapper = shallow(); + wrapper.should.matchSnapshot(); + }); + + it("should render modal stage content", () => { + const modalStageInfo = { + title: "TestModalStage", + content:
Hello World!
, + }; + sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => modalStageInfo); + const frontstageDef = new FrontstageDef(); + const contentGroup = moq.Mock.ofType(); + sinon.stub(FrontstageManager, "activeFrontstageDef").get(() => frontstageDef); + sinon.stub(frontstageDef, "contentGroup").get(() => contentGroup.object); + const wrapper = shallow(); + wrapper.should.matchSnapshot(); + }); - it("should render", () => { - const frontstageDef = new FrontstageDef(); - const wrapper = shallow(); - wrapper.should.matchSnapshot(); + it("should not render w/o frontstage", () => { + sinon.stub(FrontstageManager, "activeFrontstageDef").get(() => undefined); + const wrapper = shallow(); + wrapper.should.matchSnapshot(); + }); }); - it("should fall back to cached NineZoneState", () => { - const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = createNineZoneState(); + describe("ModalFrontstageComposer", () => { + before(async () => { + await TestUtils.initializeUiFramework(); + }); - const newFrontstageDef = new FrontstageDef(); - newFrontstageDef.nineZoneState = undefined; + after(() => { + TestUtils.terminateUiFramework(); + }); - const wrapper = mount<{ frontstageDef: FrontstageDef }>(); - wrapper.setProps({ frontstageDef: newFrontstageDef }); + it("should render modal stage content when mounted", () => { + const modalStageInfo = { + title: "TestModalStage", + content:
Hello World!
, + }; + mount(); + }); - const nineZone = wrapper.find(NineZone); - nineZone.prop("state").should.eq(frontstageDef.nineZoneState); - }); -}); + it("should add tool activated event listener", () => { + const addListenerSpy = sinon.spy(FrontstageManager.onModalFrontstageChangedEvent, "addListener"); + const removeListenerSpy = sinon.spy(FrontstageManager.onModalFrontstageChangedEvent, "removeListener"); + const sut = renderHook(() => useActiveModalFrontstageInfo()); + sut.unmount(); + addListenerSpy.calledOnce.should.true; + removeListenerSpy.calledOnce.should.true; + }); -describe("useNineZoneDispatch", () => { - beforeEach(() => { - sinon.stub(FrontstageManager, "nineZoneSize").set(() => { }); - }); + it("should update active modal info", () => { + const modalStageInfo = { + title: "TestModalStage", + content:
Hello World!
, + }; - it("should modify nineZoneState with default NineZoneReducer", () => { - const frontstageDef = new FrontstageDef(); - const nineZoneState = createNineZoneState(); - frontstageDef.nineZoneState = nineZoneState; - const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); - result.current({ - type: "PANEL_INITIALIZE", - side: "left", - size: 200, - }); - frontstageDef.nineZoneState.should.not.eq(nineZoneState); - (frontstageDef.nineZoneState.panels.left.size === 200).should.true; + sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => undefined); + renderHook(() => useActiveModalFrontstageInfo()); + act(() => { + sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => undefined); + FrontstageManager.onModalFrontstageChangedEvent.emit({ + modalFrontstageCount: 0, + }); + + sinon.stub(FrontstageManager, "activeModalFrontstage").get(() => modalStageInfo); + FrontstageManager.onModalFrontstageChangedEvent.emit({ + modalFrontstageCount: 1, + }); + }); + }); }); - it("should not modify when nineZoneState is not defined", () => { - const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = undefined; - const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); - result.current({ - type: "PANEL_INITIALIZE", - side: "left", - size: 200, + describe("ActiveFrontstageDefProvider", () => { + before(async () => { + await TestUtils.initializeUiFramework(); }); - (frontstageDef.nineZoneState === undefined).should.true; - }); - it("should set nineZoneSize when RESIZE is received", () => { - const spy = sinon.stub(FrontstageManager, "nineZoneSize").set(() => { }); - const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = createNineZoneState(); - const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); - result.current({ - type: "RESIZE", - size: { - width: 5, - height: 10, - }, - }); - spy.calledOnceWithExactly(sinon.match({ width: 5, height: 10 })); - }); + after(() => { + TestUtils.terminateUiFramework(); + }); - it("should set vertical (left/right) panel max size from percentage spec", () => { - const frontstageDef = new FrontstageDef(); - const panel = new StagePanelDef(); - sinon.stub(panel, "maxSizeSpec").get(() => ({ percentage: 50 })); - sinon.stub(frontstageDef, "leftPanel").get(() => panel); - frontstageDef.nineZoneState = createNineZoneState(); - const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); - result.current({ - type: "RESIZE", - size: { - height: 200, - width: 500, - }, - }); - frontstageDef.nineZoneState.panels.left.maxSize.should.eq(250); - }); + beforeEach(() => { + sinon.stub(FrontstageManager, "nineZoneSize").set(() => { }); + }); - it("should set horizontal (top/bottom) panel max size from percentage spec", () => { - const frontstageDef = new FrontstageDef(); - const panel = new StagePanelDef(); - sinon.stub(panel, "maxSizeSpec").get(() => ({ percentage: 50 })); - sinon.stub(frontstageDef, "topPanel").get(() => panel); - frontstageDef.nineZoneState = createNineZoneState(); - const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); - result.current({ - type: "RESIZE", - size: { - height: 200, - width: 500, - }, - }); - frontstageDef.nineZoneState.panels.top.maxSize.should.eq(100); - }); + it("should render", () => { + const frontstageDef = new FrontstageDef(); + const wrapper = shallow(); + wrapper.should.matchSnapshot(); + }); - it("should update panel size", () => { - const frontstageDef = new FrontstageDef(); - const panel = new StagePanelDef(); - sinon.stub(panel, "maxSizeSpec").get(() => 250); - sinon.stub(frontstageDef, "leftPanel").get(() => panel); - - let state = createNineZoneState(); - state = produce(state, (draft) => { - draft.panels.left.size = 300; - }); - frontstageDef.nineZoneState = state; - const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); - result.current({ - type: "RESIZE", - size: { - height: 200, - width: 500, - }, - }); - frontstageDef.nineZoneState.panels.left.size!.should.eq(250); - }); -}); + it("should fall back to cached NineZoneState", () => { + const frontstageDef = new FrontstageDef(); + frontstageDef.nineZoneState = createNineZoneState(); -describe("useNineZoneState", () => { - it("should return initial nineZoneState", () => { - const frontstageDef = new FrontstageDef(); - const nineZoneState = createNineZoneState(); - frontstageDef.nineZoneState = nineZoneState; - const { result } = renderHook(() => useNineZoneState(frontstageDef)); - nineZoneState.should.eq(result.current); - }); + const newFrontstageDef = new FrontstageDef(); + newFrontstageDef.nineZoneState = undefined; - it("should return nineZoneState of provided frontstageDef", () => { - const frontstageDef = new FrontstageDef(); - const nineZoneState = createNineZoneState(); - frontstageDef.nineZoneState = nineZoneState; - const newFrontstageDef = new FrontstageDef(); - const newNineZoneState = createNineZoneState(); - newFrontstageDef.nineZoneState = newNineZoneState; - const { result, rerender } = renderHook((def: FrontstageDef) => useNineZoneState(def), { - initialProps: frontstageDef, - }); - rerender(newFrontstageDef); - newNineZoneState.should.eq(result.current); - }); + const wrapper = mount<{ frontstageDef: FrontstageDef }>(); + wrapper.setProps({ frontstageDef: newFrontstageDef }); - it("should return updated nineZoneState", () => { - const frontstageDef = new FrontstageDef(); - const nineZoneState = createNineZoneState(); - const newNineZoneState = createNineZoneState(); - frontstageDef.nineZoneState = nineZoneState; - const { result } = renderHook(() => useNineZoneState(frontstageDef)); - act(() => { - frontstageDef.nineZoneState = newNineZoneState; + const nineZone = wrapper.find(NineZone); + nineZone.prop("state").should.eq(frontstageDef.nineZoneState); }); - newNineZoneState.should.eq(result.current); }); - it("should ignore nineZoneState changes of other frontstages", () => { - const frontstageDef = new FrontstageDef(); - const nineZoneState = createNineZoneState(); - const newNineZoneState = createNineZoneState(); - frontstageDef.nineZoneState = nineZoneState; - const { result } = renderHook(() => useNineZoneState(frontstageDef)); - act(() => { - (new FrontstageDef()).nineZoneState = newNineZoneState; + describe("useNineZoneDispatch", () => { + beforeEach(() => { + sinon.stub(FrontstageManager, "nineZoneSize").set(() => { }); }); - nineZoneState.should.eq(result.current); - }); -}); -describe("useSavedFrontstageState", () => { - it("should load saved nineZoneState", async () => { - const setting = createFrontstageState(); - const uiSettings = new UiSettingsStub(); - sinon.stub(uiSettings, "getSetting").resolves({ - status: UiSettingsStatus.Success, - setting, - }); - const frontstageDef = new FrontstageDef(); - renderHook(() => useSavedFrontstageState(frontstageDef), { - wrapper: (props) => , + it("should modify nineZoneState with default NineZoneReducer", () => { + const frontstageDef = new FrontstageDef(); + const nineZoneState = createNineZoneState(); + frontstageDef.nineZoneState = nineZoneState; + const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); + result.current({ + type: "PANEL_INITIALIZE", + side: "left", + size: 200, + }); + frontstageDef.nineZoneState.should.not.eq(nineZoneState); + (frontstageDef.nineZoneState.panels.left.size === 200).should.true; }); - await TestUtils.flushAsyncOperations(); - frontstageDef.nineZoneState?.should.matchSnapshot(); - }); - it("should not load nineZoneState when nineZoneState is already initialized", async () => { - const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = createNineZoneState(); - const uiSettings = new UiSettingsStub(); - const spy = sinon.spy(uiSettings, "getSetting"); - renderHook(() => useSavedFrontstageState(frontstageDef), { - wrapper: (props) => , + it("should not modify when nineZoneState is not defined", () => { + const frontstageDef = new FrontstageDef(); + frontstageDef.nineZoneState = undefined; + const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); + result.current({ + type: "PANEL_INITIALIZE", + side: "left", + size: 200, + }); + (frontstageDef.nineZoneState === undefined).should.true; }); - spy.notCalled.should.true; - }); - it("should initialize nineZoneState", async () => { - const setting = createFrontstageState(); - const uiSettings = new UiSettingsStub(); - sinon.stub(uiSettings, "getSetting").returns(Promise.resolve({ - status: UiSettingsStatus.Success, - setting, - })); - const frontstageDef = new FrontstageDef(); - sinon.stub(frontstageDef, "version").get(() => setting.version + 1); - renderHook(() => useSavedFrontstageState(frontstageDef), { - wrapper: (props) => , - }); - await TestUtils.flushAsyncOperations(); - (frontstageDef.nineZoneState !== undefined).should.true; - frontstageDef.nineZoneState!.should.not.eq(setting.nineZone); - }); - - it("should add missing widgets", async () => { - const setting = createFrontstageState(); - const uiSettings = new UiSettingsStub(); - sinon.stub(uiSettings, "getSetting").resolves({ - status: UiSettingsStatus.Success, - setting, - }); - const frontstageDef = new FrontstageDef(); - const leftPanel = new StagePanelDef(); - leftPanel.initializeFromProps({ - resizable: true, - widgets: [ - , - ], - }, StagePanelLocation.Left); - sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); - - renderHook(() => useSavedFrontstageState(frontstageDef), { - wrapper: (props) => , - }); - await TestUtils.flushAsyncOperations(); - - should().exist(frontstageDef.nineZoneState?.tabs.w1); - }); -}); - -describe("useSaveFrontstageSettings", () => { - it("should save frontstage settings", () => { - const fakeTimers = sinon.useFakeTimers(); - const uiSettings = new UiSettingsStub(); - const spy = sinon.stub(uiSettings, "saveSetting").resolves({ - status: UiSettingsStatus.Success, - }); - const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = createNineZoneState(); - renderHook(() => useSaveFrontstageSettings(frontstageDef), { - wrapper: (props) => , + it("should set nineZoneSize when RESIZE is received", () => { + const spy = sinon.stub(FrontstageManager, "nineZoneSize").set(() => { }); + const frontstageDef = new FrontstageDef(); + frontstageDef.nineZoneState = createNineZoneState(); + const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); + result.current({ + type: "RESIZE", + size: { + width: 5, + height: 10, + }, + }); + spy.calledOnceWithExactly(sinon.match({ width: 5, height: 10 })); }); - fakeTimers.tick(1000); - fakeTimers.restore(); - - spy.calledOnce.should.true; - }); - it("should not save if tab is dragged", () => { - const fakeTimers = sinon.useFakeTimers(); - const uiSettings = new UiSettingsStub(); - const spy = sinon.stub(uiSettings, "saveSetting").resolves({ - status: UiSettingsStatus.Success, - }); - const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = produce(createNineZoneState(), (draft) => { - draft.draggedTab = createDraggedTabState("t1"); + it("should set vertical (left/right) panel max size from percentage spec", () => { + const frontstageDef = new FrontstageDef(); + const panel = new StagePanelDef(); + sinon.stub(panel, "maxSizeSpec").get(() => ({ percentage: 50 })); + sinon.stub(frontstageDef, "leftPanel").get(() => panel); + frontstageDef.nineZoneState = createNineZoneState(); + const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); + result.current({ + type: "RESIZE", + size: { + height: 200, + width: 500, + }, + }); + frontstageDef.nineZoneState.panels.left.maxSize.should.eq(250); }); - renderHook(() => useSaveFrontstageSettings(frontstageDef), { - wrapper: (props) => , + + it("should set horizontal (top/bottom) panel max size from percentage spec", () => { + const frontstageDef = new FrontstageDef(); + const panel = new StagePanelDef(); + sinon.stub(panel, "maxSizeSpec").get(() => ({ percentage: 50 })); + sinon.stub(frontstageDef, "topPanel").get(() => panel); + frontstageDef.nineZoneState = createNineZoneState(); + const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); + result.current({ + type: "RESIZE", + size: { + height: 200, + width: 500, + }, + }); + frontstageDef.nineZoneState.panels.top.maxSize.should.eq(100); }); - fakeTimers.tick(1000); - fakeTimers.restore(); - spy.notCalled.should.true; - }); -}); + it("should update panel size", () => { + const frontstageDef = new FrontstageDef(); + const panel = new StagePanelDef(); + sinon.stub(panel, "maxSizeSpec").get(() => 250); + sinon.stub(frontstageDef, "leftPanel").get(() => panel); -describe("useFrontstageManager", () => { - it("should not handle onWidgetStateChangedEvent when nineZoneState is unset", () => { - const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = undefined; - renderHook(() => useFrontstageManager(frontstageDef)); - const widgetDef = new WidgetDef({}); - FrontstageManager.onWidgetStateChangedEvent.emit({ - widgetDef, - widgetState: WidgetState.Open, - }); - (frontstageDef.nineZoneState === undefined).should.true; + let state = createNineZoneState(); + state = produce(state, (draft) => { + draft.panels.left.size = 300; + }); + frontstageDef.nineZoneState = state; + const { result } = renderHook(() => useNineZoneDispatch(frontstageDef)); + result.current({ + type: "RESIZE", + size: { + height: 200, + width: 500, + }, + }); + frontstageDef.nineZoneState.panels.left.size!.should.eq(250); + }); }); - it("should handle onWidgetStateChangedEvent", () => { - const frontstageDef = new FrontstageDef(); - let nineZoneState = createNineZoneState(); - nineZoneState = addPanelWidget(nineZoneState, "left", "w1", ["t1"]); - nineZoneState = addPanelWidget(nineZoneState, "left", "w2", ["t2"]); - nineZoneState = addTab(nineZoneState, "t1"); - frontstageDef.nineZoneState = nineZoneState; - renderHook(() => useFrontstageManager(frontstageDef)); - const widgetDef = new WidgetDef({ - id: "t1", - }); - FrontstageManager.onWidgetStateChangedEvent.emit({ - widgetDef, - widgetState: WidgetState.Closed, - }); - frontstageDef.nineZoneState.widgets.w1.minimized.should.true; - }); + describe("useNineZoneState", () => { + it("should return initial nineZoneState", () => { + const frontstageDef = new FrontstageDef(); + const nineZoneState = createNineZoneState(); + frontstageDef.nineZoneState = nineZoneState; + const { result } = renderHook(() => useNineZoneState(frontstageDef)); + nineZoneState.should.eq(result.current); + }); - it("should handle onWidgetShowEvent", () => { - const frontstageDef = new FrontstageDef(); - let nineZoneState = createNineZoneState(); - nineZoneState = addPanelWidget(nineZoneState, "left", "w1", ["t1"]); - nineZoneState = addTab(nineZoneState, "t1"); - nineZoneState = produce(nineZoneState, (draft) => { - draft.panels.left.collapsed = true; + it("should return nineZoneState of provided frontstageDef", () => { + const frontstageDef = new FrontstageDef(); + const nineZoneState = createNineZoneState(); + frontstageDef.nineZoneState = nineZoneState; + const newFrontstageDef = new FrontstageDef(); + const newNineZoneState = createNineZoneState(); + newFrontstageDef.nineZoneState = newNineZoneState; + const { result, rerender } = renderHook((def: FrontstageDef) => useNineZoneState(def), { + initialProps: frontstageDef, + }); + rerender(newFrontstageDef); + newNineZoneState.should.eq(result.current); }); - frontstageDef.nineZoneState = nineZoneState; - renderHook(() => useFrontstageManager(frontstageDef)); - const widgetDef = new WidgetDef({ - id: "t1", + + it("should return updated nineZoneState", () => { + const frontstageDef = new FrontstageDef(); + const nineZoneState = createNineZoneState(); + const newNineZoneState = createNineZoneState(); + frontstageDef.nineZoneState = nineZoneState; + const { result } = renderHook(() => useNineZoneState(frontstageDef)); + act(() => { + frontstageDef.nineZoneState = newNineZoneState; + }); + newNineZoneState.should.eq(result.current); }); - FrontstageManager.onWidgetShowEvent.emit({ - widgetDef, + + it("should ignore nineZoneState changes of other frontstages", () => { + const frontstageDef = new FrontstageDef(); + const nineZoneState = createNineZoneState(); + const newNineZoneState = createNineZoneState(); + frontstageDef.nineZoneState = nineZoneState; + const { result } = renderHook(() => useNineZoneState(frontstageDef)); + act(() => { + (new FrontstageDef()).nineZoneState = newNineZoneState; + }); + nineZoneState.should.eq(result.current); }); - frontstageDef.nineZoneState.panels.left.collapsed.should.false; }); - it("should handle onWidgetExpandEvent", () => { - const frontstageDef = new FrontstageDef(); - let nineZoneState = createNineZoneState(); - nineZoneState = addPanelWidget(nineZoneState, "left", "w1", ["t1"], { minimized: true }); - nineZoneState = addPanelWidget(nineZoneState, "left", "w2", ["t2"]); - nineZoneState = addTab(nineZoneState, "t1"); - frontstageDef.nineZoneState = nineZoneState; - renderHook(() => useFrontstageManager(frontstageDef)); - const widgetDef = new WidgetDef({ - id: "t1", - }); - FrontstageManager.onWidgetExpandEvent.emit({ - widgetDef, - }); - frontstageDef.nineZoneState.widgets.w1.minimized.should.false; - }); + describe("useSavedFrontstageState", () => { + it("should load saved nineZoneState", async () => { + const setting = createFrontstageState(); + const uiSettings = new UiSettingsStub(); + sinon.stub(uiSettings, "getSetting").resolves({ + status: UiSettingsStatus.Success, + setting, + }); + const frontstageDef = new FrontstageDef(); + renderHook(() => useSavedFrontstageState(frontstageDef), { + wrapper: (props) => , + }); + await TestUtils.flushAsyncOperations(); + frontstageDef.nineZoneState?.should.matchSnapshot(); + }); - describe("onFrontstageRestoreLayoutEvent", () => { - it("should delete saved setting", () => { + it("should not load nineZoneState when nineZoneState is already initialized", async () => { const frontstageDef = new FrontstageDef(); frontstageDef.nineZoneState = createNineZoneState(); const uiSettings = new UiSettingsStub(); - const spy = sinon.spy(uiSettings, "deleteSetting"); - renderHook(() => useFrontstageManager(frontstageDef), { - wrapper: (props) => , + const spy = sinon.spy(uiSettings, "getSetting"); + renderHook(() => useSavedFrontstageState(frontstageDef), { + wrapper: (props) => , + }); + spy.notCalled.should.true; + }); + + it("should initialize nineZoneState", async () => { + const setting = createFrontstageState(); + const uiSettings = new UiSettingsStub(); + sinon.stub(uiSettings, "getSetting").returns(Promise.resolve({ + status: UiSettingsStatus.Success, + setting, + })); + const frontstageDef = new FrontstageDef(); + sinon.stub(frontstageDef, "version").get(() => setting.version + 1); + renderHook(() => useSavedFrontstageState(frontstageDef), { + wrapper: (props) => , + }); + await TestUtils.flushAsyncOperations(); + (frontstageDef.nineZoneState !== undefined).should.true; + frontstageDef.nineZoneState!.should.not.eq(setting.nineZone); + }); + + it("should add missing widgets", async () => { + const setting = createFrontstageState(); + const uiSettings = new UiSettingsStub(); + sinon.stub(uiSettings, "getSetting").resolves({ + status: UiSettingsStatus.Success, + setting, }); - FrontstageManager.onFrontstageRestoreLayoutEvent.emit({ - frontstageDef, + const frontstageDef = new FrontstageDef(); + const leftPanel = new StagePanelDef(); + leftPanel.initializeFromProps({ + resizable: true, + widgets: [ + , + ], + }, StagePanelLocation.Left); + sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); + + renderHook(() => useSavedFrontstageState(frontstageDef), { + wrapper: (props) => , }); - spy.calledOnce.should.true; + await TestUtils.flushAsyncOperations(); + + should().exist(frontstageDef.nineZoneState?.tabs.w1); }); + }); - it("should unset nineZoneState", () => { + describe("useSaveFrontstageSettings", () => { + it("should save frontstage settings", () => { + const fakeTimers = sinon.useFakeTimers(); + const uiSettings = new UiSettingsStub(); + const spy = sinon.stub(uiSettings, "saveSetting").resolves({ + status: UiSettingsStatus.Success, + }); const frontstageDef = new FrontstageDef(); frontstageDef.nineZoneState = createNineZoneState(); + renderHook(() => useSaveFrontstageSettings(frontstageDef), { + wrapper: (props) => , + }); + fakeTimers.tick(1000); + fakeTimers.restore(); + + spy.calledOnce.should.true; + }); + + it("should not save if tab is dragged", () => { + const fakeTimers = sinon.useFakeTimers(); const uiSettings = new UiSettingsStub(); - renderHook(() => useFrontstageManager(frontstageDef), { - wrapper: (props) => , + const spy = sinon.stub(uiSettings, "saveSetting").resolves({ + status: UiSettingsStatus.Success, }); - const frontstageDef1 = new FrontstageDef(); - sinon.stub(frontstageDef1, "id").get(() => "f1"); - frontstageDef1.nineZoneState = createNineZoneState(); - FrontstageManager.onFrontstageRestoreLayoutEvent.emit({ - frontstageDef: frontstageDef1, + const frontstageDef = new FrontstageDef(); + frontstageDef.nineZoneState = produce(createNineZoneState(), (draft) => { + draft.draggedTab = createDraggedTabState("t1"); + }); + renderHook(() => useSaveFrontstageSettings(frontstageDef), { + wrapper: (props) => , }); - (frontstageDef1.nineZoneState === undefined).should.true; + fakeTimers.tick(1000); + fakeTimers.restore(); + + spy.notCalled.should.true; }); }); - describe("onWidgetLabelChangedEvent", () => { - it("should update tab label", () => { + describe("useFrontstageManager", () => { + it("should not handle onWidgetStateChangedEvent when nineZoneState is unset", () => { const frontstageDef = new FrontstageDef(); - let state = createNineZoneState(); - state = addPanelWidget(state, "left", "w1", ["t1"]); - state = addTab(state, "t1"); - frontstageDef.nineZoneState = state; - const widgetDef = new WidgetDef({ id: "t1" }); + frontstageDef.nineZoneState = undefined; renderHook(() => useFrontstageManager(frontstageDef)); - - sinon.stub(widgetDef, "label").get(() => "test"); - FrontstageManager.onWidgetLabelChangedEvent.emit({ + const widgetDef = new WidgetDef({}); + FrontstageManager.onWidgetStateChangedEvent.emit({ widgetDef, + widgetState: WidgetState.Open, }); + (frontstageDef.nineZoneState === undefined).should.true; + }); - frontstageDef.nineZoneState.tabs.t1.label.should.eq("test"); + it("should handle onWidgetStateChangedEvent", () => { + const frontstageDef = new FrontstageDef(); + let nineZoneState = createNineZoneState(); + nineZoneState = addPanelWidget(nineZoneState, "left", "w1", ["t1"]); + nineZoneState = addPanelWidget(nineZoneState, "left", "w2", ["t2"]); + nineZoneState = addTab(nineZoneState, "t1"); + frontstageDef.nineZoneState = nineZoneState; + renderHook(() => useFrontstageManager(frontstageDef)); + const widgetDef = new WidgetDef({ + id: "t1", + }); + FrontstageManager.onWidgetStateChangedEvent.emit({ + widgetDef, + widgetState: WidgetState.Closed, + }); + frontstageDef.nineZoneState.widgets.w1.minimized.should.true; }); - it("should not fail if tab doesn't exist", () => { + it("should handle onWidgetShowEvent", () => { const frontstageDef = new FrontstageDef(); - frontstageDef.nineZoneState = createNineZoneState(); - const widgetDef = new WidgetDef({ id: "t1" }); + let nineZoneState = createNineZoneState(); + nineZoneState = addPanelWidget(nineZoneState, "left", "w1", ["t1"]); + nineZoneState = addTab(nineZoneState, "t1"); + nineZoneState = produce(nineZoneState, (draft) => { + draft.panels.left.collapsed = true; + }); + frontstageDef.nineZoneState = nineZoneState; renderHook(() => useFrontstageManager(frontstageDef)); + const widgetDef = new WidgetDef({ + id: "t1", + }); + FrontstageManager.onWidgetShowEvent.emit({ + widgetDef, + }); + frontstageDef.nineZoneState.panels.left.collapsed.should.false; + }); - sinon.stub(widgetDef, "label").get(() => "test"); + it("should handle onWidgetExpandEvent", () => { + const frontstageDef = new FrontstageDef(); + let nineZoneState = createNineZoneState(); + nineZoneState = addPanelWidget(nineZoneState, "left", "w1", ["t1"], { minimized: true }); + nineZoneState = addPanelWidget(nineZoneState, "left", "w2", ["t2"]); + nineZoneState = addTab(nineZoneState, "t1"); + frontstageDef.nineZoneState = nineZoneState; + renderHook(() => useFrontstageManager(frontstageDef)); + const widgetDef = new WidgetDef({ + id: "t1", + }); + FrontstageManager.onWidgetExpandEvent.emit({ + widgetDef, + }); + frontstageDef.nineZoneState.widgets.w1.minimized.should.false; + }); + + describe("onFrontstageRestoreLayoutEvent", () => { + it("should delete saved setting", () => { + const frontstageDef = new FrontstageDef(); + frontstageDef.nineZoneState = createNineZoneState(); + const uiSettings = new UiSettingsStub(); + const spy = sinon.spy(uiSettings, "deleteSetting"); + renderHook(() => useFrontstageManager(frontstageDef), { + wrapper: (props) => , + }); + FrontstageManager.onFrontstageRestoreLayoutEvent.emit({ + frontstageDef, + }); + spy.calledOnce.should.true; + }); - (() => { - FrontstageManager.onWidgetLabelChangedEvent.emit({ widgetDef }); - }).should.not.throw(); + it("should unset nineZoneState", () => { + const frontstageDef = new FrontstageDef(); + frontstageDef.nineZoneState = createNineZoneState(); + const uiSettings = new UiSettingsStub(); + renderHook(() => useFrontstageManager(frontstageDef), { + wrapper: (props) => , + }); + const frontstageDef1 = new FrontstageDef(); + sinon.stub(frontstageDef1, "id").get(() => "f1"); + frontstageDef1.nineZoneState = createNineZoneState(); + FrontstageManager.onFrontstageRestoreLayoutEvent.emit({ + frontstageDef: frontstageDef1, + }); + (frontstageDef1.nineZoneState === undefined).should.true; + }); }); - }); -}); -describe("useSyncDefinitions", () => { - it("should set panel widget state to Open", () => { - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); - const widgetDef = new WidgetDef({}); - sinon.stub(widgetDef, "id").get(() => "t1"); - const spy = sinon.spy(widgetDef, "setWidgetState"); - zoneDef.addWidgetDef(widgetDef); - renderHook(() => useSyncDefinitions(frontstageDef)); - act(() => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - frontstageDef.nineZoneState = nineZone; - }); - spy.calledOnceWithExactly(WidgetState.Open).should.true; - }); + describe("onWidgetLabelChangedEvent", () => { + it("should update tab label", () => { + const frontstageDef = new FrontstageDef(); + let state = createNineZoneState(); + state = addPanelWidget(state, "left", "w1", ["t1"]); + state = addTab(state, "t1"); + frontstageDef.nineZoneState = state; + const widgetDef = new WidgetDef({ id: "t1" }); + renderHook(() => useFrontstageManager(frontstageDef)); - it("should set panel widget state to Closed", () => { - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); - const widgetDef = new WidgetDef({}); - sinon.stub(widgetDef, "id").get(() => "t1"); - const spy = sinon.spy(widgetDef, "setWidgetState"); - zoneDef.addWidgetDef(widgetDef); - renderHook(() => useSyncDefinitions(frontstageDef)); - act(() => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1", "t2"], { activeTabId: "t2" }); - nineZone = addTab(nineZone, "t1"); - nineZone = addTab(nineZone, "t2"); - frontstageDef.nineZoneState = nineZone; - }); - spy.calledOnceWithExactly(WidgetState.Closed).should.true; - }); + sinon.stub(widgetDef, "label").get(() => "test"); + FrontstageManager.onWidgetLabelChangedEvent.emit({ + widgetDef, + }); - it("should set StagePanelDef size", () => { - const frontstageDef = new FrontstageDef(); - const rightPanel = new StagePanelDef(); - sinon.stub(frontstageDef, "rightPanel").get(() => rightPanel); - const spy = sinon.spy(rightPanel, "size", ["set"]); - renderHook(() => useSyncDefinitions(frontstageDef)); - act(() => { - let nineZone = createNineZoneState(); - nineZone = produce(nineZone, (draft) => { - draft.panels.right.size = 234; + frontstageDef.nineZoneState.tabs.t1.label.should.eq("test"); + }); + + it("should not fail if tab doesn't exist", () => { + const frontstageDef = new FrontstageDef(); + frontstageDef.nineZoneState = createNineZoneState(); + const widgetDef = new WidgetDef({ id: "t1" }); + renderHook(() => useFrontstageManager(frontstageDef)); + + sinon.stub(widgetDef, "label").get(() => "test"); + + (() => { + FrontstageManager.onWidgetLabelChangedEvent.emit({ widgetDef }); + }).should.not.throw(); }); - frontstageDef.nineZoneState = nineZone; }); - sinon.assert.calledOnceWithExactly(spy.set, 234); }); - it("should set StagePanelState.Off", () => { - const frontstageDef = new FrontstageDef(); - const rightPanel = new StagePanelDef(); - const spy = sinon.spy(); - sinon.stub(rightPanel, "panelState").get(() => StagePanelState.Off).set(spy); - sinon.stub(frontstageDef, "rightPanel").get(() => rightPanel); - renderHook(() => useSyncDefinitions(frontstageDef)); - act(() => { - let nineZone = createNineZoneState(); - nineZone = produce(nineZone, (draft) => { - draft.panels.right.collapsed = true; + describe("useSyncDefinitions", () => { + it("should set panel widget state to Open", () => { + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); + const widgetDef = new WidgetDef({}); + sinon.stub(widgetDef, "id").get(() => "t1"); + const spy = sinon.spy(widgetDef, "setWidgetState"); + zoneDef.addWidgetDef(widgetDef); + renderHook(() => useSyncDefinitions(frontstageDef)); + act(() => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + frontstageDef.nineZoneState = nineZone; }); - frontstageDef.nineZoneState = nineZone; + spy.calledOnceWithExactly(WidgetState.Open).should.true; }); - sinon.assert.calledOnceWithExactly(spy, StagePanelState.Off); - }); - it("should set floating widget state to Open", () => { - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); - const widgetDef = new WidgetDef({}); - sinon.stub(widgetDef, "id").get(() => "t1"); - const spy = sinon.spy(widgetDef, "setWidgetState"); - zoneDef.addWidgetDef(widgetDef); - renderHook(() => useSyncDefinitions(frontstageDef)); - act(() => { - let nineZone = createNineZoneState(); - nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - frontstageDef.nineZoneState = nineZone; + it("should set panel widget state to Closed", () => { + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); + const widgetDef = new WidgetDef({}); + sinon.stub(widgetDef, "id").get(() => "t1"); + const spy = sinon.spy(widgetDef, "setWidgetState"); + zoneDef.addWidgetDef(widgetDef); + renderHook(() => useSyncDefinitions(frontstageDef)); + act(() => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1", "t2"], { activeTabId: "t2" }); + nineZone = addTab(nineZone, "t1"); + nineZone = addTab(nineZone, "t2"); + frontstageDef.nineZoneState = nineZone; + }); + spy.calledOnceWithExactly(WidgetState.Closed).should.true; }); - spy.calledOnceWithExactly(WidgetState.Open).should.true; - }); - it("should set floating widget state to Closed", () => { - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); - const widgetDef = new WidgetDef({}); - sinon.stub(widgetDef, "id").get(() => "t1"); - const spy = sinon.spy(widgetDef, "setWidgetState"); - zoneDef.addWidgetDef(widgetDef); - renderHook(() => useSyncDefinitions(frontstageDef)); - act(() => { - let nineZone = createNineZoneState(); - nineZone = addFloatingWidget(nineZone, "w1", ["t1", "t2"], undefined, { activeTabId: "t2" }); - nineZone = addTab(nineZone, "t1"); - frontstageDef.nineZoneState = nineZone; + it("should set StagePanelDef size", () => { + const frontstageDef = new FrontstageDef(); + const rightPanel = new StagePanelDef(); + sinon.stub(frontstageDef, "rightPanel").get(() => rightPanel); + const spy = sinon.spy(rightPanel, "size", ["set"]); + renderHook(() => useSyncDefinitions(frontstageDef)); + act(() => { + let nineZone = createNineZoneState(); + nineZone = produce(nineZone, (draft) => { + draft.panels.right.size = 234; + }); + frontstageDef.nineZoneState = nineZone; + }); + sinon.assert.calledOnceWithExactly(spy.set, 234); }); - spy.calledOnceWithExactly(WidgetState.Closed).should.true; - }); -}); -describe("initializeNineZoneState", () => { - it("should initialize widgets", () => { - const frontstageDef = new FrontstageDef(); - sinon.stub(frontstageDef, "centerLeft").get(() => new ZoneDef()); - sinon.stub(frontstageDef, "bottomLeft").get(() => new ZoneDef()); - sinon.stub(frontstageDef, "leftPanel").get(() => new StagePanelDef()); - sinon.stub(frontstageDef, "centerRight").get(() => new ZoneDef()); - sinon.stub(frontstageDef, "bottomRight").get(() => new ZoneDef()); - sinon.stub(frontstageDef, "rightPanel").get(() => new StagePanelDef()); - sinon.stub(frontstageDef, "topPanel").get(() => new StagePanelDef()); - sinon.stub(frontstageDef, "topMostPanel").get(() => new StagePanelDef()); - sinon.stub(frontstageDef, "bottomPanel").get(() => new StagePanelDef()); - sinon.stub(frontstageDef, "bottomMostPanel").get(() => new StagePanelDef()); - const state = initializeNineZoneState(frontstageDef); - state.should.matchSnapshot(); - }); + it("should set StagePanelState.Off", () => { + const frontstageDef = new FrontstageDef(); + const rightPanel = new StagePanelDef(); + const spy = sinon.spy(); + sinon.stub(rightPanel, "panelState").get(() => StagePanelState.Off).set(spy); + sinon.stub(frontstageDef, "rightPanel").get(() => rightPanel); + renderHook(() => useSyncDefinitions(frontstageDef)); + act(() => { + let nineZone = createNineZoneState(); + nineZone = produce(nineZone, (draft) => { + draft.panels.right.collapsed = true; + }); + frontstageDef.nineZoneState = nineZone; + }); + sinon.assert.calledOnceWithExactly(spy, StagePanelState.Off); + }); - it("should keep one widget open", () => { - const frontstageDef = new FrontstageDef(); - const centerLeft = new ZoneDef(); - const widgetDef = new WidgetDef({ - id: "w1", + it("should set floating widget state to Open", () => { + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); + const widgetDef = new WidgetDef({}); + sinon.stub(widgetDef, "id").get(() => "t1"); + const spy = sinon.spy(widgetDef, "setWidgetState"); + zoneDef.addWidgetDef(widgetDef); + renderHook(() => useSyncDefinitions(frontstageDef)); + act(() => { + let nineZone = createNineZoneState(); + nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + frontstageDef.nineZoneState = nineZone; + }); + spy.calledOnceWithExactly(WidgetState.Open).should.true; }); - sinon.stub(frontstageDef, "centerLeft").get(() => centerLeft); - sinon.stub(centerLeft, "widgetDefs").get(() => [widgetDef]); - const state = initializeNineZoneState(frontstageDef); - state.widgets.leftStart.activeTabId.should.eq("w1"); - }); - it("should initialize size", () => { - sinon.stub(FrontstageManager, "nineZoneSize").get(() => new Size(10, 20)); - const frontstageDef = new FrontstageDef(); - const sut = initializeNineZoneState(frontstageDef); - sut.size.should.eql({ width: 10, height: 20 }); + it("should set floating widget state to Closed", () => { + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); + const widgetDef = new WidgetDef({}); + sinon.stub(widgetDef, "id").get(() => "t1"); + const spy = sinon.spy(widgetDef, "setWidgetState"); + zoneDef.addWidgetDef(widgetDef); + renderHook(() => useSyncDefinitions(frontstageDef)); + act(() => { + let nineZone = createNineZoneState(); + nineZone = addFloatingWidget(nineZone, "w1", ["t1", "t2"], undefined, { activeTabId: "t2" }); + nineZone = addTab(nineZone, "t1"); + frontstageDef.nineZoneState = nineZone; + }); + spy.calledOnceWithExactly(WidgetState.Closed).should.true; + }); }); - it("should not initialize size", () => { - const frontstageDef = new FrontstageDef(); - const sut = initializeNineZoneState(frontstageDef); - sut.size.should.eql({ width: 0, height: 0 }); - }); + describe("initializeNineZoneState", () => { + it("should initialize widgets", () => { + const frontstageDef = new FrontstageDef(); + sinon.stub(frontstageDef, "centerLeft").get(() => new ZoneDef()); + sinon.stub(frontstageDef, "bottomLeft").get(() => new ZoneDef()); + sinon.stub(frontstageDef, "leftPanel").get(() => new StagePanelDef()); + sinon.stub(frontstageDef, "centerRight").get(() => new ZoneDef()); + sinon.stub(frontstageDef, "bottomRight").get(() => new ZoneDef()); + sinon.stub(frontstageDef, "rightPanel").get(() => new StagePanelDef()); + sinon.stub(frontstageDef, "topPanel").get(() => new StagePanelDef()); + sinon.stub(frontstageDef, "topMostPanel").get(() => new StagePanelDef()); + sinon.stub(frontstageDef, "bottomPanel").get(() => new StagePanelDef()); + sinon.stub(frontstageDef, "bottomMostPanel").get(() => new StagePanelDef()); + const state = initializeNineZoneState(frontstageDef); + state.should.matchSnapshot(); + }); + + it("should keep one widget open", () => { + const frontstageDef = new FrontstageDef(); + const centerLeft = new ZoneDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "centerLeft").get(() => centerLeft); + sinon.stub(centerLeft, "widgetDefs").get(() => [widgetDef]); + const state = initializeNineZoneState(frontstageDef); + state.widgets.leftStart.activeTabId.should.eq("w1"); + }); - it("should initialize preferredPanelWidgetSize of tool settings widget", () => { - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ - id: "w1", - preferredPanelSize: "fit-content", - }); - sinon.stub(frontstageDef, "topCenter").get(() => zoneDef); - sinon.stub(zoneDef, "getSingleWidgetDef").returns(widgetDef); - const sut = initializeNineZoneState(frontstageDef); - sut.tabs[toolSettingsTabId].preferredPanelWidgetSize!.should.eq("fit-content"); - }); + it("should initialize size", () => { + sinon.stub(FrontstageManager, "nineZoneSize").get(() => new Size(10, 20)); + const frontstageDef = new FrontstageDef(); + const sut = initializeNineZoneState(frontstageDef); + sut.size.should.eql({ width: 10, height: 20 }); + }); - it("should add panel zone widgets", () => { - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - const start = new StagePanelZoneDef(); - const middle = new StagePanelZoneDef(); - const end = new StagePanelZoneDef(); - const w1 = new WidgetDef({ id: "w1" }); - const w2 = new WidgetDef({ id: "w2" }); - const w3 = new WidgetDef({ id: "w3" }); - sinon.stub(frontstageDef, "leftPanel").get(() => panelDef); - sinon.stub(panelDef.panelZones, "start").get(() => start); - sinon.stub(panelDef.panelZones, "middle").get(() => middle); - sinon.stub(panelDef.panelZones, "end").get(() => end); - sinon.stub(start, "widgetDefs").get(() => [w1]); - sinon.stub(middle, "widgetDefs").get(() => [w2]); - sinon.stub(end, "widgetDefs").get(() => [w3]); - const state = initializeNineZoneState(frontstageDef); - state.panels.left.widgets.should.eql(["leftStart", "leftMiddle", "leftEnd"]); - should().exist("w1"); - should().exist("w2"); - should().exist("w3"); - }); -}); + it("should not initialize size", () => { + const frontstageDef = new FrontstageDef(); + const sut = initializeNineZoneState(frontstageDef); + sut.size.should.eql({ width: 0, height: 0 }); + }); -describe("addPanelWidgets", () => { - it("should add widgets from panel zones", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const leftPanel = new StagePanelDef(); - const panelZones = new StagePanelZonesDef(); - const panelZone = new StagePanelZoneDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); - sinon.stub(leftPanel, "panelZones").get(() => panelZones); - sinon.stub(panelZones, "start").get(() => panelZone); - sinon.stub(panelZone, "widgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "left"); - state.panels.left.widgets[0].should.eq("leftStart"); - }); + it("should initialize preferredPanelWidgetSize of tool settings widget", () => { + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ + id: "w1", + preferredPanelSize: "fit-content", + }); + sinon.stub(frontstageDef, "topCenter").get(() => zoneDef); + sinon.stub(zoneDef, "getSingleWidgetDef").returns(widgetDef); + const sut = initializeNineZoneState(frontstageDef); + sut.tabs[toolSettingsTabId].preferredPanelWidgetSize!.should.eq("fit-content"); + }); - it("should add bottomLeft widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "bottomLeft").get(() => zoneDef); - sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "left"); - state.panels.left.widgets[0].should.eq("leftMiddle"); - state.widgets.leftMiddle.tabs.should.eql(["w1"]); - }); + it("should add panel zone widgets", () => { + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + const start = new StagePanelZoneDef(); + const middle = new StagePanelZoneDef(); + const end = new StagePanelZoneDef(); + const w1 = new WidgetDef({ id: "w1" }); + const w2 = new WidgetDef({ id: "w2" }); + const w3 = new WidgetDef({ id: "w3" }); + sinon.stub(frontstageDef, "leftPanel").get(() => panelDef); + sinon.stub(panelDef.panelZones, "start").get(() => start); + sinon.stub(panelDef.panelZones, "middle").get(() => middle); + sinon.stub(panelDef.panelZones, "end").get(() => end); + sinon.stub(start, "widgetDefs").get(() => [w1]); + sinon.stub(middle, "widgetDefs").get(() => [w2]); + sinon.stub(end, "widgetDefs").get(() => [w3]); + const state = initializeNineZoneState(frontstageDef); + state.panels.left.widgets.should.eql(["leftStart", "leftMiddle", "leftEnd"]); + should().exist("w1"); + should().exist("w2"); + should().exist("w3"); + }); + }); + + describe("addPanelWidgets", () => { + it("should add widgets from panel zones", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const leftPanel = new StagePanelDef(); + const panelZones = new StagePanelZonesDef(); + const panelZone = new StagePanelZoneDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); + sinon.stub(leftPanel, "panelZones").get(() => panelZones); + sinon.stub(panelZones, "start").get(() => panelZone); + sinon.stub(panelZone, "widgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "left"); + state.panels.left.widgets[0].should.eq("leftStart"); + }); - it("should add centerRight widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); - sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "right"); - state.panels.right.widgets[0].should.eq("rightStart"); - state.widgets.rightStart.tabs.should.eql(["w1"]); - }); + it("should add bottomLeft widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "bottomLeft").get(() => zoneDef); + sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "left"); + state.panels.left.widgets[0].should.eq("leftMiddle"); + state.widgets.leftMiddle.tabs.should.eql(["w1"]); + }); - it("should add bottomRight widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "bottomRight").get(() => zoneDef); - sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "right"); - state.panels.right.widgets[0].should.eq("rightMiddle"); - state.widgets.rightMiddle.tabs.should.eql(["w1"]); - }); + it("should add centerRight widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); + sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "right"); + state.panels.right.widgets[0].should.eq("rightStart"); + state.widgets.rightStart.tabs.should.eql(["w1"]); + }); - it("should add leftPanel widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "leftPanel").get(() => panelDef); - sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "left"); - state.panels.left.widgets[0].should.eq("leftEnd"); - state.widgets.leftEnd.tabs.should.eql(["w1"]); - }); + it("should add bottomRight widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "bottomRight").get(() => zoneDef); + sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "right"); + state.panels.right.widgets[0].should.eq("rightMiddle"); + state.widgets.rightMiddle.tabs.should.eql(["w1"]); + }); - it("should add rightPanel widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "rightPanel").get(() => panelDef); - sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "right"); - state.panels.right.widgets[0].should.eq("rightEnd"); - state.widgets.rightEnd.tabs.should.eql(["w1"]); - }); + it("should add leftPanel widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "leftPanel").get(() => panelDef); + sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "left"); + state.panels.left.widgets[0].should.eq("leftEnd"); + state.widgets.leftEnd.tabs.should.eql(["w1"]); + }); - it("should add topPanel widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "topPanel").get(() => panelDef); - sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "top"); - state.panels.top.widgets[0].should.eq("topStart"); - state.widgets.topStart.tabs.should.eql(["w1"]); - }); + it("should add rightPanel widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "rightPanel").get(() => panelDef); + sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "right"); + state.panels.right.widgets[0].should.eq("rightEnd"); + state.widgets.rightEnd.tabs.should.eql(["w1"]); + }); - it("should add topMostPanel widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "topMostPanel").get(() => panelDef); - sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "top"); - state.panels.top.widgets[0].should.eq("topEnd"); - state.widgets.topEnd.tabs.should.eql(["w1"]); - }); + it("should add topPanel widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "topPanel").get(() => panelDef); + sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "top"); + state.panels.top.widgets[0].should.eq("topStart"); + state.widgets.topStart.tabs.should.eql(["w1"]); + }); - it("should add bottomPanel widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "bottomPanel").get(() => panelDef); - sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "bottom"); - state.panels.bottom.widgets[0].should.eq("bottomStart"); - state.widgets.bottomStart.tabs.should.eql(["w1"]); - }); + it("should add topMostPanel widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "topMostPanel").get(() => panelDef); + sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "top"); + state.panels.top.widgets[0].should.eq("topEnd"); + state.widgets.topEnd.tabs.should.eql(["w1"]); + }); - it("should add bottomMostPanel widgets", () => { - let state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - const widgetDef = new WidgetDef({ - id: "w1", - }); - sinon.stub(frontstageDef, "bottomMostPanel").get(() => panelDef); - sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); - state = addPanelWidgets(state, frontstageDef, "bottom"); - state.panels.bottom.widgets[0].should.eq("bottomEnd"); - state.widgets.bottomEnd.tabs.should.eql(["w1"]); - }); -}); + it("should add bottomPanel widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "bottomPanel").get(() => panelDef); + sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "bottom"); + state.panels.bottom.widgets[0].should.eq("bottomStart"); + state.widgets.bottomStart.tabs.should.eql(["w1"]); + }); -describe("initializePanel", () => { - it("should initialize max size", () => { - const state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const leftPanel = new StagePanelDef(); - sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); - sinon.stub(leftPanel, "maxSizeSpec").get(() => 100); - const sut = initializePanel(state, frontstageDef, "left"); - sut.panels.left.maxSize.should.eq(100); + it("should add bottomMostPanel widgets", () => { + let state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + const widgetDef = new WidgetDef({ + id: "w1", + }); + sinon.stub(frontstageDef, "bottomMostPanel").get(() => panelDef); + sinon.stub(panelDef, "panelWidgetDefs").get(() => [widgetDef]); + state = addPanelWidgets(state, frontstageDef, "bottom"); + state.panels.bottom.widgets[0].should.eq("bottomEnd"); + state.widgets.bottomEnd.tabs.should.eql(["w1"]); + }); }); - it("should initialize min size", () => { - const state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const leftPanel = new StagePanelDef(); - sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); - sinon.stub(leftPanel, "minSize").get(() => 50); - const sut = initializePanel(state, frontstageDef, "left"); - sut.panels.left.minSize.should.eq(50); - }); -}); + describe("initializePanel", () => { + it("should initialize max size", () => { + const state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const leftPanel = new StagePanelDef(); + sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); + sinon.stub(leftPanel, "maxSizeSpec").get(() => 100); + const sut = initializePanel(state, frontstageDef, "left"); + sut.panels.left.maxSize.should.eq(100); + }); -describe("addWidgets", () => { - it("should use widget label", () => { - let state = createNineZoneState(); - const widget = new WidgetDef({ - id: "w1", - label: "Widget 1", + it("should initialize min size", () => { + const state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const leftPanel = new StagePanelDef(); + sinon.stub(frontstageDef, "leftPanel").get(() => leftPanel); + sinon.stub(leftPanel, "minSize").get(() => 50); + const sut = initializePanel(state, frontstageDef, "left"); + sut.panels.left.minSize.should.eq(50); }); - state = addWidgets(state, [widget], "left", "leftStart"); - state.tabs.w1.label.should.eq("Widget 1"); }); - it("should activate tab based on widget state", () => { - let state = createNineZoneState(); - const widget = new WidgetDef({ - id: "w1", - defaultState: WidgetState.Open, + describe("addWidgets", () => { + it("should use widget label", () => { + let state = createNineZoneState(); + const widget = new WidgetDef({ + id: "w1", + label: "Widget 1", + }); + state = addWidgets(state, [widget], "left", "leftStart"); + state.tabs.w1.label.should.eq("Widget 1"); }); - state = addWidgets(state, [widget], "left", "leftStart"); - state.widgets.leftStart.activeTabId.should.eq("w1"); - }); -}); -describe("getWidgetId", () => { - it("should return 'leftStart'", () => { - getWidgetId("left", "start").should.eq("leftStart"); + it("should activate tab based on widget state", () => { + let state = createNineZoneState(); + const widget = new WidgetDef({ + id: "w1", + defaultState: WidgetState.Open, + }); + state = addWidgets(state, [widget], "left", "leftStart"); + state.widgets.leftStart.activeTabId.should.eq("w1"); + }); }); - it("should return 'leftMiddle'", () => { - getWidgetId("left", "middle").should.eq("leftMiddle"); - }); + describe("getWidgetId", () => { + it("should return 'leftStart'", () => { + getWidgetId("left", "start").should.eq("leftStart"); + }); - it("should return 'leftEnd'", () => { - getWidgetId("left", "end").should.eq("leftEnd"); - }); + it("should return 'leftMiddle'", () => { + getWidgetId("left", "middle").should.eq("leftMiddle"); + }); - it("should return 'rightStart'", () => { - getWidgetId("right", "start").should.eq("rightStart"); - }); + it("should return 'leftEnd'", () => { + getWidgetId("left", "end").should.eq("leftEnd"); + }); - it("should return 'rightMiddle'", () => { - getWidgetId("right", "middle").should.eq("rightMiddle"); - }); + it("should return 'rightStart'", () => { + getWidgetId("right", "start").should.eq("rightStart"); + }); - it("should return 'rightEnd'", () => { - getWidgetId("right", "end").should.eq("rightEnd"); - }); + it("should return 'rightMiddle'", () => { + getWidgetId("right", "middle").should.eq("rightMiddle"); + }); - it("should return 'topStart'", () => { - getWidgetId("top", "start").should.eq("topStart"); - }); + it("should return 'rightEnd'", () => { + getWidgetId("right", "end").should.eq("rightEnd"); + }); - it("should return 'topEnd'", () => { - getWidgetId("top", "end").should.eq("topEnd"); - }); + it("should return 'topStart'", () => { + getWidgetId("top", "start").should.eq("topStart"); + }); - it("should return 'bottomStart'", () => { - getWidgetId("bottom", "start").should.eq("bottomStart"); - }); + it("should return 'topEnd'", () => { + getWidgetId("top", "end").should.eq("topEnd"); + }); - it("should return 'bottomEnd'", () => { - getWidgetId("bottom", "end").should.eq("bottomEnd"); - }); -}); + it("should return 'bottomStart'", () => { + getWidgetId("bottom", "start").should.eq("bottomStart"); + }); -describe("isFrontstageStateSettingResult", () => { - it("isFrontstageStateSettingResult", () => { - isFrontstageStateSettingResult({ status: UiSettingsStatus.UnknownError }).should.false; + it("should return 'bottomEnd'", () => { + getWidgetId("bottom", "end").should.eq("bottomEnd"); + }); }); -}); -describe("setWidgetState", () => { - it("should not update for other states", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Floating); - sut.should.eq(nineZone); + describe("isFrontstageStateSettingResult", () => { + it("isFrontstageStateSettingResult", () => { + isFrontstageStateSettingResult({ status: UiSettingsStatus.UnknownError }).should.false; + }); }); - describe("WidgetState.Open", () => { - it("should open widget", () => { + describe("setWidgetState", () => { + it("should not update for other states", () => { let nineZone = createNineZoneState(); nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Open); - sut.widgets.w1.activeTabId.should.eq("t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Floating); + sut.should.eq(nineZone); }); - it("should add removed tab", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t2" }), WidgetState.Open); - sut.panels.left.widgets.length.should.eq(2); - }); + describe("WidgetState.Open", () => { + it("should open widget", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Open); + sut.widgets.w1.activeTabId.should.eq("t1"); + }); - it("should add removed tab by existing widget", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addPanelWidget(nineZone, "left", "w2", ["t2"]); - nineZone = addTab(nineZone, "t1"); - nineZone = addTab(nineZone, "t2"); - const widgetDef = new WidgetDef({ id: "t3" }); - widgetDef.tabLocation = { - ...widgetDef.tabLocation, - widgetId: "w2", - }; - const sut = setWidgetState(nineZone, widgetDef, WidgetState.Open); - sut.widgets.w2.tabs.should.eql(["t3", "t2"]); - }); + it("should add removed tab", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t2" }), WidgetState.Open); + sut.panels.left.widgets.length.should.eq(2); + }); - it("should add removed tab to existing panel widget", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addPanelWidget(nineZone, "left", "w2", ["t2_1", "t2_2", "t2_3"]); - nineZone = addPanelWidget(nineZone, "left", "w3", ["t3"]); - nineZone = addTab(nineZone, "t1"); - nineZone = addTab(nineZone, "t2_1"); - nineZone = addTab(nineZone, "t2_2"); - nineZone = addTab(nineZone, "t2_3"); - nineZone = addTab(nineZone, "t3"); - const widgetDef = new WidgetDef({ id: "t4" }); - widgetDef.tabLocation = { - ...widgetDef.tabLocation, - widgetIndex: 1, - tabIndex: 2, - }; - const sut = setWidgetState(nineZone, widgetDef, WidgetState.Open); - sut.widgets.w2.tabs.should.eql(["t2_1", "t2_2", "t4", "t2_3"]); - }); - }); + it("should add removed tab by existing widget", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addPanelWidget(nineZone, "left", "w2", ["t2"]); + nineZone = addTab(nineZone, "t1"); + nineZone = addTab(nineZone, "t2"); + const widgetDef = new WidgetDef({ id: "t3" }); + widgetDef.tabLocation = { + ...widgetDef.tabLocation, + widgetId: "w2", + }; + const sut = setWidgetState(nineZone, widgetDef, WidgetState.Open); + sut.widgets.w2.tabs.should.eql(["t3", "t2"]); + }); - describe("WidgetState.Closed", () => { - it("should not minimize if tab is not active", () => { - let nineZone = createNineZoneState(); - nineZone = addFloatingWidget(nineZone, "w1", ["t1", "t2"], undefined, { activeTabId: "t2" }); - nineZone = addTab(nineZone, "t1"); - nineZone = addTab(nineZone, "t2"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); - sut.should.eq(nineZone); + it("should add removed tab to existing panel widget", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addPanelWidget(nineZone, "left", "w2", ["t2_1", "t2_2", "t2_3"]); + nineZone = addPanelWidget(nineZone, "left", "w3", ["t3"]); + nineZone = addTab(nineZone, "t1"); + nineZone = addTab(nineZone, "t2_1"); + nineZone = addTab(nineZone, "t2_2"); + nineZone = addTab(nineZone, "t2_3"); + nineZone = addTab(nineZone, "t3"); + const widgetDef = new WidgetDef({ id: "t4" }); + widgetDef.tabLocation = { + ...widgetDef.tabLocation, + widgetIndex: 1, + tabIndex: 2, + }; + const sut = setWidgetState(nineZone, widgetDef, WidgetState.Open); + sut.widgets.w2.tabs.should.eql(["t2_1", "t2_2", "t4", "t2_3"]); + }); }); - it("should minimize floating widget", () => { - let nineZone = createNineZoneState(); - nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); - sut.widgets.w1.minimized.should.true; - }); + describe("WidgetState.Closed", () => { + it("should not minimize if tab is not active", () => { + let nineZone = createNineZoneState(); + nineZone = addFloatingWidget(nineZone, "w1", ["t1", "t2"], undefined, { activeTabId: "t2" }); + nineZone = addTab(nineZone, "t1"); + nineZone = addTab(nineZone, "t2"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); + sut.should.eq(nineZone); + }); - it("should minimize panel widget", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addPanelWidget(nineZone, "left", "w2", ["t2"]); - nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); - sut.widgets.w1.minimized.should.true; - }); + it("should minimize floating widget", () => { + let nineZone = createNineZoneState(); + nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); + sut.widgets.w1.minimized.should.true; + }); - it("should not minimize single panel widget", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); - sut.widgets.w1.minimized.should.false; + it("should minimize panel widget", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addPanelWidget(nineZone, "left", "w2", ["t2"]); + nineZone = addTab(nineZone, "t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); + sut.widgets.w1.minimized.should.true; + }); + + it("should not minimize single panel widget", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Closed); + sut.widgets.w1.minimized.should.false; + }); + + it("should add removed tab", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t2" }), WidgetState.Closed); + sut.panels.left.widgets.length.should.eq(2); + }); }); - it("should add removed tab", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t2" }), WidgetState.Closed); - sut.panels.left.widgets.length.should.eq(2); + describe("WidgetState.Hidden", () => { + it("should not update if tab is not found", () => { + const nineZone = createNineZoneState(); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Hidden); + sut.should.eq(nineZone); + }); + + it("should hide the widget", () => { + let nineZone = createNineZoneState(); + nineZone = addPanelWidget(nineZone, "left", "w1", ["t1", "t2"]); + nineZone = addTab(nineZone, "t1"); + const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Hidden); + sut.widgets.w1.tabs.should.eql(["t2"]); + }); + + it("should use default panel side for a floating widget", () => { + let nineZone = createNineZoneState(); + nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + const widgetDef = new WidgetDef({ id: "t1" }); + setWidgetState(nineZone, widgetDef, WidgetState.Hidden); + widgetDef.tabLocation.side.should.eq("left"); + widgetDef.tabLocation.widgetIndex.should.eq(0); + }); }); + }); - describe("WidgetState.Hidden", () => { + describe("showWidget ", () => { it("should not update if tab is not found", () => { const nineZone = createNineZoneState(); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Hidden); + const sut = showWidget(nineZone, "t1"); sut.should.eq(nineZone); }); - it("should hide the widget", () => { - let nineZone = createNineZoneState(); - nineZone = addPanelWidget(nineZone, "left", "w1", ["t1", "t2"]); - nineZone = addTab(nineZone, "t1"); - const sut = setWidgetState(nineZone, new WidgetDef({ id: "t1" }), WidgetState.Hidden); - sut.widgets.w1.tabs.should.eql(["t2"]); - }); - - it("should use default panel side for a floating widget", () => { + it("should bring floating widget to front", () => { let nineZone = createNineZoneState(); nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); + nineZone = addFloatingWidget(nineZone, "w2", ["t2"]); nineZone = addTab(nineZone, "t1"); - const widgetDef = new WidgetDef({ id: "t1" }); - setWidgetState(nineZone, widgetDef, WidgetState.Hidden); - widgetDef.tabLocation.side.should.eq("left"); - widgetDef.tabLocation.widgetIndex.should.eq(0); + const sut = showWidget(nineZone, "t1"); + sut.floatingWidgets.allIds[0].should.eq("w2"); + sut.floatingWidgets.allIds[1].should.eq("w1"); }); }); -}); - -describe("showWidget ", () => { - it("should not update if tab is not found", () => { - const nineZone = createNineZoneState(); - const sut = showWidget(nineZone, "t1"); - sut.should.eq(nineZone); - }); + describe("expandWidget ", () => { + it("should not update if tab is not found", () => { + const nineZone = createNineZoneState(); + const sut = expandWidget(nineZone, "t1"); + sut.should.eq(nineZone); + }); - it("should bring floating widget to front", () => { - let nineZone = createNineZoneState(); - nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); - nineZone = addFloatingWidget(nineZone, "w2", ["t2"]); - nineZone = addTab(nineZone, "t1"); - const sut = showWidget(nineZone, "t1"); - sut.floatingWidgets.allIds[0].should.eq("w2"); - sut.floatingWidgets.allIds[1].should.eq("w1"); + it("should expand floating widget", () => { + let nineZone = createNineZoneState(); + nineZone = addFloatingWidget(nineZone, "w1", ["t1"], undefined, { minimized: true }); + nineZone = addTab(nineZone, "t1"); + const sut = expandWidget(nineZone, "t1"); + sut.widgets.w1.minimized.should.false; + }); }); -}); -describe("expandWidget ", () => { - it("should not update if tab is not found", () => { - const nineZone = createNineZoneState(); - const sut = expandWidget(nineZone, "t1"); - sut.should.eq(nineZone); - }); + describe("restoreNineZoneState", () => { + it("should log error if widgetDef is not found", () => { + const spy = sinon.spy(Logger, "logError"); + const frontstageDef = new FrontstageDef(); + const savedState = { + ...createSavedNineZoneState(), + tabs: { + t1: createSavedTabState("t1"), + }, + }; + restoreNineZoneState(frontstageDef, savedState); + spy.calledOnce.should.true; + spy.firstCall.args[2]!().should.matchSnapshot(); + }); - it("should expand floating widget", () => { - let nineZone = createNineZoneState(); - nineZone = addFloatingWidget(nineZone, "w1", ["t1"], undefined, { minimized: true }); - nineZone = addTab(nineZone, "t1"); - const sut = expandWidget(nineZone, "t1"); - sut.widgets.w1.minimized.should.false; - }); -}); + it("should remove tab if widgetDef is not found", () => { + const frontstageDef = new FrontstageDef(); + sinon.stub(frontstageDef, "findWidgetDef").withArgs("t2").returns(new WidgetDef({})); + let state = createNineZoneState(); + state = addPanelWidget(state, "left", "w1", ["t1", "t2"]); + state = addTab(state, "t1"); + state = addTab(state, "t2"); + const savedState = { + ...createSavedNineZoneState(state), + tabs: { + t1: createSavedTabState("t1"), + t2: createSavedTabState("t2"), + }, + }; + const newState = restoreNineZoneState(frontstageDef, savedState); + (newState.tabs.t1 === undefined).should.true; + newState.widgets.w1.tabs.indexOf("t1").should.eq(-1); + newState.widgets.w1.tabs.indexOf("t2").should.eq(0); + }); -describe("restoreNineZoneState", () => { - it("should log error if widgetDef is not found", () => { - const spy = sinon.spy(Logger, "logError"); - const frontstageDef = new FrontstageDef(); - const savedState = { - ...createSavedNineZoneState(), - tabs: { - t1: createSavedTabState("t1"), - }, - }; - restoreNineZoneState(frontstageDef, savedState); - spy.calledOnce.should.true; - spy.firstCall.args[2]!().should.matchSnapshot(); - }); + it("should restore tabs", () => { + const frontstageDef = new FrontstageDef(); + const widgetDef = new WidgetDef({}); + sinon.stub(frontstageDef, "findWidgetDef").returns(widgetDef); + const savedState = { + ...createSavedNineZoneState(), + tabs: { + t1: createSavedTabState("t1"), + }, + }; + const sut = restoreNineZoneState(frontstageDef, savedState); + sut.should.matchSnapshot(); + }); - it("should remove tab if widgetDef is not found", () => { - const frontstageDef = new FrontstageDef(); - sinon.stub(frontstageDef, "findWidgetDef").withArgs("t2").returns(new WidgetDef({})); - let state = createNineZoneState(); - state = addPanelWidget(state, "left", "w1", ["t1", "t2"]); - state = addTab(state, "t1"); - state = addTab(state, "t2"); - const savedState = { - ...createSavedNineZoneState(state), - tabs: { - t1: createSavedTabState("t1"), - t2: createSavedTabState("t2"), - }, - }; - const newState = restoreNineZoneState(frontstageDef, savedState); - (newState.tabs.t1 === undefined).should.true; - newState.widgets.w1.tabs.indexOf("t1").should.eq(-1); - newState.widgets.w1.tabs.indexOf("t2").should.eq(0); - }); + it("should RESIZE", () => { + sinon.stub(FrontstageManager, "nineZoneSize").get(() => new Size(10, 20)); + const frontstageDef = new FrontstageDef(); + const savedState = { + ...createSavedNineZoneState({ + size: { + width: 1, + height: 2, + }, + }), + tabs: { + t1: createSavedTabState("t1"), + }, + }; - it("should restore tabs", () => { - const frontstageDef = new FrontstageDef(); - const widgetDef = new WidgetDef({}); - sinon.stub(frontstageDef, "findWidgetDef").returns(widgetDef); - const savedState = { - ...createSavedNineZoneState(), - tabs: { - t1: createSavedTabState("t1"), - }, - }; - const sut = restoreNineZoneState(frontstageDef, savedState); - sut.should.matchSnapshot(); - }); + const sut = restoreNineZoneState(frontstageDef, savedState); + sut.size.should.eql({ width: 10, height: 20 }); + }); - it("should RESIZE", () => { - sinon.stub(FrontstageManager, "nineZoneSize").get(() => new Size(10, 20)); - const frontstageDef = new FrontstageDef(); - const savedState = { - ...createSavedNineZoneState({ - size: { - width: 1, - height: 2, + it("should not RESIZE", () => { + const frontstageDef = new FrontstageDef(); + const savedState = { + ...createSavedNineZoneState({ + size: { + width: 1, + height: 2, + }, + }), + tabs: { + t1: createSavedTabState("t1"), }, - }), - tabs: { - t1: createSavedTabState("t1"), - }, - }; - - const sut = restoreNineZoneState(frontstageDef, savedState); - sut.size.should.eql({ width: 10, height: 20 }); - }); + }; - it("should not RESIZE", () => { - const frontstageDef = new FrontstageDef(); - const savedState = { - ...createSavedNineZoneState({ - size: { - width: 1, - height: 2, - }, - }), - tabs: { - t1: createSavedTabState("t1"), - }, - }; - - const sut = restoreNineZoneState(frontstageDef, savedState); - sut.size.should.eql({ width: 1, height: 2 }); + const sut = restoreNineZoneState(frontstageDef, savedState); + sut.size.should.eql({ width: 1, height: 2 }); + }); }); -}); -describe("packNineZoneState", () => { - it("should remove labels", () => { - let nineZone = createNineZoneState(); - nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); - nineZone = addTab(nineZone, "t1"); - const sut = packNineZoneState(nineZone); - sut.should.matchSnapshot(); + describe("packNineZoneState", () => { + it("should remove labels", () => { + let nineZone = createNineZoneState(); + nineZone = addFloatingWidget(nineZone, "w1", ["t1"]); + nineZone = addTab(nineZone, "t1"); + const sut = packNineZoneState(nineZone); + sut.should.matchSnapshot(); + }); }); -}); - -describe("useUpdateNineZoneSize", () => { - it("should update size of nine zone state when new frontstage is activated", () => { - const { rerender } = renderHook((props) => useUpdateNineZoneSize(props), { initialProps: new FrontstageDef() }); - const newFrontstageDef = new FrontstageDef(); - newFrontstageDef.nineZoneState = createNineZoneState(); + describe("useUpdateNineZoneSize", () => { + it("should update size of nine zone state when new frontstage is activated", () => { + const { rerender } = renderHook((props) => useUpdateNineZoneSize(props), { initialProps: new FrontstageDef() }); - sinon.stub(FrontstageManager, "nineZoneSize").get(() => new Size(10, 20)); - rerender(newFrontstageDef); + const newFrontstageDef = new FrontstageDef(); + newFrontstageDef.nineZoneState = createNineZoneState(); - newFrontstageDef.nineZoneState.size.should.eql({ width: 10, height: 20 }); - }); + sinon.stub(FrontstageManager, "nineZoneSize").get(() => new Size(10, 20)); + rerender(newFrontstageDef); - it("should not update size if FrontstageManager.nineZoneSize is not initialized", () => { - const { rerender } = renderHook((props) => useUpdateNineZoneSize(props), { initialProps: new FrontstageDef() }); + newFrontstageDef.nineZoneState.size.should.eql({ width: 10, height: 20 }); + }); - const newFrontstageDef = new FrontstageDef(); - newFrontstageDef.nineZoneState = createNineZoneState({ size: { height: 1, width: 2 } }); + it("should not update size if FrontstageManager.nineZoneSize is not initialized", () => { + const { rerender } = renderHook((props) => useUpdateNineZoneSize(props), { initialProps: new FrontstageDef() }); - rerender(newFrontstageDef); + const newFrontstageDef = new FrontstageDef(); + newFrontstageDef.nineZoneState = createNineZoneState({ size: { height: 1, width: 2 } }); - newFrontstageDef.nineZoneState.size.should.eql({ height: 1, width: 2 }); - }); -}); + rerender(newFrontstageDef); -describe("addMissingWidgets", () => { - it("should add centerLeft widgets", () => { - const state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ id: "w1" }); - sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); - sinon.stub(frontstageDef, "centerLeft").get(() => zoneDef); - const newState = addMissingWidgets(frontstageDef, state); - should().exist(newState.tabs.w1); + newFrontstageDef.nineZoneState.size.should.eql({ height: 1, width: 2 }); + }); }); - it("should add bottomLeft widgets", () => { - const state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ id: "w1" }); - sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); - sinon.stub(frontstageDef, "bottomLeft").get(() => zoneDef); - const newState = addMissingWidgets(frontstageDef, state); - should().exist(newState.tabs.w1); - }); + describe("addMissingWidgets", () => { + it("should add centerLeft widgets", () => { + const state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ id: "w1" }); + sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); + sinon.stub(frontstageDef, "centerLeft").get(() => zoneDef); + const newState = addMissingWidgets(frontstageDef, state); + should().exist(newState.tabs.w1); + }); - it("should add centerRight widgets", () => { - const state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ id: "w1" }); - sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); - sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); - const newState = addMissingWidgets(frontstageDef, state); - should().exist(newState.tabs.w1); - }); + it("should add bottomLeft widgets", () => { + const state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ id: "w1" }); + sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); + sinon.stub(frontstageDef, "bottomLeft").get(() => zoneDef); + const newState = addMissingWidgets(frontstageDef, state); + should().exist(newState.tabs.w1); + }); - it("should add bottomRight widgets", () => { - const state = createNineZoneState(); - const frontstageDef = new FrontstageDef(); - const zoneDef = new ZoneDef(); - const widgetDef = new WidgetDef({ id: "w1" }); - sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); - sinon.stub(frontstageDef, "bottomRight").get(() => zoneDef); - const newState = addMissingWidgets(frontstageDef, state); - should().exist(newState.tabs.w1); - }); + it("should add centerRight widgets", () => { + const state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ id: "w1" }); + sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); + sinon.stub(frontstageDef, "centerRight").get(() => zoneDef); + const newState = addMissingWidgets(frontstageDef, state); + should().exist(newState.tabs.w1); + }); - it("should add leftPanel widgets", () => { - let state = createNineZoneState(); - state = addPanelWidget(state, "left", "start", ["start1"]); - state = addPanelWidget(state, "left", "middle", ["middle1"]); - state = addPanelWidget(state, "left", "end", ["end1"]); - state = addTab(state, "start1"); - state = addTab(state, "middle1"); - state = addTab(state, "end1"); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - panelDef.initializeFromProps({ - resizable: true, - widgets: [ - , - ], - panelZones: { - start: { - widgets: [ - , - ], - }, - middle: { - widgets: [ - , - ], - }, - end: { - widgets: [ - , - ], - }, - }, - }, StagePanelLocation.Left); - sinon.stub(frontstageDef, "leftPanel").get(() => panelDef); - const newState = addMissingWidgets(frontstageDef, state); - newState.widgets.start.tabs.should.eql(["start1", "ws1"]); - newState.widgets.middle.tabs.should.eql(["middle1", "wm1"]); - newState.widgets.end.tabs.should.eql(["end1", "w1", "we1"]); - }); + it("should add bottomRight widgets", () => { + const state = createNineZoneState(); + const frontstageDef = new FrontstageDef(); + const zoneDef = new ZoneDef(); + const widgetDef = new WidgetDef({ id: "w1" }); + sinon.stub(zoneDef, "widgetDefs").get(() => [widgetDef]); + sinon.stub(frontstageDef, "bottomRight").get(() => zoneDef); + const newState = addMissingWidgets(frontstageDef, state); + should().exist(newState.tabs.w1); + }); - it("should add rightPanel widgets", () => { - let state = createNineZoneState(); - state = addPanelWidget(state, "right", "start", ["start1"]); - state = addPanelWidget(state, "right", "middle", ["middle1"]); - state = addPanelWidget(state, "right", "end", ["end1"]); - state = addTab(state, "start1"); - state = addTab(state, "middle1"); - state = addTab(state, "end1"); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - panelDef.initializeFromProps({ - resizable: true, - widgets: [ - , - ], - panelZones: { - start: { - widgets: [ - , - ], - }, - middle: { - widgets: [ - , - ], - }, - end: { - widgets: [ - , - ], + it("should add leftPanel widgets", () => { + let state = createNineZoneState(); + state = addPanelWidget(state, "left", "start", ["start1"]); + state = addPanelWidget(state, "left", "middle", ["middle1"]); + state = addPanelWidget(state, "left", "end", ["end1"]); + state = addTab(state, "start1"); + state = addTab(state, "middle1"); + state = addTab(state, "end1"); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + panelDef.initializeFromProps({ + resizable: true, + widgets: [ + , + ], + panelZones: { + start: { + widgets: [ + , + ], + }, + middle: { + widgets: [ + , + ], + }, + end: { + widgets: [ + , + ], + }, }, - }, - }, StagePanelLocation.Right); - sinon.stub(frontstageDef, "rightPanel").get(() => panelDef); - const newState = addMissingWidgets(frontstageDef, state); - newState.widgets.start.tabs.should.eql(["start1", "ws1"]); - newState.widgets.middle.tabs.should.eql(["middle1", "wm1"]); - newState.widgets.end.tabs.should.eql(["end1", "w1", "we1"]); - }); + }, StagePanelLocation.Left); + sinon.stub(frontstageDef, "leftPanel").get(() => panelDef); + const newState = addMissingWidgets(frontstageDef, state); + newState.widgets.start.tabs.should.eql(["start1", "ws1"]); + newState.widgets.middle.tabs.should.eql(["middle1", "wm1"]); + newState.widgets.end.tabs.should.eql(["end1", "w1", "we1"]); + }); - it("should add topPanel widgets", () => { - let state = createNineZoneState(); - state = addPanelWidget(state, "top", "start", ["start1"]); - state = addPanelWidget(state, "top", "end", ["end1"]); - state = addTab(state, "start1"); - state = addTab(state, "end1"); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - panelDef.initializeFromProps({ - resizable: true, - widgets: [ - , - ], - panelZones: { - start: { - widgets: [ - , - ], - }, - end: { - widgets: [ - , - ], + it("should add rightPanel widgets", () => { + let state = createNineZoneState(); + state = addPanelWidget(state, "right", "start", ["start1"]); + state = addPanelWidget(state, "right", "middle", ["middle1"]); + state = addPanelWidget(state, "right", "end", ["end1"]); + state = addTab(state, "start1"); + state = addTab(state, "middle1"); + state = addTab(state, "end1"); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + panelDef.initializeFromProps({ + resizable: true, + widgets: [ + , + ], + panelZones: { + start: { + widgets: [ + , + ], + }, + middle: { + widgets: [ + , + ], + }, + end: { + widgets: [ + , + ], + }, }, - }, - }, StagePanelLocation.Top); - const panelDef1 = new StagePanelDef(); - panelDef1.initializeFromProps({ - resizable: true, - widgets: [ - , - ], - }, StagePanelLocation.TopMost); - sinon.stub(frontstageDef, "topPanel").get(() => panelDef); - sinon.stub(frontstageDef, "topMostPanel").get(() => panelDef1); - const newState = addMissingWidgets(frontstageDef, state); - newState.widgets.start.tabs.should.eql(["start1", "w1", "ws1"]); - newState.widgets.end.tabs.should.eql(["end1", "w2", "we1"]); - }); + }, StagePanelLocation.Right); + sinon.stub(frontstageDef, "rightPanel").get(() => panelDef); + const newState = addMissingWidgets(frontstageDef, state); + newState.widgets.start.tabs.should.eql(["start1", "ws1"]); + newState.widgets.middle.tabs.should.eql(["middle1", "wm1"]); + newState.widgets.end.tabs.should.eql(["end1", "w1", "we1"]); + }); - it("should add bottomPanel widgets", () => { - let state = createNineZoneState(); - state = addPanelWidget(state, "bottom", "start", ["start1"]); - state = addPanelWidget(state, "bottom", "end", ["end1"]); - state = addTab(state, "start1"); - state = addTab(state, "end1"); - const frontstageDef = new FrontstageDef(); - const panelDef = new StagePanelDef(); - panelDef.initializeFromProps({ - resizable: true, - widgets: [ - , - ], - panelZones: { - start: { - widgets: [ - , - ], + it("should add topPanel widgets", () => { + let state = createNineZoneState(); + state = addPanelWidget(state, "top", "start", ["start1"]); + state = addPanelWidget(state, "top", "end", ["end1"]); + state = addTab(state, "start1"); + state = addTab(state, "end1"); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + panelDef.initializeFromProps({ + resizable: true, + widgets: [ + , + ], + panelZones: { + start: { + widgets: [ + , + ], + }, + end: { + widgets: [ + , + ], + }, }, - end: { - widgets: [ - , - ], + }, StagePanelLocation.Top); + const panelDef1 = new StagePanelDef(); + panelDef1.initializeFromProps({ + resizable: true, + widgets: [ + , + ], + }, StagePanelLocation.TopMost); + sinon.stub(frontstageDef, "topPanel").get(() => panelDef); + sinon.stub(frontstageDef, "topMostPanel").get(() => panelDef1); + const newState = addMissingWidgets(frontstageDef, state); + newState.widgets.start.tabs.should.eql(["start1", "w1", "ws1"]); + newState.widgets.end.tabs.should.eql(["end1", "w2", "we1"]); + }); + + it("should add bottomPanel widgets", () => { + let state = createNineZoneState(); + state = addPanelWidget(state, "bottom", "start", ["start1"]); + state = addPanelWidget(state, "bottom", "end", ["end1"]); + state = addTab(state, "start1"); + state = addTab(state, "end1"); + const frontstageDef = new FrontstageDef(); + const panelDef = new StagePanelDef(); + panelDef.initializeFromProps({ + resizable: true, + widgets: [ + , + ], + panelZones: { + start: { + widgets: [ + , + ], + }, + end: { + widgets: [ + , + ], + }, }, - }, - }, StagePanelLocation.Bottom); - const panelDef1 = new StagePanelDef(); - panelDef1.initializeFromProps({ - resizable: true, - widgets: [ - , - ], - }, StagePanelLocation.BottomMost); - sinon.stub(frontstageDef, "bottomPanel").get(() => panelDef); - sinon.stub(frontstageDef, "bottomMostPanel").get(() => panelDef1); - const newState = addMissingWidgets(frontstageDef, state); - newState.widgets.start.tabs.should.eql(["start1", "w1", "ws1"]); - newState.widgets.end.tabs.should.eql(["end1", "w2", "we1"]); - }); -}); - -describe("dynamic widgets", () => { - const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; - const localStorageMock = storageMock(); - - stubRaf(); - beforeEach(async () => { - Object.defineProperty(window, "localStorage", { - get: () => localStorageMock, + }, StagePanelLocation.Bottom); + const panelDef1 = new StagePanelDef(); + panelDef1.initializeFromProps({ + resizable: true, + widgets: [ + , + ], + }, StagePanelLocation.BottomMost); + sinon.stub(frontstageDef, "bottomPanel").get(() => panelDef); + sinon.stub(frontstageDef, "bottomMostPanel").get(() => panelDef1); + const newState = addMissingWidgets(frontstageDef, state); + newState.widgets.start.tabs.should.eql(["start1", "w1", "ws1"]); + newState.widgets.end.tabs.should.eql(["end1", "w2", "we1"]); + }); + }); + + describe("dynamic widgets", () => { + stubRaf(); + beforeEach(async () => { + await TestUtils.initializeUiFramework(); + await NoRenderApp.startup(); + }); + + afterEach(() => { + UiItemsManager.unregister("TestUi2Provider"); + FrontstageManager.clearFrontstageDefs(); + FrontstageManager.setActiveFrontstageDef(undefined); }); - await TestUtils.initializeUiFramework(); - await NoRenderApp.startup(); - }); - - afterEach(() => { - UiItemsManager.unregister("TestUi2Provider"); - FrontstageManager.clearFrontstageDefs(); - FrontstageManager.setActiveFrontstageDef(undefined); - }); + afterEach(() => { + TestUtils.terminateUiFramework(); + IModelApp.shutdown(); + }); - afterEach(() => { - Object.defineProperty(window, "localStorage", localStorageToRestore); - TestUtils.terminateUiFramework(); - IModelApp.shutdown(); - }); + it("should render pre-loaded extension widgets when state is initialized", async () => { + UiItemsManager.register(new TestUi2Provider()); - it("should render pre-loaded extension widgets when state is initialized", async () => { - UiItemsManager.register(new TestUi2Provider()); + const frontstageProvider = new TestFrontstageUi2(); + FrontstageManager.addFrontstageProvider(frontstageProvider); + await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); + const { findByText } = render(); + await findByText("Left Start 1"); + await findByText("TestUi2Provider RM1"); + await findByText("TestUi2Provider W1"); + }); - const frontstageProvider = new TestFrontstageUi2(); - FrontstageManager.addFrontstageProvider(frontstageProvider); - await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); - const { findByText } = render(); - await findByText("Left Start 1"); - await findByText("TestUi2Provider RM1"); - await findByText("TestUi2Provider W1"); - }); + it("should render pre-loaded extension widgets when state is restored", async () => { + UiItemsManager.register(new TestUi2Provider()); - it("should render pre-loaded extension widgets when state is restored", async () => { - UiItemsManager.register(new TestUi2Provider()); + const spy = sinon.spy(localStorageMock, "getItem"); + let state = createNineZoneState(); + state = addPanelWidget(state, "left", "leftStart", ["LeftStart1"]); + state = addTab(state, "LeftStart1"); + const setting = createFrontstageState(state); - const spy = sinon.spy(localStorageMock, "getItem"); - let state = createNineZoneState(); - state = addPanelWidget(state, "left", "leftStart", ["LeftStart1"]); - state = addTab(state, "LeftStart1"); - const setting = createFrontstageState(state); + const uiSettings = new UiSettingsStub(); + sinon.stub(uiSettings, "getSetting").resolves({ + status: UiSettingsStatus.Success, + setting, + }); - const uiSettings = new UiSettingsStub(); - sinon.stub(uiSettings, "getSetting").resolves({ - status: UiSettingsStatus.Success, - setting, - }); + const frontstageProvider = new TestFrontstageUi2(); + FrontstageManager.addFrontstageProvider(frontstageProvider); + await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); + const { findByText } = render(, { + wrapper: (props) => , + }); + await findByText("Left Start 1"); + await findByText("TestUi2Provider RM1"); + await findByText("TestUi2Provider W1"); - const frontstageProvider = new TestFrontstageUi2(); - FrontstageManager.addFrontstageProvider(frontstageProvider); - await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); - const { findByText } = render(, { - wrapper: (props) => , + sinon.assert.notCalled(spy); }); - await findByText("Left Start 1"); - await findByText("TestUi2Provider RM1"); - await findByText("TestUi2Provider W1"); - - sinon.assert.notCalled(spy); - }); - it("should render loaded extension widgets", async () => { - const frontstageProvider = new TestFrontstageUi2(); - FrontstageManager.addFrontstageProvider(frontstageProvider); - await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); - const { findByText } = render(); - await findByText("Left Start 1"); + it("should render loaded extension widgets", async () => { + const frontstageProvider = new TestFrontstageUi2(); + FrontstageManager.addFrontstageProvider(frontstageProvider); + await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); + const { findByText } = render(); + await findByText("Left Start 1"); - act(() => { - UiItemsManager.register(new TestUi2Provider()); + act(() => { + UiItemsManager.register(new TestUi2Provider()); + }); + await findByText("TestUi2Provider RM1"); + await findByText("TestUi2Provider W1"); }); - await findByText("TestUi2Provider RM1"); - await findByText("TestUi2Provider W1"); - }); - it("should stop rendering unloaded extension widgets", async () => { - const frontstageProvider = new TestFrontstageUi2(); - FrontstageManager.addFrontstageProvider(frontstageProvider); - await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); - const frontstageDef = FrontstageManager.activeFrontstageDef!; - render(); + it("should stop rendering unloaded extension widgets", async () => { + const frontstageProvider = new TestFrontstageUi2(); + FrontstageManager.addFrontstageProvider(frontstageProvider); + await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); + const frontstageDef = FrontstageManager.activeFrontstageDef!; + render(); - act(() => { - UiItemsManager.register(new TestUi2Provider()); - }); + act(() => { + UiItemsManager.register(new TestUi2Provider()); + }); - await TestUtils.flushAsyncOperations(); - should().exist(frontstageDef.nineZoneState!.tabs.LeftStart1, "LeftStart1"); - should().exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderRM1, "TestUi2ProviderRM1"); - should().exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderW1, "TestUi2ProviderW1"); - frontstageDef.nineZoneState!.widgets.rightMiddle.tabs.should.eql(["TestUi2ProviderRM1"], "rigthMiddle widget tabs"); - frontstageDef.nineZoneState!.widgets.leftStart.tabs.should.eql(["LeftStart1", "TestUi2ProviderW1"], "leftStart widget tabs"); + await TestUtils.flushAsyncOperations(); + should().exist(frontstageDef.nineZoneState!.tabs.LeftStart1, "LeftStart1"); + should().exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderRM1, "TestUi2ProviderRM1"); + should().exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderW1, "TestUi2ProviderW1"); + frontstageDef.nineZoneState!.widgets.rightMiddle.tabs.should.eql(["TestUi2ProviderRM1"], "rigthMiddle widget tabs"); + frontstageDef.nineZoneState!.widgets.leftStart.tabs.should.eql(["LeftStart1", "TestUi2ProviderW1"], "leftStart widget tabs"); - act(() => { - UiItemsManager.unregister("TestUi2Provider"); - }); + act(() => { + UiItemsManager.unregister("TestUi2Provider"); + }); - await TestUtils.flushAsyncOperations(); - should().exist(frontstageDef.nineZoneState!.tabs.LeftStart1, "LeftStart1 after unregister"); - should().not.exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderRM1, "TestUi2ProviderRM1 after unregister"); - should().not.exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderW1, "TestUi2ProviderW1 after unregister"); - should().not.exist(frontstageDef.nineZoneState!.widgets.rightMiddle, "rigthMiddle widget"); - frontstageDef.nineZoneState!.widgets.leftStart.tabs.should.eql(["LeftStart1"], "leftStart widget tabs"); - }); + await TestUtils.flushAsyncOperations(); + should().exist(frontstageDef.nineZoneState!.tabs.LeftStart1, "LeftStart1 after unregister"); + should().not.exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderRM1, "TestUi2ProviderRM1 after unregister"); + should().not.exist(frontstageDef.nineZoneState!.tabs.TestUi2ProviderW1, "TestUi2ProviderW1 after unregister"); + should().not.exist(frontstageDef.nineZoneState!.widgets.rightMiddle, "rigthMiddle widget"); + frontstageDef.nineZoneState!.widgets.leftStart.tabs.should.eql(["LeftStart1"], "leftStart widget tabs"); + }); - it("should render from 1.0 definition", async () => { - const frontstageProvider = new TestFrontstageUi1(); - FrontstageManager.addFrontstageProvider(frontstageProvider); - await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); - const frontstageDef = FrontstageManager.activeFrontstageDef!; - render(); + it("should render from 1.0 definition", async () => { + const frontstageProvider = new TestFrontstageUi1(); + FrontstageManager.addFrontstageProvider(frontstageProvider); + await FrontstageManager.setActiveFrontstageDef(frontstageProvider.frontstageDef); + const frontstageDef = FrontstageManager.activeFrontstageDef!; + render(); - await TestUtils.flushAsyncOperations(); - const state = frontstageDef.nineZoneState!; + await TestUtils.flushAsyncOperations(); + const state = frontstageDef.nineZoneState!; - state.panels.left.widgets.should.eql(["leftStart", "leftMiddle", "leftEnd"]); - state.panels.right.widgets.should.eql(["rightStart", "rightMiddle", "rightEnd"]); - state.panels.top.widgets.should.eql(["topStart", "topEnd"]); - state.panels.bottom.widgets.should.eql(["bottomStart", "bottomEnd"]); + state.panels.left.widgets.should.eql(["leftStart", "leftMiddle", "leftEnd"]); + state.panels.right.widgets.should.eql(["rightStart", "rightMiddle", "rightEnd"]); + state.panels.top.widgets.should.eql(["topStart", "topEnd"]); + state.panels.bottom.widgets.should.eql(["bottomStart", "bottomEnd"]); - state.widgets.leftStart.tabs.should.eql(["CenterLeft1", "LeftStart1"]); - state.widgets.leftMiddle.tabs.should.eql(["BottomLeft1", "LeftMiddle1"]); - state.widgets.leftEnd.tabs.should.eql(["Left1", "LeftEnd1"]); + state.widgets.leftStart.tabs.should.eql(["CenterLeft1", "LeftStart1"]); + state.widgets.leftMiddle.tabs.should.eql(["BottomLeft1", "LeftMiddle1"]); + state.widgets.leftEnd.tabs.should.eql(["Left1", "LeftEnd1"]); - state.widgets.rightStart.tabs.should.eql(["CenterRight1", "RightStart1"]); - state.widgets.rightMiddle.tabs.should.eql(["BottomRight1", "RightMiddle1"]); - state.widgets.rightEnd.tabs.should.eql(["Right1", "RightEnd1"]); + state.widgets.rightStart.tabs.should.eql(["CenterRight1", "RightStart1"]); + state.widgets.rightMiddle.tabs.should.eql(["BottomRight1", "RightMiddle1"]); + state.widgets.rightEnd.tabs.should.eql(["Right1", "RightEnd1"]); - state.widgets.topStart.tabs.should.eql(["Top1", "TopStart1"]); - state.widgets.topEnd.tabs.should.eql(["TopMost1", "TopEnd1"]); + state.widgets.topStart.tabs.should.eql(["Top1", "TopStart1"]); + state.widgets.topEnd.tabs.should.eql(["TopMost1", "TopEnd1"]); - state.widgets.bottomStart.tabs.should.eql(["Bottom1", "BottomStart1"]); - state.widgets.bottomEnd.tabs.should.eql(["BottomMost1", "BottomEnd1"]); + state.widgets.bottomStart.tabs.should.eql(["Bottom1", "BottomStart1"]); + state.widgets.bottomEnd.tabs.should.eql(["BottomMost1", "BottomEnd1"]); + }); }); }); diff --git a/ui/framework/src/test/widgets/NavigationWidget.test.snap b/ui/framework/src/test/widgets/NavigationWidget.test.snap index b8343cf8793..8f3740adf69 100644 --- a/ui/framework/src/test/widgets/NavigationWidget.test.snap +++ b/ui/framework/src/test/widgets/NavigationWidget.test.snap @@ -83,3 +83,87 @@ exports[`NavigationWidget NavigationWidget should render correctly 1`] = ` } /> `; + +exports[`NavigationWidget localStorage Wrapper NavigationWidget NavigationWidget should render correctly 1`] = ` + + + + + } + panelAlignment={0} + /> + } + navigationWidgetDef={ + NavigationWidgetDef { + "_classId": undefined, + "_defaultState": 4, + "_fillZone": false, + "_handleSyncUiEvent": [Function], + "_id": "navigationWidget", + "_isFloatingStateSupported": false, + "_isFloatingStateWindowResizable": true, + "_isFreeform": false, + "_isStatusBar": false, + "_isToolSettings": false, + "_label": "", + "_navigationAidId": "", + "_onWidgetStateChanged": undefined, + "_preferredPanelSize": undefined, + "_priority": 0, + "_restoreTransientState": undefined, + "_saveTransientState": undefined, + "_state": 4, + "_stateChanged": false, + "_syncEventIds": Array [], + "_tabLocation": Object { + "side": "left", + "tabIndex": 0, + "widgetId": "", + "widgetIndex": 0, + }, + "_toolbarBaseName": "[]NavigationWidget", + "_tooltip": "", + "_widgetType": 1, + "horizontalDirection": 4, + "horizontalItems": undefined, + "horizontalPanelAlignment": 1, + "verticalDirection": 1, + "verticalItems": undefined, + "verticalPanelAlignment": 0, + } + } + verticalToolbar={ + + + + + } + panelAlignment={0} + /> + } +/> +`; diff --git a/ui/framework/src/test/widgets/NavigationWidget.test.tsx b/ui/framework/src/test/widgets/NavigationWidget.test.tsx index 6909fdc4522..5092506cc54 100644 --- a/ui/framework/src/test/widgets/NavigationWidget.test.tsx +++ b/ui/framework/src/test/widgets/NavigationWidget.test.tsx @@ -17,46 +17,61 @@ import { ConfigurableUiManager } from "../../ui-framework/configurableui/Configu import { CoreTools } from "../../ui-framework/tools/CoreToolDefinitions"; import { FrameworkVersion } from "../../ui-framework/hooks/useFrameworkVersion"; import { NavigationAidControl } from "../../ui-framework/navigationaids/NavigationAidControl"; -import TestUtils from "../TestUtils"; +import TestUtils, { storageMock } from "../TestUtils"; import { UiShowHideManager } from "../../ui-framework/utils/UiShowHideManager"; -describe("NavigationWidget", () => { +describe("NavigationWidget localStorage Wrapper", () => { + + const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; + const localStorageMock = storageMock(); before(async () => { - await TestUtils.initializeUiFramework(); + Object.defineProperty(window, "localStorage", { + get: () => localStorageMock, + }); }); after(() => { - TestUtils.terminateUiFramework(); + Object.defineProperty(window, "localStorage", localStorageToRestore); }); - const widgetProps: AnyWidgetProps = { - id: "navigationWidget", - classId: "NavigationWidget", - defaultState: WidgetState.Open, - isFreeform: true, - iconSpec: "icon-home", - labelKey: "SampleApp:Test.my-label", - navigationAidId: "StandardRotationNavigationAid", - horizontalDirection: Direction.Top, - verticalDirection: Direction.Left, - }; + describe("NavigationWidget", () => { - it("NavigationWidgetDef from WidgetProps", () => { + before(async () => { + await TestUtils.initializeUiFramework(); + }); - const widgetDef = new NavigationWidgetDef(widgetProps); // eslint-disable-line deprecation/deprecation - expect(widgetDef).to.be.instanceof(NavigationWidgetDef); // eslint-disable-line deprecation/deprecation + after(() => { + TestUtils.terminateUiFramework(); + }); - const navigationWidgetDef = widgetDef; + const widgetProps: AnyWidgetProps = { + id: "navigationWidget", + classId: "NavigationWidget", + defaultState: WidgetState.Open, + isFreeform: true, + iconSpec: "icon-home", + labelKey: "SampleApp:Test.my-label", + navigationAidId: "StandardRotationNavigationAid", + horizontalDirection: Direction.Top, + verticalDirection: Direction.Left, + }; - const reactNode = navigationWidgetDef.reactNode; - expect(reactNode).to.not.be.undefined; + it("NavigationWidgetDef from WidgetProps", () => { - const cornerNode = navigationWidgetDef.renderCornerItem(); - expect(cornerNode).to.not.be.undefined; - }); + const widgetDef = new NavigationWidgetDef(widgetProps); // eslint-disable-line deprecation/deprecation + expect(widgetDef).to.be.instanceof(NavigationWidgetDef); // eslint-disable-line deprecation/deprecation + + const navigationWidgetDef = widgetDef; + + const reactNode = navigationWidgetDef.reactNode; + expect(reactNode).to.not.be.undefined; - const horizontalToolbar = + const cornerNode = navigationWidgetDef.renderCornerItem(); + expect(cornerNode).to.not.be.undefined; + }); + + const horizontalToolbar = { } />; - const verticalToolbar = + const verticalToolbar = { } />; - it("NavigationWidget should render", () => { - mount( - , - ); - }); + it("NavigationWidget should render", () => { + mount( + , + ); + }); - it("NavigationWidget should render correctly", () => { - shallow( - , - ).should.matchSnapshot(); - }); + it("NavigationWidget should render correctly", () => { + shallow( + , + ).should.matchSnapshot(); + }); - it("NavigationWidget should render with an item list", () => { - const hItemList = new ItemList([CoreTools.selectElementCommand]); - const vItemList = new ItemList([CoreTools.fitViewCommand]); + it("NavigationWidget should render with an item list", () => { + const hItemList = new ItemList([CoreTools.selectElementCommand]); + const vItemList = new ItemList([CoreTools.fitViewCommand]); - mount( - , - ); - }); + mount( + , + ); + }); - it("NavigationWidget should support update", () => { - const wrapper = mount( - , - ); - expect(wrapper.find(ToolButton).length).to.eq(4); - - wrapper.setProps({ verticalToolbar: undefined }); - wrapper.update(); - expect(wrapper.find(ToolButton).length).to.eq(2); - }); + it("NavigationWidget should support update", () => { + const wrapper = mount( + , + ); + expect(wrapper.find(ToolButton).length).to.eq(4); + + wrapper.setProps({ verticalToolbar: undefined }); + wrapper.update(); + expect(wrapper.find(ToolButton).length).to.eq(2); + }); - class TestContentControl extends ContentControl { - constructor(info: ConfigurableCreateInfo, options: any) { - super(info, options); + class TestContentControl extends ContentControl { + constructor(info: ConfigurableCreateInfo, options: any) { + super(info, options); - this.reactNode =
; + this.reactNode =
; + } } - } - class TestNavigationAidControl extends NavigationAidControl { - constructor(info: ConfigurableCreateInfo, options: any) { - super(info, options); + class TestNavigationAidControl extends NavigationAidControl { + constructor(info: ConfigurableCreateInfo, options: any) { + super(info, options); - this.reactNode =
Test Navigation Aid
; + this.reactNode =
Test Navigation Aid
; + } } - } - it("NavigationWidgetDef with invalid navigation aid should throw Error", () => { - const def = new NavigationWidgetDef({ // eslint-disable-line deprecation/deprecation - navigationAidId: "Aid1", + it("NavigationWidgetDef with invalid navigation aid should throw Error", () => { + const def = new NavigationWidgetDef({ // eslint-disable-line deprecation/deprecation + navigationAidId: "Aid1", + }); + ConfigurableUiManager.registerControl("Aid1", TestContentControl); + expect(() => def.renderCornerItem()).to.throw(Error); + ConfigurableUiManager.unregisterControl("Aid1"); }); - ConfigurableUiManager.registerControl("Aid1", TestContentControl); - expect(() => def.renderCornerItem()).to.throw(Error); - ConfigurableUiManager.unregisterControl("Aid1"); - }); - it("NavigationWidgetDef should handle updateNavigationAid", () => { - const def = new NavigationWidgetDef({ // eslint-disable-line deprecation/deprecation - navigationAidId: "Aid1", - }); - ConfigurableUiManager.registerControl("Aid1", TestNavigationAidControl); + it("NavigationWidgetDef should handle updateNavigationAid", () => { + const def = new NavigationWidgetDef({ // eslint-disable-line deprecation/deprecation + navigationAidId: "Aid1", + }); + ConfigurableUiManager.registerControl("Aid1", TestNavigationAidControl); - const element = def.reactNode; - expect(def.reactNode).to.eq(element); - const wrapper = mount(element as React.ReactElement); + const element = def.reactNode; + expect(def.reactNode).to.eq(element); + const wrapper = mount(element as React.ReactElement); - const connection = moq.Mock.ofType(); - FrontstageManager.setActiveNavigationAid("Aid1", connection.object); - wrapper.update(); + const connection = moq.Mock.ofType(); + FrontstageManager.setActiveNavigationAid("Aid1", connection.object); + wrapper.update(); - FrontstageManager.setActiveToolId(CoreTools.selectElementCommand.toolId); + FrontstageManager.setActiveToolId(CoreTools.selectElementCommand.toolId); - ConfigurableUiManager.unregisterControl("Aid1"); - }); + ConfigurableUiManager.unregisterControl("Aid1"); + }); - it("NavigationAidHost should render in 2.0 mode", () => { - mount( - - - ); - }); + it("NavigationAidHost should render in 2.0 mode", () => { + mount( + + + ); + }); - it("NavigationAidHost should render in 2.0 mode with snapWidgetOpacity", () => { - UiShowHideManager.snapWidgetOpacity = true; - mount( - - - ); - UiShowHideManager.snapWidgetOpacity = false; + it("NavigationAidHost should render in 2.0 mode with snapWidgetOpacity", () => { + UiShowHideManager.snapWidgetOpacity = true; + mount( + + + ); + UiShowHideManager.snapWidgetOpacity = false; + }); }); - }); diff --git a/ui/framework/src/test/widgets/ToolWidgetComposer.test.snap b/ui/framework/src/test/widgets/ToolWidgetComposer.test.snap index 4e69e853db6..84b983b0082 100644 --- a/ui/framework/src/test/widgets/ToolWidgetComposer.test.snap +++ b/ui/framework/src/test/widgets/ToolWidgetComposer.test.snap @@ -1,5 +1,40 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`FrameworkAccuDraw localStorage Wrapper ToolWidgetComposer ToolWidgetComposer should render correctly 1`] = ` + + + +`; + +exports[`FrameworkAccuDraw localStorage Wrapper ToolWidgetComposer ToolWidgetComposer with should render 1`] = ` + + + } + onMouseEnter={[Function]} + /> + +`; + exports[`ToolWidgetComposer ToolWidgetComposer should render correctly 1`] = ` { +describe("FrameworkAccuDraw localStorage Wrapper", () => { + + const localStorageToRestore = Object.getOwnPropertyDescriptor(window, "localStorage")!; + const localStorageMock = storageMock(); before(async () => { - await TestUtils.initializeUiFramework(); + Object.defineProperty(window, "localStorage", { + get: () => localStorageMock, + }); }); after(() => { - TestUtils.terminateUiFramework(); + Object.defineProperty(window, "localStorage", localStorageToRestore); }); - it("ToolWidgetComposer should render", () => { - mount(); - }); + describe("ToolWidgetComposer", () => { - it("ToolWidgetComposer should render correctly", () => { - shallow().should.matchSnapshot(); - }); + before(async () => { + await TestUtils.initializeUiFramework(); + }); - it("ToolWidgetComposer with should render", () => { - shallow(} />).should.matchSnapshot(); - }); + after(() => { + TestUtils.terminateUiFramework(); + }); - it("BackstageAppButtonProps should render", () => { - const wrapper = mount(); - wrapper.setProps({ icon: "icon-bentley" }); - }); + it("ToolWidgetComposer should render", () => { + mount(); + }); - it("BackstageAppButtonProps should update with default icon", () => { - const wrapper = mount(); - wrapper.setProps({ icon: undefined }); - }); + it("ToolWidgetComposer should render correctly", () => { + shallow().should.matchSnapshot(); + }); - it("BackstageAppButton should render in 2.0 mode", () => { - mount( - - - ); - }); + it("ToolWidgetComposer with should render", () => { + shallow(} />).should.matchSnapshot(); + }); + + it("BackstageAppButtonProps should render", () => { + const wrapper = mount(); + wrapper.setProps({ icon: "icon-bentley" }); + }); + + it("BackstageAppButtonProps should update with default icon", () => { + const wrapper = mount(); + wrapper.setProps({ icon: undefined }); + }); + it("BackstageAppButton should render in 2.0 mode", () => { + mount( + + + ); + }); + + }); }); diff --git a/ui/framework/src/ui-framework.ts b/ui/framework/src/ui-framework.ts index 6fa3c490b55..76756cf57d3 100644 --- a/ui/framework/src/ui-framework.ts +++ b/ui/framework/src/ui-framework.ts @@ -145,6 +145,7 @@ export * from "./ui-framework/selection/SelectionContextItemDef"; export * from "./ui-framework/selection/HideIsolateEmphasizeManager"; export * from "./ui-framework/selection/ClearEmphasisStatusField"; +export * from "./ui-framework/settings/ui/UiSettingsPage"; export * from "./ui-framework/settings/quantityformatting/QuantityFormat"; export * from "./ui-framework/shared/ActionButtonItemDef"; @@ -224,7 +225,8 @@ export * from "./ui-framework/uiadmin/FrameworkUiAdmin"; export * from "./ui-framework/uiprovider/DefaultDialogGridContainer"; -export * from "./ui-framework/uisettings/IModelAppUiSettings"; +export * from "./ui-framework/uisettings/AppUiSettings"; +export * from "./ui-framework/uisettings/UserSettingsStorage"; export * from "./ui-framework/uisettings/useUiSettings"; export * from "./ui-framework/utils/ViewUtilities"; diff --git a/ui/framework/src/ui-framework/UiFramework.ts b/ui/framework/src/ui-framework/UiFramework.ts index b42e403f8a9..80a0b347fe9 100644 --- a/ui/framework/src/ui-framework/UiFramework.ts +++ b/ui/framework/src/ui-framework/UiFramework.ts @@ -6,6 +6,8 @@ * @module Utilities */ +// cSpell:ignore configurableui clientservices + import { Store } from "redux"; import { GuidString, Logger, ProcessDetector } from "@bentley/bentleyjs-core"; import { isFrontendAuthorizationClient } from "@bentley/frontend-authorization-client"; @@ -16,7 +18,7 @@ import { Presentation } from "@bentley/presentation-frontend"; import { TelemetryEvent } from "@bentley/telemetry-client"; import { getClassName, UiError } from "@bentley/ui-abstract"; import { UiComponents } from "@bentley/ui-components"; -import { LocalUiSettings, SettingsManager, UiEvent, UiSettings } from "@bentley/ui-core"; +import { LocalSettingsStorage, SettingsManager, UiEvent, UiSettingsStorage } from "@bentley/ui-core"; import { BackstageManager } from "./backstage/BackstageManager"; import { DefaultIModelServices } from "./clientservices/DefaultIModelServices"; import { DefaultProjectServices } from "./clientservices/DefaultProjectServices"; @@ -34,11 +36,21 @@ import * as keyinPaletteTools from "./tools/KeyinPaletteTools"; import * as restoreLayoutTools from "./tools/RestoreLayoutTool"; import * as openSettingTools from "./tools/OpenSettingsTool"; import * as toolSettingTools from "./tools/ToolSettingsTools"; -import { UiShowHideManager } from "./utils/UiShowHideManager"; +import { UiShowHideManager, UiShowHideSettingsProvider } from "./utils/UiShowHideManager"; import { WidgetManager } from "./widgets/WidgetManager"; // cSpell:ignore Mobi +/** Interface to be implemented but any classes that wants to load their user settings when the UiSetting storage class is set. + * @beta + */ +export interface UserSettingsProvider { + /** Unique provider Id */ + providerId: string; + /** Function to load settings from settings storage */ + loadUserSettings(storage: UiSettingsStorage): Promise; +} + /** UiVisibility Event Args interface. * @public */ @@ -70,8 +82,8 @@ export class FrameworkVersionChangedEvent extends UiEvent = new Map(); + + /** Registers class that will be informed when the UserSettingsStorage location has been set or changed. This allows + * classes to load any previously saved settings from the new storage location. Common storage locations are the browser's + * local storage, or the iTwin Product Settings cloud storage available via the SettingsAdmin see `IModelApp.settingsAdmin`. + * @alpha + */ + public static registerUserSettingsProvider(entry: UserSettingsProvider) { + if (this._uiSettingsProviderRegistry.has(entry.providerId)) + return false; + + this._uiSettingsProviderRegistry.set(entry.providerId, entry); + return true; + } /** Get Show Ui event. * @public @@ -135,7 +160,7 @@ export class UiFramework { if (frameworkStateKey && store) UiFramework._frameworkStateKeyInStore = frameworkStateKey; - // set up namespace and register akk tools from package + // set up namespace and register all tools from package const frameworkNamespace = UiFramework._i18n.registerNamespace(UiFramework.i18nNamespace); [ restoreLayoutTools, @@ -174,10 +199,13 @@ export class UiFramework { UiFramework._initialized = true; + // initialize any standalone settings providers that don't need to have defaults set by iModelApp + UiShowHideSettingsProvider.initialize (); + return readFinishedPromise; } - /** Unregisters the UiFramework internationalization service namespace */ + /** Un-registers the UiFramework internationalization service namespace */ public static terminate() { UiFramework._store = undefined; UiFramework._frameworkStateKeyInStore = "frameworkState"; @@ -218,8 +246,12 @@ export class UiFramework { * @beta */ public static get frameworkState(): FrameworkState | undefined { - // eslint-disable-next-line dot-notation - return UiFramework.store.getState()[UiFramework.frameworkStateKey]; + try { + // eslint-disable-next-line dot-notation + return UiFramework.store.getState()[UiFramework.frameworkStateKey]; + } catch (_e){ + return undefined; + } } /** The Redux store */ @@ -322,7 +354,7 @@ export class UiFramework { } public static setAccudrawSnapMode(snapMode: SnapMode) { - UiFramework.store.dispatch({ type: ConfigurableUiActionId.SetSnapMode, payload: snapMode }); + UiFramework.dispatchActionToStore(ConfigurableUiActionId.SetSnapMode, snapMode, true); } public static getAccudrawSnapMode(): SnapMode { @@ -377,8 +409,18 @@ export class UiFramework { } /** @beta */ - public static setUiSettings(uiSettings: UiSettings, immediateSync = false) { - UiFramework._uiSettings = uiSettings; + public static async setUiSettingsStorage(storage: UiSettingsStorage, immediateSync = false) { + if (UiFramework._uiSettingsStorage === storage) + return; + + UiFramework._uiSettingsStorage = storage; + + // let any registered providers to load values from the new storage location + const providerKeys = [...this._uiSettingsProviderRegistry.keys()]; + for await (const key of providerKeys) { + await this._uiSettingsProviderRegistry.get(key)!.loadUserSettings(storage); + } + // istanbul ignore next if (immediateSync) SyncUiEventDispatcher.dispatchImmediateSyncUiEvent(SyncUiEventId.UiSettingsChanged); @@ -387,10 +429,8 @@ export class UiFramework { } /** @beta */ - public static getUiSettings(): UiSettings { - if (undefined === UiFramework._uiSettings) - UiFramework._uiSettings = new LocalUiSettings(); - return UiFramework._uiSettings; + public static getUiSettingsStorage(): UiSettingsStorage { + return UiFramework._uiSettingsStorage; } /** @beta */ @@ -446,7 +486,10 @@ export class UiFramework { } public static setColorTheme(theme: string) { - UiFramework.store.dispatch({ type: ConfigurableUiActionId.SetTheme, payload: theme }); + if (UiFramework.getColorTheme() === theme) + return; + + UiFramework.dispatchActionToStore(ConfigurableUiActionId.SetTheme, theme, true); } public static getColorTheme(): string { @@ -454,7 +497,10 @@ export class UiFramework { } public static setWidgetOpacity(opacity: number) { - UiFramework.store.dispatch({ type: ConfigurableUiActionId.SetWidgetOpacity, payload: opacity }); + if (UiFramework.getWidgetOpacity() === opacity) + return; + + UiFramework.dispatchActionToStore(ConfigurableUiActionId.SetWidgetOpacity, opacity, true); } public static getWidgetOpacity(): number { @@ -468,9 +514,23 @@ export class UiFramework { /** Returns the Ui Version. * @beta */ - // istanbul ignore next public static get uiVersion(): string { - return UiFramework._uiVersion; + return UiFramework.frameworkState ? UiFramework.frameworkState.configurableUiState.frameworkVersion : this._uiVersion; + } + + public static setUiVersion(version: string) { + if (UiFramework.uiVersion === version) + return; + + UiFramework.dispatchActionToStore(ConfigurableUiActionId.SetFrameworkVersion, version === "1"?"1":"2", true); + } + + public static get useDragInteraction(): boolean { + return UiFramework.frameworkState ? UiFramework.frameworkState.configurableUiState.useDragInteraction : false; + } + + public static setUseDragInteraction(useDragInteraction: boolean) { + UiFramework.dispatchActionToStore(ConfigurableUiActionId.SetDragInteraction, useDragInteraction, true); } /** Send logging message to the telemetry system @@ -490,15 +550,6 @@ export class UiFramework { // eslint-disable-next-line @typescript-eslint/no-floating-promises UiFramework.postTelemetry(`Ui Version changed to ${args.version} `, "F2772C81-962D-4755-807C-2D675A5FF399"); UiFramework._uiVersion = args.version; - - // If Ui Version 1, save widget opacity - // istanbul ignore if - if (args.oldVersion === "1") - UiFramework._version1WidgetOpacity = UiFramework.getWidgetOpacity(); - - // If Ui Version 1, restore widget opacity; otherwise, set widget opacity to 1.0 to basically turn the feature off. - // This fixes use of "backdrop-filter: blur(10px)"" CSS. - UiFramework.setWidgetOpacity(args.version === "1" ? UiFramework._version1WidgetOpacity : 1.0); }; // istanbul ignore next diff --git a/ui/framework/src/ui-framework/accudraw/AccuDrawFieldContainer.tsx b/ui/framework/src/ui-framework/accudraw/AccuDrawFieldContainer.tsx index ec94876dd29..d79a29e0262 100644 --- a/ui/framework/src/ui-framework/accudraw/AccuDrawFieldContainer.tsx +++ b/ui/framework/src/ui-framework/accudraw/AccuDrawFieldContainer.tsx @@ -14,7 +14,7 @@ import { AccuDrawSetFieldFocusEventArgs, AccuDrawSetFieldLockEventArgs, AccuDrawSetModeEventArgs, AccuDrawUiAdmin, IconSpecUtilities, } from "@bentley/ui-abstract"; -import { CommonProps, IconSpec, Orientation, UiSettings } from "@bentley/ui-core"; +import { CommonProps, IconSpec, Orientation, UiSettingsStorage } from "@bentley/ui-core"; import { AccuDrawInputField } from "./AccuDrawInputField"; import { CompassMode, IModelApp, ItemField, ScreenViewport, SelectedViewportChangedArgs } from "@bentley/imodeljs-frontend"; import { KeyboardShortcutManager } from "../keyboardshortcut/KeyboardShortcut"; @@ -30,8 +30,8 @@ import { ColorDef } from "@bentley/imodeljs-common"; export interface AccuDrawFieldContainerProps extends CommonProps { /** Orientation of the fields */ orientation: Orientation; - /** Optional parameter for persistent UI settings. Defaults to LocalUiSettings. */ - uiSettings?: UiSettings; + /** Optional parameter for persistent UI settings. Defaults to LocalSettingsStorage. */ + uiSettingsStorage?: UiSettingsStorage; /** @internal */ showZOverride?: boolean; } @@ -52,7 +52,7 @@ const defaultDistanceIcon = IconSpecUtilities.createSvgIconSpec(distanceIconSvg) /** @alpha */ export function AccuDrawFieldContainer(props: AccuDrawFieldContainerProps) { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { className, style, orientation, uiSettings, showZOverride, ...otherProps } = props; + const { className, style, orientation, uiSettingsStorage, showZOverride, ...otherProps } = props; const [containerIndex] = React.useState(() => ++AccuDrawContainerIndex); const xInputRef = React.useRef(null); diff --git a/ui/framework/src/ui-framework/accudraw/FrameworkAccuDraw.ts b/ui/framework/src/ui-framework/accudraw/FrameworkAccuDraw.ts index 83721d0eb31..5449798aa95 100644 --- a/ui/framework/src/ui-framework/accudraw/FrameworkAccuDraw.ts +++ b/ui/framework/src/ui-framework/accudraw/FrameworkAccuDraw.ts @@ -8,10 +8,11 @@ import { AccuDraw, BeButtonEvent, CompassMode, IModelApp, ItemField, NotifyMessageDetails, OutputMessagePriority, QuantityType, RotationMode } from "@bentley/imodeljs-frontend"; import { AccuDrawField, AccuDrawMode, AccuDrawSetFieldValueFromUiEventArgs, AccuDrawUiAdmin, ConditionalBooleanValue } from "@bentley/ui-abstract"; -import { UiFramework } from "../UiFramework"; +import { UiFramework, UserSettingsProvider } from "../UiFramework"; import { SyncUiEventDispatcher, SyncUiEventId } from "../syncui/SyncUiEventDispatcher"; import { AccuDrawUiSettings } from "./AccuDrawUiSettings"; import { BeUiEvent } from "@bentley/bentleyjs-core"; +import { UiSettings, UiSettingsStatus } from "@bentley/ui-core"; // cspell:ignore dont @@ -49,9 +50,12 @@ const rotationModeToKeyMap = new Map([ export class AccuDrawUiSettingsChangedEvent extends BeUiEvent<{}> { } /** @internal */ -export class FrameworkAccuDraw extends AccuDraw { +export class FrameworkAccuDraw extends AccuDraw implements UserSettingsProvider { private static _displayNotifications = false; private static _uiSettings: AccuDrawUiSettings | undefined; + private static _settingsNamespace = "AppUiSettings"; + private static _notificationsKey = "AccuDrawNotifications"; + public readonly providerId = "FrameworkAccuDraw"; /** Determines if AccuDraw.rotationMode === RotationMode.Top */ public static readonly isTopRotationConditional = new ConditionalBooleanValue(() => IModelApp.accuDraw.rotationMode === RotationMode.Top, [SyncUiEventId.AccuDrawRotationChanged]); @@ -75,7 +79,16 @@ export class FrameworkAccuDraw extends AccuDraw { /** Determines if notifications should be displayed for AccuDraw changes */ public static get displayNotifications(): boolean { return FrameworkAccuDraw._displayNotifications; } - public static set displayNotifications(v: boolean) { FrameworkAccuDraw._displayNotifications = v; } + public static set displayNotifications(v: boolean) { + FrameworkAccuDraw._displayNotifications = v; + void UiFramework.getUiSettingsStorage().saveSetting (this._settingsNamespace, this._notificationsKey, v); + } + + public async loadUserSettings(storage: UiSettings): Promise { + const result = await storage.getSetting (FrameworkAccuDraw._settingsNamespace, FrameworkAccuDraw._notificationsKey); + if (result.status === UiSettingsStatus.Success) + FrameworkAccuDraw._displayNotifications = result.setting; + } /** AccuDraw User Interface settings */ public static get uiSettings(): AccuDrawUiSettings | undefined { return FrameworkAccuDraw._uiSettings; } @@ -87,6 +100,7 @@ export class FrameworkAccuDraw extends AccuDraw { constructor() { super(); AccuDrawUiAdmin.onAccuDrawSetFieldValueFromUiEvent.addListener(this.handleSetFieldValueFromUiEvent); + UiFramework.registerUserSettingsProvider(this); } private handleSetFieldValueFromUiEvent = async (args: AccuDrawSetFieldValueFromUiEventArgs) => { diff --git a/ui/framework/src/ui-framework/configurableui/state.ts b/ui/framework/src/ui-framework/configurableui/state.ts index eb7ed6cb3b0..f04102b999e 100644 --- a/ui/framework/src/ui-framework/configurableui/state.ts +++ b/ui/framework/src/ui-framework/configurableui/state.ts @@ -21,6 +21,8 @@ export enum ConfigurableUiActionId { SetTheme = "configurableui:set_theme", SetToolPrompt = "configurableui:set_toolprompt", SetWidgetOpacity = "configurableui:set_widget_opacity", + SetDragInteraction = "configurableui:set-drag-interaction", + SetFrameworkVersion = "configurableui:set-framework-version", } /** The portion of state managed by the ConfigurableUiReducer. @@ -31,6 +33,8 @@ export interface ConfigurableUiState { toolPrompt: string; theme: string; widgetOpacity: number; + useDragInteraction: boolean; + frameworkVersion: string; } /** used on first call of ConfigurableUiReducer */ @@ -39,6 +43,8 @@ const initialState: ConfigurableUiState = { toolPrompt: "", theme: SYSTEM_PREFERRED_COLOR_THEME, widgetOpacity: WIDGET_OPACITY_DEFAULT, + useDragInteraction: false, + frameworkVersion: "1", }; /** An object with a function that creates each ConfigurableUiReducer that can be handled by our reducer. @@ -55,6 +61,8 @@ export const ConfigurableUiActions = { // eslint-disable-line @typescript-esli setWidgetOpacity: // istanbul ignore next (opacity: number) => createAction(ConfigurableUiActionId.SetWidgetOpacity, opacity), + setDragInteraction: (dragInteraction: boolean) => createAction(ConfigurableUiActionId.SetDragInteraction, dragInteraction), + setFrameworkVersion: (frameworkVersion: string) => createAction(ConfigurableUiActionId.SetFrameworkVersion, frameworkVersion), }; /** Union of ConfigurableUi Redux actions @@ -65,35 +73,28 @@ export type ConfigurableUiActionsUnion = ActionsUnion(null); const keyinSeparator = "--#--"; const [historyKeyins, setHistoryKeyins] = React.useState([]); - const uiSettings = useUiSettingsContext(); + const uiSettingsStorage = useUiSettingsStorageContext(); React.useEffect(() => { async function fetchState() { - const settingsResult = await uiSettings.getSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY); + const settingsResult = await uiSettingsStorage.getSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY); // istanbul ignore else if (UiSettingsStatus.Success === settingsResult.status) { const filteredHistory = (settingsResult.setting as string[]).filter((keyin)=>{ @@ -64,18 +64,18 @@ export function KeyinPalettePanel({ keyins, onKeyinExecuted, historyLength: allo } fetchState(); // eslint-disable-line @typescript-eslint/no-floating-promises - }, [uiSettings]); + }, [uiSettingsStorage]); // istanbul ignore next const storeHistoryKeyins = React.useCallback(async (value: string[]) => { // eslint-disable-next-line @typescript-eslint/no-floating-promises - const result = await uiSettings.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, value); + const result = await uiSettingsStorage.saveSetting(KEYIN_PALETTE_NAMESPACE, KEYIN_HISTORY_KEY, value); if (result.status !== UiSettingsStatus.Success) { const briefMessage = UiFramework.translate("keyinbrowser.couldNotSaveHistory"); const errorDetails = new NotifyMessageDetails(OutputMessagePriority.Error, briefMessage); IModelApp.notifications.outputMessage(errorDetails); } - }, [uiSettings]); + }, [uiSettingsStorage]); const allKeyins = React.useMemo(() => { const availableKeyins = []; diff --git a/ui/framework/src/ui-framework/settings/quantityformatting/QuantityFormat.tsx b/ui/framework/src/ui-framework/settings/quantityformatting/QuantityFormat.tsx index a39bd487f54..8a0414b841e 100644 --- a/ui/framework/src/ui-framework/settings/quantityformatting/QuantityFormat.tsx +++ b/ui/framework/src/ui-framework/settings/quantityformatting/QuantityFormat.tsx @@ -50,7 +50,7 @@ export function getQuantityFormatsSettingsManagerEntry(itemPriority: number, opt itemPriority, tabId: "uifw:Quantity", label: UiFramework.translate("settings.quantity-formatting.label"), subLabel: UiFramework.translate("settings.quantity-formatting.subLabel"), - page: , isDisabled: false, icon: "icon-measure", @@ -62,7 +62,7 @@ export function getQuantityFormatsSettingsManagerEntry(itemPriority: number, opt /** UI Component shown in settings page to set the active Presentation Unit System and to set format overrides. * @beta */ -export function QuantityFormatSettingsPanel({initialQuantityType, availableUnitSystems}: QuantityFormatterSettingsOptions) { +export function QuantityFormatSettingsPage({initialQuantityType, availableUnitSystems}: QuantityFormatterSettingsOptions) { const [activeUnitSystemKey, setActiveUnitSystemKey] = React.useState(IModelApp.quantityFormatter.activeUnitSystem); const [activeQuantityType, setActiveQuantityType] = React.useState(getQuantityTypeKey(initialQuantityType)); const [activeFormatterSpec, setActiveFormatterSpec] = diff --git a/ui/framework/src/ui-framework/settings/quantityformatting/UnitSystemSelector.tsx b/ui/framework/src/ui-framework/settings/quantityformatting/UnitSystemSelector.tsx index 0217d97defc..cdbf482a7c8 100644 --- a/ui/framework/src/ui-framework/settings/quantityformatting/UnitSystemSelector.tsx +++ b/ui/framework/src/ui-framework/settings/quantityformatting/UnitSystemSelector.tsx @@ -11,14 +11,18 @@ import { UiFramework } from "../../UiFramework"; import { Select } from "@bentley/ui-core"; import { UnitSystemKey } from "@bentley/imodeljs-frontend"; -/** @alpha */ +/** Props for [[UnitSystemSelector]] + * @beta + */ export interface UnitSystemSelectorProps { selectedUnitSystemKey: UnitSystemKey; onUnitSystemSelected: (unitSystem: UnitSystemKey) => void; availableUnitSystems: Set; } -/** @alpha */ +/** Select control to set the "active" Presentation Unit System. This setting determine what units are display for quantity values (i.e. foot vs meter). + * @alpha + */ export function UnitSystemSelector(props: UnitSystemSelectorProps) { // eslint-disable-line @typescript-eslint/naming-convention const label = React.useRef (UiFramework.translate("presentationUnitSystem.selector-label")); const { selectedUnitSystemKey, onUnitSystemSelected, availableUnitSystems } = props; diff --git a/ui/framework/src/ui-framework/settings/ui/UiSettingsPage.scss b/ui/framework/src/ui-framework/settings/ui/UiSettingsPage.scss new file mode 100644 index 00000000000..e946aa3b215 --- /dev/null +++ b/ui/framework/src/ui-framework/settings/ui/UiSettingsPage.scss @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Bentley Systems, Incorporated. All rights reserved. +* See LICENSE.md in the project root for license terms and full copyright notice. +*--------------------------------------------------------------------------------------------*/ +@import "~@bentley/ui-core/lib/ui-core/style/themecolors"; +@import "~@bentley/ui-core/lib/ui-core/style/typography"; +@import "~@bentley/ui-core/lib/ui-core/base/base"; + +// cspell:ignore leftpanel rightpanel + +$settings-leftpanel-width: 225px; +$settings-rightpanel-width: 220px; + +.components-settings-container { + height: calc(100% - 50px); + overflow: hidden; + } + +.uifw-settings { + background: $buic-background-dialog; + color: $buic-text-color; + border-radius: 3px; + font-size: $uicore-font-size; + display: flex; + flex-direction: column; +} + +.uifw-settings-item { + display: flex; + + > .panel { + flex: 1; + display: flex; + box-sizing: border-box; + } + + > .left-panel { + flex-direction: column; + min-width: $settings-leftpanel-width; + padding: 20px 15px 20px 15px; + + > .title { + font-size: 18px; + } + + > .description { + margin-top: 10px; + font-size: 12px; + color: $buic-text-color-muted; + } + } + + > .right-panel { + display:flex; + align-items: center; + min-width: $settings-rightpanel-width; + padding: 30px 50px 30px 30px; + + .toggle { + margin-right: 10px; + } + + .select-theme-container { + flex: 1; + } + } +} diff --git a/ui/framework/src/ui-framework/settings/ui/UiSettingsPage.tsx b/ui/framework/src/ui-framework/settings/ui/UiSettingsPage.tsx new file mode 100644 index 00000000000..8f48b2c2900 --- /dev/null +++ b/ui/framework/src/ui-framework/settings/ui/UiSettingsPage.tsx @@ -0,0 +1,208 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Bentley Systems, Incorporated. All rights reserved. +* See LICENSE.md in the project root for license terms and full copyright notice. +*--------------------------------------------------------------------------------------------*/ +/** @packageDocumentation + * @module Settings + */ + +// cSpell:ignore configurableui checkmark + +import widowSettingsIconSvg from "@bentley/icons-generic/icons/window-settings.svg?sprite"; +import "./UiSettingsPage.scss"; +import * as React from "react"; +import { Select, SelectOption, SettingsTabEntry, Slider, Toggle } from "@bentley/ui-core"; +import { UiFramework } from "../../UiFramework"; +import { ColorTheme, SYSTEM_PREFERRED_COLOR_THEME } from "../../theme/ThemeManager"; +import { UiShowHideManager } from "../../utils/UiShowHideManager"; +import { SyncUiEventArgs, SyncUiEventDispatcher, SyncUiEventId } from "../../syncui/SyncUiEventDispatcher"; +import { IconSpecUtilities } from "@bentley/ui-abstract"; + +/** UiSettingsPage displaying the active UI settings. This page lets users set the following settings. + * + * - theme - Dark, Light, or based on OS preference. + * - auto hide - Starts a timer and blanks out ui components that overlay content if there is no mouse movement for a period of time. + * - drag interaction - If set, toolbar group buttons require a press and drag or a long press to open. In this mode a child action + * item is shown as the group button and is activated when button is clicked. If a different child item is selected, it becomes the + * active group button item. + * - use proximity - Changes the opacity of toolbar from transparent to opaque as the mouse moves closer. + * - snap widget opacity - triggers an abrupt change from transparent to opaque for tool and navigation widgets, instead of a gradual change based on mouse location. + * - widget opacity - determines how transparent floating widgets in V2 and all widgets in V1 become when the mouse in not in them. + * - UI version - if allowed by props, the UI version can be toggled between V1 and V2. + * + * @beta + */ +export function UiSettingsPage({allowSettingUiFrameworkVersion}: {allowSettingUiFrameworkVersion: boolean}) { + const themeTitle = React.useRef(UiFramework.translate("settings.uiSettingsPage.themeTitle")); + const themeDescription = React.useRef(UiFramework.translate("settings.uiSettingsPage.themeDescription")); + const autoHideTitle = React.useRef(UiFramework.translate("settings.uiSettingsPage.autoHideTitle")); + const autoHideDescription = React.useRef(UiFramework.translate("settings.uiSettingsPage.autoHideDescription")); + const dragInteractionTitle = React.useRef(UiFramework.translate("settings.uiSettingsPage.dragInteractionTitle")); + const dragInteractionDescription = React.useRef(UiFramework.translate("settings.uiSettingsPage.dragInteractionDescription")); + const useNewUiTitle = React.useRef(UiFramework.translate("settings.uiSettingsPage.newUiTitle")); + const useNewUiDescription = React.useRef(UiFramework.translate("settings.uiSettingsPage.newUiDescription")); + const useProximityOpacityTitle = React.useRef(UiFramework.translate("settings.uiSettingsPage.useProximityOpacityTitle")); + const useProximityOpacityDescription = React.useRef(UiFramework.translate("settings.uiSettingsPage.useProximityOpacityDescription")); + const snapWidgetOpacityTitle = React.useRef(UiFramework.translate("settings.uiSettingsPage.snapWidgetOpacityTitle")); + const snapWidgetOpacityDescription = React.useRef(UiFramework.translate("settings.uiSettingsPage.snapWidgetOpacityDescription")); + const darkLabel = React.useRef(UiFramework.translate("settings.uiSettingsPage.dark")); + const lightLabel = React.useRef(UiFramework.translate("settings.uiSettingsPage.light")); + const systemPreferredLabel = React.useRef(UiFramework.translate("settings.uiSettingsPage.systemPreferred")); + const widgetOpacityTitle = React.useRef(UiFramework.translate("settings.uiSettingsPage.widgetOpacityTitle")); + const widgetOpacityDescription = React.useRef(UiFramework.translate("settings.uiSettingsPage.widgetOpacityDescription")); + + const [theme, setTheme] = React.useState(()=>UiFramework.getColorTheme()); + const [uiVersion, setUiVersion] = React.useState(()=>UiFramework.uiVersion); + const [useDragInteraction, setUseDragInteraction] = React.useState(()=>UiFramework.useDragInteraction); + const [widgetOpacity, setWidgetOpacity] = React.useState(()=>UiFramework.getWidgetOpacity()); + const [autoHideUi, setAutoHideUi] = React.useState(()=>UiShowHideManager.autoHideUi); + const [useProximityOpacity, setUseProximityOpacity] = React.useState(()=>UiShowHideManager.useProximityOpacity); + const [snapWidgetOpacity, setSnapWidgetOpacity] = React.useState(()=>UiShowHideManager.snapWidgetOpacity); + + React.useEffect(() => { + const syncIdsOfInterest = ["configurableui:set_theme", "configurableui:set_widget_opacity", + "configurableui:set-drag-interaction","configurableui:set-framework-version", SyncUiEventId.ShowHideManagerSettingChange ]; + + const handleSyncUiEvent = (args: SyncUiEventArgs) => { + // istanbul ignore else + if (syncIdsOfInterest.some((value: string): boolean => args.eventIds.has(value))) { + if (UiFramework.getColorTheme() !== theme) + setTheme(UiFramework.getColorTheme()); + if (UiShowHideManager.autoHideUi !== autoHideUi) + setAutoHideUi(UiShowHideManager.autoHideUi); + if (UiFramework.uiVersion !== uiVersion) + setUiVersion(UiFramework.uiVersion); + if (UiFramework.useDragInteraction !== useDragInteraction) + setUseDragInteraction(UiFramework.useDragInteraction); + if (UiFramework.getWidgetOpacity() !== widgetOpacity) + setWidgetOpacity(UiFramework.getWidgetOpacity()); + if (UiShowHideManager.autoHideUi !== autoHideUi) + setAutoHideUi(UiShowHideManager.autoHideUi); + if (UiShowHideManager.useProximityOpacity !== useProximityOpacity) + setUseProximityOpacity(UiShowHideManager.useProximityOpacity); + if (UiShowHideManager.snapWidgetOpacity !== snapWidgetOpacity) + setSnapWidgetOpacity(UiShowHideManager.snapWidgetOpacity); + } + }; + return SyncUiEventDispatcher.onSyncUiEvent.addListener(handleSyncUiEvent); + }, [autoHideUi, snapWidgetOpacity, theme, uiVersion, useDragInteraction, useProximityOpacity, widgetOpacity]); + + const defaultThemeOption = { label: systemPreferredLabel.current, value: SYSTEM_PREFERRED_COLOR_THEME }; + const themeOptions: Array = [ + defaultThemeOption, + { label: lightLabel.current, value: ColorTheme.Light }, + { label: darkLabel.current, value: ColorTheme.Dark }, + ]; + + const onThemeChange = React.useCallback((e: React.ChangeEvent) => { + e.preventDefault(); + UiFramework.setColorTheme(e.target.value); + }, []); + + const onAutoHideChange = React.useCallback(async () => { + UiShowHideManager.autoHideUi = !UiShowHideManager.autoHideUi; + },[]); + + const onUseProximityOpacityChange = React.useCallback(async () => { + UiShowHideManager.useProximityOpacity = !UiShowHideManager.useProximityOpacity; + },[]); + + const onSnapWidgetOpacityChange = React.useCallback(async () => { + UiShowHideManager.snapWidgetOpacity = !UiShowHideManager.snapWidgetOpacity; + },[]); + + const onWidgetOpacityChange = React.useCallback(async (values: readonly number[]) => { + // istanbul ignore else + if (values.length > 0) { + UiFramework.setWidgetOpacity(values[0]); + } + },[]); + const onToggleFrameworkVersion = React.useCallback(async () => { + UiFramework.setUiVersion(UiFramework.uiVersion === "2"?"1":"2"); + },[]); + + const onToggleDragInteraction = React.useCallback(async () => { + UiFramework.setUseDragInteraction(!UiFramework.useDragInteraction); + },[]); + + const currentTheme = UiFramework.getColorTheme(); + + return ( +
+ +