mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-23 10:51:30 +00:00
Compare commits
1 Commits
unit-tests
...
users/aisa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f304600eca |
File diff suppressed because one or more lines are too long
@@ -2869,7 +2869,6 @@ a:link {
|
|||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: clip;
|
overflow-x: clip;
|
||||||
min-height: fit-content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.uniqueIndexesContainer {
|
.uniqueIndexesContainer {
|
||||||
|
|||||||
211
package-lock.json
generated
211
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.3.0",
|
"@azure/cosmos": "4.2.0-beta.1",
|
||||||
"@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,71 +290,59 @@
|
|||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-http-compat": {
|
|
||||||
"version": "2.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.0.tgz",
|
|
||||||
"integrity": "sha512-qLQujmUypBBG0gxHd0j6/Jdmul6ttl24c8WGiLXIk7IHXdBlfoBqW27hyz3Xn6xbfdyVSarl1Ttbk0AwnZBYCw==",
|
|
||||||
"dependencies": {
|
|
||||||
"@azure/abort-controller": "^2.0.0",
|
|
||||||
"@azure/core-client": "^1.3.0",
|
|
||||||
"@azure/core-rest-pipeline": "^1.20.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",
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-lro/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/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": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-paging/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/core-rest-pipeline": {
|
"node_modules/@azure/core-rest-pipeline": {
|
||||||
"version": "1.20.0",
|
"version": "1.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.18.0.tgz",
|
||||||
"integrity": "sha512-ASoP8uqZBS3H/8N8at/XwFr6vYrRP3syTK0EUjDXQy0Y1/AUS+QeIRThKmTNJO2RggvBBxaXDPM7YoIwDGeA0g==",
|
"integrity": "sha512-QSoGUp4Eq/gohEFNJaUOwTN7BCc2nHTjjbm75JT0aD7W65PWM1H/tItz0GsABn22uaKyGxiMhWQLt2r+FGU89Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/abort-controller": "^2.0.0",
|
"@azure/abort-controller": "^2.0.0",
|
||||||
"@azure/core-auth": "^1.8.0",
|
"@azure/core-auth": "^1.8.0",
|
||||||
"@azure/core-tracing": "^1.0.1",
|
"@azure/core-tracing": "^1.0.1",
|
||||||
"@azure/core-util": "^1.11.0",
|
"@azure/core-util": "^1.11.0",
|
||||||
"@azure/logger": "^1.0.0",
|
"@azure/logger": "^1.0.0",
|
||||||
"@typespec/ts-http-runtime": "^0.2.2",
|
"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": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@azure/core-rest-pipeline/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/@azure/core-rest-pipeline/node_modules/https-proxy-agent": {
|
||||||
|
"version": "7.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
|
||||||
|
"integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
|
||||||
|
"dependencies": {
|
||||||
|
"agent-base": "^7.0.2",
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@azure/core-rest-pipeline/node_modules/tslib": {
|
"node_modules/@azure/core-rest-pipeline/node_modules/tslib": {
|
||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
@@ -391,16 +379,15 @@
|
|||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/@azure/cosmos": {
|
"node_modules/@azure/cosmos": {
|
||||||
"version": "4.3.0",
|
"version": "4.2.0-beta.1",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.2.0-beta.1.tgz",
|
||||||
"integrity": "sha512-0Ls3l1uWBBSphx6YRhnM+w7rSvq8qVugBCdO6kSiNuRYXEf6+YWLjbzz4e7L2kkz/6ScFdZIOJYP+XtkiRYOhA==",
|
"integrity": "sha512-mREONehm1DxjEKXGaNU6Wmpf9Ckb9IrhKFXhDFVs45pxmoEb3y2s/Ub0owuFmqlphpcS1zgtYQn5exn+lwnJuQ==",
|
||||||
"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",
|
||||||
@@ -505,66 +492,14 @@
|
|||||||
"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/keyvault-common": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/keyvault-common/-/keyvault-common-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-wRLVaroQtOqfg60cxkzUkGKrKMsCP6uYXAOomOIysSMyt1/YM0eUn9LqieAWM8DLcU4+07Fio2YGpPeqUbpP9w==",
|
|
||||||
"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"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"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": {
|
"node_modules/@azure/logger": {
|
||||||
"version": "1.2.0",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.2.0.tgz",
|
"license": "MIT",
|
||||||
"integrity": "sha512-0hKEzLhpw+ZTAfNJyRrn6s+V0nDWzXk9OjBr2TiGIu0OfMr5s2V4FpKLTAK3Ca5r5OKLbf4hkOGDPyiRjie/jA==",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typespec/ts-http-runtime": "^0.2.2",
|
"tslib": "^2.2.0"
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/logger/node_modules/tslib": {
|
"node_modules/@azure/logger/node_modules/tslib": {
|
||||||
@@ -13139,56 +13074,6 @@
|
|||||||
"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.3.0",
|
"@azure/cosmos": "4.2.0-beta.1",
|
||||||
"@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.3.0",
|
"@azure/cosmos": "4.2.0-beta.1",
|
||||||
"@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.3.0",
|
"version": "4.2.0-beta.1",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.2.0-beta.1.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,3 +1,4 @@
|
|||||||
|
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";
|
||||||
@@ -13,14 +14,18 @@ interface QueryResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MinimalQueryIterator {
|
export interface MinimalQueryIterator {
|
||||||
fetchNext: () => Promise<QueryResponse>;
|
fetchNext: (queryOperationOptions?: QueryOperationOptions) => Promise<QueryResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick<QueryIterator<any>, "fetchNext">;
|
// Pick<QueryIterator<any>, "fetchNext">;
|
||||||
|
|
||||||
export function nextPage(documentsIterator: MinimalQueryIterator, firstItemIndex: number): Promise<QueryResults> {
|
export function nextPage(
|
||||||
|
documentsIterator: MinimalQueryIterator,
|
||||||
|
firstItemIndex: number,
|
||||||
|
queryOperationOptions?: QueryOperationOptions,
|
||||||
|
): Promise<QueryResults> {
|
||||||
TelemetryProcessor.traceStart(Action.ExecuteQuery);
|
TelemetryProcessor.traceStart(Action.ExecuteQuery);
|
||||||
return documentsIterator.fetchNext().then((response) => {
|
return documentsIterator.fetchNext(queryOperationOptions).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,4 +1,5 @@
|
|||||||
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",
|
||||||
@@ -102,9 +103,20 @@ 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;
|
||||||
|
|||||||
@@ -4,18 +4,13 @@ import * as React from "react";
|
|||||||
export interface TooltipProps {
|
export interface TooltipProps {
|
||||||
children: string;
|
children: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
ariaLabelForTooltip?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InfoTooltip: React.FunctionComponent<TooltipProps> = ({
|
export const InfoTooltip: React.FunctionComponent<TooltipProps> = ({ children, className }: TooltipProps) => {
|
||||||
children,
|
|
||||||
className,
|
|
||||||
ariaLabelForTooltip = children,
|
|
||||||
}: TooltipProps) => {
|
|
||||||
return (
|
return (
|
||||||
<span className={className}>
|
<span className={className}>
|
||||||
<TooltipHost content={children}>
|
<TooltipHost content={children}>
|
||||||
<Icon iconName="Info" aria-label={ariaLabelForTooltip} className="panelInfoIcon" tabIndex={0} />
|
<Icon iconName="Info" ariaLabel={children} className="panelInfoIcon" tabIndex={0} />
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
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,
|
||||||
@@ -15,7 +14,6 @@ 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,
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ export interface IBulkDeleteResult {
|
|||||||
export const deleteDocuments = async (
|
export const deleteDocuments = async (
|
||||||
collection: CollectionBase,
|
collection: CollectionBase,
|
||||||
documentIds: DocumentId[],
|
documentIds: DocumentId[],
|
||||||
abortSignal: AbortSignal,
|
|
||||||
): Promise<IBulkDeleteResult[]> => {
|
): Promise<IBulkDeleteResult[]> => {
|
||||||
const clearMessage = logConsoleProgress(`Deleting ${documentIds.length} ${getEntityName(true)}`);
|
const clearMessage = logConsoleProgress(`Deleting ${documentIds.length} ${getEntityName(true)}`);
|
||||||
try {
|
try {
|
||||||
@@ -66,16 +65,12 @@ export const deleteDocuments = async (
|
|||||||
operationType: BulkOperationType.Delete,
|
operationType: BulkOperationType.Delete,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const promise = v2Container.items
|
const promise = v2Container.items.bulk(operations).then((bulkResults) => {
|
||||||
.bulk(operations, undefined, {
|
return bulkResults.map((bulkResult, index) => {
|
||||||
abortSignal,
|
const documentId = documentIdsChunk[index];
|
||||||
})
|
return { ...bulkResult, documentId };
|
||||||
.then((bulkResults) => {
|
|
||||||
return bulkResults.map((bulkResult, index) => {
|
|
||||||
const documentId = documentIdsChunk[index];
|
|
||||||
return { ...bulkResult, documentId };
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
promiseArray.push(promise);
|
promiseArray.push(promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ 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,3 +1,4 @@
|
|||||||
|
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";
|
||||||
@@ -8,12 +9,13 @@ 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);
|
const result: QueryResults = await nextPage(documentsIterator, firstItemIndex, queryOperationOptions);
|
||||||
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;
|
||||||
|
|||||||
@@ -126,5 +126,12 @@ async function readCollectionsWithARM(databaseId: string): Promise<DataModels.Co
|
|||||||
throw new Error(`Unsupported default experience type: ${apiType}`);
|
throw new Error(`Unsupported default experience type: ${apiType}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rpResponse?.value?.map((collection) => collection.properties?.resource as DataModels.Collection);
|
// TO DO: Remove when we get RP API Spec with materializedViews
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
return rpResponse?.value?.map((collection: any) => {
|
||||||
|
const collectionDataModel: DataModels.Collection = collection.properties?.resource as DataModels.Collection;
|
||||||
|
collectionDataModel.materializedViews = collection.properties?.resource?.materializedViews;
|
||||||
|
collectionDataModel.materializedViewDefinition = collection.properties?.resource?.materializedViewDefinition;
|
||||||
|
return collectionDataModel;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,8 @@ if (process.env.NODE_ENV === "development") {
|
|||||||
PROXY_PATH: "/proxy",
|
PROXY_PATH: "/proxy",
|
||||||
EMULATOR_ENDPOINT: "https://localhost:8081",
|
EMULATOR_ENDPOINT: "https://localhost:8081",
|
||||||
PORTAL_BACKEND_ENDPOINT: PortalBackendEndpoints.Mpac,
|
PORTAL_BACKEND_ENDPOINT: PortalBackendEndpoints.Mpac,
|
||||||
MONGO_PROXY_ENDPOINT: MongoProxyEndpoints.Mpac,
|
// MONGO_PROXY_ENDPOINT: "https://cosmos-db-portal-mongoproxy1-mpac-westus.azurewebsites.net",
|
||||||
|
MONGO_PROXY_ENDPOINT: "https://localhost:7238",
|
||||||
CASSANDRA_PROXY_ENDPOINT: CassandraProxyEndpoints.Mpac,
|
CASSANDRA_PROXY_ENDPOINT: CassandraProxyEndpoints.Mpac,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ export enum PaneKind {
|
|||||||
GlobalSettings,
|
GlobalSettings,
|
||||||
AdHocAccess,
|
AdHocAccess,
|
||||||
SwitchDirectory,
|
SwitchDirectory,
|
||||||
QuickStart,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ export interface ArmEntity {
|
|||||||
type: string;
|
type: string;
|
||||||
kind: string;
|
kind: string;
|
||||||
tags?: Tags;
|
tags?: Tags;
|
||||||
resourceGroup?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatabaseAccount extends ArmEntity {
|
export interface DatabaseAccount extends ArmEntity {
|
||||||
@@ -389,7 +388,7 @@ export interface VectorEmbeddingPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface VectorEmbedding {
|
export interface VectorEmbedding {
|
||||||
dataType: "float32" | "uint8" | "int8";
|
dataType: "float16" | "float32" | "uint8" | "int8";
|
||||||
dimensions: number;
|
dimensions: number;
|
||||||
distanceFunction: "euclidean" | "cosine" | "dotproduct";
|
distanceFunction: "euclidean" | "cosine" | "dotproduct";
|
||||||
path: string;
|
path: string;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
ItemDefinition,
|
|
||||||
JSONObject,
|
JSONObject,
|
||||||
QueryMetrics,
|
QueryMetrics,
|
||||||
Resource,
|
Resource,
|
||||||
@@ -31,11 +30,8 @@ export interface UploadDetailsRecord {
|
|||||||
numFailed: number;
|
numFailed: number;
|
||||||
numThrottled: number;
|
numThrottled: number;
|
||||||
errors: string[];
|
errors: string[];
|
||||||
resources?: ItemDefinition[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BulkInsertResult = Omit<UploadDetailsRecord, "fileName">;
|
|
||||||
|
|
||||||
export interface QueryResultsMetadata {
|
export interface QueryResultsMetadata {
|
||||||
hasMoreResults: boolean;
|
hasMoreResults: boolean;
|
||||||
firstItemIndex: number;
|
firstItemIndex: number;
|
||||||
@@ -50,7 +46,6 @@ 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 {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { AuthType } from "AuthType";
|
import { AuthType } from "AuthType";
|
||||||
import { shallow } from "enzyme";
|
import { shallow } from "enzyme";
|
||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
|
import { Features } from "Platform/Hosted/extractFeatures";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { updateCollection } from "../../../Common/dataAccess/updateCollection";
|
import { updateCollection } from "../../../Common/dataAccess/updateCollection";
|
||||||
import { updateOffer } from "../../../Common/dataAccess/updateOffer";
|
import { updateOffer } from "../../../Common/dataAccess/updateOffer";
|
||||||
@@ -252,7 +253,7 @@ describe("SettingsComponent", () => {
|
|||||||
it("should save throughput bucket changes when Save button is clicked", async () => {
|
it("should save throughput bucket changes when Save button is clicked", async () => {
|
||||||
updateUserContext({
|
updateUserContext({
|
||||||
apiType: "SQL",
|
apiType: "SQL",
|
||||||
throughputBucketsEnabled: true,
|
features: { enableThroughputBuckets: true } as Features,
|
||||||
authType: AuthType.AAD,
|
authType: AuthType.AAD,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from "Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent";
|
} from "Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent";
|
||||||
import { useDatabases } from "Explorer/useDatabases";
|
import { useDatabases } from "Explorer/useDatabases";
|
||||||
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||||
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
import { isFullTextSearchEnabled, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||||
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import DiscardIcon from "../../../../images/discard.svg";
|
import DiscardIcon from "../../../../images/discard.svg";
|
||||||
@@ -188,10 +188,13 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
this.isGlobalSecondaryIndex =
|
this.isGlobalSecondaryIndex =
|
||||||
!!this.collection?.materializedViewDefinition() || !!this.collection?.materializedViews();
|
!!this.collection?.materializedViewDefinition() || !!this.collection?.materializedViews();
|
||||||
this.isVectorSearchEnabled = isVectorSearchEnabled() && !hasDatabaseSharedThroughput(this.collection);
|
this.isVectorSearchEnabled = isVectorSearchEnabled() && !hasDatabaseSharedThroughput(this.collection);
|
||||||
this.isFullTextSearchEnabled = userContext.apiType === "SQL";
|
this.isFullTextSearchEnabled = isFullTextSearchEnabled() && !hasDatabaseSharedThroughput(this.collection);
|
||||||
|
|
||||||
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
|
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
|
||||||
this.throughputBucketsEnabled = userContext.throughputBucketsEnabled;
|
this.throughputBucketsEnabled =
|
||||||
|
userContext.apiType === "SQL" &&
|
||||||
|
userContext.features.enableThroughputBuckets &&
|
||||||
|
userContext.authType === AuthType.AAD;
|
||||||
|
|
||||||
// Mongo container with system partition key still treat as "Fixed"
|
// Mongo container with system partition key still treat as "Fixed"
|
||||||
this.isFixedContainer =
|
this.isFixedContainer =
|
||||||
@@ -1071,11 +1074,11 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
databaseId: this.collection.databaseId,
|
databaseId: this.collection.databaseId,
|
||||||
collectionId: this.collection.id(),
|
collectionId: this.collection.id(),
|
||||||
currentOffer: this.collection.offer(),
|
currentOffer: this.collection.offer(),
|
||||||
autopilotThroughput: this.collection.offer?.()?.autoscaleMaxThroughput
|
autopilotThroughput: this.collection.offer().autoscaleMaxThroughput
|
||||||
? this.collection.offer?.()?.autoscaleMaxThroughput
|
? this.collection.offer().autoscaleMaxThroughput
|
||||||
: undefined,
|
: undefined,
|
||||||
manualThroughput: this.collection.offer?.()?.manualThroughput
|
manualThroughput: this.collection.offer().manualThroughput
|
||||||
? this.collection.offer?.()?.manualThroughput
|
? this.collection.offer().manualThroughput
|
||||||
: undefined,
|
: undefined,
|
||||||
throughputBuckets: this.state.throughputBuckets,
|
throughputBuckets: this.state.throughputBuckets,
|
||||||
});
|
});
|
||||||
@@ -1091,7 +1094,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
currentOffer: this.collection.offer(),
|
currentOffer: this.collection.offer(),
|
||||||
autopilotThroughput: this.state.isAutoPilotSelected ? this.state.autoPilotThroughput : undefined,
|
autopilotThroughput: this.state.isAutoPilotSelected ? this.state.autoPilotThroughput : undefined,
|
||||||
manualThroughput: this.state.isAutoPilotSelected ? undefined : this.state.throughput,
|
manualThroughput: this.state.isAutoPilotSelected ? undefined : this.state.throughput,
|
||||||
throughputBuckets: this.throughputBucketsEnabled ? this.state.throughputBuckets : undefined,
|
|
||||||
};
|
};
|
||||||
if (this.hasProvisioningTypeChanged()) {
|
if (this.hasProvisioningTypeChanged()) {
|
||||||
if (this.state.isAutoPilotSelected) {
|
if (this.state.isAutoPilotSelected) {
|
||||||
@@ -1342,7 +1344,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.throughputBucketsEnabled && !hasDatabaseSharedThroughput(this.collection) && this.offer) {
|
if (this.throughputBucketsEnabled) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
tab: SettingsV2TabTypes.ThroughputBucketsTab,
|
tab: SettingsV2TabTypes.ThroughputBucketsTab,
|
||||||
content: <ThroughputBucketsComponent {...throughputBucketsComponentProps} />,
|
content: <ThroughputBucketsComponent {...throughputBucketsComponentProps} />,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ describe("ThroughputBucketsComponent", () => {
|
|||||||
|
|
||||||
it("renders the correct number of buckets", () => {
|
it("renders the correct number of buckets", () => {
|
||||||
render(<ThroughputBucketsComponent {...defaultProps} />);
|
render(<ThroughputBucketsComponent {...defaultProps} />);
|
||||||
expect(screen.getAllByText(/Bucket \d+/)).toHaveLength(5);
|
expect(screen.getAllByText(/Group \d+/)).toHaveLength(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders buckets in the correct order even if input is unordered", () => {
|
it("renders buckets in the correct order even if input is unordered", () => {
|
||||||
@@ -36,14 +36,8 @@ describe("ThroughputBucketsComponent", () => {
|
|||||||
];
|
];
|
||||||
render(<ThroughputBucketsComponent {...defaultProps} currentBuckets={unorderedBuckets} />);
|
render(<ThroughputBucketsComponent {...defaultProps} currentBuckets={unorderedBuckets} />);
|
||||||
|
|
||||||
const bucketLabels = screen.getAllByText(/Bucket \d+/).map((el) => el.textContent);
|
const bucketLabels = screen.getAllByText(/Group \d+/).map((el) => el.textContent);
|
||||||
expect(bucketLabels).toEqual([
|
expect(bucketLabels).toEqual(["Group 1 (Data Explorer Query Bucket)", "Group 2", "Group 3", "Group 4", "Group 5"]);
|
||||||
"Bucket 1 (Data Explorer Query Bucket)",
|
|
||||||
"Bucket 2",
|
|
||||||
"Bucket 3",
|
|
||||||
"Bucket 4",
|
|
||||||
"Bucket 5",
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders all provided buckets even if they exceed the max default bucket count", () => {
|
it("renders all provided buckets even if they exceed the max default bucket count", () => {
|
||||||
@@ -59,7 +53,7 @@ describe("ThroughputBucketsComponent", () => {
|
|||||||
|
|
||||||
render(<ThroughputBucketsComponent {...defaultProps} currentBuckets={oversizedBuckets} />);
|
render(<ThroughputBucketsComponent {...defaultProps} currentBuckets={oversizedBuckets} />);
|
||||||
|
|
||||||
expect(screen.getAllByText(/Bucket \d+/)).toHaveLength(7);
|
expect(screen.getAllByText(/Group \d+/)).toHaveLength(7);
|
||||||
|
|
||||||
expect(screen.getByDisplayValue("50")).toBeInTheDocument();
|
expect(screen.getByDisplayValue("50")).toBeInTheDocument();
|
||||||
expect(screen.getByDisplayValue("60")).toBeInTheDocument();
|
expect(screen.getByDisplayValue("60")).toBeInTheDocument();
|
||||||
@@ -177,7 +171,7 @@ describe("ThroughputBucketsComponent", () => {
|
|||||||
|
|
||||||
it("ensures default buckets are used when no buckets are provided", () => {
|
it("ensures default buckets are used when no buckets are provided", () => {
|
||||||
render(<ThroughputBucketsComponent {...defaultProps} currentBuckets={[]} />);
|
render(<ThroughputBucketsComponent {...defaultProps} currentBuckets={[]} />);
|
||||||
expect(screen.getAllByText(/Bucket \d+/)).toHaveLength(5);
|
expect(screen.getAllByText(/Group \d+/)).toHaveLength(5);
|
||||||
expect(screen.getAllByDisplayValue("100")).toHaveLength(5);
|
expect(screen.getAllByDisplayValue("100")).toHaveLength(5);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
|
|||||||
value={bucket.maxThroughputPercentage}
|
value={bucket.maxThroughputPercentage}
|
||||||
onChange={(newValue) => handleBucketChange(bucket.id, newValue)}
|
onChange={(newValue) => handleBucketChange(bucket.id, newValue)}
|
||||||
showValue={false}
|
showValue={false}
|
||||||
label={`Bucket ${bucket.id}${bucket.id === 1 ? " (Data Explorer Query Bucket)" : ""}`}
|
label={`Group ${bucket.id}${bucket.id === 1 ? " (Data Explorer Query Bucket)" : ""}`}
|
||||||
styles={{ root: { flex: 2, maxWidth: 400 } }}
|
styles={{ root: { flex: 2, maxWidth: 400 } }}
|
||||||
disabled={bucket.maxThroughputPercentage === 100}
|
disabled={bucket.maxThroughputPercentage === 100}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
serverId,
|
serverId,
|
||||||
numberOfRegions,
|
numberOfRegions,
|
||||||
isMultimaster,
|
isMultimaster,
|
||||||
false,
|
true,
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -198,32 +198,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
timeToLiveSecondsBaseline={5}
|
timeToLiveSecondsBaseline={5}
|
||||||
/>
|
/>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem
|
|
||||||
headerText="Container Policies"
|
|
||||||
itemKey="ContainerVectorPolicyTab"
|
|
||||||
key="ContainerVectorPolicyTab"
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginTop": 20,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ContainerPolicyComponent
|
|
||||||
fullTextPolicy={{}}
|
|
||||||
fullTextPolicyBaseline={{}}
|
|
||||||
isFullTextSearchEnabled={true}
|
|
||||||
isGlobalSecondaryIndex={true}
|
|
||||||
isVectorSearchEnabled={false}
|
|
||||||
onFullTextPolicyChange={[Function]}
|
|
||||||
onFullTextPolicyDirtyChange={[Function]}
|
|
||||||
onVectorEmbeddingPolicyChange={[Function]}
|
|
||||||
onVectorEmbeddingPolicyDirtyChange={[Function]}
|
|
||||||
resetShouldDiscardContainerPolicyChange={[Function]}
|
|
||||||
shouldDiscardContainerPolicies={false}
|
|
||||||
vectorEmbeddingPolicy={{}}
|
|
||||||
vectorEmbeddingPolicyBaseline={{}}
|
|
||||||
/>
|
|
||||||
</PivotItem>
|
|
||||||
<PivotItem
|
<PivotItem
|
||||||
headerText="Indexing Policy"
|
headerText="Indexing Policy"
|
||||||
itemKey="IndexingPolicyTab"
|
itemKey="IndexingPolicyTab"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Stack, Text } from "@fluentui/react";
|
import { Text } from "@fluentui/react";
|
||||||
import React, { FunctionComponent } from "react";
|
import React, { FunctionComponent } from "react";
|
||||||
import { InfoTooltip } from "../../../../Common/Tooltip/InfoTooltip";
|
import { InfoTooltip } from "../../../../Common/Tooltip/InfoTooltip";
|
||||||
import * as SharedConstants from "../../../../Shared/Constants";
|
import * as SharedConstants from "../../../../Shared/Constants";
|
||||||
@@ -44,42 +44,33 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
|
|||||||
const currencySign: string = getCurrencySign(serverId);
|
const currencySign: string = getCurrencySign(serverId);
|
||||||
const multiplier = getMultimasterMultiplier(numberOfRegions, multimasterEnabled);
|
const multiplier = getMultimasterMultiplier(numberOfRegions, multimasterEnabled);
|
||||||
const pricePerRu = isAutoscale ? getAutoscalePricePerRu(serverId, multiplier) : getPricePerRu(serverId, multiplier);
|
const pricePerRu = isAutoscale ? getAutoscalePricePerRu(serverId, multiplier) : getPricePerRu(serverId, multiplier);
|
||||||
const estimatedMonthlyCost = "Estimated monthly cost";
|
|
||||||
|
|
||||||
const iconWithEstimatedCostDisclaimer: JSX.Element = (
|
const iconWithEstimatedCostDisclaimer: JSX.Element = <InfoTooltip>{estimatedCostDisclaimer}</InfoTooltip>;
|
||||||
<InfoTooltip ariaLabelForTooltip={`${estimatedMonthlyCost} ${currency} ${estimatedCostDisclaimer}`}>
|
|
||||||
{estimatedCostDisclaimer}
|
|
||||||
</InfoTooltip>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isAutoscale) {
|
if (isAutoscale) {
|
||||||
return (
|
return (
|
||||||
<Stack style={{ marginBottom: 6 }}>
|
<Text variant="small">
|
||||||
<Text variant="small">
|
Estimated monthly cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
||||||
{estimatedMonthlyCost} ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
<b>
|
||||||
<b>
|
{currencySign + calculateEstimateNumber(monthlyPrice / 10)} -{" "}
|
||||||
{currencySign + calculateEstimateNumber(monthlyPrice / 10)} -{" "}
|
{currencySign + calculateEstimateNumber(monthlyPrice)}{" "}
|
||||||
{currencySign + calculateEstimateNumber(monthlyPrice)}{" "}
|
</b>
|
||||||
</b>
|
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits / 10} - {requestUnits}{" "}
|
||||||
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits / 10} - {requestUnits}{" "}
|
RU/s, {currencySign + pricePerRu}/RU)
|
||||||
RU/s, {currencySign + pricePerRu}/RU)
|
</Text>
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack style={{ marginBottom: 8 }}>
|
<Text variant="small">
|
||||||
<Text variant="small">
|
Estimated cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
||||||
Estimated cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
|
<b>
|
||||||
<b>
|
{currencySign + calculateEstimateNumber(hourlyPrice)} hourly /{" "}
|
||||||
{currencySign + calculateEstimateNumber(hourlyPrice)} hourly /{" "}
|
{currencySign + calculateEstimateNumber(dailyPrice)} daily /{" "}
|
||||||
{currencySign + calculateEstimateNumber(dailyPrice)} daily /{" "}
|
{currencySign + calculateEstimateNumber(monthlyPrice)} monthly{" "}
|
||||||
{currencySign + calculateEstimateNumber(monthlyPrice)} monthly{" "}
|
</b>
|
||||||
</b>
|
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits}RU/s,{" "}
|
||||||
({numberOfRegions + (numberOfRegions === 1 ? " region" : " regions")}, {requestUnits}RU/s,{" "}
|
{currencySign + pricePerRu}/RU)
|
||||||
{currencySign + pricePerRu}/RU)
|
</Text>
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Checkbox, DirectionalHint, Link, Separator, Stack, Text, TextField, TooltipHost } from "@fluentui/react";
|
import { Checkbox, DirectionalHint, Link, Stack, Text, TextField, TooltipHost } from "@fluentui/react";
|
||||||
import { getWorkloadType } from "Common/DatabaseAccountUtility";
|
import { getWorkloadType } from "Common/DatabaseAccountUtility";
|
||||||
import { CostEstimateText } from "Explorer/Controls/ThroughputInput/CostEstimateText/CostEstimateText";
|
|
||||||
import { useDatabases } from "Explorer/useDatabases";
|
import { useDatabases } from "Explorer/useDatabases";
|
||||||
import React, { FunctionComponent, useEffect, useState } from "react";
|
import React, { FunctionComponent, useEffect, useState } from "react";
|
||||||
import * as Constants from "../../../Common/Constants";
|
import * as Constants from "../../../Common/Constants";
|
||||||
@@ -10,8 +9,8 @@ import { userContext } from "../../../UserContext";
|
|||||||
import { getCollectionName } from "../../../Utils/APITypeUtils";
|
import { getCollectionName } from "../../../Utils/APITypeUtils";
|
||||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||||
import * as PricingUtils from "../../../Utils/PricingUtils";
|
import * as PricingUtils from "../../../Utils/PricingUtils";
|
||||||
|
import { CostEstimateText } from "./CostEstimateText/CostEstimateText";
|
||||||
import "./ThroughputInput.less";
|
import "./ThroughputInput.less";
|
||||||
import { isFabricNative } from "../../../Platform/Fabric/FabricUtil";
|
|
||||||
|
|
||||||
export interface ThroughputInputProps {
|
export interface ThroughputInputProps {
|
||||||
isDatabase: boolean;
|
isDatabase: boolean;
|
||||||
@@ -44,8 +43,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
if (
|
if (
|
||||||
isFreeTier ||
|
isFreeTier ||
|
||||||
isQuickstart ||
|
isQuickstart ||
|
||||||
[Constants.WorkloadType.Learning, Constants.WorkloadType.DevelopmentTesting].includes(workloadType) ||
|
[Constants.WorkloadType.Learning, Constants.WorkloadType.DevelopmentTesting].includes(workloadType)
|
||||||
isFabricNative()
|
|
||||||
) {
|
) {
|
||||||
defaultThroughput = AutoPilotUtils.autoPilotThroughput1K;
|
defaultThroughput = AutoPilotUtils.autoPilotThroughput1K;
|
||||||
} else if (workloadType === Constants.WorkloadType.Production) {
|
} else if (workloadType === Constants.WorkloadType.Production) {
|
||||||
@@ -232,92 +230,53 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isAutoscaleSelected && (
|
{isAutoscaleSelected && (
|
||||||
<Stack className="throughputInputSpacing">
|
<Stack className="throughputInputSpacing">
|
||||||
<Text style={{ marginTop: -2, fontSize: 12 }}>
|
<Text variant="small" aria-label="capacity calculator of azure cosmos db">
|
||||||
Your container throughput will automatically scale up to the maximum value you select, from a minimum of 10%
|
Estimate your required RU/s with{" "}
|
||||||
of that value.
|
<Link
|
||||||
</Text>
|
className="underlinedLink outlineNone"
|
||||||
<Stack horizontal verticalAlign="end" tokens={{ childrenGap: 8 }}>
|
target="_blank"
|
||||||
<Stack tokens={{ childrenGap: 4 }}>
|
href="https://cosmos.azure.com/capacitycalculator/"
|
||||||
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
|
aria-label="capacity calculator of azure cosmos db"
|
||||||
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}>
|
|
||||||
Minimum RU/s
|
|
||||||
</Text>
|
|
||||||
<InfoTooltip>The minimum RU/s your container will scale to</InfoTooltip>
|
|
||||||
</Stack>
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
fontFamily: "Segoe UI",
|
|
||||||
width: 70,
|
|
||||||
height: 27,
|
|
||||||
border: "none",
|
|
||||||
fontSize: 14,
|
|
||||||
backgroundColor: "transparent",
|
|
||||||
fontWeight: 400,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Math.round(throughput / 10).toString()}
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
fontFamily: "Segoe UI",
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: 400,
|
|
||||||
paddingBottom: 6,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
x 10 =
|
capacity calculator
|
||||||
</Text>
|
</Link>
|
||||||
|
.
|
||||||
|
</Text>
|
||||||
|
|
||||||
<Stack tokens={{ childrenGap: 4 }}>
|
<Stack horizontal>
|
||||||
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
|
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }} aria-label="maxRUDescription">
|
||||||
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}>
|
{isDatabase ? "Database" : getCollectionName()} Max RU/s
|
||||||
Maximum RU/s
|
</Text>
|
||||||
</Text>
|
<InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip>
|
||||||
<InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip>
|
|
||||||
</Stack>
|
|
||||||
<TextField
|
|
||||||
id="autoscaleRUValueField"
|
|
||||||
type="number"
|
|
||||||
styles={{
|
|
||||||
fieldGroup: { width: 100, height: 27, flexShrink: 0 },
|
|
||||||
field: { fontSize: 14, fontWeight: 400 },
|
|
||||||
}}
|
|
||||||
onChange={(_event, newInput?: string) => onThroughputValueChange(newInput)}
|
|
||||||
step={AutoPilotUtils.autoPilotIncrementStep}
|
|
||||||
min={AutoPilotUtils.autoPilotThroughput1K}
|
|
||||||
max={isSharded ? Number.MAX_SAFE_INTEGER.toString() : "10000"}
|
|
||||||
value={throughput.toString()}
|
|
||||||
ariaLabel={`${isDatabase ? "Database" : getCollectionName()} max RU/s`}
|
|
||||||
required={true}
|
|
||||||
errorMessage={throughputError}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<CostEstimateText requestUnits={throughput} isAutoscale={isAutoscaleSelected} />
|
<TextField
|
||||||
<Stack className="throughputInputSpacing">
|
id="autoscaleRUValueField"
|
||||||
<Text variant="small" aria-label="ruDescription">
|
type="number"
|
||||||
Estimate your required RU/s with
|
styles={{
|
||||||
<Link
|
fieldGroup: { width: 300, height: 27 },
|
||||||
className="underlinedLink"
|
field: { fontSize: 12 },
|
||||||
target="_blank"
|
}}
|
||||||
href="https://cosmos.azure.com/capacitycalculator/"
|
onChange={(event, newInput?: string) => onThroughputValueChange(newInput)}
|
||||||
aria-label="Capacity calculator"
|
step={AutoPilotUtils.autoPilotIncrementStep}
|
||||||
>
|
min={AutoPilotUtils.autoPilotThroughput1K}
|
||||||
capacity calculator
|
max={isSharded ? Number.MAX_SAFE_INTEGER.toString() : "10000"}
|
||||||
</Link>
|
value={throughput.toString()}
|
||||||
.
|
ariaLabel={`${isDatabase ? "Database" : getCollectionName()} max RU/s`}
|
||||||
</Text>
|
required={true}
|
||||||
</Stack>
|
errorMessage={throughputError}
|
||||||
<Separator className="panelSeparator" style={{ paddingTop: -8, paddingBottom: -8 }} />
|
/>
|
||||||
|
|
||||||
|
<Text variant="small">
|
||||||
|
Your {isDatabase ? "database" : getCollectionName().toLocaleLowerCase()} throughput will automatically scale
|
||||||
|
from{" "}
|
||||||
|
<b>
|
||||||
|
{AutoPilotUtils.getMinRUsBasedOnUserInput(throughput)} RU/s (10% of max RU/s) - {throughput} RU/s
|
||||||
|
</b>{" "}
|
||||||
|
based on usage.
|
||||||
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -341,6 +300,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
</Text>
|
</Text>
|
||||||
<InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip>
|
<InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<TooltipHost
|
<TooltipHost
|
||||||
directionalHint={DirectionalHint.topLeftEdge}
|
directionalHint={DirectionalHint.topLeftEdge}
|
||||||
content={
|
content={
|
||||||
@@ -365,10 +325,11 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
errorMessage={throughputError}
|
errorMessage={throughputError}
|
||||||
/>
|
/>
|
||||||
</TooltipHost>
|
</TooltipHost>
|
||||||
<CostEstimateText requestUnits={throughput} isAutoscale={isAutoscaleSelected} />
|
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<CostEstimateText requestUnits={throughput} isAutoscale={isAutoscaleSelected} />
|
||||||
|
|
||||||
{throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K && (
|
{throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K && (
|
||||||
<Stack horizontal verticalAlign="start">
|
<Stack horizontal verticalAlign="start">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,6 @@ import { isFabricMirrored, isFabricMirroredKey, scheduleRefreshFabricToken } fro
|
|||||||
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||||
import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils";
|
import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils";
|
||||||
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils";
|
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils";
|
||||||
import { featureRegistered } from "Utils/FeatureRegistrationUtils";
|
|
||||||
import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
||||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
import * as ko from "knockout";
|
import * as ko from "knockout";
|
||||||
@@ -31,7 +30,6 @@ import { readDatabases } from "../Common/dataAccess/readDatabases";
|
|||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import { ContainerConnectionInfo, IPhoenixServiceInfo, IProvisionData, IResponse } from "../Contracts/DataModels";
|
import { ContainerConnectionInfo, IPhoenixServiceInfo, IProvisionData, IResponse } from "../Contracts/DataModels";
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
import * as ViewModels from "../Contracts/ViewModels";
|
||||||
import { UploadDetailsRecord } from "../Contracts/ViewModels";
|
|
||||||
import { GitHubOAuthService } from "../GitHub/GitHubOAuthService";
|
import { GitHubOAuthService } from "../GitHub/GitHubOAuthService";
|
||||||
import { PhoenixClient } from "../Phoenix/PhoenixClient";
|
import { PhoenixClient } from "../Phoenix/PhoenixClient";
|
||||||
import * as ExplorerSettings from "../Shared/ExplorerSettings";
|
import * as ExplorerSettings from "../Shared/ExplorerSettings";
|
||||||
@@ -285,12 +283,43 @@ export default class Explorer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public openInVsCode(): void {
|
public openInVsCode(): void {
|
||||||
|
TelemetryProcessor.traceStart(Action.OpenVSCode);
|
||||||
|
this.openVsCodeButtonClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
private openVsCodeButtonClick(): void {
|
||||||
const activeTab = useTabs.getState().activeTab;
|
const activeTab = useTabs.getState().activeTab;
|
||||||
const resourceId = encodeURIComponent(userContext.databaseAccount.id);
|
const resourceId = encodeURIComponent(userContext.databaseAccount.id);
|
||||||
const database = encodeURIComponent(activeTab?.collection?.databaseId);
|
const database = encodeURIComponent(activeTab?.collection?.databaseId);
|
||||||
const container = encodeURIComponent(activeTab?.collection?.id());
|
const container = encodeURIComponent(activeTab?.collection?.id());
|
||||||
const baseUrl = `vscode://ms-azuretools.vscode-cosmosdb?resourceId=${resourceId}`;
|
const baseUrl = `vscod://ms-azuretools.vscode-cosmosdb?resourceId=${resourceId}`;
|
||||||
const vscodeUrl = activeTab ? `${baseUrl}&database=${database}&container=${container}` : baseUrl;
|
const vscodeUrl = activeTab ? `${baseUrl}&database=${database}&container=${container}` : baseUrl;
|
||||||
|
const startTime = Date.now();
|
||||||
|
let vsCodeNotOpened = false;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const timeOutTime = Date.now() - startTime;
|
||||||
|
if (!vsCodeNotOpened && timeOutTime < 1050) {
|
||||||
|
vsCodeNotOpened = true;
|
||||||
|
useDialog.getState().openDialog(openVSCodeDialogProps);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = vscodeUrl;
|
||||||
|
link.rel = "noopener noreferrer";
|
||||||
|
document.body.appendChild(link);
|
||||||
|
|
||||||
|
try {
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
TelemetryProcessor.traceStart(Action.OpenVSCode);
|
||||||
|
} catch (error) {
|
||||||
|
if (!vsCodeNotOpened) {
|
||||||
|
vsCodeNotOpened = true;
|
||||||
|
logConsoleError(`Failed to open VS Code: ${getErrorMessage(error)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const openVSCodeDialogProps: DialogProps = {
|
const openVSCodeDialogProps: DialogProps = {
|
||||||
linkProps: {
|
linkProps: {
|
||||||
@@ -305,19 +334,15 @@ export default class Explorer {
|
|||||||
secondaryButtonText: "Cancel",
|
secondaryButtonText: "Cancel",
|
||||||
|
|
||||||
onPrimaryButtonClick: () => {
|
onPrimaryButtonClick: () => {
|
||||||
try {
|
vsCodeNotOpened = false;
|
||||||
window.location.href = vscodeUrl;
|
this.openVsCodeButtonClick();
|
||||||
TelemetryProcessor.traceStart(Action.OpenVSCode);
|
useDialog.getState().closeDialog();
|
||||||
} catch (error) {
|
|
||||||
logConsoleError(`Failed to open VS Code: ${getErrorMessage(error)}`);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onSecondaryButtonClick: () => {
|
onSecondaryButtonClick: () => {
|
||||||
useDialog.getState().closeDialog();
|
useDialog.getState().closeDialog();
|
||||||
TelemetryProcessor.traceCancel(Action.OpenVSCode);
|
TelemetryProcessor.traceCancel(Action.OpenVSCode);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
useDialog.getState().openDialog(openVSCodeDialogProps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async openCESCVAFeedbackBlade(): Promise<void> {
|
public async openCESCVAFeedbackBlade(): Promise<void> {
|
||||||
@@ -1116,8 +1141,8 @@ export default class Explorer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public openUploadItemsPane(onUpload?: (data: UploadDetailsRecord[]) => void): void {
|
public openUploadItemsPane(): void {
|
||||||
useSidePanel.getState().openSidePanel("Upload " + getUploadName(), <UploadItemsPane onUpload={onUpload} />);
|
useSidePanel.getState().openSidePanel("Upload " + getUploadName(), <UploadItemsPane />);
|
||||||
}
|
}
|
||||||
public openExecuteSprocParamsPanel(storedProcedure: StoredProcedure): void {
|
public openExecuteSprocParamsPanel(storedProcedure: StoredProcedure): void {
|
||||||
useSidePanel
|
useSidePanel
|
||||||
@@ -1125,7 +1150,7 @@ export default class Explorer {
|
|||||||
.openSidePanel("Input parameters", <ExecuteSprocParamsPane storedProcedure={storedProcedure} />);
|
.openSidePanel("Input parameters", <ExecuteSprocParamsPane storedProcedure={storedProcedure} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getDownloadModalContent(fileName: string): JSX.Element {
|
public getDownloadModalConent(fileName: string): JSX.Element {
|
||||||
if (useNotebook.getState().isPhoenixNotebooks) {
|
if (useNotebook.getState().isPhoenixNotebooks) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -1171,11 +1196,6 @@ export default class Explorer {
|
|||||||
await this.initNotebooks(userContext.databaseAccount);
|
await this.initNotebooks(userContext.databaseAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userContext.authType === AuthType.AAD && userContext.apiType === "SQL") {
|
|
||||||
const throughputBucketsEnabled = await featureRegistered(userContext.subscriptionId, "ThroughputBucketing");
|
|
||||||
updateUserContext({ throughputBucketsEnabled });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.refreshSampleData();
|
this.refreshSampleData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,7 @@ 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 {
|
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||||
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";
|
||||||
@@ -1088,7 +1083,6 @@ 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) {
|
||||||
@@ -1105,8 +1099,6 @@ 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,10 +95,3 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.newVertexComponent {
|
|
||||||
padding: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,5 +13,4 @@ export enum ConsoleDataType {
|
|||||||
Info = 0,
|
Info = 0,
|
||||||
Error = 1,
|
Error = 1,
|
||||||
InProgress = 2,
|
InProgress = 2,
|
||||||
Warning = 3,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,20 +173,8 @@
|
|||||||
.message {
|
.message {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
white-space:pre-wrap;
|
white-space:pre-wrap;
|
||||||
overflow-wrap: break-word;
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.notificationConsoleContents {
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.notificationConsoleData {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,6 @@ 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";
|
||||||
@@ -92,9 +91,6 @@ 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">
|
||||||
@@ -122,10 +118,6 @@ 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" />
|
||||||
@@ -206,7 +198,6 @@ 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,19 +59,6 @@ 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"
|
||||||
@@ -242,19 +229,6 @@ 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"
|
||||||
|
|||||||
@@ -188,11 +188,6 @@ function openPane(action: ActionContracts.OpenPane, explorer: Explorer) {
|
|||||||
action.paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.AddCollection]
|
action.paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.AddCollection]
|
||||||
) {
|
) {
|
||||||
explorer.onNewCollectionClicked();
|
explorer.onNewCollectionClicked();
|
||||||
} else if (
|
|
||||||
action.paneKind === ActionContracts.PaneKind.QuickStart ||
|
|
||||||
action.paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.QuickStart]
|
|
||||||
) {
|
|
||||||
explorer.onNewCollectionClicked({ isQuickstart: true });
|
|
||||||
} else if (
|
} else if (
|
||||||
action.paneKind === ActionContracts.PaneKind.CassandraAddCollection ||
|
action.paneKind === ActionContracts.PaneKind.CassandraAddCollection ||
|
||||||
action.paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.CassandraAddCollection]
|
action.paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.CassandraAddCollection]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { FullTextPoliciesComponent } from "Explorer/Controls/FullTextSeach/FullT
|
|||||||
import { VectorEmbeddingPoliciesComponent } from "Explorer/Controls/VectorSearch/VectorEmbeddingPoliciesComponent";
|
import { VectorEmbeddingPoliciesComponent } from "Explorer/Controls/VectorSearch/VectorEmbeddingPoliciesComponent";
|
||||||
import {
|
import {
|
||||||
AllPropertiesIndexed,
|
AllPropertiesIndexed,
|
||||||
AnalyticalStoreHeader,
|
AnalyticalStorageContent,
|
||||||
ContainerVectorPolicyTooltipContent,
|
ContainerVectorPolicyTooltipContent,
|
||||||
FullTextPolicyDefault,
|
FullTextPolicyDefault,
|
||||||
getPartitionKey,
|
getPartitionKey,
|
||||||
@@ -49,7 +49,12 @@ import { Action } from "Shared/Telemetry/TelemetryConstants";
|
|||||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { getCollectionName } from "Utils/APITypeUtils";
|
import { getCollectionName } from "Utils/APITypeUtils";
|
||||||
import { isCapabilityEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
import {
|
||||||
|
isCapabilityEnabled,
|
||||||
|
isFullTextSearchEnabled,
|
||||||
|
isServerlessAccount,
|
||||||
|
isVectorSearchEnabled,
|
||||||
|
} from "Utils/CapabilityUtils";
|
||||||
import { getUpsellMessage } from "Utils/PricingUtils";
|
import { getUpsellMessage } from "Utils/PricingUtils";
|
||||||
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
||||||
import { CollapsibleSectionComponent } from "../../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
import { CollapsibleSectionComponent } from "../../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
||||||
@@ -60,7 +65,6 @@ import { useDatabases } from "../../useDatabases";
|
|||||||
import { PanelFooterComponent } from "../PanelFooterComponent";
|
import { PanelFooterComponent } from "../PanelFooterComponent";
|
||||||
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
|
||||||
import { PanelLoadingScreen } from "../PanelLoadingScreen";
|
import { PanelLoadingScreen } from "../PanelLoadingScreen";
|
||||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
|
||||||
|
|
||||||
export interface AddCollectionPanelProps {
|
export interface AddCollectionPanelProps {
|
||||||
explorer: Explorer;
|
explorer: Explorer;
|
||||||
@@ -106,7 +110,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
private collectionThroughput: number;
|
private collectionThroughput: number;
|
||||||
private isCollectionAutoscale: boolean;
|
private isCollectionAutoscale: boolean;
|
||||||
private isCostAcknowledged: boolean;
|
private isCostAcknowledged: boolean;
|
||||||
private showFullTextSearch: boolean;
|
|
||||||
|
|
||||||
constructor(props: AddCollectionPanelProps) {
|
constructor(props: AddCollectionPanelProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -141,8 +144,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
fullTextIndexes: [],
|
fullTextIndexes: [],
|
||||||
fullTextPolicyValidated: true,
|
fullTextPolicyValidated: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.showFullTextSearch = userContext.apiType === "SQL";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
@@ -265,7 +266,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
|
|
||||||
<div className="panelMainContent">
|
<div className="panelMainContent">
|
||||||
{!(isFabricNative() && this.props.databaseId !== undefined) && (
|
{!(isFabricNative() && this.props.databaseId !== undefined) && (
|
||||||
<Stack hidden={userContext.apiType === "Tables"} style={{ marginBottom: -2 }}>
|
<Stack hidden={userContext.apiType === "Tables"}>
|
||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
@@ -336,6 +337,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
size={40}
|
size={40}
|
||||||
className="panelTextField"
|
className="panelTextField"
|
||||||
aria-label="New database id, Type a new database id"
|
aria-label="New database id, Type a new database id"
|
||||||
|
autoFocus
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
value={this.state.newDatabaseId}
|
value={this.state.newDatabaseId}
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
@@ -406,12 +408,12 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
responsiveMode={999}
|
responsiveMode={999}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<Separator className="panelSeparator" />
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
<Separator className="panelSeparator" style={{ marginTop: -4, marginBottom: -4 }} />
|
|
||||||
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack horizontal style={{ marginTop: -5, marginBottom: 1 }}>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
{`${getCollectionName()} id`}
|
{`${getCollectionName()} id`}
|
||||||
@@ -449,10 +451,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Separator className="panelSeparator" style={{ marginTop: -5, marginBottom: -5 }} />
|
|
||||||
{this.shouldShowIndexingOptionsForFreeTierAccount() && (
|
{this.shouldShowIndexingOptionsForFreeTierAccount() && (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack horizontal style={{ marginTop: -4, marginBottom: -5 }}>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
Indexing
|
Indexing
|
||||||
@@ -498,7 +500,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
(!this.state.isSharedThroughputChecked ||
|
(!this.state.isSharedThroughputChecked ||
|
||||||
this.props.explorer.isFixedCollectionWithSharedThroughputSupported()) && (
|
this.props.explorer.isFixedCollectionWithSharedThroughputSupported()) && (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack horizontal style={{ marginTop: -5, marginBottom: -4 }}>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
Sharding
|
Sharding
|
||||||
@@ -554,7 +556,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
|
|
||||||
{this.state.isSharded && (
|
{this.state.isSharded && (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack horizontal style={{ marginTop: -5, marginBottom: -4 }}>
|
<Stack horizontal>
|
||||||
<span className="mandatoryStar">* </span>
|
<span className="mandatoryStar">* </span>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
{getPartitionKeyName()}
|
{getPartitionKeyName()}
|
||||||
@@ -598,7 +600,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
{userContext.apiType === "SQL" &&
|
{userContext.apiType === "SQL" &&
|
||||||
this.state.subPartitionKeys.map((subPartitionKey: string, index: number) => {
|
this.state.subPartitionKeys.map((subPartitionKey: string, index: number) => {
|
||||||
return (
|
return (
|
||||||
<Stack style={{ marginBottom: 2, marginTop: -5 }} key={`uniqueKey${index}`} horizontal>
|
<Stack style={{ marginBottom: 8 }} key={`uniqueKey${index}`} horizontal>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
width: "20px",
|
width: "20px",
|
||||||
@@ -666,7 +668,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
<Separator className="panelSeparator" style={{ marginTop: 2, marginBottom: -4 }} />
|
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -727,7 +728,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{!isFabricNative() && userContext.apiType === "SQL" && (
|
{!isFabricNative() && userContext.apiType === "SQL" && (
|
||||||
<Stack style={{ marginTop: -2, marginBottom: -4 }}>
|
<Stack>
|
||||||
{UniqueKeysHeader()}
|
{UniqueKeysHeader()}
|
||||||
{this.state.uniqueKeys.map((uniqueKey: string, i: number): JSX.Element => {
|
{this.state.uniqueKeys.map((uniqueKey: string, i: number): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
@@ -741,6 +742,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
: "Comma separated paths e.g. /firstName,/address/zipCode"
|
: "Comma separated paths e.g. /firstName,/address/zipCode"
|
||||||
}
|
}
|
||||||
className="panelTextField"
|
className="panelTextField"
|
||||||
|
autoFocus
|
||||||
value={uniqueKey}
|
value={uniqueKey}
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const uniqueKeys = this.state.uniqueKeys.map((uniqueKey: string, j: number) => {
|
const uniqueKeys = this.state.uniqueKeys.map((uniqueKey: string, j: number) => {
|
||||||
@@ -775,12 +777,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Separator className="panelSeparator" style={{ marginTop: -15, marginBottom: -4 }} />
|
|
||||||
|
|
||||||
{shouldShowAnalyticalStoreOptions() && (
|
{shouldShowAnalyticalStoreOptions() && (
|
||||||
<Stack className="panelGroupSpacing" style={{ marginTop: -4 }}>
|
<Stack className="panelGroupSpacing">
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
{AnalyticalStoreHeader()}
|
{AnalyticalStorageContent()}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Stack horizontal verticalAlign="center">
|
<Stack horizontal verticalAlign="center">
|
||||||
@@ -821,7 +821,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
<Stack className="panelGroupSpacing">
|
<Stack className="panelGroupSpacing">
|
||||||
<Text variant="small">
|
<Text variant="small">
|
||||||
Azure Synapse Link is required for creating an analytical store{" "}
|
Azure Synapse Link is required for creating an analytical store{" "}
|
||||||
{getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account. <br />
|
{getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account.{" "}
|
||||||
<Link
|
<Link
|
||||||
href="https://aka.ms/cosmosdb-synapselink"
|
href="https://aka.ms/cosmosdb-synapselink"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -1161,7 +1161,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private shouldShowFullTextSearchParameters() {
|
private shouldShowFullTextSearchParameters() {
|
||||||
return !isFabricNative() && this.showFullTextSearch;
|
return isFullTextSearchEnabled() && (isServerlessAccount() || this.shouldShowCollectionThroughputInput());
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
||||||
@@ -1316,7 +1316,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.showFullTextSearch) {
|
if (this.shouldShowFullTextSearchParameters()) {
|
||||||
indexingPolicy.fullTextIndexes = this.state.fullTextIndexes;
|
indexingPolicy.fullTextIndexes = this.state.fullTextIndexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1350,12 +1350,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
let offerThroughput: number;
|
let offerThroughput: number;
|
||||||
let autoPilotMaxThroughput: number;
|
let autoPilotMaxThroughput: number;
|
||||||
|
|
||||||
// Throughput
|
if (databaseLevelThroughput) {
|
||||||
if (isFabricNative()) {
|
|
||||||
// Fabric Native accounts are always autoscale and have a fixed throughput of 1K
|
|
||||||
autoPilotMaxThroughput = AutoPilotUtils.autoPilotThroughput1K;
|
|
||||||
offerThroughput = undefined;
|
|
||||||
} else if (databaseLevelThroughput) {
|
|
||||||
if (this.state.createNewDatabase) {
|
if (this.state.createNewDatabase) {
|
||||||
if (this.isNewDatabaseAutoscale) {
|
if (this.isNewDatabaseAutoscale) {
|
||||||
autoPilotMaxThroughput = this.newDatabaseThroughput;
|
autoPilotMaxThroughput = this.newDatabaseThroughput;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export function UniqueKeysHeader(): JSX.Element {
|
|||||||
"Unique keys provide developers with the ability to add a layer of data integrity to their database. By creating a unique key policy when a container is created, you ensure the uniqueness of one or more values per partition key.";
|
"Unique keys provide developers with the ability to add a layer of data integrity to their database. By creating a unique key policy when a container is created, you ensure the uniqueness of one or more values per partition key.";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack horizontal style={{ marginBottom: -2 }}>
|
<Stack horizontal>
|
||||||
<Text className="panelTextBold" variant="small">
|
<Text className="panelTextBold" variant="small">
|
||||||
Unique keys
|
Unique keys
|
||||||
</Text>
|
</Text>
|
||||||
@@ -98,21 +98,6 @@ export function shouldShowAnalyticalStoreOptions(): boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AnalyticalStoreHeader(): JSX.Element {
|
|
||||||
const tooltipContent =
|
|
||||||
"Enable analytical store capability to perform near real-time analytics on your operational data, without impacting the performance of transactional workloads.";
|
|
||||||
return (
|
|
||||||
<Stack horizontal style={{ marginBottom: -2 }}>
|
|
||||||
<Text className="panelTextBold" variant="small">
|
|
||||||
Analytical Store
|
|
||||||
</Text>
|
|
||||||
<TooltipHost directionalHint={DirectionalHint.bottomLeftEdge} content={tooltipContent}>
|
|
||||||
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} ariaLabel={tooltipContent} />
|
|
||||||
</TooltipHost>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function AnalyticalStorageContent(): JSX.Element {
|
export function AnalyticalStorageContent(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Text variant="small">
|
<Text variant="small">
|
||||||
|
|||||||
@@ -11,11 +11,6 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
>
|
>
|
||||||
<Stack
|
<Stack
|
||||||
hidden={false}
|
hidden={false}
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Stack
|
<Stack
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
@@ -93,6 +88,7 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
aria-label="New database id, Type a new database id"
|
aria-label="New database id, Type a new database id"
|
||||||
aria-required={true}
|
aria-required={true}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
autoFocus={true}
|
||||||
className="panelTextField"
|
className="panelTextField"
|
||||||
id="newDatabaseId"
|
id="newDatabaseId"
|
||||||
name="newDatabaseId"
|
name="newDatabaseId"
|
||||||
@@ -142,25 +138,13 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
</StyledTooltipHostBase>
|
</StyledTooltipHostBase>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<Separator
|
||||||
|
className="panelSeparator"
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Separator
|
|
||||||
className="panelSeparator"
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -4,
|
|
||||||
"marginTop": -4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack
|
<Stack
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": 1,
|
|
||||||
"marginTop": -5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="mandatoryStar"
|
className="mandatoryStar"
|
||||||
@@ -203,24 +187,9 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
value=""
|
value=""
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Separator
|
|
||||||
className="panelSeparator"
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -5,
|
|
||||||
"marginTop": -5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack
|
<Stack
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -4,
|
|
||||||
"marginTop": -5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="mandatoryStar"
|
className="mandatoryStar"
|
||||||
@@ -285,15 +254,6 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
Add hierarchical partition key
|
Add hierarchical partition key
|
||||||
</CustomizedDefaultButton>
|
</CustomizedDefaultButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Separator
|
|
||||||
className="panelSeparator"
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -4,
|
|
||||||
"marginTop": 2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
<ThroughputInput
|
<ThroughputInput
|
||||||
isDatabase={false}
|
isDatabase={false}
|
||||||
@@ -303,21 +263,9 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
setIsThroughputCapExceeded={[Function]}
|
setIsThroughputCapExceeded={[Function]}
|
||||||
setThroughputValue={[Function]}
|
setThroughputValue={[Function]}
|
||||||
/>
|
/>
|
||||||
<Stack
|
<Stack>
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -4,
|
|
||||||
"marginTop": -2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Stack
|
<Stack
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
className="panelTextBold"
|
className="panelTextBold"
|
||||||
@@ -358,53 +306,26 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
Add unique key
|
Add unique key
|
||||||
</CustomizedActionButton>
|
</CustomizedActionButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Separator
|
|
||||||
className="panelSeparator"
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -4,
|
|
||||||
"marginTop": -15,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Stack
|
<Stack
|
||||||
className="panelGroupSpacing"
|
className="panelGroupSpacing"
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginTop": -4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
className="panelTextBold"
|
className="panelTextBold"
|
||||||
variant="small"
|
variant="small"
|
||||||
>
|
>
|
||||||
<Stack
|
<Text
|
||||||
horizontal={true}
|
variant="small"
|
||||||
style={
|
|
||||||
{
|
|
||||||
"marginBottom": -2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Text
|
Enable analytical store capability to perform near real-time analytics on your operational data, without impacting the performance of transactional workloads.
|
||||||
className="panelTextBold"
|
|
||||||
variant="small"
|
<StyledLinkBase
|
||||||
|
aria-label="Learn more about analytical store."
|
||||||
|
href="https://aka.ms/analytical-store-overview"
|
||||||
|
target="_blank"
|
||||||
>
|
>
|
||||||
Analytical Store
|
Learn more
|
||||||
</Text>
|
</StyledLinkBase>
|
||||||
<StyledTooltipHostBase
|
</Text>
|
||||||
content="Enable analytical store capability to perform near real-time analytics on your operational data, without impacting the performance of transactional workloads."
|
|
||||||
directionalHint={4}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
ariaLabel="Enable analytical store capability to perform near real-time analytics on your operational data, without impacting the performance of transactional workloads."
|
|
||||||
className="panelInfoIcon"
|
|
||||||
iconName="Info"
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
</StyledTooltipHostBase>
|
|
||||||
</Stack>
|
|
||||||
</Text>
|
</Text>
|
||||||
<Stack
|
<Stack
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
@@ -461,7 +382,7 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
|
|
||||||
container
|
container
|
||||||
. Enable Synapse Link for this Cosmos DB account.
|
. Enable Synapse Link for this Cosmos DB account.
|
||||||
<br />
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
aria-label="Learn more about Azure Synapse Link."
|
aria-label="Learn more about Azure Synapse Link."
|
||||||
className="capacitycalculator-link"
|
className="capacitycalculator-link"
|
||||||
@@ -490,44 +411,6 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
|
||||||
<CollapsibleSectionComponent
|
|
||||||
isExpandedByDefault={false}
|
|
||||||
onExpand={[Function]}
|
|
||||||
title="Container Full Text Search Policy"
|
|
||||||
>
|
|
||||||
<Stack
|
|
||||||
id="collapsibleFullTextPolicySectionContent"
|
|
||||||
styles={
|
|
||||||
{
|
|
||||||
"root": {
|
|
||||||
"position": "relative",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Stack
|
|
||||||
styles={
|
|
||||||
{
|
|
||||||
"root": {
|
|
||||||
"paddingLeft": 40,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<FullTextPoliciesComponent
|
|
||||||
fullTextPolicy={
|
|
||||||
{
|
|
||||||
"defaultLanguage": "en-US",
|
|
||||||
"fullTextPaths": [],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFullTextPathChange={[Function]}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</CollapsibleSectionComponent>
|
|
||||||
</Stack>
|
|
||||||
<CollapsibleSectionComponent
|
<CollapsibleSectionComponent
|
||||||
isExpandedByDefault={false}
|
isExpandedByDefault={false}
|
||||||
onExpand={[Function]}
|
onExpand={[Function]}
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ import { PanelInfoErrorComponent } from "Explorer/Panes/PanelInfoErrorComponent"
|
|||||||
import { PanelLoadingScreen } from "Explorer/Panes/PanelLoadingScreen";
|
import { PanelLoadingScreen } from "Explorer/Panes/PanelLoadingScreen";
|
||||||
import { useDatabases } from "Explorer/useDatabases";
|
import { useDatabases } from "Explorer/useDatabases";
|
||||||
import { useSidePanel } from "hooks/useSidePanel";
|
import { useSidePanel } from "hooks/useSidePanel";
|
||||||
import React, { MutableRefObject, useEffect, useRef, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { CollectionCreation } from "Shared/Constants";
|
import { CollectionCreation } from "Shared/Constants";
|
||||||
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 { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
import { isFullTextSearchEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||||
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
||||||
|
|
||||||
export interface AddGlobalSecondaryIndexPanelProps {
|
export interface AddGlobalSecondaryIndexPanelProps {
|
||||||
@@ -75,8 +75,6 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
const [showErrorDetails, setShowErrorDetails] = useState<boolean>();
|
const [showErrorDetails, setShowErrorDetails] = useState<boolean>();
|
||||||
const [isExecuting, setIsExecuting] = useState<boolean>();
|
const [isExecuting, setIsExecuting] = useState<boolean>();
|
||||||
|
|
||||||
const showFullTextSearch: MutableRefObject<boolean> = useRef<boolean>(userContext.apiType === "SQL");
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sourceContainerOptions: IDropdownOption[] = [];
|
const sourceContainerOptions: IDropdownOption[] = [];
|
||||||
useDatabases.getState().databases.forEach((database: Database) => {
|
useDatabases.getState().databases.forEach((database: Database) => {
|
||||||
@@ -142,6 +140,10 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
return isVectorSearchEnabled() && (isServerlessAccount() || showCollectionThroughputInput());
|
return isVectorSearchEnabled() && (isServerlessAccount() || showCollectionThroughputInput());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showFullTextSearchParameters = (): boolean => {
|
||||||
|
return isFullTextSearchEnabled() && (isServerlessAccount() || showCollectionThroughputInput());
|
||||||
|
};
|
||||||
|
|
||||||
const getAnalyticalStorageTtl = (): number => {
|
const getAnalyticalStorageTtl = (): number => {
|
||||||
if (!isSynapseLinkEnabled()) {
|
if (!isSynapseLinkEnabled()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -226,7 +228,7 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showFullTextSearch) {
|
if (showFullTextSearchParameters()) {
|
||||||
indexingPolicy.fullTextIndexes = fullTextIndexes;
|
indexingPolicy.fullTextIndexes = fullTextIndexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,7 +387,7 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showFullTextSearch && (
|
{showFullTextSearchParameters() && (
|
||||||
<FullTextSearchComponent
|
<FullTextSearchComponent
|
||||||
{...{ fullTextPolicy, setFullTextPolicy, setFullTextIndexes, setFullTextPolicyValidated }}
|
{...{ fullTextPolicy, setFullTextPolicy, setFullTextIndexes, setFullTextPolicyValidated }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -172,17 +172,6 @@ exports[`AddGlobalSecondaryIndexPanel render default panel 1`] = `
|
|||||||
}
|
}
|
||||||
setEnableAnalyticalStore={[Function]}
|
setEnableAnalyticalStore={[Function]}
|
||||||
/>
|
/>
|
||||||
<FullTextSearchComponent
|
|
||||||
fullTextPolicy={
|
|
||||||
{
|
|
||||||
"defaultLanguage": "en-US",
|
|
||||||
"fullTextPaths": [],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setFullTextIndexes={[Function]}
|
|
||||||
setFullTextPolicy={[Function]}
|
|
||||||
setFullTextPolicyValidated={[Function]}
|
|
||||||
/>
|
|
||||||
<AdvancedComponent
|
<AdvancedComponent
|
||||||
setSubPartitionKeys={[Function]}
|
setSubPartitionKeys={[Function]}
|
||||||
setUseHashV1={[Function]}
|
setUseHashV1={[Function]}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
&> :not(.collapsibleSection) {
|
& > :not(.collapsibleSection) {
|
||||||
margin-bottom: @DefaultSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
|
|
||||||
&> :not(:last-child) {
|
& > :not(:last-child) {
|
||||||
margin-bottom: @DefaultSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,14 +56,6 @@
|
|||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.panelMainContent {
|
|
||||||
padding: 0 24px;
|
|
||||||
margin: 0;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.panelHeader {
|
.panelHeader {
|
||||||
@@ -121,87 +113,70 @@
|
|||||||
.deleteCollectionFeedback {
|
.deleteCollectionFeedback {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addRemoveIcon {
|
.addRemoveIcon {
|
||||||
margin-left: 4px !important;
|
margin-left: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addRemoveIconLabel {
|
.addRemoveIconLabel {
|
||||||
margin-top: 28px;
|
margin-top: 28px;
|
||||||
margin-left: 4px !important;
|
margin-left: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addRemoveIcon [alt="editEntity"]:focus,
|
.addRemoveIcon [alt="editEntity"]:focus,
|
||||||
.addRemoveIconLabel [alt="editEntity"]:focus {
|
.addRemoveIconLabel [alt="editEntity"]:focus {
|
||||||
border: 1px dashed #605e5c;
|
border: 1px dashed #605e5c;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addNewParamStyle {
|
.addNewParamStyle {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-left: 5px !important;
|
margin-left: 5px !important;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panelGroupSpacing> :not(:last-child) {
|
.panelGroupSpacing > :not(:last-child) {
|
||||||
margin-bottom: @DefaultSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fileUpload {
|
.fileUpload {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.customFileUpload {
|
.customFileUpload {
|
||||||
padding: 25px 0px 0px 10px;
|
padding: 25px 0px 0px 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fileIcon {
|
.fileIcon {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panelAddIconLabel {
|
.panelAddIconLabel {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
margin: 30px 0 0 10px;
|
margin: 30px 0 0 10px;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panelAddIcon {
|
.panelAddIcon {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
margin: 30px 0 0 10px;
|
margin: 30px 0 0 10px;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.removeIcon {
|
.removeIcon {
|
||||||
color: @InfoIconColor;
|
color: @InfoIconColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.backImageIcon {
|
.backImageIcon {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[alt="back"]:focus {
|
[alt="back"]:focus {
|
||||||
border: 1px solid #605e5c;
|
border: 1px solid #605e5c;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addEntityDatePicker {
|
.addEntityDatePicker {
|
||||||
max-width: 145px;
|
max-width: 145px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addEntityTextField {
|
.addEntityTextField {
|
||||||
width: 237px;
|
width: 237px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addButtonEntiy {
|
.addButtonEntiy {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-select-view {
|
.column-select-view {
|
||||||
margin: 20px 0px 0px 0px;
|
margin: 20px 0px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panelSeparator::before {
|
.panelSeparator::before {
|
||||||
background-color: #edebe9;
|
background-color: #edebe9;
|
||||||
}
|
}
|
||||||
@@ -180,11 +180,6 @@ 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)
|
||||||
@@ -209,7 +204,6 @@ 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) &&
|
||||||
@@ -387,7 +381,6 @@ 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());
|
||||||
@@ -417,7 +410,6 @@ 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,
|
||||||
@@ -768,6 +760,7 @@ 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>
|
||||||
@@ -950,38 +943,6 @@ 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,51 +495,6 @@ 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"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -48,11 +48,7 @@ const classNames = mergeStyleSets({
|
|||||||
warning: [{ color: theme.semanticColors.warningIcon }, iconClass],
|
warning: [{ color: theme.semanticColors.warningIcon }, iconClass],
|
||||||
});
|
});
|
||||||
|
|
||||||
export type UploadItemsPaneProps = {
|
export const UploadItemsPane: FunctionComponent = () => {
|
||||||
onUpload?: (data: UploadDetailsRecord[]) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({ onUpload }) => {
|
|
||||||
const [files, setFiles] = useState<FileList>();
|
const [files, setFiles] = useState<FileList>();
|
||||||
const [uploadFileData, setUploadFileData] = useState<UploadDetailsRecord[]>([]);
|
const [uploadFileData, setUploadFileData] = useState<UploadDetailsRecord[]>([]);
|
||||||
const [formError, setFormError] = useState<string>("");
|
const [formError, setFormError] = useState<string>("");
|
||||||
@@ -75,8 +71,6 @@ export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({ onUpl
|
|||||||
(uploadDetails) => {
|
(uploadDetails) => {
|
||||||
setUploadFileData(uploadDetails.data);
|
setUploadFileData(uploadDetails.data);
|
||||||
setFiles(undefined);
|
setFiles(undefined);
|
||||||
// Emit the upload details to the parent component
|
|
||||||
onUpload && onUpload(uploadDetails.data);
|
|
||||||
},
|
},
|
||||||
(error: Error) => {
|
(error: Error) => {
|
||||||
const errorMessage = getErrorMessage(error);
|
const errorMessage = getErrorMessage(error);
|
||||||
|
|||||||
@@ -30,10 +30,8 @@ import { KeyboardAction, KeyboardActionGroup, KeyboardActionHandler, useKeyboard
|
|||||||
import { isFabric, isFabricMirrored, isFabricNative, isFabricNativeReadOnly } from "Platform/Fabric/FabricUtil";
|
import { isFabric, isFabricMirrored, isFabricNative, isFabricNativeReadOnly } from "Platform/Fabric/FabricUtil";
|
||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { getCollectionName, getDatabaseName } from "Utils/APITypeUtils";
|
import { getCollectionName, getDatabaseName } from "Utils/APITypeUtils";
|
||||||
import { conditionalClass } from "Utils/StyleUtils";
|
|
||||||
import { Allotment, AllotmentHandle } from "allotment";
|
import { Allotment, AllotmentHandle } from "allotment";
|
||||||
import { useSidePanel } from "hooks/useSidePanel";
|
import { useSidePanel } from "hooks/useSidePanel";
|
||||||
import useZoomLevel from "hooks/useZoomLevel";
|
|
||||||
import { debounce } from "lodash";
|
import { debounce } from "lodash";
|
||||||
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||||
|
|
||||||
@@ -106,23 +104,6 @@ const useSidebarStyles = makeStyles({
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
accessibleContent: {
|
|
||||||
"@media (max-width: 420px)": {
|
|
||||||
overflow: "scroll",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
minHeightResponsive: {
|
|
||||||
"@media (max-width: 420px)": {
|
|
||||||
minHeight: "400px",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
accessibleContentZoom: {
|
|
||||||
overflow: "scroll",
|
|
||||||
},
|
|
||||||
|
|
||||||
minHeightZoom: {
|
|
||||||
minHeight: "400px",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
interface GlobalCommandsProps {
|
interface GlobalCommandsProps {
|
||||||
@@ -294,7 +275,6 @@ export const SidebarContainer: React.FC<SidebarProps> = ({ explorer }) => {
|
|||||||
const [expandedSize, setExpandedSize] = React.useState(300);
|
const [expandedSize, setExpandedSize] = React.useState(300);
|
||||||
const hasSidebar = userContext.apiType !== "Postgres" && userContext.apiType !== "VCoreMongo";
|
const hasSidebar = userContext.apiType !== "Postgres" && userContext.apiType !== "VCoreMongo";
|
||||||
const allotment = useRef<AllotmentHandle>(null);
|
const allotment = useRef<AllotmentHandle>(null);
|
||||||
const isZoomed = useZoomLevel();
|
|
||||||
|
|
||||||
const expand = useCallback(() => {
|
const expand = useCallback(() => {
|
||||||
if (!expanded) {
|
if (!expanded) {
|
||||||
@@ -345,23 +325,11 @@ export const SidebarContainer: React.FC<SidebarProps> = ({ explorer }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sidebarContainer">
|
<div className="sidebarContainer">
|
||||||
<Allotment
|
<Allotment ref={allotment} onChange={onChange} onDragEnd={onDragEnd} className="resourceTreeAndTabs">
|
||||||
ref={allotment}
|
|
||||||
onChange={onChange}
|
|
||||||
onDragEnd={onDragEnd}
|
|
||||||
className={`resourceTreeAndTabs ${styles.accessibleContent} ${conditionalClass(
|
|
||||||
isZoomed,
|
|
||||||
styles.accessibleContentZoom,
|
|
||||||
)}`}
|
|
||||||
>
|
|
||||||
{/* Collections Tree - Start */}
|
{/* Collections Tree - Start */}
|
||||||
{hasSidebar && (
|
{hasSidebar && (
|
||||||
// When collapsed, we force the pane to 24 pixels wide and make it non-resizable.
|
// When collapsed, we force the pane to 24 pixels wide and make it non-resizable.
|
||||||
<Allotment.Pane
|
<Allotment.Pane minSize={24} preferredSize={250}>
|
||||||
className={`${styles.minHeightResponsive} ${conditionalClass(isZoomed, styles.minHeightZoom)}`}
|
|
||||||
minSize={24}
|
|
||||||
preferredSize={250}
|
|
||||||
>
|
|
||||||
<CosmosFluentProvider className={mergeClasses(styles.sidebar)}>
|
<CosmosFluentProvider className={mergeClasses(styles.sidebar)}>
|
||||||
<div className={styles.sidebarContainer}>
|
<div className={styles.sidebarContainer}>
|
||||||
{loading && (
|
{loading && (
|
||||||
@@ -417,10 +385,7 @@ export const SidebarContainer: React.FC<SidebarProps> = ({ explorer }) => {
|
|||||||
</CosmosFluentProvider>
|
</CosmosFluentProvider>
|
||||||
</Allotment.Pane>
|
</Allotment.Pane>
|
||||||
)}
|
)}
|
||||||
<Allotment.Pane
|
<Allotment.Pane minSize={200}>
|
||||||
className={`${styles.minHeightResponsive} ${conditionalClass(isZoomed, styles.minHeightZoom)}`}
|
|
||||||
minSize={200}
|
|
||||||
>
|
|
||||||
<Tabs explorer={explorer} />
|
<Tabs explorer={explorer} />
|
||||||
</Allotment.Pane>
|
</Allotment.Pane>
|
||||||
</Allotment>
|
</Allotment>
|
||||||
|
|||||||
@@ -30,21 +30,6 @@
|
|||||||
margin: 0px auto;
|
margin: 0px auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.splashStackContainer {
|
|
||||||
.splashStackRow {
|
|
||||||
display: flex;
|
|
||||||
gap: 0 16px;
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 16px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
width: 85% !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainButtonsContainer {
|
.mainButtonsContainer {
|
||||||
.flex-display();
|
.flex-display();
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import LinkIcon from "../../../images/Link_blue.svg";
|
|||||||
import PowerShellIcon from "../../../images/PowerShell.svg";
|
import PowerShellIcon from "../../../images/PowerShell.svg";
|
||||||
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
|
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
|
||||||
import QuickStartIcon from "../../../images/Quickstart_Lightning.svg";
|
import QuickStartIcon from "../../../images/Quickstart_Lightning.svg";
|
||||||
import VisualStudioIcon from "../../../images/VisualStudio.svg";
|
|
||||||
import NotebookIcon from "../../../images/notebook/Notebook-resource.svg";
|
import NotebookIcon from "../../../images/notebook/Notebook-resource.svg";
|
||||||
import CollectionIcon from "../../../images/tree-collection.svg";
|
import CollectionIcon from "../../../images/tree-collection.svg";
|
||||||
import * as Constants from "../../Common/Constants";
|
import * as Constants from "../../Common/Constants";
|
||||||
@@ -126,12 +125,8 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
useDatabases.getState().sampleDataResourceTokenCollection
|
useDatabases.getState().sampleDataResourceTokenCollection
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack style={{ width: "66%", cursor: "pointer", margin: "40px auto" }} tokens={{ childrenGap: 16 }}>
|
||||||
className="splashStackContainer"
|
<Stack horizontal tokens={{ childrenGap: 16 }}>
|
||||||
style={{ width: "66%", cursor: "pointer", margin: "40px auto" }}
|
|
||||||
tokens={{ childrenGap: 16 }}
|
|
||||||
>
|
|
||||||
<Stack className="splashStackRow" horizontal>
|
|
||||||
<SplashScreenButton
|
<SplashScreenButton
|
||||||
imgSrc={QuickStartIcon}
|
imgSrc={QuickStartIcon}
|
||||||
title={"Launch quick start"}
|
title={"Launch quick start"}
|
||||||
@@ -151,7 +146,7 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack className="splashStackRow" horizontal>
|
<Stack horizontal tokens={{ childrenGap: 16 }}>
|
||||||
{useQueryCopilot.getState().copilotEnabled && (
|
{useQueryCopilot.getState().copilotEnabled && (
|
||||||
<SplashScreenButton
|
<SplashScreenButton
|
||||||
imgSrc={CopilotIcon}
|
imgSrc={CopilotIcon}
|
||||||
@@ -295,10 +290,10 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
<form className="connectExplorerFormContainer">
|
<form className="connectExplorerFormContainer">
|
||||||
<div className="splashScreenContainer">
|
<div className="splashScreenContainer">
|
||||||
<div className="splashScreen">
|
<div className="splashScreen">
|
||||||
<h2 className="title" role="heading" aria-label={title}>
|
<h1 className="title" role="heading" aria-label={title}>
|
||||||
{title}
|
{title}
|
||||||
<FeaturePanelLauncher />
|
<FeaturePanelLauncher />
|
||||||
</h2>
|
</h1>
|
||||||
<div className="subtitle">{subtitle}</div>
|
<div className="subtitle">{subtitle}</div>
|
||||||
{this.getSplashScreenButtons()}
|
{this.getSplashScreenButtons()}
|
||||||
{useCarousel.getState().showCoachMark && (
|
{useCarousel.getState().showCoachMark && (
|
||||||
@@ -463,10 +458,10 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (userContext.apiType === "VCoreMongo") {
|
if (userContext.apiType === "VCoreMongo") {
|
||||||
icon = VisualStudioIcon;
|
icon = ContainersIcon;
|
||||||
title = "Connect with VS Code";
|
title = "Connect with Studio 3T";
|
||||||
description = "Query and Manage your MongoDB cluster in Visual Studio Code";
|
description = "Prefer Studio 3T? Find your connection strings here";
|
||||||
onClick = () => this.container.openInVsCode();
|
onClick = () => useTabs.getState().openAndActivateReactTab(ReactTabKind.Connect);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import { useDialog } from "Explorer/Controls/Dialog";
|
|||||||
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||||
import { InputDataList, InputDatalistDropdownOptionSection } from "Explorer/Controls/InputDataList/InputDataList";
|
import { InputDataList, InputDatalistDropdownOptionSection } from "Explorer/Controls/InputDataList/InputDataList";
|
||||||
import { ProgressModalDialog } from "Explorer/Controls/ProgressModalDialog";
|
import { ProgressModalDialog } from "Explorer/Controls/ProgressModalDialog";
|
||||||
|
import Explorer from "Explorer/Explorer";
|
||||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import { querySampleDocuments, readSampleDocument } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
import { querySampleDocuments, readSampleDocument } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
||||||
import {
|
import {
|
||||||
@@ -63,7 +64,7 @@ import * as Logger from "../../../Common/Logger";
|
|||||||
import * as MongoProxyClient from "../../../Common/MongoProxyClient";
|
import * as MongoProxyClient from "../../../Common/MongoProxyClient";
|
||||||
import * as DataModels from "../../../Contracts/DataModels";
|
import * as DataModels from "../../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
import { CollectionBase, UploadDetailsRecord } from "../../../Contracts/ViewModels";
|
import { CollectionBase } from "../../../Contracts/ViewModels";
|
||||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import * as QueryUtils from "../../../Utils/QueryUtils";
|
import * as QueryUtils from "../../../Utils/QueryUtils";
|
||||||
import { defaultQueryFields, extractPartitionKeyValues } from "../../../Utils/QueryUtils";
|
import { defaultQueryFields, extractPartitionKeyValues } from "../../../Utils/QueryUtils";
|
||||||
@@ -143,13 +144,6 @@ export const useDocumentsTabStyles = makeStyles({
|
|||||||
deleteProgressContent: {
|
deleteProgressContent: {
|
||||||
paddingTop: tokens.spacingVerticalL,
|
paddingTop: tokens.spacingVerticalL,
|
||||||
},
|
},
|
||||||
smallScreenContent: {
|
|
||||||
"@media (max-width: 420px)": {
|
|
||||||
flexWrap: "wrap",
|
|
||||||
minHeight: "max-content",
|
|
||||||
padding: "4px",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export class DocumentsTabV2 extends TabsBase {
|
export class DocumentsTabV2 extends TabsBase {
|
||||||
@@ -308,6 +302,7 @@ type UiKeyboardEvent = (e: KeyboardEvent | React.SyntheticEvent<Element, Event>)
|
|||||||
|
|
||||||
// Export to expose to unit tests
|
// Export to expose to unit tests
|
||||||
export type ButtonsDependencies = {
|
export type ButtonsDependencies = {
|
||||||
|
_collection: ViewModels.CollectionBase;
|
||||||
selectedRows: Set<TableRowId>;
|
selectedRows: Set<TableRowId>;
|
||||||
editorState: ViewModels.DocumentExplorerState;
|
editorState: ViewModels.DocumentExplorerState;
|
||||||
isPreferredApiMongoDB: boolean;
|
isPreferredApiMongoDB: boolean;
|
||||||
@@ -318,7 +313,26 @@ export type ButtonsDependencies = {
|
|||||||
onSaveExistingDocumentClick: UiKeyboardEvent;
|
onSaveExistingDocumentClick: UiKeyboardEvent;
|
||||||
onRevertExistingDocumentClick: UiKeyboardEvent;
|
onRevertExistingDocumentClick: UiKeyboardEvent;
|
||||||
onDeleteExistingDocumentsClick: UiKeyboardEvent;
|
onDeleteExistingDocumentsClick: UiKeyboardEvent;
|
||||||
onUploadDocumentsClick: UiKeyboardEvent;
|
};
|
||||||
|
|
||||||
|
const createUploadButton = (container: Explorer): CommandButtonComponentProps => {
|
||||||
|
const label = "Upload Item";
|
||||||
|
return {
|
||||||
|
id: UPLOAD_BUTTON_ID,
|
||||||
|
iconSrc: UploadIcon,
|
||||||
|
iconAlt: label,
|
||||||
|
onCommandClick: () => {
|
||||||
|
const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection();
|
||||||
|
selectedCollection && container.openUploadItemsPane();
|
||||||
|
},
|
||||||
|
commandButtonLabel: label,
|
||||||
|
ariaLabel: label,
|
||||||
|
hasPopup: true,
|
||||||
|
disabled:
|
||||||
|
useSelectedNode.getState().isDatabaseNodeOrNoneSelected() ||
|
||||||
|
!useClientWriteEnabled.getState().clientWriteEnabled ||
|
||||||
|
useSelectedNode.getState().isQueryCopilotCollectionSelected(),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Export to expose to unit tests
|
// Export to expose to unit tests
|
||||||
@@ -331,6 +345,7 @@ export const UPLOAD_BUTTON_ID = "uploadItemBtn";
|
|||||||
|
|
||||||
// Export to expose in unit tests
|
// Export to expose in unit tests
|
||||||
export const getTabsButtons = ({
|
export const getTabsButtons = ({
|
||||||
|
_collection,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
editorState,
|
editorState,
|
||||||
isPreferredApiMongoDB,
|
isPreferredApiMongoDB,
|
||||||
@@ -341,7 +356,6 @@ export const getTabsButtons = ({
|
|||||||
onSaveExistingDocumentClick,
|
onSaveExistingDocumentClick,
|
||||||
onRevertExistingDocumentClick,
|
onRevertExistingDocumentClick,
|
||||||
onDeleteExistingDocumentsClick,
|
onDeleteExistingDocumentsClick,
|
||||||
onUploadDocumentsClick,
|
|
||||||
}: ButtonsDependencies): CommandButtonComponentProps[] => {
|
}: ButtonsDependencies): CommandButtonComponentProps[] => {
|
||||||
if (isFabric() && userContext.fabricContext?.isReadOnly) {
|
if (isFabric() && userContext.fabricContext?.isReadOnly) {
|
||||||
// All the following buttons require write access
|
// All the following buttons require write access
|
||||||
@@ -453,20 +467,7 @@ export const getTabsButtons = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isPreferredApiMongoDB) {
|
if (!isPreferredApiMongoDB) {
|
||||||
const label = "Upload Item";
|
buttons.push(createUploadButton(_collection.container));
|
||||||
buttons.push({
|
|
||||||
id: UPLOAD_BUTTON_ID,
|
|
||||||
iconSrc: UploadIcon,
|
|
||||||
iconAlt: label,
|
|
||||||
onCommandClick: onUploadDocumentsClick,
|
|
||||||
commandButtonLabel: label,
|
|
||||||
ariaLabel: label,
|
|
||||||
hasPopup: true,
|
|
||||||
disabled:
|
|
||||||
useSelectedNode.getState().isDatabaseNodeOrNoneSelected() ||
|
|
||||||
!useClientWriteEnabled.getState().clientWriteEnabled ||
|
|
||||||
useSelectedNode.getState().isQueryCopilotCollectionSelected(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buttons;
|
return buttons;
|
||||||
@@ -671,7 +672,6 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
collection: CollectionBase;
|
collection: CollectionBase;
|
||||||
}>(undefined);
|
}>(undefined);
|
||||||
const [bulkDeleteMode, setBulkDeleteMode] = useState<"inProgress" | "completed" | "aborting" | "aborted">(undefined);
|
const [bulkDeleteMode, setBulkDeleteMode] = useState<"inProgress" | "completed" | "aborting" | "aborted">(undefined);
|
||||||
const [abortController, setAbortController] = useState<AbortController | undefined>(undefined);
|
|
||||||
|
|
||||||
const setKeyboardActions = useKeyboardActionGroup(KeyboardActionGroup.ACTIVE_TAB);
|
const setKeyboardActions = useKeyboardActionGroup(KeyboardActionGroup.ACTIVE_TAB);
|
||||||
|
|
||||||
@@ -699,19 +699,13 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bulkDeleteProcess.pendingIds.length === 0 && bulkDeleteProcess.throttledIds.length === 0) {
|
if (
|
||||||
// Successfully deleted all documents
|
(bulkDeleteProcess.pendingIds.length === 0 && bulkDeleteProcess.throttledIds.length === 0) ||
|
||||||
|
bulkDeleteMode === "aborting"
|
||||||
|
) {
|
||||||
|
// Successfully deleted all documents or operation was aborted
|
||||||
bulkDeleteOperation.onCompleted(bulkDeleteProcess.successfulIds);
|
bulkDeleteOperation.onCompleted(bulkDeleteProcess.successfulIds);
|
||||||
setBulkDeleteMode("completed");
|
setBulkDeleteMode(bulkDeleteMode === "aborting" ? "aborted" : "completed");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bulkDeleteMode === "aborting") {
|
|
||||||
// Operation was aborted
|
|
||||||
abortController?.abort();
|
|
||||||
bulkDeleteOperation.onCompleted(bulkDeleteProcess.successfulIds);
|
|
||||||
setBulkDeleteMode("aborted");
|
|
||||||
setAbortController(undefined);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,10 +713,8 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
const newPendingIds = bulkDeleteProcess.pendingIds.concat(bulkDeleteProcess.throttledIds);
|
const newPendingIds = bulkDeleteProcess.pendingIds.concat(bulkDeleteProcess.throttledIds);
|
||||||
const timeout = bulkDeleteProcess.beforeExecuteMs || 0;
|
const timeout = bulkDeleteProcess.beforeExecuteMs || 0;
|
||||||
|
|
||||||
const ac = new AbortController();
|
|
||||||
setAbortController(ac);
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
deleteNoSqlDocuments(bulkDeleteOperation.collection, [...newPendingIds], ac.signal)
|
deleteNoSqlDocuments(bulkDeleteOperation.collection, [...newPendingIds])
|
||||||
.then((deleteResult) => {
|
.then((deleteResult) => {
|
||||||
let retryAfterMilliseconds = 0;
|
let retryAfterMilliseconds = 0;
|
||||||
const newSuccessful: DocumentId[] = [];
|
const newSuccessful: DocumentId[] = [];
|
||||||
@@ -878,6 +870,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateNavbarWithTabsButtons(isTabActive, {
|
updateNavbarWithTabsButtons(isTabActive, {
|
||||||
|
_collection,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
editorState,
|
editorState,
|
||||||
isPreferredApiMongoDB,
|
isPreferredApiMongoDB,
|
||||||
@@ -888,7 +881,6 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
onSaveExistingDocumentClick,
|
onSaveExistingDocumentClick,
|
||||||
onRevertExistingDocumentClick,
|
onRevertExistingDocumentClick,
|
||||||
onDeleteExistingDocumentsClick,
|
onDeleteExistingDocumentsClick,
|
||||||
onUploadDocumentsClick,
|
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -1294,47 +1286,11 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
);
|
);
|
||||||
}, [deleteDocuments, documentIds, isPreferredApiMongoDB, selectedRows]);
|
}, [deleteDocuments, documentIds, isPreferredApiMongoDB, selectedRows]);
|
||||||
|
|
||||||
const onUploadDocumentsClick = useCallback((): void => {
|
|
||||||
if (!isPreferredApiMongoDB) {
|
|
||||||
const onSuccessUpload = (data: UploadDetailsRecord[]) => {
|
|
||||||
const addedIdsSet = new Set(
|
|
||||||
data
|
|
||||||
.reduce(
|
|
||||||
(result: ItemDefinition[], record) =>
|
|
||||||
result.concat(record.resources && record.resources.length ? record.resources : []),
|
|
||||||
[],
|
|
||||||
)
|
|
||||||
.map((document) => {
|
|
||||||
const partitionKeyValueArray: PartitionKey[] = extractPartitionKeyValues(
|
|
||||||
document,
|
|
||||||
partitionKey as PartitionKeyDefinition,
|
|
||||||
);
|
|
||||||
return newDocumentId(
|
|
||||||
document as ItemDefinition & Resource,
|
|
||||||
partitionKeyProperties,
|
|
||||||
partitionKeyValueArray as string[],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const documents = new Set(documentIds);
|
|
||||||
addedIdsSet.forEach((item) => documents.add(item));
|
|
||||||
setDocumentIds(Array.from(documents));
|
|
||||||
|
|
||||||
setSelectedDocumentContent(undefined);
|
|
||||||
setClickedRowIndex(undefined);
|
|
||||||
setSelectedRows(new Set());
|
|
||||||
setEditorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
|
||||||
};
|
|
||||||
|
|
||||||
_collection.container.openUploadItemsPane(onSuccessUpload);
|
|
||||||
}
|
|
||||||
}, [_collection.container, documentIds, isPreferredApiMongoDB, newDocumentId, partitionKey, partitionKeyProperties]);
|
|
||||||
|
|
||||||
// If editor state changes, update the nav
|
// If editor state changes, update the nav
|
||||||
useEffect(
|
useEffect(
|
||||||
() =>
|
() =>
|
||||||
updateNavbarWithTabsButtons(isTabActive, {
|
updateNavbarWithTabsButtons(isTabActive, {
|
||||||
|
_collection,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
editorState,
|
editorState,
|
||||||
isPreferredApiMongoDB,
|
isPreferredApiMongoDB,
|
||||||
@@ -1343,11 +1299,11 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
onSaveNewDocumentClick,
|
onSaveNewDocumentClick,
|
||||||
onRevertNewDocumentClick,
|
onRevertNewDocumentClick,
|
||||||
onSaveExistingDocumentClick,
|
onSaveExistingDocumentClick,
|
||||||
onRevertExistingDocumentClick,
|
onRevertExistingDocumentClick: onRevertExistingDocumentClick,
|
||||||
onDeleteExistingDocumentsClick,
|
onDeleteExistingDocumentsClick: onDeleteExistingDocumentsClick,
|
||||||
onUploadDocumentsClick,
|
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
|
_collection,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
editorState,
|
editorState,
|
||||||
isPreferredApiMongoDB,
|
isPreferredApiMongoDB,
|
||||||
@@ -1358,7 +1314,6 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
onSaveExistingDocumentClick,
|
onSaveExistingDocumentClick,
|
||||||
onRevertExistingDocumentClick,
|
onRevertExistingDocumentClick,
|
||||||
onDeleteExistingDocumentsClick,
|
onDeleteExistingDocumentsClick,
|
||||||
onUploadDocumentsClick,
|
|
||||||
isTabActive,
|
isTabActive,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -2147,7 +2102,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||||||
return (
|
return (
|
||||||
<CosmosFluentProvider className={styles.container}>
|
<CosmosFluentProvider className={styles.container}>
|
||||||
<div data-test={"DocumentsTab"} className="tab-pane active" role="tabpanel" style={{ display: "flex" }}>
|
<div data-test={"DocumentsTab"} className="tab-pane active" role="tabpanel" style={{ display: "flex" }}>
|
||||||
<div data-test={"DocumentsTab/Filter"} className={`${styles.filterRow} ${styles.smallScreenContent}`}>
|
<div data-test={"DocumentsTab/Filter"} className={styles.filterRow}>
|
||||||
{!isPreferredApiMongoDB && <span> SELECT * FROM c </span>}
|
{!isPreferredApiMongoDB && <span> SELECT * FROM c </span>}
|
||||||
<InputDataList
|
<InputDataList
|
||||||
dropdownOptions={getFilterChoices()}
|
dropdownOptions={getFilterChoices()}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ exports[`Documents tab (noSql API) when rendered should render the page 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="___11ktxfv_0000000 f1o614cb fy9rknc f22iagw fsnqrgy f1f5gg8d fjodcmx f122n59 f1f09k3d fg706s2 frpde29 ___1ngl8o6_0000000 fz7mnu6 fl3egqs flhmrkm"
|
className="___11ktxfv_0000000 f1o614cb fy9rknc f22iagw fsnqrgy f1f5gg8d fjodcmx f122n59 f1f09k3d fg706s2 frpde29"
|
||||||
data-test="DocumentsTab/Filter"
|
data-test="DocumentsTab/Filter"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export default class MongoShellTabComponent extends Component<
|
|||||||
apiEndpoint: apiEndpoint,
|
apiEndpoint: apiEndpoint,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
window.origin,
|
"https://localhost:443",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ export function getMongoShellUrl(): string {
|
|||||||
const mongoEndpoint = account?.properties?.mongoEndpoint || account?.properties?.documentEndpoint;
|
const mongoEndpoint = account?.properties?.mongoEndpoint || account?.properties?.documentEndpoint;
|
||||||
const queryString = `resourceId=${resourceId}&accountName=${accountName}&mongoEndpoint=${mongoEndpoint}`;
|
const queryString = `resourceId=${resourceId}&accountName=${accountName}&mongoEndpoint=${mongoEndpoint}`;
|
||||||
|
|
||||||
return `/mongoshell/index.html?${queryString}`;
|
return `https://localhost:443/index.html?${queryString}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import RunQuery from "../../../../images/RunQuery.png";
|
|||||||
import { QueryResults } from "../../../Contracts/ViewModels";
|
import { QueryResults } from "../../../Contracts/ViewModels";
|
||||||
import { ErrorList } from "./ErrorList";
|
import { ErrorList } from "./ErrorList";
|
||||||
import { ResultsView } from "./ResultsView";
|
import { ResultsView } from "./ResultsView";
|
||||||
import useZoomLevel from "hooks/useZoomLevel";
|
|
||||||
import { conditionalClass } from "Utils/StyleUtils";
|
|
||||||
|
|
||||||
export interface ResultsViewProps {
|
export interface ResultsViewProps {
|
||||||
isMongoDB: boolean;
|
isMongoDB: boolean;
|
||||||
@@ -25,16 +23,11 @@ interface QueryResultProps extends ResultsViewProps {
|
|||||||
|
|
||||||
const ExecuteQueryCallToAction: React.FC = () => {
|
const ExecuteQueryCallToAction: React.FC = () => {
|
||||||
const styles = useQueryTabStyles();
|
const styles = useQueryTabStyles();
|
||||||
const isZoomed = useZoomLevel();
|
|
||||||
return (
|
return (
|
||||||
<div data-test="QueryTab/ResultsPane/ExecuteCTA" className={styles.executeCallToAction}>
|
<div data-test="QueryTab/ResultsPane/ExecuteCTA" className={styles.executeCallToAction}>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<img
|
<img src={RunQuery} aria-hidden="true" />
|
||||||
className={`${styles.responsiveImg} ${conditionalClass(isZoomed, styles.zoomedImageSize)}`}
|
|
||||||
src={RunQuery}
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</p>
|
</p>
|
||||||
<p>Execute a query to see the results</p>
|
<p>Execute a query to see the results</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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 } from "@azure/cosmos";
|
import { FeedOptions, QueryOperationOptions } 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 } from "Shared/StorageUtility";
|
import { LocalStorageUtility, StorageKey, getRUThreshold, ruThresholdEnabled } 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,9 +369,22 @@ 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(this.props.collection && this.props.collection.id(), this._iterator, firstItemIndex);
|
await queryDocumentsPage(
|
||||||
|
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,
|
||||||
@@ -411,9 +424,6 @@ 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);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ enum ResultsTabs {
|
|||||||
|
|
||||||
const ResultsTab: React.FC<ResultsViewProps> = ({ queryResults, isMongoDB, executeQueryDocumentsPage }) => {
|
const ResultsTab: React.FC<ResultsViewProps> = ({ queryResults, isMongoDB, executeQueryDocumentsPage }) => {
|
||||||
const styles = useQueryTabStyles();
|
const styles = useQueryTabStyles();
|
||||||
/* eslint-disable react/prop-types */
|
|
||||||
const queryResultsString = queryResults
|
const queryResultsString = queryResults
|
||||||
? isMongoDB
|
? isMongoDB
|
||||||
? MongoUtility.tojson(queryResults.documents, undefined, false)
|
? MongoUtility.tojson(queryResults.documents, undefined, false)
|
||||||
@@ -48,172 +47,6 @@ const ResultsTab: React.FC<ResultsViewProps> = ({ queryResults, isMongoDB, execu
|
|||||||
await executeQueryDocumentsPage(firstItemIndex + itemCount - 1);
|
await executeQueryDocumentsPage(firstItemIndex + itemCount - 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ExportResults: React.FC = () => {
|
|
||||||
const [showDropdown, setShowDropdown] = useState(false);
|
|
||||||
const dropdownRef = React.useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
|
||||||
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
||||||
setShowDropdown(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (showDropdown) {
|
|
||||||
document.addEventListener("mousedown", handleClickOutside);
|
|
||||||
}
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("mousedown", handleClickOutside);
|
|
||||||
};
|
|
||||||
}, [showDropdown]);
|
|
||||||
|
|
||||||
const escapeCsvValue = (value: string): string => {
|
|
||||||
return `"${value.replace(/"/g, '""')}"`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const formatValueForCsv = (value: string | object): string => {
|
|
||||||
if (value === null || value === undefined) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (typeof value === "object") {
|
|
||||||
return escapeCsvValue(JSON.stringify(value));
|
|
||||||
}
|
|
||||||
return escapeCsvValue(String(value));
|
|
||||||
};
|
|
||||||
|
|
||||||
const exportToCsv = () => {
|
|
||||||
try {
|
|
||||||
const allHeadersSet = new Set<string>();
|
|
||||||
queryResults.documents.forEach((doc) => {
|
|
||||||
Object.keys(doc).forEach((key) => allHeadersSet.add(key));
|
|
||||||
});
|
|
||||||
|
|
||||||
const allHeaders = Array.from(allHeadersSet);
|
|
||||||
const csvHeader = allHeaders.map(escapeCsvValue).join(",");
|
|
||||||
const csvData = queryResults.documents
|
|
||||||
.map((doc) =>
|
|
||||||
allHeaders.map((header) => (doc[header] !== undefined ? formatValueForCsv(doc[header]) : "")).join(","),
|
|
||||||
)
|
|
||||||
.join("\n");
|
|
||||||
|
|
||||||
const csvContent = `sep=,\n${csvHeader}\n${csvData}`;
|
|
||||||
downloadFile(csvContent, "query-results.csv", "text/csv");
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to export CSV:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const exportToJson = () => {
|
|
||||||
try {
|
|
||||||
downloadFile(queryResultsString, "query-results.json", "application/json");
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to export JSON:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const downloadFile = (content: string, fileName: string, contentType: string) => {
|
|
||||||
const blob = new Blob([content], { type: contentType });
|
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
const downloadLink = document.createElement("a");
|
|
||||||
downloadLink.href = url;
|
|
||||||
downloadLink.download = fileName;
|
|
||||||
document.body.appendChild(downloadLink);
|
|
||||||
downloadLink.click();
|
|
||||||
document.body.removeChild(downloadLink);
|
|
||||||
setTimeout(() => URL.revokeObjectURL(url), 100);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleExport = (format: "CSV" | "JSON") => {
|
|
||||||
setShowDropdown(false);
|
|
||||||
if (format === "CSV") {
|
|
||||||
exportToCsv();
|
|
||||||
} else {
|
|
||||||
exportToJson();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleKeyDown = (e: React.KeyboardEvent, format: "CSV" | "JSON") => {
|
|
||||||
if (e.key === "Enter" || e.key === " ") {
|
|
||||||
e.preventDefault();
|
|
||||||
handleExport(format);
|
|
||||||
} else if (e.key === "Escape") {
|
|
||||||
setShowDropdown(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ position: "relative", display: "inline-block" }} ref={dropdownRef}>
|
|
||||||
<Button
|
|
||||||
onClick={() => setShowDropdown((v) => !v)}
|
|
||||||
size="small"
|
|
||||||
appearance="transparent"
|
|
||||||
icon={<ArrowDownloadRegular />}
|
|
||||||
title="Download Query Results"
|
|
||||||
aria-haspopup="listbox"
|
|
||||||
aria-expanded={showDropdown}
|
|
||||||
/>
|
|
||||||
{showDropdown && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
right: 0,
|
|
||||||
zIndex: 10,
|
|
||||||
background: "white",
|
|
||||||
border: "1px solid #ccc",
|
|
||||||
borderRadius: 2,
|
|
||||||
minWidth: 60,
|
|
||||||
boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
|
|
||||||
marginTop: 4,
|
|
||||||
}}
|
|
||||||
role="listbox"
|
|
||||||
tabIndex={-1}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
display: "block",
|
|
||||||
width: "100%",
|
|
||||||
padding: "8px 16px",
|
|
||||||
background: "none",
|
|
||||||
border: "none",
|
|
||||||
textAlign: "left",
|
|
||||||
cursor: "pointer",
|
|
||||||
transition: "background 0.2s",
|
|
||||||
}}
|
|
||||||
onMouseOver={(e) => (e.currentTarget.style.background = "#f3f3f3")}
|
|
||||||
onMouseOut={(e) => (e.currentTarget.style.background = "none")}
|
|
||||||
onClick={() => handleExport("JSON")}
|
|
||||||
onKeyDown={(e) => handleKeyDown(e, "JSON")}
|
|
||||||
role="option"
|
|
||||||
tabIndex={0}
|
|
||||||
>
|
|
||||||
JSON
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
display: "block",
|
|
||||||
width: "100%",
|
|
||||||
padding: "8px 16px",
|
|
||||||
background: "none",
|
|
||||||
border: "none",
|
|
||||||
textAlign: "left",
|
|
||||||
cursor: "pointer",
|
|
||||||
transition: "background 0.2s",
|
|
||||||
}}
|
|
||||||
onMouseOver={(e) => (e.currentTarget.style.background = "#f3f3f3")}
|
|
||||||
onMouseOut={(e) => (e.currentTarget.style.background = "none")}
|
|
||||||
onClick={() => handleExport("CSV")}
|
|
||||||
onKeyDown={(e) => handleKeyDown(e, "CSV")}
|
|
||||||
role="option"
|
|
||||||
tabIndex={0}
|
|
||||||
>
|
|
||||||
CSV
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.queryResultsBar}>
|
<div className={styles.queryResultsBar}>
|
||||||
@@ -234,7 +67,6 @@ const ResultsTab: React.FC<ResultsViewProps> = ({ queryResults, isMongoDB, execu
|
|||||||
aria-label="Copy"
|
aria-label="Copy"
|
||||||
onClick={onClickCopyResults}
|
onClick={onClickCopyResults}
|
||||||
/>
|
/>
|
||||||
<ExportResults />
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.queryResultsViewer}>
|
<div className={styles.queryResultsViewer}>
|
||||||
<EditorReact language={"json"} content={queryResultsString} isReadOnly={true} ariaLabel={"Query results"} />
|
<EditorReact language={"json"} content={queryResultsString} isReadOnly={true} ariaLabel={"Query results"} />
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ export const useQueryTabStyles = makeStyles({
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
"@media (max-width: 420px)": {
|
|
||||||
overflow: "scroll",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
queryResultsMessage: {
|
queryResultsMessage: {
|
||||||
...shorthands.margin("5px"),
|
...shorthands.margin("5px"),
|
||||||
@@ -41,9 +38,6 @@ export const useQueryTabStyles = makeStyles({
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
rowGap: "12px",
|
rowGap: "12px",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
"@media (max-width: 420px)": {
|
|
||||||
height: "auto",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
queryResultsTabContentContainer: {
|
queryResultsTabContentContainer: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -99,12 +93,4 @@ export const useQueryTabStyles = makeStyles({
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
},
|
},
|
||||||
responsiveImg: {
|
|
||||||
"@media (max-width: 420px)": {
|
|
||||||
width: "50px",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
zoomedImageSize: {
|
|
||||||
width: "60px",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ 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";
|
||||||
@@ -118,9 +117,6 @@ 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" />
|
||||||
)}
|
)}
|
||||||
@@ -198,20 +194,6 @@ 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,7 +27,6 @@ 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,7 +21,7 @@ import { readTriggers } from "../../Common/dataAccess/readTriggers";
|
|||||||
import { readUserDefinedFunctions } from "../../Common/dataAccess/readUserDefinedFunctions";
|
import { readUserDefinedFunctions } from "../../Common/dataAccess/readUserDefinedFunctions";
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
import * as DataModels from "../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import { BulkInsertResult, UploadDetailsRecord } from "../../Contracts/ViewModels";
|
import { UploadDetailsRecord } from "../../Contracts/ViewModels";
|
||||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
@@ -1092,13 +1092,17 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async bulkInsertDocuments(documents: JSONObject[]): Promise<BulkInsertResult> {
|
public async bulkInsertDocuments(documents: JSONObject[]): Promise<{
|
||||||
const stats: BulkInsertResult = {
|
numSucceeded: number;
|
||||||
|
numFailed: number;
|
||||||
|
numThrottled: number;
|
||||||
|
errors: string[];
|
||||||
|
}> {
|
||||||
|
const stats = {
|
||||||
numSucceeded: 0,
|
numSucceeded: 0,
|
||||||
numFailed: 0,
|
numFailed: 0,
|
||||||
numThrottled: 0,
|
numThrottled: 0,
|
||||||
errors: [] as string[],
|
errors: [] as string[],
|
||||||
resources: [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const chunkSize = 100; // 100 is the max # of bulk operations the SDK currently accepts
|
const chunkSize = 100; // 100 is the max # of bulk operations the SDK currently accepts
|
||||||
@@ -1116,7 +1120,6 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
responses.forEach((response, index) => {
|
responses.forEach((response, index) => {
|
||||||
if (response.statusCode === 201) {
|
if (response.statusCode === 201) {
|
||||||
stats.numSucceeded++;
|
stats.numSucceeded++;
|
||||||
stats.resources.push(response.resourceBody);
|
|
||||||
} else if (response.statusCode === 429) {
|
} else if (response.statusCode === 429) {
|
||||||
documentsToAttempt.push(attemptedDocuments[index]);
|
documentsToAttempt.push(attemptedDocuments[index]);
|
||||||
} else if (response.statusCode === 409) {
|
} else if (response.statusCode === 409) {
|
||||||
@@ -1149,22 +1152,18 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
numFailed: 0,
|
numFailed: 0,
|
||||||
numThrottled: 0,
|
numThrottled: 0,
|
||||||
errors: [],
|
errors: [],
|
||||||
resources: [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const parsedContent = JSON.parse(documentContent);
|
const parsedContent = JSON.parse(documentContent);
|
||||||
if (Array.isArray(parsedContent)) {
|
if (Array.isArray(parsedContent)) {
|
||||||
const { numSucceeded, numFailed, numThrottled, errors, resources } =
|
const { numSucceeded, numFailed, numThrottled, errors } = await this.bulkInsertDocuments(parsedContent);
|
||||||
await this.bulkInsertDocuments(parsedContent);
|
|
||||||
record.numSucceeded = numSucceeded;
|
record.numSucceeded = numSucceeded;
|
||||||
record.numFailed = numFailed;
|
record.numFailed = numFailed;
|
||||||
record.numThrottled = numThrottled;
|
record.numThrottled = numThrottled;
|
||||||
record.errors = errors;
|
record.errors = errors;
|
||||||
record.resources = record.resources.concat(resources);
|
|
||||||
} else {
|
} else {
|
||||||
const resource = await createDocument(this, parsedContent);
|
await createDocument(this, parsedContent);
|
||||||
record.resources.push(resource);
|
|
||||||
record.numSucceeded++;
|
record.numSucceeded++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ export enum StorageKey {
|
|||||||
DatabaseAccountId,
|
DatabaseAccountId,
|
||||||
EncryptedKeyToken,
|
EncryptedKeyToken,
|
||||||
IsCrossPartitionQueryEnabled,
|
IsCrossPartitionQueryEnabled,
|
||||||
QueryControlEnabled,
|
|
||||||
MaxDegreeOfParellism,
|
MaxDegreeOfParellism,
|
||||||
IsGraphAutoVizDisabled,
|
IsGraphAutoVizDisabled,
|
||||||
TenantId,
|
TenantId,
|
||||||
|
|||||||
@@ -117,7 +117,6 @@ export interface UserContext {
|
|||||||
readonly feedbackPolicies?: AdminFeedbackPolicySettings;
|
readonly feedbackPolicies?: AdminFeedbackPolicySettings;
|
||||||
readonly dataPlaneRbacEnabled?: boolean;
|
readonly dataPlaneRbacEnabled?: boolean;
|
||||||
readonly refreshCosmosClient?: boolean;
|
readonly refreshCosmosClient?: boolean;
|
||||||
throughputBucketsEnabled?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiType = "SQL" | "Mongo" | "Gremlin" | "Tables" | "Cassandra" | "Postgres" | "VCoreMongo";
|
export type ApiType = "SQL" | "Mongo" | "Gremlin" | "Tables" | "Cassandra" | "Postgres" | "VCoreMongo";
|
||||||
|
|||||||
@@ -20,3 +20,7 @@ export const isServerlessAccount = (): boolean => {
|
|||||||
export const isVectorSearchEnabled = (): boolean => {
|
export const isVectorSearchEnabled = (): boolean => {
|
||||||
return userContext.apiType === "SQL" && isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLVectorSearch);
|
return userContext.apiType === "SQL" && isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLVectorSearch);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isFullTextSearchEnabled = (): boolean => {
|
||||||
|
return userContext.apiType === "SQL" && isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLFullTextSearch);
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export function validateEndpoint(
|
|||||||
endpointToValidate: string | undefined,
|
endpointToValidate: string | undefined,
|
||||||
allowedEndpoints: ReadonlyArray<string>,
|
allowedEndpoints: ReadonlyArray<string>,
|
||||||
): boolean {
|
): boolean {
|
||||||
|
return true;
|
||||||
try {
|
try {
|
||||||
return validateEndpointInternal(
|
return validateEndpointInternal(
|
||||||
endpointToValidate,
|
endpointToValidate,
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
import { configContext } from "ConfigContext";
|
|
||||||
import { FeatureRegistration } from "Contracts/DataModels";
|
|
||||||
import { AuthorizationTokenHeaderMetadata } from "Contracts/ViewModels";
|
|
||||||
import { getAuthorizationHeader } from "Utils/AuthorizationUtils";
|
|
||||||
|
|
||||||
export const featureRegistered = async (subscriptionId: string, feature: string) => {
|
|
||||||
const api_version = "2021-07-01";
|
|
||||||
const url = `${configContext.ARM_ENDPOINT}/subscriptions/${subscriptionId}/providers/Microsoft.Features/featureProviders/Microsoft.DocumentDB/subscriptionFeatureRegistrations/${feature}?api-version=${api_version}`;
|
|
||||||
const authorizationHeader: AuthorizationTokenHeaderMetadata = getAuthorizationHeader();
|
|
||||||
const headers = { [authorizationHeader.header]: authorizationHeader.token };
|
|
||||||
|
|
||||||
let response;
|
|
||||||
|
|
||||||
try {
|
|
||||||
response = await _fetchWithTimeout(url, headers);
|
|
||||||
} catch (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!response?.ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const featureRegistration = (await response?.json()) as FeatureRegistration;
|
|
||||||
return featureRegistration?.properties?.state === "Registered";
|
|
||||||
};
|
|
||||||
|
|
||||||
async function _fetchWithTimeout(
|
|
||||||
url: string,
|
|
||||||
headers: {
|
|
||||||
[x: string]: string;
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
const timeout = 10000;
|
|
||||||
const options = { timeout };
|
|
||||||
|
|
||||||
const controller = new AbortController();
|
|
||||||
const id = setTimeout(() => controller.abort(), timeout);
|
|
||||||
|
|
||||||
const response = await window.fetch(url, {
|
|
||||||
headers,
|
|
||||||
...options,
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
clearTimeout(id);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
@@ -245,7 +245,7 @@ export function downloadItem(
|
|||||||
},
|
},
|
||||||
"Cancel",
|
"Cancel",
|
||||||
undefined,
|
undefined,
|
||||||
container.getDownloadModalContent(name),
|
container.getDownloadModalConent(name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
export async function downloadNotebookItem(
|
export async function downloadNotebookItem(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export function isInvalidParentFrameOrigin(event: MessageEvent): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isValidOrigin(allowedOrigins: ReadonlyArray<string>, event: MessageEvent): boolean {
|
function isValidOrigin(allowedOrigins: ReadonlyArray<string>, event: MessageEvent): boolean {
|
||||||
|
return true;
|
||||||
const eventOrigin = (event && event.origin) || "";
|
const eventOrigin = (event && event.origin) || "";
|
||||||
const windowOrigin = (window && window.origin) || "";
|
const windowOrigin = (window && window.origin) || "";
|
||||||
if (eventOrigin === windowOrigin) {
|
if (eventOrigin === windowOrigin) {
|
||||||
|
|||||||
@@ -23,7 +23,3 @@ 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,7 +1,4 @@
|
|||||||
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";
|
||||||
|
|
||||||
@@ -89,18 +86,6 @@ 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,
|
||||||
|
|||||||
@@ -21,11 +21,3 @@ export function copyStyles(sourceDoc: Document, targetDoc: Document): void {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Conditionally returns a class name based on a boolean condition.
|
|
||||||
* If the condition is true, returns the `trueValue` class; otherwise, returns `falseValue` (or an empty string if not provided).
|
|
||||||
*/
|
|
||||||
export function conditionalClass(condition: boolean, trueValue: string, falseValue?: string): string {
|
|
||||||
return condition ? trueValue : falseValue || "";
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Lists the Cassandra keyspaces under an existing Azure Cosmos DB database account. */
|
/* Lists the Cassandra keyspaces under an existing Azure Cosmos DB database account. */
|
||||||
export async function listCassandraKeyspaces(
|
export async function listCassandraKeyspaces(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given database account and collection. */
|
/* Retrieves the metrics determined by the given filter for the given database account and collection. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given collection, split by partition. */
|
/* Retrieves the metrics determined by the given filter for the given collection, split by partition. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given collection and region, split by partition. */
|
/* Retrieves the metrics determined by the given filter for the given collection and region, split by partition. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given database account, collection and region. */
|
/* Retrieves the metrics determined by the given filter for the given database account, collection and region. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given database account and database. */
|
/* Retrieves the metrics determined by the given filter for the given database account and database. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given database account and region. */
|
/* Retrieves the metrics determined by the given filter for the given database account and region. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the properties of an existing Azure Cosmos DB database account. */
|
/* Retrieves the properties of an existing Azure Cosmos DB database account. */
|
||||||
export async function get(
|
export async function get(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Lists the graphs under an existing Azure Cosmos DB database account. */
|
/* Lists the graphs under an existing Azure Cosmos DB database account. */
|
||||||
export async function listGraphs(
|
export async function listGraphs(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Lists the Gremlin databases under an existing Azure Cosmos DB database account. */
|
/* Lists the Gremlin databases under an existing Azure Cosmos DB database account. */
|
||||||
export async function listGremlinDatabases(
|
export async function listGremlinDatabases(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* List Cosmos DB locations and their properties */
|
/* List Cosmos DB locations and their properties */
|
||||||
export async function list(subscriptionId: string): Promise<Types.LocationListResult | Types.CloudError> {
|
export async function list(subscriptionId: string): Promise<Types.LocationListResult | Types.CloudError> {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Lists the MongoDB databases under an existing Azure Cosmos DB database account. */
|
/* Lists the MongoDB databases under an existing Azure Cosmos DB database account. */
|
||||||
export async function listMongoDBDatabases(
|
export async function listMongoDBDatabases(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Lists all of the available Cosmos DB Resource Provider operations. */
|
/* Lists all of the available Cosmos DB Resource Provider operations. */
|
||||||
export async function list(): Promise<Types.OperationListResult> {
|
export async function list(): Promise<Types.OperationListResult> {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given partition key range id. */
|
/* Retrieves the metrics determined by the given filter for the given partition key range id. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given partition key range id and region. */
|
/* Retrieves the metrics determined by the given filter for the given partition key range id and region. */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given database account. This url is only for PBS and Replication Latency data */
|
/* Retrieves the metrics determined by the given filter for the given database account. This url is only for PBS and Replication Latency data */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given account, source and target region. This url is only for PBS and Replication Latency data */
|
/* Retrieves the metrics determined by the given filter for the given account, source and target region. This url is only for PBS and Replication Latency data */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Retrieves the metrics determined by the given filter for the given account target region. This url is only for PBS and Replication Latency data */
|
/* Retrieves the metrics determined by the given filter for the given account target region. This url is only for PBS and Replication Latency data */
|
||||||
export async function listMetrics(
|
export async function listMetrics(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Lists the SQL databases under an existing Azure Cosmos DB database account. */
|
/* Lists the SQL databases under an existing Azure Cosmos DB database account. */
|
||||||
export async function listSqlDatabases(
|
export async function listSqlDatabases(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
import { configContext } from "../../../../ConfigContext";
|
const apiVersion = "2024-12-01-preview";
|
||||||
const apiVersion = "2025-05-01-preview";
|
|
||||||
|
|
||||||
/* Lists the Tables under an existing Azure Cosmos DB database account. */
|
/* Lists the Tables under an existing Azure Cosmos DB database account. */
|
||||||
export async function listTables(
|
export async function listTables(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Run "npm run generateARMClients" to regenerate
|
Run "npm run generateARMClients" to regenerate
|
||||||
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
Edting this file directly should be done with extreme caution as not to diverge from ARM REST specs
|
||||||
|
|
||||||
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2025-05-01-preview/cosmos-db.json
|
Generated from: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/preview/2024-12-01-preview/cosmos-db.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The List operation response, that contains the client encryption keys and their properties. */
|
/* The List operation response, that contains the client encryption keys and their properties. */
|
||||||
@@ -580,8 +580,6 @@ export interface DatabaseAccountGetProperties {
|
|||||||
|
|
||||||
/* Flag to indicate enabling/disabling of Per-Region Per-partition autoscale Preview feature on the account */
|
/* Flag to indicate enabling/disabling of Per-Region Per-partition autoscale Preview feature on the account */
|
||||||
enablePerRegionPerPartitionAutoscale?: boolean;
|
enablePerRegionPerPartitionAutoscale?: boolean;
|
||||||
/* Flag to indicate if All Versions and Deletes Change feed feature is enabled on the account */
|
|
||||||
enableAllVersionsAndDeletesChangeFeed?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Properties to create and update Azure Cosmos DB database accounts. */
|
/* Properties to create and update Azure Cosmos DB database accounts. */
|
||||||
@@ -684,8 +682,6 @@ export interface DatabaseAccountCreateUpdateProperties {
|
|||||||
|
|
||||||
/* Flag to indicate enabling/disabling of Per-Region Per-partition autoscale Preview feature on the account */
|
/* Flag to indicate enabling/disabling of Per-Region Per-partition autoscale Preview feature on the account */
|
||||||
enablePerRegionPerPartitionAutoscale?: boolean;
|
enablePerRegionPerPartitionAutoscale?: boolean;
|
||||||
/* Flag to indicate if All Versions and Deletes Change feed feature is enabled on the account */
|
|
||||||
enableAllVersionsAndDeletesChangeFeed?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parameters to create and update Cosmos DB database accounts. */
|
/* Parameters to create and update Cosmos DB database accounts. */
|
||||||
@@ -791,8 +787,6 @@ export interface DatabaseAccountUpdateProperties {
|
|||||||
|
|
||||||
/* Flag to indicate enabling/disabling of Per-Region Per-partition autoscale Preview feature on the account */
|
/* Flag to indicate enabling/disabling of Per-Region Per-partition autoscale Preview feature on the account */
|
||||||
enablePerRegionPerPartitionAutoscale?: boolean;
|
enablePerRegionPerPartitionAutoscale?: boolean;
|
||||||
/* Flag to indicate if All Versions and Deletes Change feed feature is enabled on the account */
|
|
||||||
enableAllVersionsAndDeletesChangeFeed?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parameters for patching Azure Cosmos DB database account properties. */
|
/* Parameters for patching Azure Cosmos DB database account properties. */
|
||||||
@@ -1222,8 +1216,6 @@ export interface PhysicalPartitionThroughputInfoResource {
|
|||||||
id: string;
|
id: string;
|
||||||
/* Throughput of a physical partition */
|
/* Throughput of a physical partition */
|
||||||
throughput?: number;
|
throughput?: number;
|
||||||
/* Target throughput of a physical partition */
|
|
||||||
targetThroughput?: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cosmos DB client encryption key resource object. */
|
/* Cosmos DB client encryption key resource object. */
|
||||||
@@ -1293,16 +1285,12 @@ export interface SqlContainerResource {
|
|||||||
/* The configuration for defining Materialized Views. This must be specified only for creating a Materialized View container. */
|
/* The configuration for defining Materialized Views. This must be specified only for creating a Materialized View container. */
|
||||||
materializedViewDefinition?: MaterializedViewDefinition;
|
materializedViewDefinition?: MaterializedViewDefinition;
|
||||||
|
|
||||||
/* Materialized Views defined on the container. */
|
|
||||||
materializedViews?: MaterializedViewDetails[];
|
|
||||||
|
|
||||||
/* List of computed properties */
|
/* List of computed properties */
|
||||||
computedProperties?: ComputedProperty[];
|
computedProperties?: ComputedProperty[];
|
||||||
|
|
||||||
/* The vector embedding policy for the container. */
|
/* The vector embedding policy for the container. */
|
||||||
vectorEmbeddingPolicy?: VectorEmbeddingPolicy;
|
vectorEmbeddingPolicy?: VectorEmbeddingPolicy;
|
||||||
|
|
||||||
/* The FullText policy for the container. */
|
|
||||||
fullTextPolicy?: FullTextPolicy;
|
fullTextPolicy?: FullTextPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1335,14 +1323,6 @@ export interface VectorEmbeddingPolicy {
|
|||||||
vectorEmbeddings?: VectorEmbedding[];
|
vectorEmbeddings?: VectorEmbedding[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cosmos DB FullText Policy */
|
|
||||||
export interface FullTextPolicy {
|
|
||||||
/* The default language for a full text paths. */
|
|
||||||
defaultLanguage?: string;
|
|
||||||
/* List of FullText Paths */
|
|
||||||
fullTextPaths?: FullTextPath[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* undocumented */
|
/* undocumented */
|
||||||
export interface ExcludedPath {
|
export interface ExcludedPath {
|
||||||
/* The path for which the indexing behavior applies to. Index paths typically start with root and end with wildcard (/path/*) */
|
/* The path for which the indexing behavior applies to. Index paths typically start with root and end with wildcard (/path/*) */
|
||||||
@@ -1381,7 +1361,7 @@ export interface VectorEmbedding {
|
|||||||
/* The path to the vector field in the document. */
|
/* The path to the vector field in the document. */
|
||||||
path: string;
|
path: string;
|
||||||
/* Indicates the data type of vector. */
|
/* Indicates the data type of vector. */
|
||||||
dataType: "float32" | "uint8" | "int8";
|
dataType: "float16" | "float32" | "uint8" | "int8";
|
||||||
|
|
||||||
/* The distance function to use for distance calculation in between vectors. */
|
/* The distance function to use for distance calculation in between vectors. */
|
||||||
distanceFunction: "euclidean" | "cosine" | "dotproduct";
|
distanceFunction: "euclidean" | "cosine" | "dotproduct";
|
||||||
@@ -1390,12 +1370,26 @@ export interface VectorEmbedding {
|
|||||||
dimensions: number;
|
dimensions: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Represents the full text path specification. */
|
export interface FullTextPolicy {
|
||||||
|
/**
|
||||||
|
* The default language for the full text .
|
||||||
|
*/
|
||||||
|
defaultLanguage: string;
|
||||||
|
/**
|
||||||
|
* The paths to be indexed for full text search.
|
||||||
|
*/
|
||||||
|
fullTextPaths: FullTextPath[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface FullTextPath {
|
export interface FullTextPath {
|
||||||
/* The path to the full text field in the document. */
|
/**
|
||||||
|
* The path to be indexed for full text search.
|
||||||
|
*/
|
||||||
path: string;
|
path: string;
|
||||||
/* The language of the full text field in the document. */
|
/**
|
||||||
language?: string;
|
* The language for the full text path.
|
||||||
|
*/
|
||||||
|
language: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List of composite path */
|
/* List of composite path */
|
||||||
@@ -1499,14 +1493,6 @@ export interface MaterializedViewDefinition {
|
|||||||
definition: string;
|
definition: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MaterializedViewDetails, contains Id & _rid fields of materialized view. */
|
|
||||||
export interface MaterializedViewDetails {
|
|
||||||
/* Id field of Materialized container. */
|
|
||||||
id?: string;
|
|
||||||
/* _rid field of Materialized container. */
|
|
||||||
_rid?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cosmos DB SQL storedProcedure resource object */
|
/* Cosmos DB SQL storedProcedure resource object */
|
||||||
export interface SqlStoredProcedureResource {
|
export interface SqlStoredProcedureResource {
|
||||||
/* Name of the Cosmos DB SQL storedProcedure */
|
/* Name of the Cosmos DB SQL storedProcedure */
|
||||||
|
|||||||
@@ -64,8 +64,7 @@ import {
|
|||||||
getMsalInstance,
|
getMsalInstance,
|
||||||
} from "../Utils/AuthorizationUtils";
|
} from "../Utils/AuthorizationUtils";
|
||||||
import { isInvalidParentFrameOrigin, shouldProcessMessage } from "../Utils/MessageValidation";
|
import { isInvalidParentFrameOrigin, shouldProcessMessage } from "../Utils/MessageValidation";
|
||||||
import { get, getReadOnlyKeys, listKeys } from "../Utils/arm/generatedClients/cosmos/databaseAccounts";
|
import { getReadOnlyKeys, listKeys } from "../Utils/arm/generatedClients/cosmos/databaseAccounts";
|
||||||
import * as Types from "../Utils/arm/generatedClients/cosmos/types";
|
|
||||||
import { applyExplorerBindings } from "../applyExplorerBindings";
|
import { applyExplorerBindings } from "../applyExplorerBindings";
|
||||||
|
|
||||||
// This hook will create a new instance of Explorer.ts and bind it to the DOM
|
// This hook will create a new instance of Explorer.ts and bind it to the DOM
|
||||||
@@ -347,14 +346,6 @@ async function configureHostedWithAAD(config: AAD): Promise<Explorer> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// TO DO - Remove once we have ARG API support for enableMaterializedViews property
|
|
||||||
const databaseAccount: Types.DatabaseAccountGetResults = await get(
|
|
||||||
subscriptionId,
|
|
||||||
account.resourceGroup,
|
|
||||||
account.name,
|
|
||||||
);
|
|
||||||
config.databaseAccount.properties.enableMaterializedViews = databaseAccount.properties?.enableMaterializedViews;
|
|
||||||
|
|
||||||
updateUserContext({
|
updateUserContext({
|
||||||
databaseAccount: config.databaseAccount,
|
databaseAccount: config.databaseAccount,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export const useTabs: UseStore<TabsState> = create((set, get) => ({
|
|||||||
.forEach((tab) => tab.onCloseTabButtonClick()),
|
.forEach((tab) => tab.onCloseTabButtonClick()),
|
||||||
closeTab: (tab: TabsBase): void => {
|
closeTab: (tab: TabsBase): void => {
|
||||||
let tabIndex: number;
|
let tabIndex: number;
|
||||||
const { activeTab, openedTabs, openedReactTabs } = get();
|
const { activeTab, openedTabs } = get();
|
||||||
const updatedTabs = openedTabs.filter((openedTab, index) => {
|
const updatedTabs = openedTabs.filter((openedTab, index) => {
|
||||||
if (tab.tabId === openedTab.tabId) {
|
if (tab.tabId === openedTab.tabId) {
|
||||||
tabIndex = index;
|
tabIndex = index;
|
||||||
@@ -127,10 +127,6 @@ export const useTabs: UseStore<TabsState> = create((set, get) => ({
|
|||||||
|
|
||||||
set({ openedTabs: updatedTabs });
|
set({ openedTabs: updatedTabs });
|
||||||
|
|
||||||
if (updatedTabs.length === 0 && openedReactTabs.length > 0) {
|
|
||||||
set({ activeTab: undefined, activeReactTab: openedReactTabs[openedReactTabs.length - 1] });
|
|
||||||
}
|
|
||||||
|
|
||||||
get().persistTabsState();
|
get().persistTabsState();
|
||||||
},
|
},
|
||||||
closeAllNotebookTabs: (hardClose): void => {
|
closeAllNotebookTabs: (hardClose): void => {
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
|
|
||||||
const useZoomLevel = (threshold: number = 2): boolean => {
|
|
||||||
const [isZoomed, setIsZoomed] = useState<boolean>(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const checkZoom = () => {
|
|
||||||
const zoomLevel = window.devicePixelRatio;
|
|
||||||
setIsZoomed(zoomLevel >= threshold);
|
|
||||||
};
|
|
||||||
|
|
||||||
checkZoom();
|
|
||||||
window.addEventListener("resize", checkZoom);
|
|
||||||
return () => window.removeEventListener("resize", checkZoom);
|
|
||||||
}, [threshold]);
|
|
||||||
|
|
||||||
return isZoomed;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useZoomLevel;
|
|
||||||
@@ -16,7 +16,7 @@ Results of this file should be checked into the repo.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// CHANGE THESE VALUES TO GENERATE NEW CLIENTS
|
// CHANGE THESE VALUES TO GENERATE NEW CLIENTS
|
||||||
const version = "2025-05-01-preview";
|
const version = "2024-12-01-preview";
|
||||||
/* The following are legal options for resourceName but you generally will only use cosmos:
|
/* The following are legal options for resourceName but you generally will only use cosmos:
|
||||||
"cosmos" | "managedCassandra" | "mongorbac" | "notebook" | "privateEndpointConnection" | "privateLinkResources" |
|
"cosmos" | "managedCassandra" | "mongorbac" | "notebook" | "privateEndpointConnection" | "privateLinkResources" |
|
||||||
"rbac" | "restorable" | "services" | "dataTransferService"
|
"rbac" | "restorable" | "services" | "dataTransferService"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
<clear />
|
<clear />
|
||||||
<add name="X-Xss-Protection" value="1; mode=block" />
|
<add name="X-Xss-Protection" value="1; mode=block" />
|
||||||
<add name="X-Content-Type-Options" value="nosniff" />
|
<add name="X-Content-Type-Options" value="nosniff" />
|
||||||
<add name="Content-Security-Policy" value="frame-ancestors 'self' portal.azure.com *.portal.azure.com portal.azure.us portal.azure.cn portal.microsoftazure.de df.onecloud.azure-test.net *.fabric.microsoft.com *.powerbi.com *.analysis-df.windows.net dataexplorer-preview.azurewebsites.net" />
|
<add name="Content-Security-Policy" value="frame-src 'vscode:' frame-ancestors 'self' portal.azure.com *.portal.azure.com portal.azure.us portal.azure.cn portal.microsoftazure.de df.onecloud.azure-test.net *.fabric.microsoft.com *.powerbi.com *.analysis-df.windows.net dataexplorer-preview.azurewebsites.net" />
|
||||||
</customHeaders>
|
</customHeaders>
|
||||||
<redirectHeaders>
|
<redirectHeaders>
|
||||||
<clear />
|
<clear />
|
||||||
|
|||||||
@@ -78,18 +78,11 @@ 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, javascriptRule];
|
const rules = [fontRule, lessRule, imagesRule, cssRule, htmlRule, typescriptRule];
|
||||||
const envVars = {
|
const envVars = {
|
||||||
GIT_SHA: gitSha,
|
GIT_SHA: gitSha,
|
||||||
PORT: process.env.PORT || "1234",
|
PORT: process.env.PORT || "1234",
|
||||||
|
|||||||
Reference in New Issue
Block a user