mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-10-13 15:28:05 +01:00
Upgrade Cosmos SDK to v4.3 (#2137)
* Upgrade Cosmos SDK to v4.3 * push pkg lock * fix tests * fix package-lock.json * fix package-lock * fix package-lock.json * fix package-lock.json * log console warning when RU limit is reached * fix tests * fix format * fix tests * added description to RU limit message * show warning icon on tab header --------- Co-authored-by: Asier Isayas <aisayas@microsoft.com>
This commit is contained in:
parent
c5ed537109
commit
0fc6647627
197
package-lock.json
generated
197
package-lock.json
generated
@ -10,7 +10,7 @@
|
|||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/arm-cosmosdb": "9.1.0",
|
"@azure/arm-cosmosdb": "9.1.0",
|
||||||
"@azure/cosmos": "4.2.0-beta.1",
|
"@azure/cosmos": "4.3.0",
|
||||||
"@azure/cosmos-language-service": "0.0.5",
|
"@azure/cosmos-language-service": "0.0.5",
|
||||||
"@azure/identity": "4.5.0",
|
"@azure/identity": "4.5.0",
|
||||||
"@azure/msal-browser": "2.14.2",
|
"@azure/msal-browser": "2.14.2",
|
||||||
@ -290,57 +290,69 @@
|
|||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-rest-pipeline": {
|
"node_modules/@azure/core-http-compat": {
|
||||||
"version": "1.18.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.0.tgz",
|
||||||
"integrity": "sha512-QSoGUp4Eq/gohEFNJaUOwTN7BCc2nHTjjbm75JT0aD7W65PWM1H/tItz0GsABn22uaKyGxiMhWQLt2r+FGU89Q==",
|
"integrity": "sha512-qLQujmUypBBG0gxHd0j6/Jdmul6ttl24c8WGiLXIk7IHXdBlfoBqW27hyz3Xn6xbfdyVSarl1Ttbk0AwnZBYCw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/abort-controller": "^2.0.0",
|
"@azure/abort-controller": "^2.0.0",
|
||||||
"@azure/core-auth": "^1.8.0",
|
"@azure/core-client": "^1.3.0",
|
||||||
"@azure/core-tracing": "^1.0.1",
|
"@azure/core-rest-pipeline": "^1.20.0"
|
||||||
"@azure/core-util": "^1.11.0",
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@azure/core-lro": {
|
||||||
|
"version": "2.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz",
|
||||||
|
"integrity": "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-util": "^1.2.0",
|
||||||
"@azure/logger": "^1.0.0",
|
"@azure/logger": "^1.0.0",
|
||||||
"http-proxy-agent": "^7.0.0",
|
|
||||||
"https-proxy-agent": "^7.0.0",
|
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-rest-pipeline/node_modules/agent-base": {
|
"node_modules/@azure/core-lro/node_modules/tslib": {
|
||||||
"version": "7.1.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
},
|
||||||
|
"node_modules/@azure/core-paging": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.3.4"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-rest-pipeline/node_modules/http-proxy-agent": {
|
"node_modules/@azure/core-paging/node_modules/tslib": {
|
||||||
"version": "7.0.2",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
"dependencies": {
|
|
||||||
"agent-base": "^7.1.0",
|
|
||||||
"debug": "^4.3.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-rest-pipeline/node_modules/https-proxy-agent": {
|
"node_modules/@azure/core-rest-pipeline": {
|
||||||
"version": "7.0.5",
|
"version": "1.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.20.0.tgz",
|
||||||
"integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
|
"integrity": "sha512-ASoP8uqZBS3H/8N8at/XwFr6vYrRP3syTK0EUjDXQy0Y1/AUS+QeIRThKmTNJO2RggvBBxaXDPM7YoIwDGeA0g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"agent-base": "^7.0.2",
|
"@azure/abort-controller": "^2.0.0",
|
||||||
"debug": "4"
|
"@azure/core-auth": "^1.8.0",
|
||||||
|
"@azure/core-tracing": "^1.0.1",
|
||||||
|
"@azure/core-util": "^1.11.0",
|
||||||
|
"@azure/logger": "^1.0.0",
|
||||||
|
"@typespec/ts-http-runtime": "^0.2.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-rest-pipeline/node_modules/tslib": {
|
"node_modules/@azure/core-rest-pipeline/node_modules/tslib": {
|
||||||
@ -379,15 +391,16 @@
|
|||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/@azure/cosmos": {
|
"node_modules/@azure/cosmos": {
|
||||||
"version": "4.2.0-beta.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.2.0-beta.1.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.3.0.tgz",
|
||||||
"integrity": "sha512-mREONehm1DxjEKXGaNU6Wmpf9Ckb9IrhKFXhDFVs45pxmoEb3y2s/Ub0owuFmqlphpcS1zgtYQn5exn+lwnJuQ==",
|
"integrity": "sha512-0Ls3l1uWBBSphx6YRhnM+w7rSvq8qVugBCdO6kSiNuRYXEf6+YWLjbzz4e7L2kkz/6ScFdZIOJYP+XtkiRYOhA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/abort-controller": "^2.0.0",
|
"@azure/abort-controller": "^2.0.0",
|
||||||
"@azure/core-auth": "^1.7.1",
|
"@azure/core-auth": "^1.7.1",
|
||||||
"@azure/core-rest-pipeline": "^1.15.1",
|
"@azure/core-rest-pipeline": "^1.15.1",
|
||||||
"@azure/core-tracing": "^1.1.1",
|
"@azure/core-tracing": "^1.1.1",
|
||||||
"@azure/core-util": "^1.8.1",
|
"@azure/core-util": "^1.8.1",
|
||||||
|
"@azure/keyvault-keys": "^4.8.0",
|
||||||
"fast-json-stable-stringify": "^2.1.0",
|
"fast-json-stable-stringify": "^2.1.0",
|
||||||
"jsbi": "^4.3.0",
|
"jsbi": "^4.3.0",
|
||||||
"priorityqueuejs": "^2.0.0",
|
"priorityqueuejs": "^2.0.0",
|
||||||
@ -492,14 +505,66 @@
|
|||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
},
|
},
|
||||||
"node_modules/@azure/logger": {
|
"node_modules/@azure/keyvault-common": {
|
||||||
"version": "1.0.4",
|
"version": "2.0.0",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@azure/keyvault-common/-/keyvault-common-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-wRLVaroQtOqfg60cxkzUkGKrKMsCP6uYXAOomOIysSMyt1/YM0eUn9LqieAWM8DLcU4+07Fio2YGpPeqUbpP9w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-auth": "^1.3.0",
|
||||||
|
"@azure/core-client": "^1.5.0",
|
||||||
|
"@azure/core-rest-pipeline": "^1.8.0",
|
||||||
|
"@azure/core-tracing": "^1.0.0",
|
||||||
|
"@azure/core-util": "^1.10.0",
|
||||||
|
"@azure/logger": "^1.1.4",
|
||||||
"tslib": "^2.2.0"
|
"tslib": "^2.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0.0"
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@azure/keyvault-common/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
},
|
||||||
|
"node_modules/@azure/keyvault-keys": {
|
||||||
|
"version": "4.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/keyvault-keys/-/keyvault-keys-4.9.0.tgz",
|
||||||
|
"integrity": "sha512-ZBP07+K4Pj3kS4TF4XdkqFcspWwBHry3vJSOFM5k5ZABvf7JfiMonvaFk2nBF6xjlEbMpz5PE1g45iTMme0raQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-auth": "^1.3.0",
|
||||||
|
"@azure/core-client": "^1.5.0",
|
||||||
|
"@azure/core-http-compat": "^2.0.1",
|
||||||
|
"@azure/core-lro": "^2.2.0",
|
||||||
|
"@azure/core-paging": "^1.1.1",
|
||||||
|
"@azure/core-rest-pipeline": "^1.8.1",
|
||||||
|
"@azure/core-tracing": "^1.0.0",
|
||||||
|
"@azure/core-util": "^1.0.0",
|
||||||
|
"@azure/keyvault-common": "^2.0.0",
|
||||||
|
"@azure/logger": "^1.0.0",
|
||||||
|
"tslib": "^2.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@azure/keyvault-keys/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
},
|
||||||
|
"node_modules/@azure/logger": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-0hKEzLhpw+ZTAfNJyRrn6s+V0nDWzXk9OjBr2TiGIu0OfMr5s2V4FpKLTAK3Ca5r5OKLbf4hkOGDPyiRjie/jA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@typespec/ts-http-runtime": "^0.2.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/logger/node_modules/tslib": {
|
"node_modules/@azure/logger/node_modules/tslib": {
|
||||||
@ -13074,6 +13139,56 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@typespec/ts-http-runtime": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-Gz/Sm64+Sq/vklJu1tt9t+4R2lvnud8NbTD/ZfpZtMiUX7YeVpCA8j6NSW8ptwcoLL+NmYANwqP8DV0q/bwl2w==",
|
||||||
|
"dependencies": {
|
||||||
|
"http-proxy-agent": "^7.0.0",
|
||||||
|
"https-proxy-agent": "^7.0.0",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typespec/ts-http-runtime/node_modules/agent-base": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typespec/ts-http-runtime/node_modules/http-proxy-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
|
||||||
|
"dependencies": {
|
||||||
|
"agent-base": "^7.1.0",
|
||||||
|
"debug": "^4.3.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typespec/ts-http-runtime/node_modules/https-proxy-agent": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||||
|
"dependencies": {
|
||||||
|
"agent-base": "^7.1.2",
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typespec/ts-http-runtime/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
},
|
||||||
"node_modules/@ungap/url-search-params": {
|
"node_modules/@ungap/url-search-params": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/arm-cosmosdb": "9.1.0",
|
"@azure/arm-cosmosdb": "9.1.0",
|
||||||
"@azure/cosmos": "4.2.0-beta.1",
|
"@azure/cosmos": "4.3.0",
|
||||||
"@azure/cosmos-language-service": "0.0.5",
|
"@azure/cosmos-language-service": "0.0.5",
|
||||||
"@azure/identity": "4.5.0",
|
"@azure/identity": "4.5.0",
|
||||||
"@azure/msal-browser": "2.14.2",
|
"@azure/msal-browser": "2.14.2",
|
||||||
|
6
preview/package-lock.json
generated
6
preview/package-lock.json
generated
@ -10,7 +10,7 @@
|
|||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/arm-cosmosdb": "9.1.0",
|
"@azure/arm-cosmosdb": "9.1.0",
|
||||||
"@azure/cosmos": "4.2.0-beta.1",
|
"@azure/cosmos": "4.3.0",
|
||||||
"@azure/cosmos-language-service": "0.0.5",
|
"@azure/cosmos-language-service": "0.0.5",
|
||||||
"@azure/identity": "4.5.0",
|
"@azure/identity": "4.5.0",
|
||||||
"@azure/msal-browser": "2.14.2",
|
"@azure/msal-browser": "2.14.2",
|
||||||
@ -377,8 +377,8 @@
|
|||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/@azure/cosmos": {
|
"node_modules/@azure/cosmos": {
|
||||||
"version": "4.2.0-beta.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.2.0-beta.1.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.3.0.tgz",
|
||||||
"integrity": "sha512-mREONehm1DxjEKXGaNU6Wmpf9Ckb9IrhKFXhDFVs45pxmoEb3y2s/Ub0owuFmqlphpcS1zgtYQn5exn+lwnJuQ==",
|
"integrity": "sha512-mREONehm1DxjEKXGaNU6Wmpf9Ckb9IrhKFXhDFVs45pxmoEb3y2s/Ub0owuFmqlphpcS1zgtYQn5exn+lwnJuQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/abort-controller": "^2.0.0",
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { QueryOperationOptions } from "@azure/cosmos";
|
|
||||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
import * as Constants from "../Common/Constants";
|
import * as Constants from "../Common/Constants";
|
||||||
import { QueryResults } from "../Contracts/ViewModels";
|
import { QueryResults } from "../Contracts/ViewModels";
|
||||||
@ -14,18 +13,14 @@ interface QueryResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MinimalQueryIterator {
|
export interface MinimalQueryIterator {
|
||||||
fetchNext: (queryOperationOptions?: QueryOperationOptions) => Promise<QueryResponse>;
|
fetchNext: () => Promise<QueryResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick<QueryIterator<any>, "fetchNext">;
|
// Pick<QueryIterator<any>, "fetchNext">;
|
||||||
|
|
||||||
export function nextPage(
|
export function nextPage(documentsIterator: MinimalQueryIterator, firstItemIndex: number): Promise<QueryResults> {
|
||||||
documentsIterator: MinimalQueryIterator,
|
|
||||||
firstItemIndex: number,
|
|
||||||
queryOperationOptions?: QueryOperationOptions,
|
|
||||||
): Promise<QueryResults> {
|
|
||||||
TelemetryProcessor.traceStart(Action.ExecuteQuery);
|
TelemetryProcessor.traceStart(Action.ExecuteQuery);
|
||||||
return documentsIterator.fetchNext(queryOperationOptions).then((response) => {
|
return documentsIterator.fetchNext().then((response) => {
|
||||||
TelemetryProcessor.traceSuccess(Action.ExecuteQuery, { dataExplorerArea: Constants.Areas.Tab });
|
TelemetryProcessor.traceSuccess(Action.ExecuteQuery, { dataExplorerArea: Constants.Areas.Tab });
|
||||||
const documents = response.resources;
|
const documents = response.resources;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { monaco } from "Explorer/LazyMonaco";
|
import { monaco } from "Explorer/LazyMonaco";
|
||||||
import { getRUThreshold, ruThresholdEnabled } from "Shared/StorageUtility";
|
|
||||||
|
|
||||||
export enum QueryErrorSeverity {
|
export enum QueryErrorSeverity {
|
||||||
Error = "Error",
|
Error = "Error",
|
||||||
@ -103,20 +102,9 @@ export interface ErrorEnrichment {
|
|||||||
learnMoreUrl?: string;
|
learnMoreUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const REPLACEMENT_MESSAGES: Record<string, (original: string) => string> = {
|
const REPLACEMENT_MESSAGES: Record<string, (original: string) => string> = {};
|
||||||
OPERATION_RU_LIMIT_EXCEEDED: (original) => {
|
|
||||||
if (ruThresholdEnabled()) {
|
|
||||||
const threshold = getRUThreshold();
|
|
||||||
return `Query exceeded the Request Unit (RU) limit of ${threshold} RUs. You can change this limit in Data Explorer settings.`;
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const HELP_LINKS: Record<string, string> = {
|
const HELP_LINKS: Record<string, string> = {};
|
||||||
OPERATION_RU_LIMIT_EXCEEDED:
|
|
||||||
"https://learn.microsoft.com/en-us/azure/cosmos-db/data-explorer#configure-request-unit-threshold",
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class QueryError {
|
export default class QueryError {
|
||||||
message: string;
|
message: string;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
exports[`getCommonQueryOptions builds the correct default options objects 1`] = `
|
exports[`getCommonQueryOptions builds the correct default options objects 1`] = `
|
||||||
{
|
{
|
||||||
"disableNonStreamingOrderByQuery": true,
|
"disableNonStreamingOrderByQuery": true,
|
||||||
|
"enableQueryControl": false,
|
||||||
"enableScanInQuery": true,
|
"enableScanInQuery": true,
|
||||||
"forceQueryPlan": true,
|
"forceQueryPlan": true,
|
||||||
"maxDegreeOfParallelism": 0,
|
"maxDegreeOfParallelism": 0,
|
||||||
@ -14,6 +15,7 @@ exports[`getCommonQueryOptions builds the correct default options objects 1`] =
|
|||||||
exports[`getCommonQueryOptions reads from localStorage 1`] = `
|
exports[`getCommonQueryOptions reads from localStorage 1`] = `
|
||||||
{
|
{
|
||||||
"disableNonStreamingOrderByQuery": true,
|
"disableNonStreamingOrderByQuery": true,
|
||||||
|
"enableQueryControl": false,
|
||||||
"enableScanInQuery": true,
|
"enableScanInQuery": true,
|
||||||
"forceQueryPlan": true,
|
"forceQueryPlan": true,
|
||||||
"maxDegreeOfParallelism": 17,
|
"maxDegreeOfParallelism": 17,
|
||||||
|
@ -26,6 +26,7 @@ export const getCommonQueryOptions = (options: FeedOptions): FeedOptions => {
|
|||||||
options.maxItemCount ||
|
options.maxItemCount ||
|
||||||
(storedItemPerPageSetting !== undefined && storedItemPerPageSetting) ||
|
(storedItemPerPageSetting !== undefined && storedItemPerPageSetting) ||
|
||||||
Queries.itemsPerPage;
|
Queries.itemsPerPage;
|
||||||
|
options.enableQueryControl = LocalStorageUtility.getEntryBoolean(StorageKey.QueryControlEnabled);
|
||||||
options.maxDegreeOfParallelism = LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism);
|
options.maxDegreeOfParallelism = LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism);
|
||||||
options.disableNonStreamingOrderByQuery = !isVectorSearchEnabled();
|
options.disableNonStreamingOrderByQuery = !isVectorSearchEnabled();
|
||||||
return options;
|
return options;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { QueryOperationOptions } from "@azure/cosmos";
|
|
||||||
import { QueryResults } from "../../Contracts/ViewModels";
|
import { QueryResults } from "../../Contracts/ViewModels";
|
||||||
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
||||||
import { getEntityName } from "../DocumentUtility";
|
import { getEntityName } from "../DocumentUtility";
|
||||||
@ -9,13 +8,12 @@ export const queryDocumentsPage = async (
|
|||||||
resourceName: string,
|
resourceName: string,
|
||||||
documentsIterator: MinimalQueryIterator,
|
documentsIterator: MinimalQueryIterator,
|
||||||
firstItemIndex: number,
|
firstItemIndex: number,
|
||||||
queryOperationOptions?: QueryOperationOptions,
|
|
||||||
): Promise<QueryResults> => {
|
): Promise<QueryResults> => {
|
||||||
const entityName = getEntityName();
|
const entityName = getEntityName();
|
||||||
const clearMessage = logConsoleProgress(`Querying ${entityName} for container ${resourceName}`);
|
const clearMessage = logConsoleProgress(`Querying ${entityName} for container ${resourceName}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result: QueryResults = await nextPage(documentsIterator, firstItemIndex, queryOperationOptions);
|
const result: QueryResults = await nextPage(documentsIterator, firstItemIndex);
|
||||||
const itemCount = (result.documents && result.documents.length) || 0;
|
const itemCount = (result.documents && result.documents.length) || 0;
|
||||||
logConsoleInfo(`Successfully fetched ${itemCount} ${entityName} for container ${resourceName}`);
|
logConsoleInfo(`Successfully fetched ${itemCount} ${entityName} for container ${resourceName}`);
|
||||||
return result;
|
return result;
|
||||||
|
@ -50,6 +50,7 @@ export interface QueryResults extends QueryResultsMetadata {
|
|||||||
roundTrips?: number;
|
roundTrips?: number;
|
||||||
headers?: any;
|
headers?: any;
|
||||||
queryMetrics?: QueryMetrics;
|
queryMetrics?: QueryMetrics;
|
||||||
|
ruThresholdExceeded?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Button {
|
export interface Button {
|
||||||
|
@ -16,7 +16,12 @@ import * as StorageUtility from "../../../Shared/StorageUtility";
|
|||||||
import { LocalStorageUtility, StorageKey } from "../../../Shared/StorageUtility";
|
import { LocalStorageUtility, StorageKey } from "../../../Shared/StorageUtility";
|
||||||
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
import {
|
||||||
|
logConsoleError,
|
||||||
|
logConsoleInfo,
|
||||||
|
logConsoleProgress,
|
||||||
|
logConsoleWarning,
|
||||||
|
} from "../../../Utils/NotificationConsoleUtils";
|
||||||
import { EditorReact } from "../../Controls/Editor/EditorReact";
|
import { EditorReact } from "../../Controls/Editor/EditorReact";
|
||||||
import * as InputTypeaheadComponent from "../../Controls/InputTypeahead/InputTypeaheadComponent";
|
import * as InputTypeaheadComponent from "../../Controls/InputTypeahead/InputTypeaheadComponent";
|
||||||
import * as TabComponent from "../../Controls/Tabs/TabComponent";
|
import * as TabComponent from "../../Controls/Tabs/TabComponent";
|
||||||
@ -1083,6 +1088,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
|||||||
public static reportToConsole(type: ConsoleDataType.InProgress, msg: string, ...errorData: any[]): () => void;
|
public static reportToConsole(type: ConsoleDataType.InProgress, msg: string, ...errorData: any[]): () => void;
|
||||||
public static reportToConsole(type: ConsoleDataType.Info, msg: string, ...errorData: any[]): void;
|
public static reportToConsole(type: ConsoleDataType.Info, msg: string, ...errorData: any[]): void;
|
||||||
public static reportToConsole(type: ConsoleDataType.Error, msg: string, ...errorData: any[]): void;
|
public static reportToConsole(type: ConsoleDataType.Error, msg: string, ...errorData: any[]): void;
|
||||||
|
public static reportToConsole(type: ConsoleDataType.Warning, msg: string, ...errorData: any[]): void;
|
||||||
public static reportToConsole(type: ConsoleDataType, msg: string, ...errorData: any[]): void | (() => void) {
|
public static reportToConsole(type: ConsoleDataType, msg: string, ...errorData: any[]): void | (() => void) {
|
||||||
let errorDataStr = "";
|
let errorDataStr = "";
|
||||||
if (errorData && errorData.length > 0) {
|
if (errorData && errorData.length > 0) {
|
||||||
@ -1099,6 +1105,8 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
|||||||
return logConsoleInfo(consoleMessage);
|
return logConsoleInfo(consoleMessage);
|
||||||
case ConsoleDataType.InProgress:
|
case ConsoleDataType.InProgress:
|
||||||
return logConsoleProgress(consoleMessage);
|
return logConsoleProgress(consoleMessage);
|
||||||
|
case ConsoleDataType.Warning:
|
||||||
|
return logConsoleWarning(consoleMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,4 +13,5 @@ export enum ConsoleDataType {
|
|||||||
Info = 0,
|
Info = 0,
|
||||||
Error = 1,
|
Error = 1,
|
||||||
InProgress = 2,
|
InProgress = 2,
|
||||||
|
Warning = 3,
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import ErrorRedIcon from "../../../../images/error_red.svg";
|
|||||||
import infoBubbleIcon from "../../../../images/info-bubble-9x9.svg";
|
import infoBubbleIcon from "../../../../images/info-bubble-9x9.svg";
|
||||||
import InfoIcon from "../../../../images/info_color.svg";
|
import InfoIcon from "../../../../images/info_color.svg";
|
||||||
import LoadingIcon from "../../../../images/loading.svg";
|
import LoadingIcon from "../../../../images/loading.svg";
|
||||||
|
import WarningIcon from "../../../../images/warning.svg";
|
||||||
import { ClientDefaults, KeyCodes } from "../../../Common/Constants";
|
import { ClientDefaults, KeyCodes } from "../../../Common/Constants";
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
import { useNotificationConsole } from "../../../hooks/useNotificationConsole";
|
import { useNotificationConsole } from "../../../hooks/useNotificationConsole";
|
||||||
@ -91,6 +92,9 @@ export class NotificationConsoleComponent extends React.Component<
|
|||||||
const numInfoItems = this.state.allConsoleData.filter(
|
const numInfoItems = this.state.allConsoleData.filter(
|
||||||
(data: ConsoleData) => data.type === ConsoleDataType.Info,
|
(data: ConsoleData) => data.type === ConsoleDataType.Info,
|
||||||
).length;
|
).length;
|
||||||
|
const numWarningItems = this.state.allConsoleData.filter(
|
||||||
|
(data: ConsoleData) => data.type === ConsoleDataType.Warning,
|
||||||
|
).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="notificationConsoleContainer">
|
<div className="notificationConsoleContainer">
|
||||||
@ -118,6 +122,10 @@ export class NotificationConsoleComponent extends React.Component<
|
|||||||
<img src={infoBubbleIcon} alt="Info items" />
|
<img src={infoBubbleIcon} alt="Info items" />
|
||||||
<span className="numInfoItems">{numInfoItems}</span>
|
<span className="numInfoItems">{numInfoItems}</span>
|
||||||
</span>
|
</span>
|
||||||
|
<span className="notificationConsoleHeaderIconWithData">
|
||||||
|
<img src={WarningIcon} alt="Warning items" />
|
||||||
|
<span className="numWarningItems">{numWarningItems}</span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
{userContext.features.pr && <PrPreview pr={userContext.features.pr} />}
|
{userContext.features.pr && <PrPreview pr={userContext.features.pr} />}
|
||||||
<span className="consoleSplitter" />
|
<span className="consoleSplitter" />
|
||||||
@ -198,6 +206,7 @@ export class NotificationConsoleComponent extends React.Component<
|
|||||||
{item.type === ConsoleDataType.Info && <img className="infoIcon" src={InfoIcon} alt="info" />}
|
{item.type === ConsoleDataType.Info && <img className="infoIcon" src={InfoIcon} alt="info" />}
|
||||||
{item.type === ConsoleDataType.Error && <img className="errorIcon" src={ErrorRedIcon} alt="error" />}
|
{item.type === ConsoleDataType.Error && <img className="errorIcon" src={ErrorRedIcon} alt="error" />}
|
||||||
{item.type === ConsoleDataType.InProgress && <img className="loaderIcon" src={LoaderIcon} alt="in progress" />}
|
{item.type === ConsoleDataType.InProgress && <img className="loaderIcon" src={LoaderIcon} alt="in progress" />}
|
||||||
|
{item.type === ConsoleDataType.Warning && <img className="warningIcon" src={WarningIcon} alt="warning" />}
|
||||||
<span className="date">{item.date}</span>
|
<span className="date">{item.date}</span>
|
||||||
<span className="message" role="alert" aria-live="assertive">
|
<span className="message" role="alert" aria-live="assertive">
|
||||||
{item.message}
|
{item.message}
|
||||||
|
@ -59,6 +59,19 @@ exports[`NotificationConsoleComponent renders the console 1`] = `
|
|||||||
0
|
0
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
<span
|
||||||
|
className="notificationConsoleHeaderIconWithData"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Warning items"
|
||||||
|
src={{}}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="numWarningItems"
|
||||||
|
>
|
||||||
|
0
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="consoleSplitter"
|
className="consoleSplitter"
|
||||||
@ -229,6 +242,19 @@ exports[`NotificationConsoleComponent renders the console 2`] = `
|
|||||||
1
|
1
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
<span
|
||||||
|
className="notificationConsoleHeaderIconWithData"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Warning items"
|
||||||
|
src={{}}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="numWarningItems"
|
||||||
|
>
|
||||||
|
0
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="consoleSplitter"
|
className="consoleSplitter"
|
||||||
|
@ -180,6 +180,11 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
? LocalStorageUtility.getEntryNumber(StorageKey.MaxWaitTimeInSeconds)
|
? LocalStorageUtility.getEntryNumber(StorageKey.MaxWaitTimeInSeconds)
|
||||||
: Constants.Queries.DefaultMaxWaitTimeInSeconds,
|
: Constants.Queries.DefaultMaxWaitTimeInSeconds,
|
||||||
);
|
);
|
||||||
|
const [queryControlEnabled, setQueryControlEnabled] = useState<boolean>(
|
||||||
|
LocalStorageUtility.hasItem(StorageKey.QueryControlEnabled)
|
||||||
|
? LocalStorageUtility.getEntryString(StorageKey.QueryControlEnabled) === "true"
|
||||||
|
: false,
|
||||||
|
);
|
||||||
const [maxDegreeOfParallelism, setMaxDegreeOfParallelism] = useState<number>(
|
const [maxDegreeOfParallelism, setMaxDegreeOfParallelism] = useState<number>(
|
||||||
LocalStorageUtility.hasItem(StorageKey.MaxDegreeOfParellism)
|
LocalStorageUtility.hasItem(StorageKey.MaxDegreeOfParellism)
|
||||||
? LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism)
|
? LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism)
|
||||||
@ -204,6 +209,7 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
!isEmulator;
|
!isEmulator;
|
||||||
const shouldShowGraphAutoVizOption = userContext.apiType === "Gremlin" && !isEmulator;
|
const shouldShowGraphAutoVizOption = userContext.apiType === "Gremlin" && !isEmulator;
|
||||||
const shouldShowCrossPartitionOption = userContext.apiType !== "Gremlin" && !isEmulator;
|
const shouldShowCrossPartitionOption = userContext.apiType !== "Gremlin" && !isEmulator;
|
||||||
|
const shouldShowEnhancedQueryControl = userContext.apiType === "SQL";
|
||||||
const shouldShowParallelismOption = userContext.apiType !== "Gremlin" && !isEmulator;
|
const shouldShowParallelismOption = userContext.apiType !== "Gremlin" && !isEmulator;
|
||||||
const showEnableEntraIdRbac =
|
const showEnableEntraIdRbac =
|
||||||
isDataplaneRbacSupported(userContext.apiType) &&
|
isDataplaneRbacSupported(userContext.apiType) &&
|
||||||
@ -381,6 +387,7 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
LocalStorageUtility.setEntryNumber(StorageKey.MaxWaitTimeInSeconds, MaxWaitTimeInSeconds);
|
LocalStorageUtility.setEntryNumber(StorageKey.MaxWaitTimeInSeconds, MaxWaitTimeInSeconds);
|
||||||
LocalStorageUtility.setEntryString(StorageKey.ContainerPaginationEnabled, containerPaginationEnabled.toString());
|
LocalStorageUtility.setEntryString(StorageKey.ContainerPaginationEnabled, containerPaginationEnabled.toString());
|
||||||
LocalStorageUtility.setEntryString(StorageKey.IsCrossPartitionQueryEnabled, crossPartitionQueryEnabled.toString());
|
LocalStorageUtility.setEntryString(StorageKey.IsCrossPartitionQueryEnabled, crossPartitionQueryEnabled.toString());
|
||||||
|
LocalStorageUtility.setEntryString(StorageKey.QueryControlEnabled, queryControlEnabled.toString());
|
||||||
LocalStorageUtility.setEntryNumber(StorageKey.MaxDegreeOfParellism, maxDegreeOfParallelism);
|
LocalStorageUtility.setEntryNumber(StorageKey.MaxDegreeOfParellism, maxDegreeOfParallelism);
|
||||||
LocalStorageUtility.setEntryString(StorageKey.PriorityLevel, priorityLevel.toString());
|
LocalStorageUtility.setEntryString(StorageKey.PriorityLevel, priorityLevel.toString());
|
||||||
LocalStorageUtility.setEntryString(StorageKey.CopilotSampleDBEnabled, copilotSampleDBEnabled.toString());
|
LocalStorageUtility.setEntryString(StorageKey.CopilotSampleDBEnabled, copilotSampleDBEnabled.toString());
|
||||||
@ -410,6 +417,7 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
`Updated items per page setting to ${LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage)}`,
|
`Updated items per page setting to ${LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage)}`,
|
||||||
);
|
);
|
||||||
logConsoleInfo(`${crossPartitionQueryEnabled ? "Enabled" : "Disabled"} cross-partition query feed option`);
|
logConsoleInfo(`${crossPartitionQueryEnabled ? "Enabled" : "Disabled"} cross-partition query feed option`);
|
||||||
|
logConsoleInfo(`${queryControlEnabled ? "Enabled" : "Disabled"} query control option`);
|
||||||
logConsoleInfo(
|
logConsoleInfo(
|
||||||
`Updated the max degree of parallelism query feed option to ${LocalStorageUtility.getEntryNumber(
|
`Updated the max degree of parallelism query feed option to ${LocalStorageUtility.getEntryNumber(
|
||||||
StorageKey.MaxDegreeOfParellism,
|
StorageKey.MaxDegreeOfParellism,
|
||||||
@ -760,7 +768,6 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
)}
|
)}
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
|
||||||
<AccordionItem value="5">
|
<AccordionItem value="5">
|
||||||
<AccordionHeader>
|
<AccordionHeader>
|
||||||
<div className={styles.header}>RU Limit</div>
|
<div className={styles.header}>RU Limit</div>
|
||||||
@ -943,6 +950,38 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
)}
|
)}
|
||||||
|
{shouldShowEnhancedQueryControl && (
|
||||||
|
<AccordionItem value="10">
|
||||||
|
<AccordionHeader>
|
||||||
|
<div className={styles.header}>Enhanced query control</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
Query up to the max degree of parallelism.
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/performance-tips-query-sdk?tabs=v3&pivots=programming-language-nodejs#enhanced-query-control"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
Learn more{" "}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<Checkbox
|
||||||
|
styles={{
|
||||||
|
label: { padding: 0 },
|
||||||
|
}}
|
||||||
|
className="padding"
|
||||||
|
ariaLabel="EnableQueryControl"
|
||||||
|
checked={queryControlEnabled}
|
||||||
|
onChange={() => setQueryControlEnabled(!queryControlEnabled)}
|
||||||
|
label="Enable query control"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
)}
|
||||||
{shouldShowParallelismOption && (
|
{shouldShowParallelismOption && (
|
||||||
<AccordionItem value="10">
|
<AccordionItem value="10">
|
||||||
<AccordionHeader>
|
<AccordionHeader>
|
||||||
|
@ -495,6 +495,51 @@ exports[`Settings Pane should render Default properly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
<AccordionItem
|
||||||
|
value="10"
|
||||||
|
>
|
||||||
|
<AccordionHeader>
|
||||||
|
<div
|
||||||
|
className="___15c001r_0000000 fq02s40"
|
||||||
|
>
|
||||||
|
Enhanced query control
|
||||||
|
</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div
|
||||||
|
className="___1dfa554_0000000 fo7qwa0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="___10gar1i_0000000 f1fow5ox f1ugzwwg"
|
||||||
|
>
|
||||||
|
Query up to the max degree of parallelism.
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/performance-tips-query-sdk?tabs=v3&pivots=programming-language-nodejs#enhanced-query-control"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
|
||||||
|
Learn more
|
||||||
|
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
ariaLabel="EnableQueryControl"
|
||||||
|
checked={false}
|
||||||
|
className="padding"
|
||||||
|
label="Enable query control"
|
||||||
|
onChange={[Function]}
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"label": {
|
||||||
|
"padding": 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
<AccordionItem
|
<AccordionItem
|
||||||
value="10"
|
value="10"
|
||||||
>
|
>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import { FeedOptions, QueryOperationOptions } from "@azure/cosmos";
|
import { FeedOptions } from "@azure/cosmos";
|
||||||
import { AuthType } from "AuthType";
|
import { AuthType } from "AuthType";
|
||||||
import QueryError, { createMonacoErrorLocationResolver, createMonacoMarkersForQueryErrors } from "Common/QueryError";
|
import QueryError, { createMonacoErrorLocationResolver, createMonacoMarkersForQueryErrors } from "Common/QueryError";
|
||||||
import { SplitterDirection } from "Common/Splitter";
|
import { SplitterDirection } from "Common/Splitter";
|
||||||
@ -19,7 +19,7 @@ import { CosmosFluentProvider } from "Explorer/Theme/ThemeUtil";
|
|||||||
import { useSelectedNode } from "Explorer/useSelectedNode";
|
import { useSelectedNode } from "Explorer/useSelectedNode";
|
||||||
import { KeyboardAction } from "KeyboardShortcuts";
|
import { KeyboardAction } from "KeyboardShortcuts";
|
||||||
import { QueryConstants } from "Shared/Constants";
|
import { QueryConstants } from "Shared/Constants";
|
||||||
import { LocalStorageUtility, StorageKey, getRUThreshold, ruThresholdEnabled } from "Shared/StorageUtility";
|
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
import { Allotment } from "allotment";
|
import { Allotment } from "allotment";
|
||||||
import { useClientWriteEnabled } from "hooks/useClientWriteEnabled";
|
import { useClientWriteEnabled } from "hooks/useClientWriteEnabled";
|
||||||
@ -369,22 +369,9 @@ class QueryTabComponentImpl extends React.Component<QueryTabComponentImplProps,
|
|||||||
this.setState({
|
this.setState({
|
||||||
isExecutionError: false,
|
isExecutionError: false,
|
||||||
});
|
});
|
||||||
|
this.props.tabsBaseInstance.isExecutionWarning(false);
|
||||||
let queryOperationOptions: QueryOperationOptions;
|
|
||||||
if (userContext.apiType === "SQL" && ruThresholdEnabled()) {
|
|
||||||
const ruThreshold: number = getRUThreshold();
|
|
||||||
queryOperationOptions = {
|
|
||||||
ruCapPerOperation: ruThreshold,
|
|
||||||
} as QueryOperationOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
const queryDocuments = async (firstItemIndex: number) =>
|
const queryDocuments = async (firstItemIndex: number) =>
|
||||||
await queryDocumentsPage(
|
await queryDocumentsPage(this.props.collection && this.props.collection.id(), this._iterator, firstItemIndex);
|
||||||
this.props.collection && this.props.collection.id(),
|
|
||||||
this._iterator,
|
|
||||||
firstItemIndex,
|
|
||||||
queryOperationOptions,
|
|
||||||
);
|
|
||||||
this.props.tabsBaseInstance.isExecuting(true);
|
this.props.tabsBaseInstance.isExecuting(true);
|
||||||
this.setState({
|
this.setState({
|
||||||
isExecuting: true,
|
isExecuting: true,
|
||||||
@ -424,6 +411,9 @@ class QueryTabComponentImpl extends React.Component<QueryTabComponentImplProps,
|
|||||||
firstItemIndex,
|
firstItemIndex,
|
||||||
queryDocuments,
|
queryDocuments,
|
||||||
);
|
);
|
||||||
|
if (queryResults.ruThresholdExceeded) {
|
||||||
|
this.props.tabsBaseInstance.isExecutionWarning(true);
|
||||||
|
}
|
||||||
this.setState({ queryResults, errors: [] });
|
this.setState({ queryResults, errors: [] });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.props.tabsBaseInstance.isExecutionError(true);
|
this.props.tabsBaseInstance.isExecutionError(true);
|
||||||
|
@ -18,6 +18,7 @@ import React, { MutableRefObject, useEffect, useRef, useState } from "react";
|
|||||||
import loadingIcon from "../../../images/circular_loader_black_16x16.gif";
|
import loadingIcon from "../../../images/circular_loader_black_16x16.gif";
|
||||||
import errorIcon from "../../../images/close-black.svg";
|
import errorIcon from "../../../images/close-black.svg";
|
||||||
import errorQuery from "../../../images/error_no_outline.svg";
|
import errorQuery from "../../../images/error_no_outline.svg";
|
||||||
|
import warningIconSvg from "../../../images/warning.svg";
|
||||||
import { useObservable } from "../../hooks/useObservable";
|
import { useObservable } from "../../hooks/useObservable";
|
||||||
import { ReactTabKind, useTabs } from "../../hooks/useTabs";
|
import { ReactTabKind, useTabs } from "../../hooks/useTabs";
|
||||||
import TabsBase from "./TabsBase";
|
import TabsBase from "./TabsBase";
|
||||||
@ -117,6 +118,9 @@ function TabNav({ tab, active, tabKind }: { tab?: Tab; active: boolean; tabKind?
|
|||||||
>
|
>
|
||||||
<span className="statusIconContainer" style={{ width: tabKind === ReactTabKind.Home ? 0 : 18 }}>
|
<span className="statusIconContainer" style={{ width: tabKind === ReactTabKind.Home ? 0 : 18 }}>
|
||||||
{useObservable(tab?.isExecutionError || ko.observable(false)) && <ErrorIcon tab={tab} active={active} />}
|
{useObservable(tab?.isExecutionError || ko.observable(false)) && <ErrorIcon tab={tab} active={active} />}
|
||||||
|
{useObservable(tab?.isExecutionWarning || ko.observable(false)) && (
|
||||||
|
<WarningIcon tab={tab} active={active} />
|
||||||
|
)}
|
||||||
{isTabExecuting(tab, tabKind) && (
|
{isTabExecuting(tab, tabKind) && (
|
||||||
<img className="loadingIcon" title="Loading" src={loadingIcon} alt="Loading" />
|
<img className="loadingIcon" title="Loading" src={loadingIcon} alt="Loading" />
|
||||||
)}
|
)}
|
||||||
@ -194,6 +198,20 @@ const ErrorIcon = ({ tab, active }: { tab: Tab; active: boolean }) => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const WarningIcon = ({ tab, active }: { tab: Tab; active: boolean }) => (
|
||||||
|
<div
|
||||||
|
id="warningStatusIcon"
|
||||||
|
role="button"
|
||||||
|
title="Click to view more details"
|
||||||
|
tabIndex={active ? 0 : undefined}
|
||||||
|
className={active ? "actionsEnabled warningIconContainer" : "warningIconContainer"}
|
||||||
|
onClick={({ nativeEvent: e }) => tab.onErrorDetailsClick(undefined, e)}
|
||||||
|
onKeyPress={({ nativeEvent: e }) => tab.onErrorDetailsKeyPress(undefined, e)}
|
||||||
|
>
|
||||||
|
<img src={warningIconSvg} alt="Warning Icon" style={{ height: 15, marginBottom: 5 }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
function TabPane({ tab, active }: { tab: Tab; active: boolean }) {
|
function TabPane({ tab, active }: { tab: Tab; active: boolean }) {
|
||||||
const ref = useRef<HTMLDivElement>();
|
const ref = useRef<HTMLDivElement>();
|
||||||
const attrs = {
|
const attrs = {
|
||||||
|
@ -27,6 +27,7 @@ export default class TabsBase extends WaitsForTemplateViewModel {
|
|||||||
public tabTitle: ko.Observable<string>;
|
public tabTitle: ko.Observable<string>;
|
||||||
public tabPath: ko.Observable<string>;
|
public tabPath: ko.Observable<string>;
|
||||||
public isExecutionError = ko.observable(false);
|
public isExecutionError = ko.observable(false);
|
||||||
|
public isExecutionWarning = ko.observable(false);
|
||||||
public isExecuting = ko.observable(false);
|
public isExecuting = ko.observable(false);
|
||||||
protected _theme: string;
|
protected _theme: string;
|
||||||
public onLoadStartKey: number;
|
public onLoadStartKey: number;
|
||||||
|
@ -21,6 +21,7 @@ export enum StorageKey {
|
|||||||
DatabaseAccountId,
|
DatabaseAccountId,
|
||||||
EncryptedKeyToken,
|
EncryptedKeyToken,
|
||||||
IsCrossPartitionQueryEnabled,
|
IsCrossPartitionQueryEnabled,
|
||||||
|
QueryControlEnabled,
|
||||||
MaxDegreeOfParellism,
|
MaxDegreeOfParellism,
|
||||||
IsGraphAutoVizDisabled,
|
IsGraphAutoVizDisabled,
|
||||||
TenantId,
|
TenantId,
|
||||||
|
@ -23,3 +23,7 @@ export const logConsoleError = (msg: string): void => {
|
|||||||
export const logConsoleInfo = (msg: string): void => {
|
export const logConsoleInfo = (msg: string): void => {
|
||||||
log(ConsoleDataType.Info, msg);
|
log(ConsoleDataType.Info, msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const logConsoleWarning = (msg: string): void => {
|
||||||
|
log(ConsoleDataType.Warning, msg);
|
||||||
|
};
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { PartitionKey, PartitionKeyDefinition } from "@azure/cosmos";
|
import { PartitionKey, PartitionKeyDefinition } from "@azure/cosmos";
|
||||||
|
import { getRUThreshold, ruThresholdEnabled } from "Shared/StorageUtility";
|
||||||
|
import { userContext } from "UserContext";
|
||||||
|
import { logConsoleWarning } from "Utils/NotificationConsoleUtils";
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
import * as ViewModels from "../Contracts/ViewModels";
|
||||||
|
|
||||||
@ -86,6 +89,18 @@ export const queryPagesUntilContentPresent = async (
|
|||||||
results.roundTrips = roundTrips;
|
results.roundTrips = roundTrips;
|
||||||
results.requestCharge = Number(results.requestCharge) + netRequestCharge;
|
results.requestCharge = Number(results.requestCharge) + netRequestCharge;
|
||||||
netRequestCharge = Number(results.requestCharge);
|
netRequestCharge = Number(results.requestCharge);
|
||||||
|
|
||||||
|
if (results.hasMoreResults && userContext.apiType === "SQL" && ruThresholdEnabled()) {
|
||||||
|
const ruThreshold: number = getRUThreshold();
|
||||||
|
if (netRequestCharge > ruThreshold) {
|
||||||
|
logConsoleWarning(
|
||||||
|
`Warning: Query has exceeded the Request Unit threshold of ${ruThreshold} RUs. Query results show only those documents returned before the threshold was exceeded`,
|
||||||
|
);
|
||||||
|
results.ruThresholdExceeded = true;
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const resultsMetadata = {
|
const resultsMetadata = {
|
||||||
hasMoreResults: results.hasMoreResults,
|
hasMoreResults: results.hasMoreResults,
|
||||||
itemCount: results.itemCount,
|
itemCount: results.itemCount,
|
||||||
|
@ -78,11 +78,18 @@ const typescriptRule = {
|
|||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const javascriptRule = {
|
||||||
|
test: /\.m?js$/,
|
||||||
|
resolve: {
|
||||||
|
fullySpecified: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
/** @type {(_env: Record<string, string>, argv: Record<string, unknown>) => import("webpack").Configuration} */
|
/** @type {(_env: Record<string, string>, argv: Record<string, unknown>) => import("webpack").Configuration} */
|
||||||
module.exports = function (_env = {}, argv = {}) {
|
module.exports = function (_env = {}, argv = {}) {
|
||||||
const mode = argv.mode || "development";
|
const mode = argv.mode || "development";
|
||||||
const rules = [fontRule, lessRule, imagesRule, cssRule, htmlRule, typescriptRule];
|
const rules = [fontRule, lessRule, imagesRule, cssRule, htmlRule, typescriptRule, javascriptRule];
|
||||||
const envVars = {
|
const envVars = {
|
||||||
GIT_SHA: gitSha,
|
GIT_SHA: gitSha,
|
||||||
PORT: process.env.PORT || "1234",
|
PORT: process.env.PORT || "1234",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user