Compare commits

...

50 Commits

Author SHA1 Message Date
sunghyunkang1111
7314f6d259 add databaseName in the connection strings 2024-01-18 08:56:00 -06:00
sunghyunkang1111
a616cf8bda Fix the teaching bubble popup and enable copilot card 2024-01-17 10:33:47 -06:00
sunghyunkang1111
5d13463bdb Copilot settings (#1719)
* gating copilot with AFEC

* Add enable sample DB in settings

* Add enable sample DB in settings

* Add enable sample DB in settings

* PR comments
2024-01-09 13:32:20 -06:00
MokireddySampath
c4cceceafc Status attribute added for the message to be readout by screenreader (#1709) 2024-01-04 20:43:44 +05:30
MokireddySampath
532a453f5a Aria label has been updated to the button(Enable copilot/Disable copilot) (#1706) 2024-01-04 19:38:05 +05:30
MokireddySampath
9355a3ae04 Altt text and role has been added to the 'copilot icon' (#1705) 2024-01-04 19:37:50 +05:30
MokireddySampath
14456c2102 label has been added to the textfield of copilot promptbar (#1704) 2024-01-04 19:37:35 +05:30
MokireddySampath
0c9264e8b3 Bug 2819239:Screen reader does not announce the loading information which appears on invoking the 'Send' button. (#1703)
* Alert has been added and content also added accordign to the loader state

* Snapshot of tests have been updated
2024-01-04 19:37:16 +05:30
MokireddySampath
0dd1032357 Bug 2817823: [Programmatic access - Cosmos DB Query Copilot - Query]: Accessible name is not defined for the 'Like', 'Dislike' and 'Send' buttons present on the page. (#1700)
* text color of link has been changed to get the contrast ratio of atleaast 4.5:1

* screen reader names have been added to the buttons

* Update QueryCopilotPromptbar.tsx
2024-01-04 19:35:12 +05:30
MokireddySampath
5011d12f16 text color of link has been changed to get the contrast ratio of atleaast 4.5:1 (#1699) 2024-01-04 19:34:58 +05:30
MokireddySampath
a7e5ff2a9f status role has been added for the screen reader to announce the status message displayed (#1697) 2024-01-04 19:34:26 +05:30
MokireddySampath
ad1391f623 visual and arialabel were different which has been changed as required and tests have been updated (#1685) 2024-01-04 19:34:14 +05:30
MokireddySampath
a2a5407b15 Label has been added to the text field on selecting autoscale in throughputc (#1676) 2024-01-04 19:33:55 +05:30
Laurent Nguyen
e9181f19d7 Fix datatables issue and indicator not loading for Table API > Entities. Upgrade jquery. Fix right panel resize issue. (#1713)
* Fix datatables issue and indicator not loading for Table API > Entities

* Fix jquery and datatables compile issues. Add patch for datatables.net-colreorder error in types

* Fix side panel size. Fix bug resizing side panel.

* Update PanelContainerComponent unit test snapshot

* Fix commented code
2024-01-03 14:52:34 +01:00
JustinKol
c91ac39248 Query Max Retry settings (#1688)
* Added query retry settings

* prettier run

* Fixed tests and queryDocuments

* Fixed tests

* corrected logic

* Updated tests and logic

* Removed optional flag

* Added default value text

* Reworded text

* moved retry options to CosmosClient

* removed unused references to retryOptions

* Reverting formatting

* reverting

* revert

* prettier run

* Correct default and added options directly to the client

* Prettier run and unit test update

* Corrected tooltip and constant name

* Added inSeconds to WaitTime
2023-12-29 08:12:20 -05:00
Armando Trejo Oliver
c82a4737c6 Add support for Dogfood (#1715)
* Add support for Dogfood

* Format
2023-12-20 05:53:02 -08:00
jawelton74
c6aefacc4e Fix the Nuget Publish MPAC action in CI. (#1712) 2023-12-13 11:44:46 -08:00
bogercraig
bf7c0aac63 Enabling endpoint discovery to test region failure in a non-dev environment. (#1711) 2023-12-13 10:44:17 -08:00
Laurent Nguyen
1bf4683894 Make Data Explorer work on node v18 (#1654)
* Upgrade packages to enable npm i with node 18

* Fix crypto and querystring issue

* Fix webpack errors during npm start

* Upgrade monaco editor. Fix alias in webconfig

* Remove deprecated file-loader. Upgrade webpack to latest.

* Fix format

* Upgrade webpack, eslint and typescript

* Update p-retry and fluentui packages

* Revert monaco package upgrade

* Fix notebook compile errors

* Fix lint errors

* Update jest snapshots

* Fix unit tests

* Update node version to 18

* Fix compile error

* Fix compile error

* Fix format

* Turn off warning overlay for webpack devServer

* Fix format

* Re-add monaco webpack plugin and upgrade monaco-editor

* Update package-lock.json

* Fix build issue

* Move MonacoWebpackPlugin to previous place in webpack.config.js

* update package-lock.json

* Fix package-lock.json

* Update package-lock.json

* Fix export ChoiceItem not found warning for self serve. Remove warning turn off in webpack config.

* Update checkout and setup actions in for ci tests

* Disable Gallery callout

* Fix disable gallery header

* Totally disable New gallery callout

* Upgrade all github actions to latest
2023-12-13 10:24:40 -08:00
sunghyunkang1111
59a50d72fe Remove copilot feature registration check (#1708)
* Remove copilot banner

* fix test
2023-12-11 14:42:10 -06:00
bogercraig
b19aa3fbca Reverting enabling endpoint discovery since it didn't have time during CCOA to bake in MPAC. (#1698) 2023-11-28 13:29:27 -08:00
MokireddySampath
0f69b7998f outline offset has been added for the focus indicator to be visible on navigation (#1551) 2023-11-22 00:08:59 +05:30
MokireddySampath
acd4787b3d WCAG 1.3.1,WCAG 4.1.2: Ensures every form element has a label (textarea) (#1549) 2023-11-22 00:08:32 +05:30
MokireddySampath
4ec6e7b8cc aria posinset has been removed, since it is not an attribute that is supported by the HTML elements used (#1547) 2023-11-22 00:08:17 +05:30
MokireddySampath
4fcbf7f0ea Alert is being updated for every change, hence the screenreader readsout the alert everytime a change occursin the input (#1544)
* Alert is being updated for every change, hence the screenreader readsout the alert everytime a change occursin the input

* Update DeleteCollectionConfirmationPane.tsx

* Update DeleteCollectionConfirmationPane.tsx
2023-11-22 00:07:33 +05:30
MokireddySampath
d0c75e4490 role has been changed to buttton for the graphic images of edit and delete buttons (#1652) 2023-11-22 00:07:02 +05:30
MokireddySampath
50bd17dd61 role=presentation is removed for the image in add new clause button, since it is not accepted format (#1653) 2023-11-22 00:06:35 +05:30
MokireddySampath
3d300cc1e4 heading has been changed to follow the hierarchy down the page (#1656) 2023-11-22 00:06:09 +05:30
MokireddySampath
6e956d27ad Provisioned throughput checkbox is not aligned (#1661) 2023-11-22 00:05:42 +05:30
MokireddySampath
b419bec5a3 Bug 2748872: "Back" button is not keyboard accessible which is present under "Email" screen. (#1665)
* Keyboard navigation was not present to the back button on the add row table dialog which has been added through this commit

* Update PanelComponent.less
2023-11-22 00:02:05 +05:30
MokireddySampath
d305eb9f9b Aria-label text link hs been changed to match the visble link (#1666) 2023-11-22 00:01:45 +05:30
MokireddySampath
05f3bef5b9 Dependency has been added tot he useeffect for tabs to avoid rerendering continuosly (#1682) 2023-11-22 00:00:03 +05:30
bogercraig
6af1925d15 Enabling enableEndpointDiscovery to test DE Region Outage Resiliency (#1694)
* Setting enableEndpointDiscovery to true to test client resilience during region outage.
When this is set to false, it can impact the SDK's failover behavior.
2023-11-16 11:56:39 -08:00
sunghyunkang1111
b9cbfc924f do not throw error when checking for initial checking of copilot enablement (#1693) 2023-11-14 17:22:12 -06:00
sindhuba
1aa4c18119 Increase NPS sample size and remove constraints (#1692)
* Increase NPS sample size and remove constraints

* Run npm format

* Run npm format:check
2023-11-14 22:26:57 +05:30
sunghyunkang1111
0ab07419ce fix the phoenix endpoint (#1691) 2023-11-10 18:53:23 -06:00
sunghyunkang1111
40b8127a6f P1 bugs for copilot (#1689)
* P1 bugs for copilot

* P1 bugs for copilot

* P1 bugs for copilot

* Update branding and AFEC

* Update branding and AFEC

* add timeout for ARM calls

* increase test timeout

* fix formatting

* fix formatting

* fix formatting

* fix formatting

* don't call ARM when connectionstring login
2023-11-10 16:55:39 -06:00
sunghyunkang1111
0e124f4881 Copilot user db (#1672)
* Implement copilot for user database

* Fix minor bugs

* fix bugs

* Add user database copilot

* Add placeholder text on copilot

* Add AFEC adn killswitch

* Add new v2 sampledatabase endpoint

* Add telemetry

* fix telemetry bug

* Add query edited telemetry

* add authorization header

* Add back to the staging env for phoenix

* point to stage for phoenix

* Preview commit for test env

* Preview link for staging

* change the staging url

* fix lint, unit tests

* fix lint, unit tests

* fix formatting
2023-11-09 11:55:25 -06:00
vchske
a5e1b37ba6 Bugbash updates (#1684)
* Minor changes to vcore mongo quickstart based on feedback

* Text change vcore to vCore
2023-11-08 16:04:06 -08:00
jawelton74
15d111e3db Add directions to use AAD login if account blocked from connection (#1683)
string login.
2023-11-01 15:46:54 -07:00
Asier Isayas
1726e4df51 Remove enableResourceGraph feature flag (#1681)
* fetch subs and accounts via graph

* fixed subscription rendering

* add feature flag enableResourceGraph

* add feature flag enableResourceGraph

* remove enableResourceGraph feature flag

---------

Co-authored-by: Asier Isayas <aisayas@microsoft.com>
2023-10-27 14:09:21 -04:00
vchske
bc68b4dbf9 Minor changes to vcore mongo quickstart based on feedback (#1678) 2023-10-26 16:46:01 -07:00
vchske
15e35eaa82 Adds restarting vcore mongo shell if user enters wrong password (#1675)
* Adds restarting vcore mongo shell if user enters wrong password

* Deleted unnecessary comment
2023-10-26 16:40:59 -07:00
Asier Isayas
f69cd4c495 Fetch subs and accounts via MS graph (#1677)
* fetch subs and accounts via graph

* fixed subscription rendering

* add feature flag enableResourceGraph

* add feature flag enableResourceGraph

---------

Co-authored-by: Asier Isayas <aisayas@microsoft.com>
2023-10-26 12:00:39 -04:00
Laurent Nguyen
661f6f4bfb Clear console and properly handle error message when querying database or containers (#1679) 2023-10-26 15:55:48 +00:00
JustinKol
3a703b0bd0 Explorer null handling (#1658)
* Cassandra null value handling

* prettier run

* Added boolean and date

* Reverted null handling switch statement and added editing warning

* ran prettier

* putting new line back in

* prettier run

* changed warning message

* updated snapshot

* fixed undefined condition

* removed toString from undefined
2023-10-25 10:12:42 -04:00
jawelton74
70c031d04b Check for accounts that are restricted from connection string login. (#1673)
* Call Portal Backend to check for accounts that are restricted from
connection string login.

* Remove debug logging and revert to actual backend endpoint.

* Use React hooks for displaying error message.

* Move accountrestrictions route under guest.

* Check restrictions before resource token check.

* Revert test changes.
2023-10-23 12:04:19 -07:00
MokireddySampath
b949f60c2a Defect2271490 (#1474)
* arialabel has been added to close button of invitational youtube video

* heading role has been addedd and tag has been changed to h1

* outline has been restored to choose columns link in entities page

* header text color changed to meet luminosity ratio requirement

* capacity calculator link has been added with underline on focus

* add property is readout twice while using screenreader

* arialabel added to the add property button

* screenreader content changed to announce the entire alert

* alert message is partially readout on error

* Update fulldatatables.less

* Update queryBuilder.less

* Update TableEntity.tsx

* Update ThroughputInput.less

* Update ThroughputInput.tsx

* Update ThroughputInput.test.tsx.snap

* Update NewVertexComponent.tsx

* Update PanelInfoErrorComponent.tsx

* Update AddTableEntityPanel.tsx

* Update AddTableEntityPanel.test.tsx.snap

* Update SplashScreen.tsx

* Update QuickstartCarousel.tsx

* Update RightPaneForm.tsx

* Update fulldatatables.less
2023-10-23 18:04:59 +05:30
vchske
deb0ebcf92 Updating vcore mongo quickstart text based on feedback (#1669)
* Updating quickstart text based on feedback

* Escaping apostrophe
2023-10-20 12:32:22 -07:00
Laurent Nguyen
2d3048eafe Fabric: handle resource tokens (#1667)
* Update contracts for new all resource messages

* Add timestamp to token message signature

* Reconstruct resource tree with databases and collections parsed from token dictionary keys

* Create FabricDatabase and FabricCollection to turn off interaction

* Remove unnecessary FabricCollection derived class

* Handle resource tokens

* Bug fix

* Fix linting issues

* Fix update document

* Fix partitition keys

* Remove special case for FabricDatabase tree node

* Modify readCollections to follow normal flow with Fabric

* Move fabric databases refresh to data access and remove special case in Explorer

* Revert Explorer.tsx changes

* Disable database context menu and delete container context menu

* Remove create database/container button for Fabric

* Fix format

* Renew token logic

* Parallelize read collections calls to speed up

* Disable readDatabaseOffer, because it is too slow for now

* Reduce TOKEN_VALIDITY_MS a bit to make sure renewal happens before expiration. Receving new tokens new refreshes databases

* Add container element for Main app in HTML

* Do not handle "openTab" message anymore

* Fix style of main div

* Simplify conditional load of the fabric .css

* Fix format

* Fix tsc can't find dynamic less import

---------

Co-authored-by: Armando Trejo Oliver <artrejo@microsoft.com>
2023-10-19 23:12:52 +02:00
173 changed files with 36918 additions and 25408 deletions

View File

@@ -53,4 +53,9 @@ module.exports = {
}, },
], ],
}, },
settings: {
react: {
version: "detect",
},
},
}; };

View File

@@ -14,11 +14,11 @@ jobs:
name: "Log Code Metrics" name: "Log Code Metrics"
if: github.ref == 'refs/heads/master' if: github.ref == 'refs/heads/master'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: node utils/codeMetrics.js - run: node utils/codeMetrics.js
env: env:
@@ -27,11 +27,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: "Compile TypeScript" name: "Compile TypeScript"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: npm run compile - run: npm run compile
- run: npm run compile:strict - run: npm run compile:strict
@@ -39,44 +39,44 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: "Check Format" name: "Check Format"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: npm run format:check - run: npm run format:check
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: "Lint" name: "Lint"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: npm run lint - run: npm run lint
unittest: unittest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: "Unit Tests" name: "Unit Tests"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: npm run test - run: npm run test
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: "Build" name: "Build"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: npm run build:contracts - run: npm run build:contracts
- name: Restore Build Cache - name: Restore Build Cache
@@ -86,10 +86,10 @@ jobs:
key: ${{ runner.os }}-build-cache key: ${{ runner.os }}-build-cache
- run: npm run pack:prod - run: npm run pack:prod
env: env:
NODE_OPTIONS: '--max-old-space-size=4096' NODE_OPTIONS: "--max-old-space-size=4096"
- run: cp -r ./Contracts ./dist/contracts - run: cp -r ./Contracts ./dist/contracts
- run: cp -r ./configs ./dist/configs - run: cp -r ./configs ./dist/configs
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: dist name: dist
path: dist/ path: dist/
@@ -107,11 +107,11 @@ jobs:
if: false if: false
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- uses: southpolesteve/cosmos-emulator-github-action@v1 - uses: southpolesteve/cosmos-emulator-github-action@v1
- name: End to End Tests - name: End to End Tests
run: | run: |
@@ -124,7 +124,7 @@ jobs:
DATA_EXPLORER_ENDPOINT: "https://localhost:1234/explorer.html?platform=Emulator" DATA_EXPLORER_ENDPOINT: "https://localhost:1234/explorer.html?platform=Emulator"
PLATFORM: "Emulator" PLATFORM: "Emulator"
NODE_TLS_REJECT_UNAUTHORIZED: 0 NODE_TLS_REJECT_UNAUTHORIZED: 0
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: screenshots name: screenshots
@@ -149,11 +149,11 @@ jobs:
- ./test/sql/resourceToken.spec.ts - ./test/sql/resourceToken.spec.ts
- ./test/tables/container.spec.ts - ./test/tables/container.spec.ts
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: npm start & - run: npm start &
- run: npm run wait-for-server - run: npm run wait-for-server
@@ -162,7 +162,7 @@ jobs:
# Run tests up to three times # Run tests up to three times
for i in $(seq 1 3); do npx jest -c ./jest.config.playwright.js ${{ matrix['test-file'] }} && s=0 && break || s=$? && sleep 1; done; (exit $s) for i in $(seq 1 3); do npx jest -c ./jest.config.playwright.js ${{ matrix['test-file'] }} && s=0 && break || s=$? && sleep 1; done; (exit $s)
shell: bash shell: bash
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: screenshots name: screenshots
@@ -180,14 +180,14 @@ jobs:
with: with:
nuget-api-key: ${{ secrets.NUGET_API_KEY }} nuget-api-key: ${{ secrets.NUGET_API_KEY }}
- name: Download Dist Folder - name: Download Dist Folder
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
with: with:
name: dist name: dist
- run: cp ./configs/prod.json config.json - run: cp ./configs/prod.json config.json
- run: nuget sources add -Name "ADO" -Source "$NUGET_SOURCE" -UserName "jawelton@microsoft.com" -Password "$AZURE_DEVOPS_PAT" - run: nuget sources add -Name "ADO" -Source "$NUGET_SOURCE" -UserName "jawelton@microsoft.com" -Password "$AZURE_DEVOPS_PAT"
- run: nuget pack -Version "2.0.0-github-${GITHUB_SHA}" - run: nuget pack -Version "2.0.0-github-${GITHUB_SHA}"
- run: nuget push -SkipDuplicate -Source "$NUGET_SOURCE" -ApiKey Az *.nupkg - run: nuget push -SkipDuplicate -Source "$NUGET_SOURCE" -ApiKey Az *.nupkg
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
name: packages name: packages
with: with:
path: "*.nupkg" path: "*.nupkg"
@@ -204,7 +204,7 @@ jobs:
with: with:
nuget-api-key: ${{ secrets.NUGET_API_KEY }} nuget-api-key: ${{ secrets.NUGET_API_KEY }}
- name: Download Dist Folder - name: Download Dist Folder
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
with: with:
name: dist name: dist
- run: cp ./configs/mpac.json config.json - run: cp ./configs/mpac.json config.json
@@ -212,7 +212,7 @@ jobs:
- run: nuget sources add -Name "ADO" -Source "$NUGET_SOURCE" -UserName "jawelton@microsoft.com" -Password "$AZURE_DEVOPS_PAT" - run: nuget sources add -Name "ADO" -Source "$NUGET_SOURCE" -UserName "jawelton@microsoft.com" -Password "$AZURE_DEVOPS_PAT"
- run: nuget pack -Version "2.0.0-github-${GITHUB_SHA}" - run: nuget pack -Version "2.0.0-github-${GITHUB_SHA}"
- run: nuget push -SkipDuplicate -Source "$NUGET_SOURCE" -ApiKey Az *.nupkg - run: nuget push -SkipDuplicate -Source "$NUGET_SOURCE" -ApiKey Az *.nupkg
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
name: packages name: packages
with: with:
path: "*.nupkg" path: "*.nupkg"

View File

@@ -20,9 +20,9 @@ jobs:
NOTEBOOKS_TEST_RUNNER_CLIENT_SECRET: ${{ secrets.NOTEBOOKS_TEST_RUNNER_CLIENT_SECRET }} NOTEBOOKS_TEST_RUNNER_CLIENT_SECRET: ${{ secrets.NOTEBOOKS_TEST_RUNNER_CLIENT_SECRET }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Use Node.js 14.x - name: Use Node.js 18.x
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: 14.x node-version: 18.x
- run: npm ci - run: npm ci
- run: node utils/cleanupDBs.js - run: node utils/cleanupDBs.js

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

View File

@@ -2897,9 +2897,21 @@ a:link {
padding-left: 8px; padding-left: 8px;
} }
.settingsSectionInlineCheckbox {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
align-items: center;
gap: 5px;
}
.settingsSectionLabel { .settingsSectionLabel {
margin-bottom: @DefaultSpace; margin-bottom: @DefaultSpace;
margin-right: 5px; margin-right: 5px;
.panelInfoIcon {
margin-left: 5px;
}
} }
.pageOptionsPart { .pageOptionsPart {

53038
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,12 +12,12 @@
"@azure/msal-browser": "2.14.2", "@azure/msal-browser": "2.14.2",
"@babel/plugin-proposal-class-properties": "7.12.1", "@babel/plugin-proposal-class-properties": "7.12.1",
"@babel/plugin-proposal-decorators": "7.12.12", "@babel/plugin-proposal-decorators": "7.12.12",
"@fluentui/react": "8.14.3", "@fluentui/react": "8.112.1",
"@fluentui/react-components": "9.32.1", "@fluentui/react-components": "9.34.0",
"@jupyterlab/services": "6.0.2", "@jupyterlab/services": "6.0.2",
"@jupyterlab/terminal": "3.0.3", "@jupyterlab/terminal": "3.0.3",
"@microsoft/applicationinsights-web": "2.6.1", "@microsoft/applicationinsights-web": "2.6.1",
"@nteract/commutable": "7.4.2", "@nteract/commutable": "7.5.1",
"@nteract/connected-components": "6.8.2", "@nteract/connected-components": "6.8.2",
"@nteract/core": "15.1.0", "@nteract/core": "15.1.0",
"@nteract/data-explorer": "8.0.3", "@nteract/data-explorer": "8.0.3",
@@ -49,20 +49,20 @@
"applicationinsights": "1.8.0", "applicationinsights": "1.8.0",
"bootstrap": "3.4.1", "bootstrap": "3.4.1",
"canvas": "file:./canvas", "canvas": "file:./canvas",
"clean-webpack-plugin": "3.0.0", "clean-webpack-plugin": "4.0.0",
"clipboard-copy": "4.0.1", "clipboard-copy": "4.0.1",
"copy-webpack-plugin": "9.0.1", "copy-webpack-plugin": "11.0.0",
"crossroads": "0.12.2", "crossroads": "0.12.2",
"css-element-queries": "1.1.1", "css-element-queries": "1.1.1",
"d3": "6.1.1", "d3": "6.1.1",
"datatables.net-colreorder-dt": "1.5.1", "datatables.net-colreorder-dt": "1.7.0",
"datatables.net-dt": "1.10.19", "datatables.net-dt": "1.13.8",
"date-fns": "1.29.0", "date-fns": "1.29.0",
"dayjs": "1.8.19", "dayjs": "1.8.19",
"dom-to-image": "2.6.0", "dom-to-image": "2.6.0",
"dotenv": "8.2.0", "dotenv": "8.2.0",
"eslint-plugin-jest": "23.13.2", "eslint-plugin-jest": "27.4.2",
"eslint-plugin-react": "7.20.0", "eslint-plugin-react": "7.33.2",
"hasher": "1.2.0", "hasher": "1.2.0",
"html2canvas": "1.0.0-rc.5", "html2canvas": "1.0.0-rc.5",
"i18next": "19.8.4", "i18next": "19.8.4",
@@ -71,14 +71,15 @@
"iframe-resizer-react": "1.1.0", "iframe-resizer-react": "1.1.0",
"immutable": "4.0.0-rc.12", "immutable": "4.0.0-rc.12",
"is-ci": "2.0.0", "is-ci": "2.0.0",
"jquery": "3.5.1", "jquery": "3.7.1",
"jquery-typeahead": "2.10.6", "jquery-typeahead": "2.11.1",
"jquery-ui-dist": "1.12.1", "jquery-ui-dist": "1.13.2",
"knockout": "3.5.1", "knockout": "3.5.1",
"mkdirp": "1.0.4", "mkdirp": "1.0.4",
"monaco-editor": "0.18.1", "monaco-editor": "0.44.0",
"ms": "2.1.3", "ms": "2.1.3",
"p-retry": "4.2.0", "patch-package": "8.0.0",
"p-retry": "4.6.2",
"plotly.js-cartesian-dist-min": "1.52.3", "plotly.js-cartesian-dist-min": "1.52.3",
"post-robot": "10.0.42", "post-robot": "10.0.42",
"q": "1.5.1", "q": "1.5.1",
@@ -86,7 +87,7 @@
"react-animate-height": "2.0.8", "react-animate-height": "2.0.8",
"react-dnd": "14.0.2", "react-dnd": "14.0.2",
"react-dnd-html5-backend": "14.0.0", "react-dnd-html5-backend": "14.0.0",
"react-dom": "16.13.1", "react-dom": "16.14.0",
"react-hotkeys": "2.0.0", "react-hotkeys": "2.0.0",
"react-i18next": "11.8.5", "react-i18next": "11.8.5",
"react-notification-system": "0.2.17", "react-notification-system": "0.2.17",
@@ -94,14 +95,12 @@
"react-splitter-layout": "4.0.0", "react-splitter-layout": "4.0.0",
"react-string-format": "1.0.1", "react-string-format": "1.0.1",
"react-youtube": "9.0.1", "react-youtube": "9.0.1",
"redux": "4.0.4",
"reflect-metadata": "0.1.13", "reflect-metadata": "0.1.13",
"rx-jupyter": "5.5.12", "rx-jupyter": "5.5.12",
"rxjs": "6.6.3",
"sanitize-html": "2.3.3", "sanitize-html": "2.3.3",
"styled-components": "4.3.2", "styled-components": "5.0.1",
"swr": "0.4.0", "swr": "0.4.0",
"terser-webpack-plugin": "5.1.4", "terser-webpack-plugin": "5.3.9",
"underscore": "1.9.1", "underscore": "1.9.1",
"utility-types": "3.10.0", "utility-types": "3.10.0",
"zustand": "3.5.0" "zustand": "3.5.0"
@@ -116,11 +115,14 @@
"@types/codemirror": "0.0.56", "@types/codemirror": "0.0.56",
"@types/crossroads": "0.0.30", "@types/crossroads": "0.0.30",
"@types/d3": "5.9.2", "@types/d3": "5.9.2",
"@types/datatables.net": "1.10.28",
"@types/datatables.net-colreorder": "1.4.5",
"@types/dom-to-image": "2.6.2", "@types/dom-to-image": "2.6.2",
"@types/enzyme": "3.10.7", "@types/enzyme": "3.10.7",
"@types/enzyme-adapter-react-16": "1.0.6", "@types/enzyme-adapter-react-16": "1.0.6",
"@types/hasher": "0.0.31", "@types/hasher": "0.0.31",
"@types/jest": "26.0.20", "@types/jest": "26.0.20",
"@types/jquery": "3.5.29",
"@types/node": "12.11.1", "@types/node": "12.11.1",
"@types/post-robot": "10.0.1", "@types/post-robot": "10.0.1",
"@types/q": "1.5.1", "@types/q": "1.5.1",
@@ -134,61 +136,62 @@
"@types/styled-components": "5.1.1", "@types/styled-components": "5.1.1",
"@types/underscore": "1.7.36", "@types/underscore": "1.7.36",
"@types/youtube-player": "5.5.6", "@types/youtube-player": "5.5.6",
"@typescript-eslint/eslint-plugin": "4.22.0", "@typescript-eslint/eslint-plugin": "6.7.4",
"@typescript-eslint/parser": "4.22.0", "@typescript-eslint/parser": "6.7.4",
"@webpack-cli/serve": "1.5.2", "@webpack-cli/serve": "2.0.5",
"babel-jest": "24.9.0", "babel-jest": "24.9.0",
"babel-loader": "8.1.0", "babel-loader": "8.1.0",
"buffer": "5.1.0", "buffer": "5.1.0",
"case-sensitive-paths-webpack-plugin": "2.3.0", "case-sensitive-paths-webpack-plugin": "2.4.0",
"create-file-webpack": "1.0.2", "create-file-webpack": "1.0.2",
"css-loader": "1.0.0", "css-loader": "6.8.1",
"enzyme": "3.11.0", "enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.5", "enzyme-adapter-react-16": "1.15.5",
"enzyme-to-json": "3.6.1", "enzyme-to-json": "3.6.1",
"eslint": "7.8.1", "eslint": "8.50.0",
"eslint-cli": "1.1.1", "eslint-cli": "1.1.1",
"eslint-plugin-no-null": "1.0.2", "eslint-plugin-no-null": "1.0.2",
"eslint-plugin-prefer-arrow": "1.2.2", "eslint-plugin-prefer-arrow": "1.2.3",
"eslint-plugin-react-hooks": "4.2.0", "eslint-plugin-react-hooks": "4.6.0",
"expect-playwright": "0.3.3", "expect-playwright": "0.3.3",
"fast-glob": "3.2.5", "fast-glob": "3.2.5",
"file-loader": "2.0.0",
"fs-extra": "7.0.0", "fs-extra": "7.0.0",
"html-inline-css-webpack-plugin": "1.11.0", "html-inline-css-webpack-plugin": "1.11.2",
"html-loader": "0.5.5", "html-loader": "0.5.5",
"html-loader-jest": "0.2.1", "html-loader-jest": "0.2.1",
"html-webpack-plugin": "5.3.2", "html-webpack-plugin": "5.5.3",
"jest": "26.6.3", "jest": "26.6.3",
"jest-canvas-mock": "2.3.1", "jest-canvas-mock": "2.3.1",
"jest-playwright-preset": "1.5.1", "jest-playwright-preset": "1.5.1",
"jest-react-hooks-shallow": "1.5.1", "jest-react-hooks-shallow": "1.5.1",
"jest-trx-results-processor": "0.0.7", "jest-trx-results-processor": "0.0.7",
"less": "3.8.1", "less": "3.8.1",
"less-loader": "4.1.0", "less-loader": "11.1.3",
"less-vars-loader": "1.1.0", "less-vars-loader": "1.1.0",
"mini-css-extract-plugin": "2.1.0", "mini-css-extract-plugin": "2.1.0",
"monaco-editor-webpack-plugin": "1.7.0", "monaco-editor-webpack-plugin": "7.1.0",
"node-fetch": "2.6.1", "node-fetch": "2.6.1",
"playwright": "1.13.0", "playwright": "1.13.0",
"prettier": "3.0.3", "prettier": "3.0.3",
"process": "0.11.10", "process": "0.11.10",
"querystring-es3": "0.2.1",
"raw-loader": "0.5.1", "raw-loader": "0.5.1",
"react-dev-utils": "11.0.4", "react-dev-utils": "11.0.4",
"rimraf": "3.0.0", "rimraf": "3.0.0",
"sinon": "3.2.1", "sinon": "3.2.1",
"style-loader": "0.23.0", "style-loader": "0.23.0",
"ts-loader": "9.2.4", "ts-loader": "9.2.4",
"typedoc": "0.20.36", "typedoc": "0.21.5",
"typescript": "4.3.4", "typescript": "4.3.5",
"url-loader": "1.1.1", "url-loader": "4.1.1",
"wait-on": "4.0.2", "wait-on": "4.0.2",
"webpack": "5.47.0", "webpack": "5.88.2",
"webpack-bundle-analyzer": "4.4.2", "webpack-bundle-analyzer": "4.9.1",
"webpack-cli": "4.7.2", "webpack-cli": "5.1.4",
"webpack-dev-server": "3.11.2" "webpack-dev-server": "4.15.1"
}, },
"scripts": { "scripts": {
"postinstall": "patch-package",
"start": "webpack serve --mode development", "start": "webpack serve --mode development",
"dev": "echo \"WARNING: npm run dev has been deprecated\" && npm run build", "dev": "echo \"WARNING: npm run dev has been deprecated\" && npm run build",
"build:dataExplorer:ci": "npm run build:ci", "build:dataExplorer:ci": "npm run build:ci",
@@ -235,4 +238,4 @@
"printWidth": 120, "printWidth": 120,
"endOfLine": "auto" "endOfLine": "auto"
} }
} }

View File

@@ -0,0 +1,22 @@
diff --git a/node_modules/datatables.net-colreorder/types/types.d.ts b/node_modules/datatables.net-colreorder/types/types.d.ts
index e5dc283..1930c2b 100644
--- a/node_modules/datatables.net-colreorder/types/types.d.ts
+++ b/node_modules/datatables.net-colreorder/types/types.d.ts
@@ -7,7 +7,7 @@
/// <reference types="jquery" />
-import DataTables, {Api} from 'datatables.net';
+import DataTables, { Api } from 'datatables.net';
export default DataTables;
@@ -40,6 +40,8 @@ declare module 'datatables.net' {
/**
* Create a new ColReorder instance for the target DataTable
*/
+ // Ignore this error: error TS7013: Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.
+ // @ts-ignore
new (dt: Api<any>, settings: boolean | ConfigColReorder);
/**

View File

@@ -145,6 +145,9 @@ export class Queries {
public static QueryEditorMinHeightRatio: number = 0.1; public static QueryEditorMinHeightRatio: number = 0.1;
public static QueryEditorMaxHeightRatio: number = 0.4; public static QueryEditorMaxHeightRatio: number = 0.4;
public static readonly DefaultMaxDegreeOfParallelism = 6; public static readonly DefaultMaxDegreeOfParallelism = 6;
public static readonly DefaultRetryAttempts = 9;
public static readonly DefaultRetryIntervalInMs = 0;
public static readonly DefaultMaxWaitTimeInSeconds = 30;
} }
export class SavedQueries { export class SavedQueries {
@@ -171,6 +174,7 @@ export class Areas {
public static Tab: string = "Tab"; public static Tab: string = "Tab";
public static ShareDialog: string = "Share Access Dialog"; public static ShareDialog: string = "Share Access Dialog";
public static Notebook: string = "Notebook"; public static Notebook: string = "Notebook";
public static Copilot: string = "Copilot";
} }
export class HttpHeaders { export class HttpHeaders {

View File

@@ -1,6 +1,9 @@
import * as Cosmos from "@azure/cosmos"; import * as Cosmos from "@azure/cosmos";
import { sendCachedDataMessage } from "Common/MessageHandler"; import { sendCachedDataMessage } from "Common/MessageHandler";
import { getAuthorizationTokenUsingResourceTokens } from "Common/getAuthorizationTokenUsingResourceTokens";
import { AuthorizationToken, MessageTypes } from "Contracts/MessageTypes"; import { AuthorizationToken, MessageTypes } from "Contracts/MessageTypes";
import { checkDatabaseResourceTokensValidity } from "Platform/Fabric/FabricUtil";
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
import { AuthType } from "../AuthType"; import { AuthType } from "../AuthType";
import { PriorityLevel } from "../Common/Constants"; import { PriorityLevel } from "../Common/Constants";
import { Platform, configContext } from "../ConfigContext"; import { Platform, configContext } from "../ConfigContext";
@@ -28,12 +31,33 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
} }
if (configContext.platform === Platform.Fabric) { if (configContext.platform === Platform.Fabric) {
const authorizationToken = await sendCachedDataMessage<AuthorizationToken>(MessageTypes.GetAuthorizationToken, [ switch (requestInfo.resourceType) {
requestInfo, case Cosmos.ResourceType.conflicts:
]); case Cosmos.ResourceType.container:
console.log("Response from Fabric: ", authorizationToken); case Cosmos.ResourceType.sproc:
headers[HttpHeaders.msDate] = authorizationToken.XDate; case Cosmos.ResourceType.udf:
return authorizationToken.PrimaryReadWriteToken; case Cosmos.ResourceType.trigger:
case Cosmos.ResourceType.item:
case Cosmos.ResourceType.pkranges:
// User resource tokens
headers[HttpHeaders.msDate] = new Date().toUTCString();
const resourceTokens = userContext.fabricDatabaseConnectionInfo.resourceTokens;
checkDatabaseResourceTokensValidity(userContext.fabricDatabaseConnectionInfo.resourceTokensTimestamp);
return getAuthorizationTokenUsingResourceTokens(resourceTokens, requestInfo.path, requestInfo.resourceId);
case Cosmos.ResourceType.none:
case Cosmos.ResourceType.database:
case Cosmos.ResourceType.offer:
case Cosmos.ResourceType.user:
case Cosmos.ResourceType.permission:
// User master tokens
const authorizationToken = await sendCachedDataMessage<AuthorizationToken>(MessageTypes.GetAuthorizationToken, [
requestInfo,
]);
console.log("Response from Fabric: ", authorizationToken);
headers[HttpHeaders.msDate] = authorizationToken.XDate;
return decodeURIComponent(authorizationToken.PrimaryReadWriteToken);
}
} }
if (userContext.masterKey) { if (userContext.masterKey) {
@@ -125,11 +149,15 @@ export function client(): Cosmos.CosmosClient {
endpoint: endpoint() || "https://cosmos.azure.com", // CosmosClient gets upset if we pass a bad URL. This should never actually get called endpoint: endpoint() || "https://cosmos.azure.com", // CosmosClient gets upset if we pass a bad URL. This should never actually get called
key: userContext.masterKey, key: userContext.masterKey,
tokenProvider, tokenProvider,
connectionPolicy: {
enableEndpointDiscovery: false,
},
userAgentSuffix: "Azure Portal", userAgentSuffix: "Azure Portal",
defaultHeaders: _defaultHeaders, defaultHeaders: _defaultHeaders,
connectionPolicy: {
retryOptions: {
maxRetryAttemptCount: LocalStorageUtility.getEntryNumber(StorageKey.RetryAttempts),
fixedRetryIntervalInMilliseconds: LocalStorageUtility.getEntryNumber(StorageKey.RetryInterval),
maxWaitTimeInSeconds: LocalStorageUtility.getEntryNumber(StorageKey.MaxWaitTimeInSeconds),
},
},
}; };
if (configContext.PROXY_PATH !== undefined) { if (configContext.PROXY_PATH !== undefined) {

View File

@@ -1,7 +1,5 @@
jest.mock("./MessageHandler"); jest.mock("./MessageHandler");
import { LogEntryLevel } from "../Contracts/Diagnostics";
import * as Logger from "./Logger"; import * as Logger from "./Logger";
import { MessageTypes } from "../Contracts/ExplorerContracts";
import { sendMessage } from "./MessageHandler"; import { sendMessage } from "./MessageHandler";
describe("Logger", () => { describe("Logger", () => {
@@ -11,16 +9,16 @@ describe("Logger", () => {
it("should log info messages", () => { it("should log info messages", () => {
Logger.logInfo("Test info", "DocDB"); Logger.logInfo("Test info", "DocDB");
expect(sendMessage).toBeCalled(); expect(sendMessage).toHaveBeenCalled();
}); });
it("should log error messages", () => { it("should log error messages", () => {
Logger.logError("Test error", "DocDB"); Logger.logError("Test error", "DocDB");
expect(sendMessage).toBeCalled(); expect(sendMessage).toHaveBeenCalled();
}); });
it("should log warnings", () => { it("should log warnings", () => {
Logger.logWarning("Test warning", "DocDB"); Logger.logWarning("Test warning", "DocDB");
expect(sendMessage).toBeCalled(); expect(sendMessage).toHaveBeenCalled();
}); });
}); });

View File

@@ -1,3 +1,4 @@
import { isServerlessAccount } from "Utils/CapabilityUtils";
import * as _ from "underscore"; import * as _ from "underscore";
import * as DataModels from "../Contracts/DataModels"; import * as DataModels from "../Contracts/DataModels";
import * as ViewModels from "../Contracts/ViewModels"; import * as ViewModels from "../Contracts/ViewModels";
@@ -8,12 +9,11 @@ import { useDatabases } from "../Explorer/useDatabases";
import { userContext } from "../UserContext"; import { userContext } from "../UserContext";
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils"; import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
import { BackendDefaults, HttpStatusCodes, SavedQueries } from "./Constants"; import { BackendDefaults, HttpStatusCodes, SavedQueries } from "./Constants";
import { handleError } from "./ErrorHandlingUtils";
import { createCollection } from "./dataAccess/createCollection"; import { createCollection } from "./dataAccess/createCollection";
import { createDocument } from "./dataAccess/createDocument"; import { createDocument } from "./dataAccess/createDocument";
import { deleteDocument } from "./dataAccess/deleteDocument"; import { deleteDocument } from "./dataAccess/deleteDocument";
import { queryDocuments } from "./dataAccess/queryDocuments"; import { queryDocuments } from "./dataAccess/queryDocuments";
import { handleError } from "./ErrorHandlingUtils";
import { isServerlessAccount } from "Utils/CapabilityUtils";
export class QueriesClient { export class QueriesClient {
private static readonly PartitionKey: DataModels.PartitionKey = { private static readonly PartitionKey: DataModels.PartitionKey = {

View File

@@ -146,6 +146,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
onClick={onEditEntity} onClick={onEditEntity}
tabIndex={0} tabIndex={0}
onKeyPress={handleKeyPress} onKeyPress={handleKeyPress}
role="button"
/> />
</div> </div>
</TooltipHost> </TooltipHost>
@@ -160,6 +161,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
onClick={onDeleteEntity} onClick={onDeleteEntity}
tabIndex={0} tabIndex={0}
onKeyPress={handleKeyPressdelete} onKeyPress={handleKeyPressdelete}
role="button"
/> />
</TooltipHost> </TooltipHost>
)} )}

View File

@@ -1,5 +1,5 @@
import { getCommonQueryOptions } from "./queryDocuments";
import { LocalStorageUtility, StorageKey } from "../../Shared/StorageUtility"; import { LocalStorageUtility, StorageKey } from "../../Shared/StorageUtility";
import { getCommonQueryOptions } from "./queryDocuments";
describe("getCommonQueryOptions", () => { describe("getCommonQueryOptions", () => {
it("builds the correct default options objects", () => { it("builds the correct default options objects", () => {

View File

@@ -26,6 +26,5 @@ export const getCommonQueryOptions = (options: FeedOptions): FeedOptions => {
(storedItemPerPageSetting !== undefined && storedItemPerPageSetting) || (storedItemPerPageSetting !== undefined && storedItemPerPageSetting) ||
Queries.itemsPerPage; Queries.itemsPerPage;
options.maxDegreeOfParallelism = LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism); options.maxDegreeOfParallelism = LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism);
return options; return options;
}; };

View File

@@ -1,18 +1,57 @@
import { ContainerResponse } from "@azure/cosmos";
import { Queries } from "Common/Constants"; import { Queries } from "Common/Constants";
import { Platform, configContext } from "ConfigContext";
import { AuthType } from "../../AuthType"; import { AuthType } from "../../AuthType";
import * as DataModels from "../../Contracts/DataModels"; import * as DataModels from "../../Contracts/DataModels";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { listCassandraTables } from "../../Utils/arm/generatedClients/cosmos/cassandraResources"; import { listCassandraTables } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
import { listGremlinGraphs } from "../../Utils/arm/generatedClients/cosmos/gremlinResources"; import { listGremlinGraphs } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
import { listMongoDBCollections } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources"; import { listMongoDBCollections } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
import { listSqlContainers } from "../../Utils/arm/generatedClients/cosmos/sqlResources"; import { listSqlContainers } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { listTables } from "../../Utils/arm/generatedClients/cosmos/tableResources"; import { listTables } from "../../Utils/arm/generatedClients/cosmos/tableResources";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient"; import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils"; import { handleError } from "../ErrorHandlingUtils";
export async function readCollections(databaseId: string): Promise<DataModels.Collection[]> { export async function readCollections(databaseId: string): Promise<DataModels.Collection[]> {
const clearMessage = logConsoleProgress(`Querying containers for database ${databaseId}`); const clearMessage = logConsoleProgress(`Querying containers for database ${databaseId}`);
if (
configContext.platform === Platform.Fabric &&
userContext.fabricDatabaseConnectionInfo &&
userContext.fabricDatabaseConnectionInfo.databaseId === databaseId
) {
const collections: DataModels.Collection[] = [];
const promises: Promise<ContainerResponse>[] = [];
for (const collectionResourceId in userContext.fabricDatabaseConnectionInfo.resourceTokens) {
// Dictionary key looks like this: dbs/SampleDB/colls/Container
const resourceIdObj = collectionResourceId.split("/");
const tokenDatabaseId = resourceIdObj[1];
const tokenCollectionId = resourceIdObj[3];
if (tokenDatabaseId === databaseId) {
promises.push(client().database(databaseId).container(tokenCollectionId).read());
}
}
try {
const responses = await Promise.all(promises);
responses.forEach((response) => {
collections.push(response.resource as DataModels.Collection);
});
// Sort collections by id before returning
collections.sort((a, b) => a.id.localeCompare(b.id));
return collections;
} catch (error) {
handleError(error, "ReadCollections", `Error while querying containers for database ${databaseId}`);
throw error;
} finally {
clearMessage();
}
}
try { try {
if ( if (
userContext.authType === AuthType.AAD && userContext.authType === AuthType.AAD &&

View File

@@ -1,15 +1,22 @@
import { Platform, configContext } from "ConfigContext";
import { AuthType } from "../../AuthType"; import { AuthType } from "../../AuthType";
import { Offer, ReadDatabaseOfferParams } from "../../Contracts/DataModels"; import { Offer, ReadDatabaseOfferParams } from "../../Contracts/DataModels";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { getCassandraKeyspaceThroughput } from "../../Utils/arm/generatedClients/cosmos/cassandraResources"; import { getCassandraKeyspaceThroughput } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
import { getGremlinDatabaseThroughput } from "../../Utils/arm/generatedClients/cosmos/gremlinResources"; import { getGremlinDatabaseThroughput } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
import { getMongoDBDatabaseThroughput } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources"; import { getMongoDBDatabaseThroughput } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
import { getSqlDatabaseThroughput } from "../../Utils/arm/generatedClients/cosmos/sqlResources"; import { getSqlDatabaseThroughput } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { handleError } from "../ErrorHandlingUtils"; import { handleError } from "../ErrorHandlingUtils";
import { readOfferWithSDK } from "./readOfferWithSDK"; import { readOfferWithSDK } from "./readOfferWithSDK";
export const readDatabaseOffer = async (params: ReadDatabaseOfferParams): Promise<Offer> => { export const readDatabaseOffer = async (params: ReadDatabaseOfferParams): Promise<Offer> => {
if (configContext.platform === Platform.Fabric) {
// TODO This works, but is very slow, because it requests the token, so we skip for now
console.error("Skiping readDatabaseOffer for Fabric");
return undefined;
}
const clearMessage = logConsoleProgress(`Querying offer for database ${params.databaseId}`); const clearMessage = logConsoleProgress(`Querying offer for database ${params.databaseId}`);
try { try {

View File

@@ -1,17 +1,53 @@
import { Platform, configContext } from "ConfigContext";
import { AuthType } from "../../AuthType"; import { AuthType } from "../../AuthType";
import * as DataModels from "../../Contracts/DataModels"; import * as DataModels from "../../Contracts/DataModels";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { listCassandraKeyspaces } from "../../Utils/arm/generatedClients/cosmos/cassandraResources"; import { listCassandraKeyspaces } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
import { listGremlinDatabases } from "../../Utils/arm/generatedClients/cosmos/gremlinResources"; import { listGremlinDatabases } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
import { listMongoDBDatabases } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources"; import { listMongoDBDatabases } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
import { listSqlDatabases } from "../../Utils/arm/generatedClients/cosmos/sqlResources"; import { listSqlDatabases } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient"; import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils"; import { handleError } from "../ErrorHandlingUtils";
export async function readDatabases(): Promise<DataModels.Database[]> { export async function readDatabases(): Promise<DataModels.Database[]> {
let databases: DataModels.Database[]; let databases: DataModels.Database[];
const clearMessage = logConsoleProgress(`Querying databases`); const clearMessage = logConsoleProgress(`Querying databases`);
if (configContext.platform === Platform.Fabric && userContext.fabricDatabaseConnectionInfo?.resourceTokens) {
const tokensData = userContext.fabricDatabaseConnectionInfo;
const databaseIdsSet = new Set<string>(); // databaseId
for (const collectionResourceId in tokensData.resourceTokens) {
// Dictionary key looks like this: dbs/SampleDB/colls/Container
const resourceIdObj = collectionResourceId.split("/");
if (resourceIdObj.length !== 4) {
handleError(`Resource key not recognized: ${resourceIdObj}`, "ReadDatabases", `Error while querying databases`);
clearMessage();
return [];
}
const databaseId = resourceIdObj[1];
databaseIdsSet.add(databaseId);
}
const databases: DataModels.Database[] = Array.from(databaseIdsSet.values())
.sort((a, b) => a.localeCompare(b))
.map((databaseId) => ({
_rid: "",
_self: "",
_etag: "",
_ts: 0,
id: databaseId,
collections: [],
}));
clearMessage();
return databases;
}
try { try {
if ( if (
userContext.authType === AuthType.AAD && userContext.authType === AuthType.AAD &&

View File

@@ -0,0 +1,66 @@
export function getAuthorizationTokenUsingResourceTokens(
resourceTokens: { [resourceId: string]: string },
path: string,
resourceId: string,
): string {
// console.log(`getting token for path: "${path}" and resourceId: "${resourceId}"`);
if (resourceTokens && Object.keys(resourceTokens).length > 0) {
// For database account access(through getDatabaseAccount API), path and resourceId are "",
// so in this case we return the first token to be used for creating the auth header as the
// service will accept any token in this case
if (!path && !resourceId) {
return resourceTokens[Object.keys(resourceTokens)[0]];
}
// If we have exact resource token for the path use it
if (resourceId && resourceTokens[resourceId]) {
return resourceTokens[resourceId];
}
// minimum valid path /dbs
if (!path || path.length < 4) {
console.error(
`Unable to get authotization token for Path:"${path}" and resourcerId:"${resourceId}". Invalid path.`,
);
return null;
}
path = trimSlashFromLeftAndRight(path);
const pathSegments = (path && path.split("/")) || [];
// Item path
if (pathSegments.length === 6) {
// Look for a container token matching the item path
const containerPath = pathSegments.slice(0, 4).map(decodeURIComponent).join("/");
if (resourceTokens[containerPath]) {
return resourceTokens[containerPath];
}
}
// This is legacy behavior that lets someone use a resource token pointing ONLY at an ID
// It was used when _rid was exposed by the SDK, but now that we are using user provided ids it is not needed
// However removing it now would be a breaking change
// if it's an incomplete path like /dbs/db1/colls/, start from the parent resource
let index = pathSegments.length % 2 === 0 ? pathSegments.length - 1 : pathSegments.length - 2;
for (; index > 0; index -= 2) {
const id = decodeURI(pathSegments[index]);
if (resourceTokens[id]) {
return resourceTokens[id];
}
}
}
console.error(`Unable to get authotization token for Path:"${path}" and resourcerId:"${resourceId}"`);
return null;
}
const trimLeftSlashes = new RegExp("^[/]+");
const trimRightSlashes = new RegExp("[/]+$");
function trimSlashFromLeftAndRight(inputString: string): string {
if (typeof inputString !== "string") {
throw new Error("invalid input: input is not string");
}
return inputString.replace(trimLeftSlashes, "").replace(trimRightSlashes, "");
}

View File

@@ -1,3 +1,4 @@
import { JunoEndpoints } from "Common/Constants";
import { import {
allowedAadEndpoints, allowedAadEndpoints,
allowedArcadiaEndpoints, allowedArcadiaEndpoints,
@@ -64,6 +65,8 @@ let configContext: Readonly<ConfigContext> = {
`^https:\\/\\/.*\\.fabric\\.microsoft\\.com$`, `^https:\\/\\/.*\\.fabric\\.microsoft\\.com$`,
`^https:\\/\\/.*\\.powerbi\\.com$`, `^https:\\/\\/.*\\.powerbi\\.com$`,
`^https:\\/\\/.*\\.analysis-df\\.net$`, `^https:\\/\\/.*\\.analysis-df\\.net$`,
`^https:\\/\\/.*\\.analysis-df\\.windows\\.net$`,
`^https:\\/\\/.*\\.azure-test\\.net$`,
], // Webpack injects this at build time ], // Webpack injects this at build time
gitSha: process.env.GIT_SHA, gitSha: process.env.GIT_SHA,
hostedExplorerURL: "https://cosmos.azure.com/", hostedExplorerURL: "https://cosmos.azure.com/",
@@ -77,7 +80,7 @@ let configContext: Readonly<ConfigContext> = {
ARCADIA_LIVY_ENDPOINT_DNS_ZONE: "dev.azuresynapse.net", ARCADIA_LIVY_ENDPOINT_DNS_ZONE: "dev.azuresynapse.net",
GITHUB_CLIENT_ID: "6cb2f63cf6f7b5cbdeca", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1189306 GITHUB_CLIENT_ID: "6cb2f63cf6f7b5cbdeca", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1189306
GITHUB_TEST_ENV_CLIENT_ID: "b63fc8cbf87fd3c6e2eb", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1777772 GITHUB_TEST_ENV_CLIENT_ID: "b63fc8cbf87fd3c6e2eb", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1777772
JUNO_ENDPOINT: "https://tools.cosmos.azure.com", JUNO_ENDPOINT: JunoEndpoints.Prod,
BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com", BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com",
isTerminalEnabled: false, isTerminalEnabled: false,
isPhoenixEnabled: false, isPhoenixEnabled: false,

View File

@@ -0,0 +1,13 @@
export interface QueryRequestOptions {
$skipToken?: string;
$top?: number;
subscriptions: string[];
}
export interface QueryResponse {
$skipToken: string;
count: number;
data: any;
resultTruncated: boolean;
totalRecords: number;
}

View File

@@ -88,13 +88,13 @@ export interface GenerateTokenResponse {
} }
export interface Subscription { export interface Subscription {
uniqueDisplayName: string; uniqueDisplayName?: string;
displayName: string; displayName: string;
subscriptionId: string; subscriptionId: string;
tenantId: string; tenantId?: string;
state: string; state: string;
subscriptionPolicies: SubscriptionPolicies; subscriptionPolicies?: SubscriptionPolicies;
authorizationSource: string; authorizationSource?: string;
} }
export interface SubscriptionPolicies { export interface SubscriptionPolicies {
@@ -457,8 +457,11 @@ export interface ContainerInfo {
} }
export interface IProvisionData { export interface IProvisionData {
cosmosEndpoint: string; cosmosEndpoint?: string;
poolId: string; poolId: string;
databaseId?: string;
containerId?: string;
mode?: string;
} }
export interface IContainerData { export interface IContainerData {
@@ -601,3 +604,14 @@ export enum PhoenixErrorType {
PhoenixFlightFallback = "PhoenixFlightFallback", PhoenixFlightFallback = "PhoenixFlightFallback",
UserMissingPermissionsError = "UserMissingPermissionsError", UserMissingPermissionsError = "UserMissingPermissionsError",
} }
export interface CopilotEnabledConfiguration {
isEnabled: boolean;
}
export interface FeatureRegistration {
name: string;
properties: {
state: string;
};
}

View File

@@ -9,14 +9,12 @@ export type FabricMessage =
type: "initialize"; type: "initialize";
message: { message: {
endpoint: string | undefined; endpoint: string | undefined;
databaseId: string | undefined;
resourceTokens: unknown | undefined;
resourceTokensTimestamp: number | undefined;
error: string | undefined; error: string | undefined;
}; };
} }
| {
type: "openTab";
databaseName: string;
collectionName: string | undefined;
}
| { | {
type: "authorizationToken"; type: "authorizationToken";
message: { message: {
@@ -24,6 +22,15 @@ export type FabricMessage =
error: string | undefined; error: string | undefined;
data: AuthorizationToken | undefined; data: AuthorizationToken | undefined;
}; };
}
| {
type: "allResourceTokens";
message: {
endpoint: string | undefined;
databaseId: string | undefined;
resourceTokens: unknown | undefined;
resourceTokensTimestamp: number | undefined;
};
}; };
export type DataExploreMessage = export type DataExploreMessage =
@@ -40,6 +47,9 @@ export type DataExploreMessage =
type: MessageTypes.GetAuthorizationToken; type: MessageTypes.GetAuthorizationToken;
id: string; id: string;
params: GetCosmosTokenMessageOptions[]; params: GetCosmosTokenMessageOptions[];
}
| {
type: MessageTypes.GetAllResourceTokens;
}; };
export type GetCosmosTokenMessageOptions = { export type GetCosmosTokenMessageOptions = {
@@ -55,4 +65,13 @@ export type CosmosDBTokenResponse = {
export type CosmosDBConnectionInfoResponse = { export type CosmosDBConnectionInfoResponse = {
endpoint: string; endpoint: string;
databaseId: string;
resourceTokens: unknown;
}; };
export interface FabricDatabaseConnectionInfo {
endpoint: string;
databaseId: string;
resourceTokens: { [resourceId: string]: string };
resourceTokensTimestamp: number;
}

View File

@@ -40,6 +40,7 @@ export enum MessageTypes {
// Data Explorer -> Fabric communication // Data Explorer -> Fabric communication
GetAuthorizationToken, GetAuthorizationToken,
GetAllResourceTokens,
} }
export interface AuthorizationToken { export interface AuthorizationToken {

View File

@@ -109,6 +109,7 @@ describe("iframe rendering when there is no data", () => {
theme: 4, theme: 4,
}, },
}, },
origin: "http://localhost",
}; };
const divElement = `<div id="${Heatmap.elementId}"></div>`; const divElement = `<div id="${Heatmap.elementId}"></div>`;
@@ -129,6 +130,7 @@ describe("iframe rendering when there is no data", () => {
theme: 2, theme: 2,
}, },
}, },
origin: "http://localhost",
}; };
const divElement = `<div id="${Heatmap.elementId}"></div>`; const divElement = `<div id="${Heatmap.elementId}"></div>`;

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
* https://github.com/running-coder/jquery-typeahead/issues/156 * https://github.com/running-coder/jquery-typeahead/issues/156
* TODO: Replace this minimum definition by the official one when it comes out. * TODO: Replace this minimum definition by the official one when it comes out.
*/ */
/// <reference path="jquery.d.ts" /> /// <reference types="jquery" />
interface JQueryTypeaheadParam { interface JQueryTypeaheadParam {
input: string; input: string;

View File

@@ -3,7 +3,7 @@
// Definitions by: Boris Yankov <https://github.com/borisyankov/>, John Reilly <https://github.com/johnnyreilly> // Definitions by: Boris Yankov <https://github.com/borisyankov/>, John Reilly <https://github.com/johnnyreilly>
// Definitions: https://github.com/borisyankov/DefinitelyTyped // Definitions: https://github.com/borisyankov/DefinitelyTyped
/// <reference path="jquery.d.ts"/> /// <reference types="jquery"/>
declare namespace JQueryUI { declare namespace JQueryUI {
// Accordion ////////////////////////////////////////////////// // Accordion //////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

4
src/Definitions/less.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module "*.less" {
const value: string;
export default value;
}

View File

@@ -129,20 +129,22 @@ export const createCollectionContextMenuButton = (
}); });
} }
items.push({ if (configContext.platform !== Platform.Fabric) {
iconSrc: DeleteCollectionIcon, items.push({
onClick: () => { iconSrc: DeleteCollectionIcon,
useSelectedNode.getState().setSelectedNode(selectedCollection); onClick: () => {
useSidePanel useSelectedNode.getState().setSelectedNode(selectedCollection);
.getState() useSidePanel
.openSidePanel( .getState()
"Delete " + getCollectionName(), .openSidePanel(
<DeleteCollectionConfirmationPane refreshDatabases={() => container.refreshAllDatabases()} />, "Delete " + getCollectionName(),
); <DeleteCollectionConfirmationPane refreshDatabases={() => container.refreshAllDatabases()} />,
}, );
label: `Delete ${getCollectionName()}`, },
styleClass: "deleteCollectionMenuItem", label: `Delete ${getCollectionName()}`,
}); styleClass: "deleteCollectionMenuItem",
});
}
return items; return items;
}; };

View File

@@ -27,6 +27,7 @@ export interface AccordionItemComponentProps {
isExpanded?: boolean; isExpanded?: boolean;
containerStyles?: React.CSSProperties; containerStyles?: React.CSSProperties;
styles?: React.CSSProperties; styles?: React.CSSProperties;
children: JSX.Element;
} }
interface AccordionItemComponentState { interface AccordionItemComponentState {

View File

@@ -16,6 +16,7 @@ export interface CollapsiblePanelProps {
isCollapsed: boolean; isCollapsed: boolean;
onCollapsedChanged: (newValue: boolean) => void; onCollapsedChanged: (newValue: boolean) => void;
collapseToLeft?: boolean; collapseToLeft?: boolean;
children: JSX.Element | JSX.Element[];
} }
export class CollapsiblePanel extends React.Component<CollapsiblePanelProps> { export class CollapsiblePanel extends React.Component<CollapsiblePanelProps> {

View File

@@ -7,6 +7,7 @@ describe("CollapsibleSectionComponent", () => {
const props: CollapsibleSectionProps = { const props: CollapsibleSectionProps = {
title: "Sample title", title: "Sample title",
isExpandedByDefault: true, isExpandedByDefault: true,
children: <></>,
}; };
const wrapper = shallow(<CollapsibleSectionComponent {...props} />); const wrapper = shallow(<CollapsibleSectionComponent {...props} />);

View File

@@ -7,6 +7,7 @@ export interface CollapsibleSectionProps {
title: string; title: string;
isExpandedByDefault: boolean; isExpandedByDefault: boolean;
onExpand?: () => void; onExpand?: () => void;
children: JSX.Element;
} }
export interface CollapsibleSectionState { export interface CollapsibleSectionState {

View File

@@ -99,7 +99,7 @@ export class DiffEditorViewModel {
) { ) {
this.editorContainer = document.getElementById(this.getEditorId()); this.editorContainer = document.getElementById(this.getEditorId());
this.editorContainer.innerHTML = ""; this.editorContainer.innerHTML = "";
const options: monaco.editor.IDiffEditorConstructionOptions = { const options: monaco.editor.IStandaloneDiffEditorConstructionOptions = {
lineNumbers: this.params.lineNumbers || "off", lineNumbers: this.params.lineNumbers || "off",
fontSize: 12, fontSize: 12,
ariaLabel: this.params.ariaLabel, ariaLabel: this.params.ariaLabel,

View File

@@ -52,7 +52,11 @@ class EditorViewModel extends JsonEditorViewModel {
if (EditorViewModel.providerRegistered.indexOf("sql") < 0) { if (EditorViewModel.providerRegistered.indexOf("sql") < 0) {
const { SqlCompletionItemProvider } = await import("@azure/cosmos-language-service"); const { SqlCompletionItemProvider } = await import("@azure/cosmos-language-service");
const monaco = await loadMonaco(); const monaco = await loadMonaco();
monaco.languages.registerCompletionItemProvider("sql", new SqlCompletionItemProvider()); monaco.languages.registerCompletionItemProvider(
"sql",
// TODO cosmos-language-service could be outdated
new SqlCompletionItemProvider() as unknown as monaco.languages.CompletionItemProvider,
);
EditorViewModel.providerRegistered.push("sql"); EditorViewModel.providerRegistered.push("sql");
} }
} }

View File

@@ -48,7 +48,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
public componentDidUpdate(previous: EditorReactProps) { public componentDidUpdate(previous: EditorReactProps) {
if (this.props.content !== previous.content) { if (this.props.content !== previous.content) {
this.editor.setValue(this.props.content); this.editor?.setValue(this.props.content);
} }
} }
@@ -93,7 +93,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
* Create the monaco editor and attach to DOM * Create the monaco editor and attach to DOM
*/ */
private async createEditor(createCallback: (e: monaco.editor.IStandaloneCodeEditor) => void) { private async createEditor(createCallback: (e: monaco.editor.IStandaloneCodeEditor) => void) {
const options: monaco.editor.IEditorConstructionOptions = { const options: monaco.editor.IStandaloneEditorConstructionOptions = {
language: this.props.language, language: this.props.language,
value: this.props.content, value: this.props.content,
readOnly: this.props.isReadOnly, readOnly: this.props.isReadOnly,
@@ -111,7 +111,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
this.rootNode.innerHTML = ""; this.rootNode.innerHTML = "";
const monaco = await loadMonaco(); const monaco = await loadMonaco();
createCallback(monaco.editor.create(this.rootNode, options)); createCallback(monaco?.editor?.create(this.rootNode, options));
if (this.rootNode.innerHTML) { if (this.rootNode.innerHTML) {
this.setState({ this.setState({

View File

@@ -90,7 +90,7 @@ export class JsonEditorViewModel extends WaitsForTemplateViewModel {
protected async createEditor(content: string, createCallback: (e: monaco.editor.IStandaloneCodeEditor) => void) { protected async createEditor(content: string, createCallback: (e: monaco.editor.IStandaloneCodeEditor) => void) {
this.registerCompletionItemProvider(); this.registerCompletionItemProvider();
this.editorContainer = document.getElementById(this.getEditorId()); this.editorContainer = document.getElementById(this.getEditorId());
const options: monaco.editor.IEditorConstructionOptions = { const options: monaco.editor.IStandaloneEditorConstructionOptions = {
value: content, value: content,
language: this.getEditorLanguage(), language: this.getEditorLanguage(),
readOnly: this.params.isReadOnly, readOnly: this.params.isReadOnly,

View File

@@ -29,6 +29,6 @@ describe("CodeOfConduct", () => {
const wrapper = shallow(<CodeOfConduct {...codeOfConductProps} />); const wrapper = shallow(<CodeOfConduct {...codeOfConductProps} />);
wrapper.find(".genericPaneSubmitBtn").first().simulate("click"); wrapper.find(".genericPaneSubmitBtn").first().simulate("click");
await Promise.resolve(); await Promise.resolve();
expect(codeOfConductProps.onAcceptCodeOfConduct).toBeCalled(); expect(codeOfConductProps.onAcceptCodeOfConduct).toHaveBeenCalled();
}); });
}); });

View File

@@ -9,7 +9,7 @@ import { updateUserContext } from "../../../UserContext";
import Explorer from "../../Explorer"; import Explorer from "../../Explorer";
import { CollectionSettingsTabV2 } from "../../Tabs/SettingsTabV2"; import { CollectionSettingsTabV2 } from "../../Tabs/SettingsTabV2";
import { SettingsComponent, SettingsComponentProps, SettingsComponentState } from "./SettingsComponent"; import { SettingsComponent, SettingsComponentProps, SettingsComponentState } from "./SettingsComponent";
import { isDirty, TtlType } from "./SettingsUtils"; import { TtlType, isDirty } from "./SettingsUtils";
import { collection } from "./TestUtils"; import { collection } from "./TestUtils";
jest.mock("../../../Common/dataAccess/getIndexTransformationProgress", () => ({ jest.mock("../../../Common/dataAccess/getIndexTransformationProgress", () => ({
getIndexTransformationProgress: jest.fn().mockReturnValue(undefined), getIndexTransformationProgress: jest.fn().mockReturnValue(undefined),
@@ -190,8 +190,8 @@ describe("SettingsComponent", () => {
id: "id", id: "id",
}; };
await settingsComponentInstance.onSaveClick(); await settingsComponentInstance.onSaveClick();
expect(updateCollection).toBeCalled(); expect(updateCollection).toHaveBeenCalled();
expect(updateOffer).toBeCalled(); expect(updateOffer).toHaveBeenCalled();
}); });
it("revert resets state values", async () => { it("revert resets state values", async () => {

View File

@@ -1,8 +1,8 @@
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import React from "react"; import React from "react";
import { renderToString } from "react-dom/server";
import { MongoIndexTypes, MongoNotificationMessage, MongoNotificationType } from "../../SettingsUtils"; import { MongoIndexTypes, MongoNotificationMessage, MongoNotificationType } from "../../SettingsUtils";
import { MongoIndexingPolicyComponent, MongoIndexingPolicyComponentProps } from "./MongoIndexingPolicyComponent"; import { MongoIndexingPolicyComponent, MongoIndexingPolicyComponentProps } from "./MongoIndexingPolicyComponent";
import { renderToString } from "react-dom/server";
describe("MongoIndexingPolicyComponent", () => { describe("MongoIndexingPolicyComponent", () => {
const baseProps: MongoIndexingPolicyComponentProps = { const baseProps: MongoIndexingPolicyComponentProps = {
@@ -84,7 +84,7 @@ describe("MongoIndexingPolicyComponent", () => {
]; ];
test.each(cases)( test.each(cases)(
"", "mongo indexing policy saveable and discardable",
( (
notification: MongoNotificationMessage, notification: MongoNotificationMessage,
indexToDropIsPresent: boolean, indexToDropIsPresent: boolean,
@@ -111,8 +111,10 @@ describe("MongoIndexingPolicyComponent", () => {
); );
if (mongoWarningNotificationMessage) { if (mongoWarningNotificationMessage) {
const elementAsString = renderToString(mongoIndexingPolicyComponent.getMongoWarningNotificationMessage()); const elementAsString = renderToString(mongoIndexingPolicyComponent.getMongoWarningNotificationMessage());
// eslint-disable-next-line jest/no-conditional-expect
expect(elementAsString).toContain(mongoWarningNotificationMessage); expect(elementAsString).toContain(mongoWarningNotificationMessage);
} else { } else {
// eslint-disable-next-line jest/no-conditional-expect
expect(mongoIndexingPolicyComponent.getMongoWarningNotificationMessage()).toBeUndefined(); expect(mongoIndexingPolicyComponent.getMongoWarningNotificationMessage()).toBeUndefined();
} }
}, },

View File

@@ -23,12 +23,12 @@ describe("ThroughputInput Pane", () => {
}); });
it("should switch mode properly", () => { it("should switch mode properly", () => {
wrapper.find('[aria-label="Manual database throughput"]').simulate("change"); wrapper.find('[id="Manual-input"]').simulate("change");
expect(wrapper.find('[aria-label="Throughput header"]').at(0).text()).toBe( expect(wrapper.find('[aria-label="Throughput header"]').at(0).text()).toBe(
"Container throughput (400 - unlimited RU/s)", "Container throughput (400 - unlimited RU/s)",
); );
wrapper.find('[aria-label="Autoscale database throughput"]').simulate("change"); wrapper.find('[id="Autoscale-input"]').simulate("change");
expect(wrapper.find('[aria-label="Throughput header"]').at(0).text()).toBe("Container throughput (autoscale)"); expect(wrapper.find('[aria-label="Throughput header"]').at(0).text()).toBe("Container throughput (autoscale)");
}); });
}); });

View File

@@ -189,7 +189,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
<input <input
id="Autoscale-input" id="Autoscale-input"
className="throughputInputRadioBtn" className="throughputInputRadioBtn"
aria-label="Autoscale database throughput" aria-label={`${getThroughputLabelText()} Autoscale`}
aria-required={true} aria-required={true}
checked={isAutoscaleSelected} checked={isAutoscaleSelected}
type="radio" type="radio"
@@ -204,7 +204,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
<input <input
id="Manual-input" id="Manual-input"
className="throughputInputRadioBtn" className="throughputInputRadioBtn"
aria-label="Manual database throughput" aria-label={`${getThroughputLabelText()} Manual`}
checked={!isAutoscaleSelected} checked={!isAutoscaleSelected}
type="radio" type="radio"
aria-required={true} aria-required={true}
@@ -271,11 +271,17 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
<Stack className="throughputInputSpacing"> <Stack className="throughputInputSpacing">
<Text variant="small" aria-label="ruDescription"> <Text variant="small" aria-label="ruDescription">
Estimate your required RU/s with&nbsp; Estimate your required RU/s with&nbsp;
<Link target="_blank" href="https://cosmos.azure.com/capacitycalculator/" aria-label="capacityLink"> <Link target="_blank" href="https://cosmos.azure.com/capacitycalculator/" aria-label="Capacity calculator">
capacity calculator capacity calculator
</Link> </Link>
. .
</Text> </Text>
<Stack horizontal>
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }} aria-label="maxRUDescription">
{isDatabase ? "Database" : getCollectionName()} Required RU/s
</Text>
<InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip>
</Stack>
<TooltipHost <TooltipHost
directionalHint={DirectionalHint.topLeftEdge} directionalHint={DirectionalHint.topLeftEdge}
@@ -296,7 +302,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
min={SharedConstants.CollectionCreation.DefaultCollectionRUs400} min={SharedConstants.CollectionCreation.DefaultCollectionRUs400}
max={userContext.isTryCosmosDBSubscription ? Constants.TryCosmosExperience.maxRU : Infinity} max={userContext.isTryCosmosDBSubscription ? Constants.TryCosmosExperience.maxRU : Infinity}
value={throughput.toString()} value={throughput.toString()}
aria-label="Max request units per second" ariaLabel={`${isDatabase ? "Database" : getCollectionName()} Required RU/s`}
required={true} required={true}
errorMessage={throughputError} errorMessage={throughputError}
/> />

View File

@@ -18,17 +18,17 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
horizontal={true} horizontal={true}
> >
<div <div
className="ms-Stack css-53" className="ms-Stack css-109"
> >
<span <span
className="mandatoryStar" className="mandatoryStar"
key=".0:$.0" key=".0:$.$.0"
> >
*  * 
</span> </span>
<Text <Text
aria-label="Throughput header" aria-label="Throughput header"
key=".0:$.1" key=".0:$.$.1"
style={ style={
Object { Object {
"fontWeight": 600, "fontWeight": 600,
@@ -39,7 +39,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
> >
<span <span
aria-label="Throughput header" aria-label="Throughput header"
className="css-54" className="css-110"
style={ style={
Object { Object {
"fontWeight": 600, "fontWeight": 600,
@@ -51,7 +51,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
</span> </span>
</Text> </Text>
<InfoTooltip <InfoTooltip
key=".0:$.2" key=".0:$.$.2"
> >
<span> <span>
<StyledTooltipHostBase <StyledTooltipHostBase
@@ -336,12 +336,13 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
} }
> >
<div <div
className="ms-TooltipHost root-55" className="ms-TooltipHost root-111"
onBlurCapture={[Function]} onBlurCapture={[Function]}
onFocusCapture={[Function]} onFocusCapture={[Function]}
onKeyDown={[Function]} onKeyDown={[Function]}
onMouseEnter={[Function]} onMouseEnter={[Function]}
onMouseLeave={[Function]} onMouseLeave={[Function]}
role="none"
> >
<StyledIconBase <StyledIconBase
ariaLabel="Set the throughput — Request Units per second (RU/s) — required for the workload. A read of a 1 KB document uses 1 RU. Select manual if you plan to scale RU/s yourself. Select autoscale to allow the system to scale RU/s based on usage." ariaLabel="Set the throughput — Request Units per second (RU/s) — required for the workload. A read of a 1 KB document uses 1 RU. Select manual if you plan to scale RU/s yourself. Select autoscale to allow the system to scale RU/s based on usage."
@@ -631,7 +632,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
> >
<i <i
aria-label="Set the throughput — Request Units per second (RU/s) — required for the workload. A read of a 1 KB document uses 1 RU. Select manual if you plan to scale RU/s yourself. Select autoscale to allow the system to scale RU/s based on usage." aria-label="Set the throughput — Request Units per second (RU/s) — required for the workload. A read of a 1 KB document uses 1 RU. Select manual if you plan to scale RU/s yourself. Select autoscale to allow the system to scale RU/s based on usage."
className="panelInfoIcon root-57" className="panelInfoIcon root-114"
data-icon-name="Info" data-icon-name="Info"
role="img" role="img"
tabIndex={0} tabIndex={0}
@@ -640,6 +641,24 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
</i> </i>
</IconBase> </IconBase>
</StyledIconBase> </StyledIconBase>
<div
hidden={true}
id="tooltip0"
style={
Object {
"border": 0,
"height": 1,
"margin": -1,
"overflow": "hidden",
"padding": 0,
"position": "absolute",
"whiteSpace": "nowrap",
"width": 1,
}
}
>
Set the throughput — Request Units per second (RU/s) — required for the workload. A read of a 1 KB document uses 1 RU. Select manual if you plan to scale RU/s yourself. Select autoscale to allow the system to scale RU/s based on usage.
</div>
</div> </div>
</TooltipHostBase> </TooltipHostBase>
</StyledTooltipHostBase> </StyledTooltipHostBase>
@@ -652,14 +671,14 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
verticalAlign="center" verticalAlign="center"
> >
<div <div
className="ms-Stack css-58" className="ms-Stack css-115"
> >
<div <div
key=".0:$.0" key=".0:$.$.0"
role="radiogroup" role="radiogroup"
> >
<input <input
aria-label="Autoscale database throughput" aria-label="Container throughput (autoscale) Autoscale"
aria-required={true} aria-required={true}
checked={true} checked={true}
className="throughputInputRadioBtn" className="throughputInputRadioBtn"
@@ -676,7 +695,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
Autoscale Autoscale
</label> </label>
<input <input
aria-label="Manual database throughput" aria-label="Container throughput (autoscale) Manual"
aria-required={true} aria-required={true}
checked={false} checked={false}
className="throughputInputRadioBtn" className="throughputInputRadioBtn"
@@ -699,16 +718,16 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
className="throughputInputSpacing" className="throughputInputSpacing"
> >
<div <div
className="ms-Stack throughputInputSpacing css-59" className="ms-Stack throughputInputSpacing css-116"
> >
<Text <Text
aria-label="capacity calculator of azure cosmos db" aria-label="capacity calculator of azure cosmos db"
key=".0:$.0" key=".0:$.$.0"
variant="small" variant="small"
> >
<span <span
aria-label="capacity calculator of azure cosmos db" aria-label="capacity calculator of azure cosmos db"
className="css-54" className="css-110"
> >
Estimate your required RU/s with Estimate your required RU/s with
@@ -998,7 +1017,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
> >
<a <a
aria-label="capacity calculator of azure cosmos db" aria-label="capacity calculator of azure cosmos db"
className="ms-Link root-60" className="ms-Link root-117"
href="https://cosmos.azure.com/capacitycalculator/" href="https://cosmos.azure.com/capacitycalculator/"
onClick={[Function]} onClick={[Function]}
target="_blank" target="_blank"
@@ -1012,14 +1031,14 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
</Text> </Text>
<Stack <Stack
horizontal={true} horizontal={true}
key=".0:$.1" key=".0:$.$.1"
> >
<div <div
className="ms-Stack css-53" className="ms-Stack css-109"
> >
<Text <Text
aria-label="maxRUDescription" aria-label="maxRUDescription"
key=".0:$.0" key=".0:$.$.0"
style={ style={
Object { Object {
"fontWeight": 600, "fontWeight": 600,
@@ -1030,7 +1049,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
> >
<span <span
aria-label="maxRUDescription" aria-label="maxRUDescription"
className="css-54" className="css-110"
style={ style={
Object { Object {
"fontWeight": 600, "fontWeight": 600,
@@ -1043,7 +1062,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
</span> </span>
</Text> </Text>
<InfoTooltip <InfoTooltip
key=".0:$.1" key=".0:$.$.1"
> >
<span> <span>
<StyledTooltipHostBase <StyledTooltipHostBase
@@ -1328,12 +1347,13 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
} }
> >
<div <div
className="ms-TooltipHost root-55" className="ms-TooltipHost root-111"
onBlurCapture={[Function]} onBlurCapture={[Function]}
onFocusCapture={[Function]} onFocusCapture={[Function]}
onKeyDown={[Function]} onKeyDown={[Function]}
onMouseEnter={[Function]} onMouseEnter={[Function]}
onMouseLeave={[Function]} onMouseLeave={[Function]}
role="none"
> >
<StyledIconBase <StyledIconBase
ariaLabel="Set the max RU/s to the highest RU/s you want your container to scale to. The container will scale between 10% of max RU/s to the max RU/s based on usage." ariaLabel="Set the max RU/s to the highest RU/s you want your container to scale to. The container will scale between 10% of max RU/s to the max RU/s based on usage."
@@ -1623,7 +1643,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
> >
<i <i
aria-label="Set the max RU/s to the highest RU/s you want your container to scale to. The container will scale between 10% of max RU/s to the max RU/s based on usage." aria-label="Set the max RU/s to the highest RU/s you want your container to scale to. The container will scale between 10% of max RU/s to the max RU/s based on usage."
className="panelInfoIcon root-57" className="panelInfoIcon root-114"
data-icon-name="Info" data-icon-name="Info"
role="img" role="img"
tabIndex={0} tabIndex={0}
@@ -1632,6 +1652,24 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
</i> </i>
</IconBase> </IconBase>
</StyledIconBase> </StyledIconBase>
<div
hidden={true}
id="tooltip1"
style={
Object {
"border": 0,
"height": 1,
"margin": -1,
"overflow": "hidden",
"padding": 0,
"position": "absolute",
"whiteSpace": "nowrap",
"width": 1,
}
}
>
Set the max RU/s to the highest RU/s you want your container to scale to. The container will scale between 10% of max RU/s to the max RU/s based on usage.
</div>
</div> </div>
</TooltipHostBase> </TooltipHostBase>
</StyledTooltipHostBase> </StyledTooltipHostBase>
@@ -1643,7 +1681,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
ariaLabel="Container max RU/s" ariaLabel="Container max RU/s"
errorMessage="" errorMessage=""
id="autoscaleRUValueField" id="autoscaleRUValueField"
key=".0:$.2" key=".0:$.$.2"
max="9007199254740991" max="9007199254740991"
min={1000} min={1000}
onChange={[Function]} onChange={[Function]}
@@ -1953,18 +1991,18 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
value="4000" value="4000"
> >
<div <div
className="ms-TextField is-required root-62" className="ms-TextField is-required root-119"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
> >
<div <div
className="ms-TextField-fieldGroup fieldGroup-63" className="ms-TextField-fieldGroup fieldGroup-120"
> >
<input <input
aria-invalid={false} aria-invalid={false}
aria-label="Container max RU/s" aria-label="Container max RU/s"
className="ms-TextField-field field-64" className="ms-TextField-field field-121"
id="autoscaleRUValueField" id="autoscaleRUValueField"
max="9007199254740991" max="9007199254740991"
min={1000} min={1000}
@@ -1983,11 +2021,11 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
</TextFieldBase> </TextFieldBase>
</StyledTextFieldBase> </StyledTextFieldBase>
<Text <Text
key=".0:$.3" key=".0:$.$.3"
variant="small" variant="small"
> >
<span <span
className="css-54" className="css-110"
> >
Your Your
container container

View File

@@ -59,6 +59,10 @@
} }
} }
[data-test="Gallery"]{
outline-offset: -1px;
}
.selected { .selected {
& > .treeNodeHeader { & > .treeNodeHeader {
background-color: @AccentExtra; background-color: @AccentExtra;

View File

@@ -3,7 +3,10 @@ import { isPublicInternetAccessAllowed } from "Common/DatabaseAccountUtility";
import { sendMessage } from "Common/MessageHandler"; import { sendMessage } from "Common/MessageHandler";
import { Platform, configContext } from "ConfigContext"; import { Platform, configContext } from "ConfigContext";
import { MessageTypes } from "Contracts/ExplorerContracts"; import { MessageTypes } from "Contracts/ExplorerContracts";
import { getCopilotEnabled, isCopilotFeatureRegistered } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
import { IGalleryItem } from "Juno/JunoClient"; import { IGalleryItem } from "Juno/JunoClient";
import { requestDatabaseResourceTokens } from "Platform/Fabric/FabricUtil";
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointValidation"; import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointValidation";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useQueryCopilot } from "hooks/useQueryCopilot";
import * as ko from "knockout"; import * as ko from "knockout";
@@ -91,7 +94,7 @@ export default class Explorer {
}; };
private static readonly MaxNbDatabasesToAutoExpand = 5; private static readonly MaxNbDatabasesToAutoExpand = 5;
private phoenixClient: PhoenixClient; public phoenixClient: PhoenixClient;
constructor() { constructor() {
const startKey: number = TelemetryProcessor.traceStart(Action.InitializeDataExplorer, { const startKey: number = TelemetryProcessor.traceStart(Action.InitializeDataExplorer, {
dataExplorerArea: Constants.Areas.ResourceTree, dataExplorerArea: Constants.Areas.ResourceTree,
@@ -273,6 +276,7 @@ export default class Explorer {
const NINETY_DAYS_IN_MS = 7776000000; const NINETY_DAYS_IN_MS = 7776000000;
const ONE_DAY_IN_MS = 86400000; const ONE_DAY_IN_MS = 86400000;
const THREE_DAYS_IN_MS = 259200000;
const isAccountNewerThanNinetyDays = isAccountNewerThanThresholdInMs( const isAccountNewerThanNinetyDays = isAccountNewerThanThresholdInMs(
userContext.databaseAccount?.systemData?.createdAt || "", userContext.databaseAccount?.systemData?.createdAt || "",
NINETY_DAYS_IN_MS, NINETY_DAYS_IN_MS,
@@ -292,32 +296,32 @@ export default class Explorer {
} }
} }
// Try Cosmos DB subscription - survey shown to random 25% of users at day 1 in Data Explorer. // Try Cosmos DB subscription - survey shown to 100% of users at day 1 in Data Explorer.
if (userContext.isTryCosmosDBSubscription) { if (userContext.isTryCosmosDBSubscription) {
if ( if (isAccountNewerThanThresholdInMs(userContext.databaseAccount?.systemData?.createdAt || "", ONE_DAY_IN_MS)) {
isAccountNewerThanThresholdInMs(userContext.databaseAccount?.systemData?.createdAt || "", ONE_DAY_IN_MS) && this.sendNPSMessage();
this.getRandomInt(100) < 25
) {
sendMessage({ type: MessageTypes.DisplayNPSSurvey });
localStorage.setItem("lastSubmitted", Date.now().toString());
} }
} else { } else {
// An existing account is lesser than 90 days old. For existing account show to random 10 % of users in Data Explorer. // An existing account is older than 3 days but less than 90 days old. For existing account show to 100% of users in Data Explorer.
if (isAccountNewerThanNinetyDays) { if (
if (this.getRandomInt(100) < 10) { !isAccountNewerThanThresholdInMs(userContext.databaseAccount?.systemData?.createdAt || "", THREE_DAYS_IN_MS) &&
sendMessage({ type: MessageTypes.DisplayNPSSurvey }); isAccountNewerThanNinetyDays
localStorage.setItem("lastSubmitted", Date.now().toString()); ) {
} this.sendNPSMessage();
} else { } else {
// An existing account is greater than 90 days. For existing account show to random 25 % of users in Data Explorer. // An existing account is greater than 90 days. For existing account show to random 33% of users in Data Explorer.
if (this.getRandomInt(100) < 25) { if (this.getRandomInt(100) < 33) {
sendMessage({ type: MessageTypes.DisplayNPSSurvey }); this.sendNPSMessage();
localStorage.setItem("lastSubmitted", Date.now().toString());
} }
} }
} }
} }
private sendNPSMessage() {
sendMessage({ type: MessageTypes.DisplayNPSSurvey });
localStorage.setItem("lastSubmitted", Date.now().toString());
}
public async refreshDatabaseForResourceToken(): Promise<void> { public async refreshDatabaseForResourceToken(): Promise<void> {
const databaseId = userContext.parsedResourceToken?.databaseId; const databaseId = userContext.parsedResourceToken?.databaseId;
const collectionId = userContext.parsedResourceToken?.collectionId; const collectionId = userContext.parsedResourceToken?.collectionId;
@@ -379,6 +383,13 @@ export default class Explorer {
}; };
public onRefreshResourcesClick = (): void => { public onRefreshResourcesClick = (): void => {
if (configContext.platform === Platform.Fabric) {
// Requesting the tokens will trigger a refresh of the databases
// TODO: Once the id is returned from Fabric, we can await this call and then refresh the databases here
requestDatabaseResourceTokens();
return;
}
userContext.authType === AuthType.ResourceToken userContext.authType === AuthType.ResourceToken
? this.refreshDatabaseForResourceToken() ? this.refreshDatabaseForResourceToken()
: this.refreshAllDatabases(); : this.refreshAllDatabases();
@@ -403,7 +414,7 @@ export default class Explorer {
this._isInitializingNotebooks = false; this._isInitializingNotebooks = false;
} }
public async allocateContainer(poolId: PoolIdType): Promise<void> { public async allocateContainer(poolId: PoolIdType, mode?: string): Promise<void> {
const shouldUseNotebookStates = poolId === PoolIdType.DefaultPoolId ? true : false; const shouldUseNotebookStates = poolId === PoolIdType.DefaultPoolId ? true : false;
const notebookServerInfo = shouldUseNotebookStates const notebookServerInfo = shouldUseNotebookStates
? useNotebook.getState().notebookServerInfo ? useNotebook.getState().notebookServerInfo
@@ -417,10 +428,6 @@ export default class Explorer {
(notebookServerInfo === undefined || (notebookServerInfo === undefined ||
(notebookServerInfo && notebookServerInfo.notebookServerEndpoint === undefined)) (notebookServerInfo && notebookServerInfo.notebookServerEndpoint === undefined))
) { ) {
const provisionData: IProvisionData = {
cosmosEndpoint: userContext?.databaseAccount?.properties?.documentEndpoint,
poolId: shouldUseNotebookStates ? undefined : poolId,
};
const connectionStatus: ContainerConnectionInfo = { const connectionStatus: ContainerConnectionInfo = {
status: ConnectionStatusType.Connecting, status: ConnectionStatusType.Connecting,
}; };
@@ -428,14 +435,26 @@ export default class Explorer {
shouldUseNotebookStates && useNotebook.getState().setConnectionInfo(connectionStatus); shouldUseNotebookStates && useNotebook.getState().setConnectionInfo(connectionStatus);
let connectionInfo; let connectionInfo;
let provisionData: IProvisionData;
try { try {
TelemetryProcessor.traceStart(Action.PhoenixConnection, { TelemetryProcessor.traceStart(Action.PhoenixConnection, {
dataExplorerArea: Areas.Notebook, dataExplorerArea: Areas.Notebook,
}); });
shouldUseNotebookStates if (shouldUseNotebookStates) {
? useNotebook.getState().setIsAllocating(true) useNotebook.getState().setIsAllocating(true);
: useQueryCopilot.getState().setIsAllocatingContainer(true); provisionData = {
cosmosEndpoint: userContext?.databaseAccount?.properties?.documentEndpoint,
poolId: undefined,
};
} else {
useQueryCopilot.getState().setIsAllocatingContainer(true);
provisionData = {
poolId: poolId,
databaseId: useTabs.getState().activeTab.collection.databaseId,
containerId: useTabs.getState().activeTab.collection.id(),
mode: mode,
};
}
connectionInfo = await this.phoenixClient.allocateContainer(provisionData); connectionInfo = await this.phoenixClient.allocateContainer(provisionData);
if (!connectionInfo?.data?.phoenixServiceUrl) { if (!connectionInfo?.data?.phoenixServiceUrl) {
throw new Error(`PhoenixServiceUrl is invalid!`); throw new Error(`PhoenixServiceUrl is invalid!`);
@@ -451,19 +470,21 @@ export default class Explorer {
error: getErrorMessage(error), error: getErrorMessage(error),
errorStack: getErrorStack(error), errorStack: getErrorStack(error),
}); });
connectionStatus.status = ConnectionStatusType.Failed; if (shouldUseNotebookStates) {
shouldUseNotebookStates connectionStatus.status = ConnectionStatusType.Failed;
? useNotebook.getState().resetContainerConnection(connectionStatus) shouldUseNotebookStates
: useQueryCopilot.getState().resetContainerConnection(); ? useNotebook.getState().resetContainerConnection(connectionStatus)
if (error?.status === HttpStatusCodes.Forbidden && error.message) { : useQueryCopilot.getState().resetContainerConnection();
useDialog.getState().showOkModalDialog("Connection Failed", `${error.message}`); if (error?.status === HttpStatusCodes.Forbidden && error.message) {
} else { useDialog.getState().showOkModalDialog("Connection Failed", `${error.message}`);
useDialog } else {
.getState() useDialog
.showOkModalDialog( .getState()
"Connection Failed", .showOkModalDialog(
"We are unable to connect to the temporary workspace. Please try again in a few minutes. If the error persists, file a support ticket.", "Connection Failed",
); "We are unable to connect to the temporary workspace. Please try again in a few minutes. If the error persists, file a support ticket.",
);
}
} }
throw error; throw error;
} finally { } finally {
@@ -477,11 +498,11 @@ export default class Explorer {
} }
} }
private async setNotebookInfo( public async setNotebookInfo(
shouldUseNotebookStates: boolean, shouldUseNotebookStates: boolean,
connectionInfo: IResponse<IPhoenixServiceInfo>, connectionInfo: IResponse<IPhoenixServiceInfo>,
connectionStatus: DataModels.ContainerConnectionInfo, connectionStatus: DataModels.ContainerConnectionInfo,
) { ): Promise<void> {
const containerData = { const containerData = {
forwardingId: connectionInfo.data.forwardingId, forwardingId: connectionInfo.data.forwardingId,
dbAccountName: userContext.databaseAccount.name, dbAccountName: userContext.databaseAccount.name,
@@ -502,6 +523,7 @@ export default class Explorer {
shouldUseNotebookStates shouldUseNotebookStates
? useNotebook.getState().setNotebookServerInfo(noteBookServerInfo) ? useNotebook.getState().setNotebookServerInfo(noteBookServerInfo)
: useQueryCopilot.getState().setNotebookServerInfo(noteBookServerInfo); : useQueryCopilot.getState().setNotebookServerInfo(noteBookServerInfo);
shouldUseNotebookStates && shouldUseNotebookStates &&
this.notebookManager?.notebookClient this.notebookManager?.notebookClient
.getMemoryUsage() .getMemoryUsage()
@@ -1364,6 +1386,24 @@ export default class Explorer {
await this.refreshSampleData(); await this.refreshSampleData();
} }
public async configureCopilot(): Promise<void> {
if (userContext.apiType !== "SQL" || !userContext.subscriptionId) {
return;
}
const copilotEnabledPromise = getCopilotEnabled();
const copilotUserDBEnabledPromise = isCopilotFeatureRegistered(userContext.subscriptionId);
const [copilotEnabled, copilotUserDBEnabled] = await Promise.all([
copilotEnabledPromise,
copilotUserDBEnabledPromise,
]);
const copilotSampleDBEnabled = LocalStorageUtility.getEntryString(StorageKey.CopilotSampleDBEnabled) === "true";
useQueryCopilot.getState().setCopilotEnabled(copilotEnabled && copilotUserDBEnabled);
useQueryCopilot.getState().setCopilotUserDBEnabled(copilotUserDBEnabled);
useQueryCopilot
.getState()
.setCopilotSampleDBEnabled(copilotEnabled && copilotUserDBEnabled && copilotSampleDBEnabled);
}
public async refreshSampleData(): Promise<void> { public async refreshSampleData(): Promise<void> {
if (!userContext.sampleDataConnectionInfo) { if (!userContext.sampleDataConnectionInfo) {
return; return;

View File

@@ -367,7 +367,7 @@ describe("GraphExplorer", () => {
}); });
it("should submit g.V() as docdb query with proper parameters", () => { it("should submit g.V() as docdb query with proper parameters", () => {
expect(queryDocuments).toBeCalledWith("databaseId", "collectionId", DOCDB_G_DOT_V_QUERY, { expect(queryDocuments).toHaveBeenCalledWith("databaseId", "collectionId", DOCDB_G_DOT_V_QUERY, {
maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE, maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE,
enableCrossPartitionQuery: true, enableCrossPartitionQuery: true,
}); });
@@ -404,7 +404,7 @@ describe("GraphExplorer", () => {
}); });
it("should submit g.V() as docdb query with proper parameters", () => { it("should submit g.V() as docdb query with proper parameters", () => {
expect(queryDocuments).toBeCalledWith("databaseId", "collectionId", DOCDB_G_DOT_V_QUERY, { expect(queryDocuments).toHaveBeenCalledWith("databaseId", "collectionId", DOCDB_G_DOT_V_QUERY, {
maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE, maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE,
enableCrossPartitionQuery: true, enableCrossPartitionQuery: true,
}); });

View File

@@ -1163,15 +1163,12 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
)}"`, )}"`,
).then( ).then(
(documents: DataModels.DocumentId[]) => { (documents: DataModels.DocumentId[]) => {
$.each( $.each(documents, (index: number, doc: any) => {
documents, newIconsMap[doc["_graph_icon_property_value"]] = {
(index: number, doc: { _graph_icon_property_value: string; icon: string; format: string }) => { data: doc["icon"],
newIconsMap[doc["_graph_icon_property_value"]] = { format: doc["format"],
data: doc["icon"], };
format: doc["format"], });
};
},
);
// Update graph configuration // Update graph configuration
this.setState({ this.setState({

View File

@@ -43,7 +43,7 @@ describe("Graph Style Component", () => {
expect(asFragment).toMatchSnapshot(); expect(asFragment).toMatchSnapshot();
}); });
it("should render node properties dropdown list ", () => { it("should render node properties dropdown list", () => {
const dropDownList = screen.getByText("Show vertex (node) as"); const dropDownList = screen.getByText("Show vertex (node) as");
expect(dropDownList).toBeDefined(); expect(dropDownList).toBeDefined();
}); });

View File

@@ -345,7 +345,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
describe("Open Postgres and vCore Mongo buttons", () => { describe("Open Postgres and vCore Mongo buttons", () => {
const openPostgresShellButtonLabel = "Open PSQL shell"; const openPostgresShellButtonLabel = "Open PSQL shell";
const openVCoreMongoShellButtonLabel = "Open MongoDB (vcore) shell"; const openVCoreMongoShellButtonLabel = "Open MongoDB (vCore) shell";
beforeAll(() => { beforeAll(() => {
mockExplorer = {} as Explorer; mockExplorer = {} as Explorer;

View File

@@ -1,6 +1,3 @@
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
import { ReactTabKind, useTabs } from "hooks/useTabs";
import * as React from "react"; import * as React from "react";
import AddCollectionIcon from "../../../../images/AddCollection.svg"; import AddCollectionIcon from "../../../../images/AddCollection.svg";
import AddDatabaseIcon from "../../../../images/AddDatabase.svg"; import AddDatabaseIcon from "../../../../images/AddDatabase.svg";
@@ -50,31 +47,36 @@ export function createStaticCommandBarButtons(
return createStaticCommandBarButtonsForResourceToken(container, selectedNodeState); return createStaticCommandBarButtonsForResourceToken(container, selectedNodeState);
} }
const newCollectionBtn = createNewCollectionGroup(container);
const buttons: CommandButtonComponentProps[] = []; const buttons: CommandButtonComponentProps[] = [];
buttons.push(newCollectionBtn); // Avoid starting with a divider
if ( const addDivider = () => {
configContext.platform !== Platform.Fabric && if (buttons.length > 0) {
userContext.apiType !== "Tables" &&
userContext.apiType !== "Cassandra"
) {
const addSynapseLink = createOpenSynapseLinkDialogButton(container);
if (addSynapseLink) {
buttons.push(createDivider()); buttons.push(createDivider());
buttons.push(addSynapseLink); }
};
if (configContext.platform !== Platform.Fabric) {
const newCollectionBtn = createNewCollectionGroup(container);
buttons.push(newCollectionBtn);
if (userContext.apiType !== "Tables" && userContext.apiType !== "Cassandra") {
const addSynapseLink = createOpenSynapseLinkDialogButton(container);
if (addSynapseLink) {
addDivider();
buttons.push(addSynapseLink);
}
}
if (userContext.apiType !== "Tables") {
newCollectionBtn.children = [createNewCollectionGroup(container)];
const newDatabaseBtn = createNewDatabase(container);
newCollectionBtn.children.push(newDatabaseBtn);
} }
} }
if (userContext.apiType !== "Tables" && configContext.platform !== Platform.Fabric) {
newCollectionBtn.children = [createNewCollectionGroup(container)];
const newDatabaseBtn = createNewDatabase(container);
newCollectionBtn.children.push(newDatabaseBtn);
}
if (useNotebook.getState().isNotebookEnabled) { if (useNotebook.getState().isNotebookEnabled) {
buttons.push(createDivider()); addDivider();
const notebookButtons: CommandButtonComponentProps[] = []; const notebookButtons: CommandButtonComponentProps[] = [];
const newNotebookButton = createNewNotebookButton(container); const newNotebookButton = createNewNotebookButton(container);
@@ -128,7 +130,7 @@ export function createStaticCommandBarButtons(
const isQuerySupported = userContext.apiType === "SQL" || userContext.apiType === "Gremlin"; const isQuerySupported = userContext.apiType === "SQL" || userContext.apiType === "Gremlin";
if (isQuerySupported) { if (isQuerySupported) {
buttons.push(createDivider()); addDivider();
const newSqlQueryBtn = createNewSQLQueryButton(selectedNodeState); const newSqlQueryBtn = createNewSQLQueryButton(selectedNodeState);
buttons.push(newSqlQueryBtn); buttons.push(newSqlQueryBtn);
} }
@@ -198,7 +200,7 @@ export function createControlCommandBarButtons(container: Explorer): CommandButt
{ {
iconSrc: SettingsIcon, iconSrc: SettingsIcon,
iconAlt: "Settings", iconAlt: "Settings",
onCommandClick: () => useSidePanel.getState().openSidePanel("Settings", <SettingsPane />), onCommandClick: () => useSidePanel.getState().openSidePanel("Settings", <SettingsPane explorer={container} />),
commandButtonLabel: undefined, commandButtonLabel: undefined,
ariaLabel: "Settings", ariaLabel: "Settings",
tooltipText: "Settings", tooltipText: "Settings",
@@ -332,13 +334,8 @@ function createNewSQLQueryButton(selectedNodeState: SelectedNodeState): CommandB
iconSrc: AddSqlQueryIcon, iconSrc: AddSqlQueryIcon,
iconAlt: label, iconAlt: label,
onCommandClick: () => { onCommandClick: () => {
if (useSelectedNode.getState().isQueryCopilotCollectionSelected()) { const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection();
useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot); selectedCollection && selectedCollection.onNewQueryClick(selectedCollection);
traceOpen(Action.OpenQueryCopilotFromNewQuery, { apiType: userContext.apiType });
} else {
const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection();
selectedCollection && selectedCollection.onNewQueryClick(selectedCollection);
}
}, },
commandButtonLabel: label, commandButtonLabel: label,
ariaLabel: label, ariaLabel: label,
@@ -518,7 +515,7 @@ function createOpenTerminalButtonByKind(
case ViewModels.TerminalKind.Postgres: case ViewModels.TerminalKind.Postgres:
return "PSQL"; return "PSQL";
case ViewModels.TerminalKind.VCoreMongo: case ViewModels.TerminalKind.VCoreMongo:
return "MongoDB (vcore)"; return "MongoDB (vCore)";
default: default:
return ""; return "";
} }

View File

@@ -35,7 +35,7 @@ describe("CommandBarUtil tests", () => {
// Click gets called // Click gets called
converted.onClick(); converted.onClick();
expect(btn.onCommandClick).toBeCalled(); expect(btn.onCommandClick).toHaveBeenCalled();
}); });
it("should convert NavbarButtonConfig to split button", () => { it("should convert NavbarButtonConfig to split button", () => {

View File

@@ -6,6 +6,7 @@ import {
IDropdownOption, IDropdownOption,
IDropdownStyles, IDropdownStyles,
} from "@fluentui/react"; } from "@fluentui/react";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import * as React from "react"; import * as React from "react";
import _ from "underscore"; import _ from "underscore";
import ChevronDownIcon from "../../../../images/Chevron_down.svg"; import ChevronDownIcon from "../../../../images/Chevron_down.svg";
@@ -57,7 +58,11 @@ export const convertButton = (btns: CommandButtonComponentProps[], backgroundCol
}, },
onClick: (ev?: React.MouseEvent<HTMLElement, MouseEvent> | React.KeyboardEvent<HTMLElement>) => { onClick: (ev?: React.MouseEvent<HTMLElement, MouseEvent> | React.KeyboardEvent<HTMLElement>) => {
btn.onCommandClick(ev); btn.onCommandClick(ev);
TelemetryProcessor.trace(Action.ClickCommandBarButton, ActionModifiers.Mark, { label }); let copilotEnabled = false;
if (useQueryCopilot.getState().copilotEnabled && useQueryCopilot.getState().copilotUserDBEnabled) {
copilotEnabled = useQueryCopilot.getState().copilotEnabledforExecution;
}
TelemetryProcessor.trace(Action.ClickCommandBarButton, ActionModifiers.Mark, { label, copilotEnabled });
}, },
key: `${btn.commandButtonLabel}${index}`, key: `${btn.commandButtonLabel}${index}`,
text: label, text: label,

View File

@@ -1,14 +1,14 @@
import { makeNotebookRecord } from "@nteract/commutable";
import { actions, state } from "@nteract/core";
import * as Immutable from "immutable"; import * as Immutable from "immutable";
import { StateObservable } from "redux-observable"; import { StateObservable } from "redux-observable";
import { Subject, of } from "rxjs"; import { Subject, of } from "rxjs";
import { toArray } from "rxjs/operators"; import { toArray } from "rxjs/operators";
import { makeNotebookRecord } from "@nteract/commutable";
import { actions, state, epics } from "@nteract/core";
import * as sinon from "sinon"; import * as sinon from "sinon";
import { CdbAppState, makeCdbRecord } from "./types";
import { launchWebSocketKernelEpic } from "./epics";
import { NotebookUtil } from "../NotebookUtil"; import { NotebookUtil } from "../NotebookUtil";
import { launchWebSocketKernelEpic } from "./epics";
import { CdbAppState, makeCdbRecord } from "./types";
import { sessions } from "rx-jupyter"; import { sessions } from "rx-jupyter";
@@ -117,7 +117,7 @@ describe("launchWebSocketKernelEpic", () => {
const kernelRef = "fake"; const kernelRef = "fake";
it("launches remote kernels", async () => { it("launches remote kernels", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const cwd = "/"; const cwd = "/";
const kernelId = "123"; const kernelId = "123";
@@ -183,7 +183,7 @@ describe("launchWebSocketKernelEpic", () => {
}); });
it("launches any kernel with no kernelspecs in the state", async () => { it("launches any kernel with no kernelspecs in the state", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const cwd = "/"; const cwd = "/";
const kernelId = "123"; const kernelId = "123";
@@ -236,7 +236,7 @@ describe("launchWebSocketKernelEpic", () => {
}); });
it("launches no kernel if no kernel is specified and state has no kernelspecs", async () => { it("launches no kernel if no kernel is specified and state has no kernelspecs", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const cwd = "/"; const cwd = "/";
const kernelId = "123"; const kernelId = "123";
@@ -289,7 +289,7 @@ describe("launchWebSocketKernelEpic", () => {
}); });
it("emits an error if backend returns an error", async () => { it("emits an error if backend returns an error", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const cwd = "/"; const cwd = "/";
const action$ = of( const action$ = of(
@@ -388,7 +388,7 @@ describe("launchWebSocketKernelEpic", () => {
}); });
it("launches supported kernel in kernelspecs", async () => { it("launches supported kernel in kernelspecs", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const action$ = of( const action$ = of(
actions.launchKernelByName({ actions.launchKernelByName({
@@ -409,7 +409,7 @@ describe("launchWebSocketKernelEpic", () => {
}); });
it("launches undefined kernel uses default kernel from kernelspecs", async () => { it("launches undefined kernel uses default kernel from kernelspecs", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const action$ = of( const action$ = of(
actions.launchKernelByName({ actions.launchKernelByName({
@@ -431,7 +431,7 @@ describe("launchWebSocketKernelEpic", () => {
}); });
it("launches unsupported kernel uses default kernel from kernelspecs", async () => { it("launches unsupported kernel uses default kernel from kernelspecs", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const action$ = of( const action$ = of(
actions.launchKernelByName({ actions.launchKernelByName({
@@ -453,7 +453,7 @@ describe("launchWebSocketKernelEpic", () => {
}); });
it("launches unsupported kernel uses kernelspecs with similar name", async () => { it("launches unsupported kernel uses kernelspecs with similar name", async () => {
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState); const state$ = new StateObservable(new Subject<CdbAppState>() as any, initialState);
const action$ = of( const action$ = of(
actions.launchKernelByName({ actions.launchKernelByName({

View File

@@ -69,8 +69,8 @@ const addInitialCodeCellEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<{} | actions.CreateCellBelow> => { ): Observable<{} | actions.CreateCellBelow> => {
return action$.pipe( return action$.pipe(
ofType(actions.FETCH_CONTENT_FULFILLED), ofType(actions.FETCH_CONTENT_FULFILLED) as any,
mergeMap((action) => { mergeMap((action: any) => {
const state = state$.value; const state = state$.value;
const contentRef = action.payload.contentRef; const contentRef = action.payload.contentRef;
const model = selectors.model(state, { contentRef }); const model = selectors.model(state, { contentRef });
@@ -116,7 +116,7 @@ const formWebSocketURL = (serverConfig: NotebookServiceConfig, kernelId: string,
*/ */
export const acquireKernelInfoEpic = (action$: Observable<actions.NewKernelAction>) => { export const acquireKernelInfoEpic = (action$: Observable<actions.NewKernelAction>) => {
return action$.pipe( return action$.pipe(
ofType(actions.LAUNCH_KERNEL_SUCCESSFUL), ofType(actions.LAUNCH_KERNEL_SUCCESSFUL) as any,
switchMap((action: actions.NewKernelAction) => { switchMap((action: actions.NewKernelAction) => {
const { const {
payload: { payload: {
@@ -271,9 +271,9 @@ export const launchWebSocketKernelEpic = (
state$: StateObservable<CdbAppState>, state$: StateObservable<CdbAppState>,
) => { ) => {
return action$.pipe( return action$.pipe(
ofType(actions.LAUNCH_KERNEL_BY_NAME), ofType(actions.LAUNCH_KERNEL_BY_NAME) as any,
// Only accept jupyter servers for the host with this epic // Only accept jupyter servers for the host with this epic
filter(() => selectors.isCurrentHostJupyter(state$.value)), filter(() => selectors.isCurrentHostJupyter(state$.value as never)),
switchMap((action: actions.LaunchKernelByNameAction) => { switchMap((action: actions.LaunchKernelByNameAction) => {
const state = state$.value; const state = state$.value;
const host = selectors.currentHost(state); const host = selectors.currentHost(state);
@@ -382,7 +382,7 @@ export const restartWebSocketKernelEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
) => ) =>
action$.pipe( action$.pipe(
ofType(actions.RESTART_KERNEL), ofType(actions.RESTART_KERNEL) as any,
concatMap((action: actions.RestartKernel) => { concatMap((action: actions.RestartKernel) => {
const state = state$.value; const state = state$.value;
@@ -449,7 +449,7 @@ export const restartWebSocketKernelEpic = (
}); });
const awaitKernelReady = action$.pipe( const awaitKernelReady = action$.pipe(
ofType(actions.LAUNCH_KERNEL_SUCCESSFUL), ofType(actions.LAUNCH_KERNEL_SUCCESSFUL) as any,
filter((action: actions.NewKernelAction | actions.RestartKernel) => action.payload.kernelRef === newKernelRef), filter((action: actions.NewKernelAction | actions.RestartKernel) => action.payload.kernelRef === newKernelRef),
take(1), take(1),
timeout(60000), // If kernel doesn't come up within this interval we will abort follow-on actions. timeout(60000), // If kernel doesn't come up within this interval we will abort follow-on actions.
@@ -492,9 +492,9 @@ const changeWebSocketKernelEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
) => { ) => {
return action$.pipe( return action$.pipe(
ofType(actions.CHANGE_KERNEL_BY_NAME), ofType(actions.CHANGE_KERNEL_BY_NAME) as any,
// Only accept jupyter servers for the host with this epic // Only accept jupyter servers for the host with this epic
filter(() => selectors.isCurrentHostJupyter(state$.value)), filter(() => selectors.isCurrentHostJupyter(state$.value as never)),
switchMap((action: actions.ChangeKernelByName) => { switchMap((action: actions.ChangeKernelByName) => {
const { const {
payload: { contentRef, oldKernelRef, kernelSpecName }, payload: { contentRef, oldKernelRef, kernelSpecName },
@@ -574,8 +574,8 @@ const focusInitialCodeCellEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<{} | actions.FocusCell> => { ): Observable<{} | actions.FocusCell> => {
return action$.pipe( return action$.pipe(
ofType(actions.CREATE_CELL_APPEND), ofType(actions.CREATE_CELL_APPEND) as any,
mergeMap((action) => { mergeMap((action: any) => {
const state = state$.value; const state = state$.value;
const contentRef = action.payload.contentRef; const contentRef = action.payload.contentRef;
const model = selectors.model(state, { contentRef }); const model = selectors.model(state, { contentRef });
@@ -616,8 +616,8 @@ const notificationsToUserEpic = (action$: Observable<any>, state$: StateObservab
actions.SAVE_FULFILLED, actions.SAVE_FULFILLED,
actions.SAVE_FAILED, actions.SAVE_FAILED,
actions.FETCH_CONTENT_FAILED, actions.FETCH_CONTENT_FAILED,
), ) as any,
mergeMap((action) => { mergeMap((action: any) => {
switch (action.type) { switch (action.type) {
case actions.RESTART_KERNEL_SUCCESSFUL: { case actions.RESTART_KERNEL_SUCCESSFUL: {
const title = "Kernel restart"; const title = "Kernel restart";
@@ -662,8 +662,8 @@ const handleKernelConnectionLostEpic = (
state$: StateObservable<CdbAppState>, state$: StateObservable<CdbAppState>,
): Observable<CdbActions.UpdateKernelRestartDelayAction | actions.RestartKernel | {}> => { ): Observable<CdbActions.UpdateKernelRestartDelayAction | actions.RestartKernel | {}> => {
return action$.pipe( return action$.pipe(
ofType(actions.UPDATE_DISPLAY_FAILED), ofType(actions.UPDATE_DISPLAY_FAILED) as any,
mergeMap((action) => { mergeMap((action: any) => {
const state = state$.value; const state = state$.value;
const msg = "Notebook was disconnected from kernel"; const msg = "Notebook was disconnected from kernel";
@@ -721,8 +721,8 @@ export const cleanKernelOnConnectionLostEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<actions.KillKernelSuccessful> => { ): Observable<actions.KillKernelSuccessful> => {
return action$.pipe( return action$.pipe(
ofType(actions.UPDATE_DISPLAY_FAILED), ofType(actions.UPDATE_DISPLAY_FAILED) as any,
switchMap((action) => { switchMap((action: any) => {
const contentRef = action.payload.contentRef; const contentRef = action.payload.contentRef;
const kernelRef = selectors.kernelRefByContentRef(state$.value, { contentRef }); const kernelRef = selectors.kernelRefByContentRef(state$.value, { contentRef });
return of( return of(
@@ -744,8 +744,8 @@ const executeFocusedCellAndFocusNextEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<{} | actions.FocusNextCellEditor> => { ): Observable<{} | actions.FocusNextCellEditor> => {
return action$.pipe( return action$.pipe(
ofType(CdbActions.EXECUTE_FOCUSED_CELL_AND_FOCUS_NEXT), ofType(CdbActions.EXECUTE_FOCUSED_CELL_AND_FOCUS_NEXT) as any,
mergeMap((action) => { mergeMap((action: any) => {
const contentRef = action.payload.contentRef; const contentRef = action.payload.contentRef;
return concat( return concat(
of(actions.executeFocusedCell({ contentRef })), of(actions.executeFocusedCell({ contentRef })),
@@ -765,8 +765,8 @@ const closeUnsupportedMimetypesEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<{}> => { ): Observable<{}> => {
return action$.pipe( return action$.pipe(
ofType(actions.FETCH_CONTENT_FULFILLED), ofType(actions.FETCH_CONTENT_FULFILLED) as any,
mergeMap((action) => { mergeMap((action: any) => {
const mimetype = action.payload.model.mimetype; const mimetype = action.payload.model.mimetype;
if (!TextFile.handles(mimetype)) { if (!TextFile.handles(mimetype)) {
const filepath = action.payload.filepath; const filepath = action.payload.filepath;
@@ -796,8 +796,8 @@ const closeContentFailedToFetchEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<{}> => { ): Observable<{}> => {
return action$.pipe( return action$.pipe(
ofType(actions.FETCH_CONTENT_FAILED), ofType(actions.FETCH_CONTENT_FAILED) as any,
mergeMap((action) => { mergeMap((action: any) => {
const filepath = action.payload.filepath; const filepath = action.payload.filepath;
// Close tab and show error message // Close tab and show error message
useTabs useTabs
@@ -818,7 +818,7 @@ const traceNotebookTelemetryEpic = (
state$: StateObservable<CdbAppState>, state$: StateObservable<CdbAppState>,
): Observable<{}> => { ): Observable<{}> => {
return action$.pipe( return action$.pipe(
ofType(cdbActions.TRACE_NOTEBOOK_TELEMETRY), ofType(cdbActions.TRACE_NOTEBOOK_TELEMETRY) as any,
mergeMap((action: cdbActions.TraceNotebookTelemetryAction) => { mergeMap((action: cdbActions.TraceNotebookTelemetryAction) => {
const state = state$.value; const state = state$.value;
@@ -844,7 +844,7 @@ const traceNotebookInfoEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<{} | cdbActions.TraceNotebookTelemetryAction> => { ): Observable<{} | cdbActions.TraceNotebookTelemetryAction> => {
return action$.pipe( return action$.pipe(
ofType(actions.FETCH_CONTENT_FULFILLED), ofType(actions.FETCH_CONTENT_FULFILLED) as any,
mergeMap((action: { payload: any }) => { mergeMap((action: { payload: any }) => {
const state = state$.value; const state = state$.value;
const contentRef = action.payload.contentRef; const contentRef = action.payload.contentRef;
@@ -897,7 +897,7 @@ const traceNotebookKernelEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<cdbActions.TraceNotebookTelemetryAction> => { ): Observable<cdbActions.TraceNotebookTelemetryAction> => {
return action$.pipe( return action$.pipe(
ofType(actions.LAUNCH_KERNEL_SUCCESSFUL), ofType(actions.LAUNCH_KERNEL_SUCCESSFUL) as any,
mergeMap((action: { payload: any; type: string }) => { mergeMap((action: { payload: any; type: string }) => {
return of( return of(
cdbActions.traceNotebookTelemetry({ cdbActions.traceNotebookTelemetry({
@@ -917,8 +917,8 @@ const resetCellStatusOnExecuteCanceledEpic = (
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<actions.UpdateCellStatus> => { ): Observable<actions.UpdateCellStatus> => {
return action$.pipe( return action$.pipe(
ofType(actions.EXECUTE_CANCELED), ofType(actions.EXECUTE_CANCELED) as any,
mergeMap((action) => { mergeMap((action: any) => {
const contentRef = action.payload.contentRef; const contentRef = action.payload.contentRef;
const model = state$.value.core.entities.contents.byRef.get(contentRef).model; const model = state$.value.core.entities.contents.byRef.get(contentRef).model;
let busyCellIds: string[] = []; let busyCellIds: string[] = [];
@@ -960,8 +960,8 @@ export function autoSaveCurrentContentEpic(
state$: StateObservable<AppState>, state$: StateObservable<AppState>,
): Observable<actions.Save> { ): Observable<actions.Save> {
return state$.pipe( return state$.pipe(
map((state) => autoSaveInterval(state)), map((state) => autoSaveInterval(state)) as any,
switchMap((time) => interval(time)), switchMap((time) => interval(time as number)) as any,
mergeMap(() => { mergeMap(() => {
const state = state$.value; const state = state$.value;
return from( return from(
@@ -976,7 +976,7 @@ export function autoSaveCurrentContentEpic(
) )
.keys(), .keys(),
); );
}), }) as any,
filter((contentRef: ContentRef) => { filter((contentRef: ContentRef) => {
const model = selectors.model(state$.value, { contentRef }); const model = selectors.model(state$.value, { contentRef });
const content = selectors.content(state$.value, { contentRef }); const content = selectors.content(state$.value, { contentRef });
@@ -985,12 +985,12 @@ export function autoSaveCurrentContentEpic(
model.type === "notebook" && model.type === "notebook" &&
NotebookUtil.getContentProviderType(content.filepath) !== NotebookContentProviderType.JupyterContentProviderType NotebookUtil.getContentProviderType(content.filepath) !== NotebookContentProviderType.JupyterContentProviderType
) { ) {
return selectors.notebook.isDirty(model); return selectors.notebook.isDirty(model as never);
} }
return false; return false;
}), }) as any,
map((contentRef: ContentRef) => actions.save({ contentRef })), map((contentRef: ContentRef) => actions.save({ contentRef })) as any,
); ) as any;
} }
export const allEpics = [ export const allEpics = [

View File

@@ -34,11 +34,11 @@ export default function configureStore(
const protect = (epic: Epic) => { const protect = (epic: Epic) => {
return (action$: Observable<any>, state$: any, dependencies: any) => return (action$: Observable<any>, state$: any, dependencies: any) =>
epic(action$, state$, dependencies).pipe( epic(action$ as any, state$, dependencies).pipe(
catchError((error, caught) => { catchError((error, caught) => {
traceFailure("Epic failure", error); traceFailure("Epic failure", error);
return caught; return caught;
}), }) as any,
); );
}; };
@@ -52,7 +52,7 @@ export default function configureStore(
}; };
const protectEpics = (epics: Epic[]): Epic[] => { const protectEpics = (epics: Epic[]): Epic[] => {
return epics.map((epic) => protect(epic)); return epics.map((epic) => protect(epic)) as any;
}; };
const filteredCoreEpics = getCoreEpics(autoStartKernelOnNotebookOpen); const filteredCoreEpics = getCoreEpics(autoStartKernelOnNotebookOpen);
@@ -64,7 +64,7 @@ export default function configureStore(
core: coreReducer as any, core: coreReducer as any,
cdb: cdbReducer, cdb: cdbReducer,
}, },
epics: protectEpics([...filteredCoreEpics, ...allEpics]), epics: protectEpics([...filteredCoreEpics, ...allEpics] as any),
epicDependencies: { contentProvider }, epicDependencies: { contentProvider },
epicMiddleware: customMiddlewares.concat(catchErrorMiddleware), epicMiddleware: customMiddlewares.concat(catchErrorMiddleware),
enhancer: composeEnhancers, enhancer: composeEnhancers,
@@ -106,5 +106,5 @@ export const getCoreEpics = (autoStartKernelOnNotebookOpen: boolean): Epic[] =>
filteredCoreEpics.push(coreEpics.launchKernelWhenNotebookSetEpic); filteredCoreEpics.push(coreEpics.launchKernelWhenNotebookSetEpic);
} }
return filteredCoreEpics; return filteredCoreEpics as any;
}; };

View File

@@ -154,7 +154,7 @@ function openPane(action: ActionContracts.OpenPane, explorer: Explorer) {
action.paneKind === ActionContracts.PaneKind.GlobalSettings || action.paneKind === ActionContracts.PaneKind.GlobalSettings ||
action.paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.GlobalSettings] action.paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.GlobalSettings]
) { ) {
useSidePanel.getState().openSidePanel("Settings", <SettingsPane />); useSidePanel.getState().openSidePanel("Settings", <SettingsPane explorer={explorer} />);
} }
} }

View File

@@ -1431,8 +1431,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
this.setState({ isExecuting: false }); this.setState({ isExecuting: false });
TelemetryProcessor.traceSuccess(Action.CreateCollection, telemetryData, startKey); TelemetryProcessor.traceSuccess(Action.CreateCollection, telemetryData, startKey);
useSidePanel.getState().closeSidePanel(); useSidePanel.getState().closeSidePanel();
// open NPS Survey Dialog once the collection is created
this.props.explorer.openNPSSurveyDialog();
} catch (error) { } catch (error) {
const errorMessage: string = getErrorMessage(error); const errorMessage: string = getErrorMessage(error);
this.setState({ isExecuting: false, errorMessage, showErrorDetails: true }); this.setState({ isExecuting: false, errorMessage, showErrorDetails: true });

View File

@@ -23,7 +23,7 @@ describe("Cassandra add collection pane test", () => {
expect(screen.getByRole("combobox", { name: "Choose existing keyspace id" })).toBeDefined(); expect(screen.getByRole("combobox", { name: "Choose existing keyspace id" })).toBeDefined();
}); });
it("enter Keyspace name ", () => { it("enter Keyspace name", () => {
fireEvent.change(screen.getByRole("textbox", { name: "Keyspace id" }), { target: { value: "table1" } }); fireEvent.change(screen.getByRole("textbox", { name: "Keyspace id" }), { target: { value: "table1" } });
expect(screen.getByText("CREATE TABLE table1.")).toBeDefined(); expect(screen.getByText("CREATE TABLE table1.")).toBeDefined();
}); });

View File

@@ -314,7 +314,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
</Stack> </Stack>
{!isServerlessAccount() && isKeyspaceShared && !keyspaceCreateNew && ( {!isServerlessAccount() && isKeyspaceShared && !keyspaceCreateNew && (
<Stack> <Stack horizontal verticalAlign="center">
<input <input
type="checkbox" type="checkbox"
id="tableSharedThroughput" id="tableSharedThroughput"

View File

@@ -35,10 +35,11 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
const collectionName = getCollectionName().toLocaleLowerCase(); const collectionName = getCollectionName().toLocaleLowerCase();
const paneTitle = "Delete " + collectionName; const paneTitle = "Delete " + collectionName;
const onSubmit = async (): Promise<void> => { const onSubmit = async (): Promise<void> => {
const collection = useSelectedNode.getState().findSelectedCollection(); const collection = useSelectedNode.getState().findSelectedCollection();
if (!collection || inputCollectionName !== collection.id()) { if (!collection || inputCollectionName !== collection.id()) {
const errorMessage = "Input " + collectionName + " id does not match the selected " + collectionName; const errorMessage = "Input id " + inputCollectionName + " does not match the selected " + collection.id();
setFormError(errorMessage); setFormError(errorMessage);
NotificationConsoleUtils.logConsoleError( NotificationConsoleUtils.logConsoleError(
`Error while deleting ${collectionName} ${collection.id()}: ${errorMessage}`, `Error while deleting ${collectionName} ${collection.id()}: ${errorMessage}`,

View File

@@ -32,7 +32,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
variant="small" variant="small"
> >
<span <span
className="css-53" className="css-109"
> >
Confirm by typing the Confirm by typing the
container container
@@ -340,19 +340,19 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
value="" value=""
> >
<div <div
className="ms-TextField is-required root-55" className="ms-TextField is-required root-111"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
> >
<div <div
className="ms-TextField-fieldGroup fieldGroup-56" className="ms-TextField-fieldGroup fieldGroup-112"
> >
<input <input
aria-invalid={false} aria-invalid={false}
aria-label="Confirm by typing the container id" aria-label="Confirm by typing the container id"
autoFocus={true} autoFocus={true}
className="ms-TextField-field field-57" className="ms-TextField-field field-113"
id="confirmCollectionId" id="confirmCollectionId"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@@ -1259,7 +1259,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1285,7 +1285,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1297,14 +1297,16 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1335,7 +1337,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -1362,7 +1364,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1387,14 +1389,16 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1428,7 +1432,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1445,7 +1449,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -1457,7 +1461,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1473,12 +1477,13 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -1489,14 +1494,16 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1519,13 +1526,21 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -1538,7 +1553,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -1551,7 +1566,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1565,7 +1580,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1579,7 +1594,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -1595,7 +1610,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -1604,7 +1619,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1620,7 +1635,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -1632,7 +1647,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -1645,7 +1660,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -1667,18 +1682,18 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -1728,7 +1743,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1737,7 +1752,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1745,7 +1760,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1767,14 +1782,16 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1796,7 +1813,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2086,7 +2103,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
> >
<button <button
aria-label="OK" aria-label="OK"
className="ms-Button ms-Button--primary root-66" className="ms-Button ms-Button--primary root-122"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -2098,16 +2115,16 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-67" className="ms-Button-flexContainer flexContainer-123"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-68" className="ms-Button-textContainer textContainer-124"
> >
<span <span
className="ms-Button-label label-70" className="ms-Button-label label-126"
id="id__3" id="id__5"
key="id__3" key="id__5"
> >
OK OK
</span> </span>

View File

@@ -306,7 +306,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
} }
> >
<label <label
className="ms-Label root-53" className="ms-Label root-109"
> >
Partition key value Partition key value
</label> </label>
@@ -316,11 +316,11 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
horizontal={true} horizontal={true}
> >
<div <div
className="ms-Stack css-54" className="ms-Stack css-110"
> >
<Dropdown <Dropdown
defaultSelectedKey="string" defaultSelectedKey="string"
key=".0:$.0" key=".0:$.$.0"
label="Key" label="Key"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -661,7 +661,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
}, },
] ]
} }
responsiveMode={3} responsiveMode={0}
styles={[Function]} styles={[Function]}
tabIndex={0} tabIndex={0}
theme={ theme={
@@ -1225,7 +1225,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
} }
> >
<label <label
className="ms-Label ms-Dropdown-label root-71" className="ms-Label ms-Dropdown-label root-129"
id="Dropdown0-label" id="Dropdown0-label"
> >
Key Key
@@ -1236,7 +1236,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
aria-expanded="false" aria-expanded="false"
aria-haspopup="listbox" aria-haspopup="listbox"
aria-labelledby="Dropdown0-label Dropdown0-option" aria-labelledby="Dropdown0-label Dropdown0-option"
className="ms-Dropdown dropdown-55" className="ms-Dropdown dropdown-111"
data-is-focusable={true} data-is-focusable={true}
data-ktp-target={true} data-ktp-target={true}
id="Dropdown0" id="Dropdown0"
@@ -1251,25 +1251,23 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
tabIndex={0} tabIndex={0}
> >
<span <span
aria-atomic={true}
aria-invalid={false} aria-invalid={false}
aria-live="polite" className="ms-Dropdown-title title-156"
className="ms-Dropdown-title title-97"
id="Dropdown0-option" id="Dropdown0-option"
> >
String String
</span> </span>
<span <span
className="ms-Dropdown-caretDownWrapper caretDownWrapper-57" className="ms-Dropdown-caretDownWrapper caretDownWrapper-113"
> >
<StyledIconBase <StyledIconBase
aria-hidden={true} aria-hidden={true}
className="ms-Dropdown-caretDown caretDown-58" className="ms-Dropdown-caretDown caretDown-114"
iconName="ChevronDown" iconName="ChevronDown"
> >
<IconBase <IconBase
aria-hidden={true} aria-hidden={true}
className="ms-Dropdown-caretDown caretDown-58" className="ms-Dropdown-caretDown caretDown-114"
iconName="ChevronDown" iconName="ChevronDown"
styles={[Function]} styles={[Function]}
theme={ theme={
@@ -1548,7 +1546,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
> >
<i <i
aria-hidden={true} aria-hidden={true}
className="ms-Dropdown-caretDown caretDown-73" className="ms-Dropdown-caretDown caretDown-132"
data-icon-name="ChevronDown" data-icon-name="ChevronDown"
> >
@@ -1563,7 +1561,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
</Dropdown> </Dropdown>
<StyledTextFieldBase <StyledTextFieldBase
id="confirmCollectionId" id="confirmCollectionId"
key=".0:$.1" key=".0:$.$.1"
label="Value" label="Value"
onChange={[Function]} onChange={[Function]}
tabIndex={0} tabIndex={0}
@@ -1852,7 +1850,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
validateOnLoad={true} validateOnLoad={true}
> >
<div <div
className="ms-TextField root-75" className="ms-TextField root-134"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
@@ -2141,7 +2139,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
} }
> >
<label <label
className="ms-Label root-53" className="ms-Label root-109"
htmlFor="confirmCollectionId" htmlFor="confirmCollectionId"
id="TextFieldLabel3" id="TextFieldLabel3"
> >
@@ -2150,12 +2148,12 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
</LabelBase> </LabelBase>
</StyledLabelBase> </StyledLabelBase>
<div <div
className="ms-TextField-fieldGroup fieldGroup-76" className="ms-TextField-fieldGroup fieldGroup-135"
> >
<input <input
aria-invalid={false} aria-invalid={false}
aria-labelledby="TextFieldLabel3" aria-labelledby="TextFieldLabel3"
className="ms-TextField-field field-77" className="ms-TextField-field field-136"
id="confirmCollectionId" id="confirmCollectionId"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@@ -2464,7 +2462,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
} }
> >
<label <label
className="ms-Label root-53" className="ms-Label root-109"
> >
Enter input parameters (if any) Enter input parameters (if any)
</label> </label>
@@ -2474,11 +2472,11 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
horizontal={true} horizontal={true}
> >
<div <div
className="ms-Stack css-54" className="ms-Stack css-110"
> >
<Dropdown <Dropdown
defaultSelectedKey="string" defaultSelectedKey="string"
key=".0:$.0" key=".0:$.$.0"
label="Key" label="Key"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -2819,7 +2817,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
}, },
] ]
} }
responsiveMode={3} responsiveMode={0}
styles={[Function]} styles={[Function]}
tabIndex={0} tabIndex={0}
theme={ theme={
@@ -3101,12 +3099,12 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
> >
<StyledLabelBase <StyledLabelBase
className="ms-Dropdown-label" className="ms-Dropdown-label"
id="Dropdown4-label" id="Dropdown6-label"
styles={[Function]} styles={[Function]}
> >
<LabelBase <LabelBase
className="ms-Dropdown-label" className="ms-Dropdown-label"
id="Dropdown4-label" id="Dropdown6-label"
styles={[Function]} styles={[Function]}
theme={ theme={
Object { Object {
@@ -3383,8 +3381,8 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
} }
> >
<label <label
className="ms-Label ms-Dropdown-label root-71" className="ms-Label ms-Dropdown-label root-129"
id="Dropdown4-label" id="Dropdown6-label"
> >
Key Key
</label> </label>
@@ -3393,11 +3391,11 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
<div <div
aria-expanded="false" aria-expanded="false"
aria-haspopup="listbox" aria-haspopup="listbox"
aria-labelledby="Dropdown4-label Dropdown4-option" aria-labelledby="Dropdown6-label Dropdown6-option"
className="ms-Dropdown dropdown-55" className="ms-Dropdown dropdown-111"
data-is-focusable={true} data-is-focusable={true}
data-ktp-target={true} data-ktp-target={true}
id="Dropdown4" id="Dropdown6"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
onClick={[Function]} onClick={[Function]}
@@ -3409,25 +3407,23 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
tabIndex={0} tabIndex={0}
> >
<span <span
aria-atomic={true}
aria-invalid={false} aria-invalid={false}
aria-live="polite" className="ms-Dropdown-title title-156"
className="ms-Dropdown-title title-97" id="Dropdown6-option"
id="Dropdown4-option"
> >
String String
</span> </span>
<span <span
className="ms-Dropdown-caretDownWrapper caretDownWrapper-57" className="ms-Dropdown-caretDownWrapper caretDownWrapper-113"
> >
<StyledIconBase <StyledIconBase
aria-hidden={true} aria-hidden={true}
className="ms-Dropdown-caretDown caretDown-58" className="ms-Dropdown-caretDown caretDown-114"
iconName="ChevronDown" iconName="ChevronDown"
> >
<IconBase <IconBase
aria-hidden={true} aria-hidden={true}
className="ms-Dropdown-caretDown caretDown-58" className="ms-Dropdown-caretDown caretDown-114"
iconName="ChevronDown" iconName="ChevronDown"
styles={[Function]} styles={[Function]}
theme={ theme={
@@ -3706,7 +3702,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
> >
<i <i
aria-hidden={true} aria-hidden={true}
className="ms-Dropdown-caretDown caretDown-73" className="ms-Dropdown-caretDown caretDown-132"
data-icon-name="ChevronDown" data-icon-name="ChevronDown"
> >
@@ -3722,7 +3718,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="" defaultValue=""
id="confirmCollectionId" id="confirmCollectionId"
key=".0:$.1" key=".0:$.$.1"
label="Param" label="Param"
onChange={[Function]} onChange={[Function]}
tabIndex={0} tabIndex={0}
@@ -4012,19 +4008,19 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
validateOnLoad={true} validateOnLoad={true}
> >
<div <div
className="ms-TextField root-75" className="ms-TextField root-134"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
> >
<StyledLabelBase <StyledLabelBase
htmlFor="confirmCollectionId" htmlFor="confirmCollectionId"
id="TextFieldLabel7" id="TextFieldLabel9"
styles={[Function]} styles={[Function]}
> >
<LabelBase <LabelBase
htmlFor="confirmCollectionId" htmlFor="confirmCollectionId"
id="TextFieldLabel7" id="TextFieldLabel9"
styles={[Function]} styles={[Function]}
theme={ theme={
Object { Object {
@@ -4301,21 +4297,21 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
} }
> >
<label <label
className="ms-Label root-53" className="ms-Label root-109"
htmlFor="confirmCollectionId" htmlFor="confirmCollectionId"
id="TextFieldLabel7" id="TextFieldLabel9"
> >
Param Param
</label> </label>
</LabelBase> </LabelBase>
</StyledLabelBase> </StyledLabelBase>
<div <div
className="ms-TextField-fieldGroup fieldGroup-76" className="ms-TextField-fieldGroup fieldGroup-135"
> >
<input <input
aria-invalid={false} aria-invalid={false}
aria-labelledby="TextFieldLabel7" aria-labelledby="TextFieldLabel9"
className="ms-TextField-field field-77" className="ms-TextField-field field-136"
id="confirmCollectionId" id="confirmCollectionId"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@@ -4331,6 +4327,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
</TextFieldBase> </TextFieldBase>
</StyledTextFieldBase> </StyledTextFieldBase>
<div <div
key=".0:$.$.2/.$.$.0"
tabIndex={0} tabIndex={0}
> >
<StyledImageBase <StyledImageBase
@@ -4628,7 +4625,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
width={20} width={20}
> >
<div <div
className="ms-Image addRemoveIconLabel root-86" className="ms-Image addRemoveIconLabel root-145"
style={ style={
Object { Object {
"height": 30, "height": 30,
@@ -4638,7 +4635,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
> >
<img <img
alt="Delete param" alt="Delete param"
className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-87" className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-146"
id="deleteparam" id="deleteparam"
key="fabricImage[object Object]" key="fabricImage[object Object]"
onClick={[Function]} onClick={[Function]}
@@ -4652,6 +4649,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
</StyledImageBase> </StyledImageBase>
</div> </div>
<div <div
key=".0:$.$.2/.$.$.1"
tabIndex={0} tabIndex={0}
> >
<StyledImageBase <StyledImageBase
@@ -4949,7 +4947,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
width={20} width={20}
> >
<div <div
className="ms-Image addRemoveIconLabel root-86" className="ms-Image addRemoveIconLabel root-145"
style={ style={
Object { Object {
"height": 30, "height": 30,
@@ -4959,7 +4957,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
> >
<img <img
alt="Add param" alt="Add param"
className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-87" className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-146"
id="addparam" id="addparam"
key="fabricImage[object Object]" key="fabricImage[object Object]"
onClick={[Function]} onClick={[Function]}
@@ -4981,14 +4979,14 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
tabIndex={0} tabIndex={0}
> >
<div <div
className="ms-Stack css-54" className="ms-Stack css-110"
onClick={[Function]} onClick={[Function]}
tabIndex={0} tabIndex={0}
> >
<StyledImageBase <StyledImageBase
alt="Add param" alt="Add param"
height={30} height={30}
key=".0:$.0" key=".0:$.$.0"
src={Object {}} src={Object {}}
width={20} width={20}
> >
@@ -5273,7 +5271,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
width={20} width={20}
> >
<div <div
className="ms-Image root-86" className="ms-Image root-145"
style={ style={
Object { Object {
"height": 30, "height": 30,
@@ -5283,7 +5281,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
> >
<img <img
alt="Add param" alt="Add param"
className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-87" className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-146"
key="fabricImage[object Object]" key="fabricImage[object Object]"
onError={[Function]} onError={[Function]}
onLoad={[Function]} onLoad={[Function]}
@@ -5294,10 +5292,10 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
</StyledImageBase> </StyledImageBase>
<Text <Text
className="addNewParamStyle" className="addNewParamStyle"
key=".0:$.1" key=".0:$.$.1"
> >
<span <span
className="addNewParamStyle css-88" className="addNewParamStyle css-147"
> >
Add New Param Add New Param
</span> </span>
@@ -6194,7 +6192,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -6220,7 +6218,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -6232,14 +6230,16 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -6270,7 +6270,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -6297,7 +6297,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -6322,14 +6322,16 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -6363,7 +6365,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -6380,7 +6382,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -6392,7 +6394,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -6408,12 +6410,13 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -6424,14 +6427,16 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -6454,13 +6459,21 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -6473,7 +6486,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -6486,7 +6499,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -6500,7 +6513,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -6514,7 +6527,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -6530,7 +6543,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -6539,7 +6552,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -6555,7 +6568,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -6567,7 +6580,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -6580,7 +6593,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -6602,18 +6615,18 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -6663,7 +6676,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -6672,7 +6685,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -6680,7 +6693,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -6702,14 +6715,16 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -6731,7 +6746,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -7021,7 +7036,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
> >
<button <button
aria-label="Execute" aria-label="Execute"
className="ms-Button ms-Button--primary root-89" className="ms-Button ms-Button--primary root-148"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -7033,16 +7048,16 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-90" className="ms-Button-flexContainer flexContainer-149"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-91" className="ms-Button-textContainer textContainer-150"
> >
<span <span
className="ms-Button-label label-93" className="ms-Button-label label-152"
id="id__8" id="id__12"
key="id__8" key="id__12"
> >
Execute Execute
</span> </span>

View File

@@ -112,8 +112,9 @@
margin-top: 28px; margin-top: 28px;
margin-left: 4px !important; margin-left: 4px !important;
} }
.addRemoveIcon [alt="editEntity"]:focus,.addRemoveIconLabel [alt="editEntity"]:focus{ .addRemoveIcon [alt="editEntity"]:focus,
border:1px dashed #605E5C .addRemoveIconLabel [alt="editEntity"]:focus {
border: 1px dashed #605e5c;
} }
.addNewParamStyle { .addNewParamStyle {
margin-top: 5px; margin-top: 5px;
@@ -153,6 +154,9 @@
.backImageIcon { .backImageIcon {
margin-top: 8px; margin-top: 8px;
} }
[alt="back"]:focus {
border: 1px solid #605e5c;
}
.addEntityDatePicker { .addEntityDatePicker {
max-width: 145px; max-width: 145px;
} }

View File

@@ -29,7 +29,7 @@ export class PanelContainerComponent extends React.Component<PanelContainerProps
}; };
} }
omponentDidMount(): void { componentDidMount(): void {
window.addEventListener("resize", () => this.setState({ height: this.getPanelHeight() })); window.addEventListener("resize", () => this.setState({ height: this.getPanelHeight() }));
} }
@@ -62,12 +62,12 @@ export class PanelContainerComponent extends React.Component<PanelContainerProps
customWidth={this.props.panelWidth ? this.props.panelWidth : "440px"} customWidth={this.props.panelWidth ? this.props.panelWidth : "440px"}
headerClassName="panelHeader" headerClassName="panelHeader"
onRenderNavigationContent={this.props.onRenderNavigationContent} onRenderNavigationContent={this.props.onRenderNavigationContent}
isFooterAtBottom={true}
styles={{ styles={{
navigation: { borderBottom: "1px solid #cccccc" }, navigation: { borderBottom: "1px solid #cccccc" },
content: { padding: 0, height: "100%" }, content: { padding: 0 },
scrollableContent: { height: "100%" },
header: { padding: "0 0 8px 34px" }, header: { padding: "0 0 8px 34px" },
commands: { marginTop: 8 }, commands: { marginTop: 8, paddingTop: 0 },
}} }}
style={{ height: this.state.height }} style={{ height: this.state.height }}
> >

View File

@@ -32,14 +32,8 @@ export const PanelInfoErrorComponent: React.FunctionComponent<PanelInfoErrorProp
return ( return (
<Stack className="panelInfoErrorContainer" horizontal verticalAlign="center"> <Stack className="panelInfoErrorContainer" horizontal verticalAlign="center">
{icon} {icon}
<span className="panelWarningErrorDetailsLinkContainer"> <span className="panelWarningErrorDetailsLinkContainer" role="alert" aria-live="assertive">
<Text <Text aria-label={message} className="panelWarningErrorMessage" variant="small">
role="alert"
aria-live="assertive"
aria-label={message}
className="panelWarningErrorMessage"
variant="small"
>
{message} {message}
{link && linkText && ( {link && linkText && (
<Link target="_blank" href={link}> <Link target="_blank" href={link}>

View File

@@ -1,5 +1,5 @@
import { fireEvent, render, screen } from "@testing-library/react"; import { fireEvent, render, screen } from "@testing-library/react";
import { mount, ReactWrapper } from "enzyme"; import { ReactWrapper, mount } from "enzyme";
import React from "react"; import React from "react";
import { RightPaneForm } from "./RightPaneForm"; import { RightPaneForm } from "./RightPaneForm";
@@ -34,6 +34,6 @@ describe("Right Pane Form", () => {
it("should render error in header", () => { it("should render error in header", () => {
render(<RightPaneForm {...props} formError="file already Exist" />); render(<RightPaneForm {...props} formError="file already Exist" />);
expect(screen.getByLabelText("error")).toBeDefined(); expect(screen.getByLabelText("error")).toBeDefined();
expect(screen.getByRole("alert").innerHTML).toEqual("file already Exist"); expect(screen.getByRole("alert").innerHTML).toContain("file already Exist");
}); });
}); });

View File

@@ -901,7 +901,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -927,7 +927,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -939,14 +939,16 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -977,7 +979,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -1004,7 +1006,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1029,14 +1031,16 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1070,7 +1074,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1087,7 +1091,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -1099,7 +1103,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1115,12 +1119,13 @@ exports[`Right Pane Form should render Default properly 1`] = `
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -1131,14 +1136,16 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1161,13 +1168,21 @@ exports[`Right Pane Form should render Default properly 1`] = `
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -1180,7 +1195,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -1193,7 +1208,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1207,7 +1222,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1221,7 +1236,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -1237,7 +1252,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -1246,7 +1261,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1262,7 +1277,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -1274,7 +1289,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -1287,7 +1302,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -1309,18 +1324,18 @@ exports[`Right Pane Form should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -1370,7 +1385,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1379,7 +1394,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1387,7 +1402,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1409,14 +1424,16 @@ exports[`Right Pane Form should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1438,7 +1455,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1728,7 +1745,7 @@ exports[`Right Pane Form should render Default properly 1`] = `
> >
<button <button
aria-label="Load" aria-label="Load"
className="ms-Button ms-Button--primary root-53" className="ms-Button ms-Button--primary root-109"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -1740,14 +1757,14 @@ exports[`Right Pane Form should render Default properly 1`] = `
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-54" className="ms-Button-flexContainer flexContainer-110"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-55" className="ms-Button-textContainer textContainer-111"
> >
<span <span
className="ms-Button-label label-57" className="ms-Button-label label-113"
id="id__0" id="id__0"
key="id__0" key="id__0"
> >

View File

@@ -6,7 +6,7 @@ import { SettingsPane } from "./SettingsPane";
describe("Settings Pane", () => { describe("Settings Pane", () => {
it("should render Default properly", () => { it("should render Default properly", () => {
const wrapper = shallow(<SettingsPane />); const wrapper = shallow(<SettingsPane explorer={null} />);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
@@ -18,7 +18,7 @@ describe("Settings Pane", () => {
}, },
} as DatabaseAccount, } as DatabaseAccount,
}); });
const wrapper = shallow(<SettingsPane />); const wrapper = shallow(<SettingsPane explorer={null} />);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
}); });

View File

@@ -16,13 +16,20 @@ import * as StringUtility from "Shared/StringUtility";
import { userContext } from "UserContext"; import { userContext } from "UserContext";
import { logConsoleInfo } from "Utils/NotificationConsoleUtils"; import { logConsoleInfo } from "Utils/NotificationConsoleUtils";
import * as PriorityBasedExecutionUtils from "Utils/PriorityBasedExecutionUtils"; import * as PriorityBasedExecutionUtils from "Utils/PriorityBasedExecutionUtils";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import { useSidePanel } from "hooks/useSidePanel"; import { useSidePanel } from "hooks/useSidePanel";
import React, { FunctionComponent, useState } from "react"; import React, { FunctionComponent, useState } from "react";
import Explorer from "../../Explorer";
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm"; import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
export const SettingsPane: FunctionComponent = () => { export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
explorer,
}: {
explorer: Explorer;
}): JSX.Element => {
const closeSidePanel = useSidePanel((state) => state.closeSidePanel); const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
const [isExecuting, setIsExecuting] = useState<boolean>(false); const [isExecuting, setIsExecuting] = useState<boolean>(false);
const [refreshExplorer, setRefreshExplorer] = useState<boolean>(false);
const [pageOption, setPageOption] = useState<string>( const [pageOption, setPageOption] = useState<string>(
LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage) === Constants.Queries.unlimitedItemsPerPage LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage) === Constants.Queries.unlimitedItemsPerPage
? Constants.Queries.UnlimitedPageOption ? Constants.Queries.UnlimitedPageOption
@@ -53,6 +60,21 @@ export const SettingsPane: FunctionComponent = () => {
? LocalStorageUtility.getEntryString(StorageKey.IsGraphAutoVizDisabled) ? LocalStorageUtility.getEntryString(StorageKey.IsGraphAutoVizDisabled)
: "false", : "false",
); );
const [retryAttempts, setRetryAttempts] = useState<number>(
LocalStorageUtility.hasItem(StorageKey.RetryAttempts)
? LocalStorageUtility.getEntryNumber(StorageKey.RetryAttempts)
: Constants.Queries.DefaultRetryAttempts,
);
const [retryInterval, setRetryInterval] = useState<number>(
LocalStorageUtility.hasItem(StorageKey.RetryInterval)
? LocalStorageUtility.getEntryNumber(StorageKey.RetryInterval)
: Constants.Queries.DefaultRetryIntervalInMs,
);
const [MaxWaitTimeInSeconds, setMaxWaitTimeInSeconds] = useState<number>(
LocalStorageUtility.hasItem(StorageKey.MaxWaitTimeInSeconds)
? LocalStorageUtility.getEntryNumber(StorageKey.MaxWaitTimeInSeconds)
: Constants.Queries.DefaultMaxWaitTimeInSeconds,
);
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)
@@ -63,13 +85,17 @@ export const SettingsPane: FunctionComponent = () => {
? LocalStorageUtility.getEntryString(StorageKey.PriorityLevel) ? LocalStorageUtility.getEntryString(StorageKey.PriorityLevel)
: Constants.PriorityLevel.Default, : Constants.PriorityLevel.Default,
); );
const [copilotSampleDBEnabled, setCopilotSampleDBEnabled] = useState<boolean>(
LocalStorageUtility.getEntryString(StorageKey.CopilotSampleDBEnabled) === "true",
);
const explorerVersion = configContext.gitSha; const explorerVersion = configContext.gitSha;
const shouldShowQueryPageOptions = userContext.apiType === "SQL"; const shouldShowQueryPageOptions = userContext.apiType === "SQL";
const shouldShowGraphAutoVizOption = userContext.apiType === "Gremlin"; const shouldShowGraphAutoVizOption = userContext.apiType === "Gremlin";
const shouldShowCrossPartitionOption = userContext.apiType !== "Gremlin"; const shouldShowCrossPartitionOption = userContext.apiType !== "Gremlin";
const shouldShowParallelismOption = userContext.apiType !== "Gremlin"; const shouldShowParallelismOption = userContext.apiType !== "Gremlin";
const shouldShowPriorityLevelOption = PriorityBasedExecutionUtils.isFeatureEnabled(); const shouldShowPriorityLevelOption = PriorityBasedExecutionUtils.isFeatureEnabled();
const handlerOnSubmit = () => { const shouldShowCopilotSampleDBOption = userContext.apiType === "SQL" && useQueryCopilot.getState().copilotEnabled;
const handlerOnSubmit = async () => {
setIsExecuting(true); setIsExecuting(true);
LocalStorageUtility.setEntryNumber( LocalStorageUtility.setEntryNumber(
@@ -78,10 +104,14 @@ export const SettingsPane: FunctionComponent = () => {
); );
LocalStorageUtility.setEntryNumber(StorageKey.CustomItemPerPage, customItemPerPage); LocalStorageUtility.setEntryNumber(StorageKey.CustomItemPerPage, customItemPerPage);
LocalStorageUtility.setEntryBoolean(StorageKey.QueryTimeoutEnabled, queryTimeoutEnabled); LocalStorageUtility.setEntryBoolean(StorageKey.QueryTimeoutEnabled, queryTimeoutEnabled);
LocalStorageUtility.setEntryNumber(StorageKey.RetryAttempts, retryAttempts);
LocalStorageUtility.setEntryNumber(StorageKey.RetryInterval, retryInterval);
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.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());
if (shouldShowGraphAutoVizOption) { if (shouldShowGraphAutoVizOption) {
LocalStorageUtility.setEntryBoolean( LocalStorageUtility.setEntryBoolean(
@@ -121,6 +151,7 @@ export const SettingsPane: FunctionComponent = () => {
logConsoleInfo( logConsoleInfo(
`Updated query setting to ${LocalStorageUtility.getEntryString(StorageKey.SetPartitionKeyUndefined)}`, `Updated query setting to ${LocalStorageUtility.getEntryString(StorageKey.SetPartitionKeyUndefined)}`,
); );
refreshExplorer && (await explorer.refreshExplorer());
closeSidePanel(); closeSidePanel();
}; };
@@ -179,6 +210,33 @@ export const SettingsPane: FunctionComponent = () => {
} }
}; };
const handleOnQueryRetryAttemptsSpinButtonChange = (ev: React.MouseEvent<HTMLElement>, newValue?: string): void => {
const retryAttempts = Number(newValue);
if (!isNaN(retryAttempts)) {
setRetryAttempts(retryAttempts);
}
};
const handleOnRetryIntervalSpinButtonChange = (ev: React.MouseEvent<HTMLElement>, newValue?: string): void => {
const retryInterval = Number(newValue);
if (!isNaN(retryInterval)) {
setRetryInterval(retryInterval);
}
};
const handleOnMaxWaitTimeSpinButtonChange = (ev: React.MouseEvent<HTMLElement>, newValue?: string): void => {
const MaxWaitTimeInSeconds = Number(newValue);
if (!isNaN(MaxWaitTimeInSeconds)) {
setMaxWaitTimeInSeconds(MaxWaitTimeInSeconds);
}
};
const handleSampleDatabaseChange = async (ev: React.MouseEvent<HTMLElement>, checked?: boolean): Promise<void> => {
setCopilotSampleDBEnabled(checked);
useQueryCopilot.getState().setCopilotSampleDBEnabled(checked);
setRefreshExplorer(false);
};
const choiceButtonStyles = { const choiceButtonStyles = {
root: { root: {
clear: "both", clear: "both",
@@ -325,6 +383,77 @@ export const SettingsPane: FunctionComponent = () => {
)} )}
<div className="settingsSection"> <div className="settingsSection">
<div className="settingsSectionPart"> <div className="settingsSectionPart">
<div className="settingsSectionLabel">
Retry Settings
<InfoTooltip>Retry policy associated with throttled requests during CosmosDB queries.</InfoTooltip>
</div>
<div>
<legend id="queryRetryAttemptsLabel" className="settingsSectionLabel legendLabel">
Max retry attempts
</legend>
<InfoTooltip>Max number of retries to be performed for a request. Default value 9.</InfoTooltip>
</div>
<SpinButton
labelPosition={Position.top}
min={1}
step={1}
value={"" + retryAttempts}
onChange={handleOnQueryRetryAttemptsSpinButtonChange}
incrementButtonAriaLabel="Increase value by 1"
decrementButtonAriaLabel="Decrease value by 1"
onIncrement={(newValue) => setRetryAttempts(parseInt(newValue) + 1 || retryAttempts)}
onDecrement={(newValue) => setRetryAttempts(parseInt(newValue) - 1 || retryAttempts)}
onValidate={(newValue) => setRetryAttempts(parseInt(newValue) || retryAttempts)}
styles={queryTimeoutSpinButtonStyles}
/>
<div>
<legend id="queryRetryAttemptsLabel" className="settingsSectionLabel legendLabel">
Fixed retry interval (ms)
</legend>
<InfoTooltip>
Fixed retry interval in milliseconds to wait between each retry ignoring the retryAfter returned as part
of the response. Default value is 0 milliseconds.
</InfoTooltip>
</div>
<SpinButton
labelPosition={Position.top}
min={1000}
step={1000}
value={"" + retryInterval}
onChange={handleOnRetryIntervalSpinButtonChange}
incrementButtonAriaLabel="Increase value by 1000"
decrementButtonAriaLabel="Decrease value by 1000"
onIncrement={(newValue) => setRetryInterval(parseInt(newValue) + 1000 || retryInterval)}
onDecrement={(newValue) => setRetryInterval(parseInt(newValue) - 1000 || retryInterval)}
onValidate={(newValue) => setRetryInterval(parseInt(newValue) || retryInterval)}
styles={queryTimeoutSpinButtonStyles}
/>
<div>
<legend id="queryRetryAttemptsLabel" className="settingsSectionLabel legendLabel">
Max wait time (s)
</legend>
<InfoTooltip>
Max wait time in seconds to wait for a request while the retries are happening. Default value 30
seconds.
</InfoTooltip>
</div>
<SpinButton
labelPosition={Position.top}
min={1}
step={1}
value={"" + MaxWaitTimeInSeconds}
onChange={handleOnMaxWaitTimeSpinButtonChange}
incrementButtonAriaLabel="Increase value by 1"
decrementButtonAriaLabel="Decrease value by 1"
onIncrement={(newValue) => setMaxWaitTimeInSeconds(parseInt(newValue) + 1 || MaxWaitTimeInSeconds)}
onDecrement={(newValue) => setMaxWaitTimeInSeconds(parseInt(newValue) - 1 || MaxWaitTimeInSeconds)}
onValidate={(newValue) => setMaxWaitTimeInSeconds(parseInt(newValue) || MaxWaitTimeInSeconds)}
styles={queryTimeoutSpinButtonStyles}
/>
</div>
</div>
<div className="settingsSection">
<div className="settingsSectionPart settingsSectionInlineCheckbox">
<div className="settingsSectionLabel"> <div className="settingsSectionLabel">
Enable container pagination Enable container pagination
<InfoTooltip> <InfoTooltip>
@@ -344,7 +473,7 @@ export const SettingsPane: FunctionComponent = () => {
</div> </div>
{shouldShowCrossPartitionOption && ( {shouldShowCrossPartitionOption && (
<div className="settingsSection"> <div className="settingsSection">
<div className="settingsSectionPart"> <div className="settingsSectionPart settingsSectionInlineCheckbox">
<div className="settingsSectionLabel"> <div className="settingsSectionLabel">
Enable cross-partition query Enable cross-partition query
<InfoTooltip> <InfoTooltip>
@@ -435,6 +564,30 @@ export const SettingsPane: FunctionComponent = () => {
</div> </div>
</div> </div>
)} )}
{shouldShowCopilotSampleDBOption && (
<div className="settingsSection">
<div className="settingsSectionPart settingsSectionInlineCheckbox">
<div className="settingsSectionLabel">
Enable sample database
<InfoTooltip>
This is a sample database and collection with synthetic product data you can use to explore using
NoSQL queries and Copilot. This will appear as another database in the Data Explorer UI, and is
created by, and maintained by Microsoft at no cost to you.
</InfoTooltip>
</div>
<Checkbox
styles={{
label: { padding: 0 },
}}
className="padding"
ariaLabel="Enable sample db for Copilot"
checked={copilotSampleDBEnabled}
onChange={handleSampleDatabaseChange}
/>
</div>
</div>
)}
<div className="settingsSection"> <div className="settingsSection">
<div className="settingsSectionPart"> <div className="settingsSectionPart">
<div className="settingsSectionLabel">Explorer Version</div> <div className="settingsSectionLabel">Explorer Version</div>

View File

@@ -142,6 +142,139 @@ exports[`Settings Pane should render Default properly 1`] = `
> >
<div <div
className="settingsSectionPart" className="settingsSectionPart"
>
<div
className="settingsSectionLabel"
>
Retry Settings
<InfoTooltip>
Retry policy associated with throttled requests during CosmosDB queries.
</InfoTooltip>
</div>
<div>
<legend
className="settingsSectionLabel legendLabel"
id="queryRetryAttemptsLabel"
>
Max retry attempts
</legend>
<InfoTooltip>
Max number of retries to be performed for a request. Default value 9.
</InfoTooltip>
</div>
<StyledSpinButton
decrementButtonAriaLabel="Decrease value by 1"
incrementButtonAriaLabel="Increase value by 1"
labelPosition={0}
min={1}
onChange={[Function]}
onDecrement={[Function]}
onIncrement={[Function]}
onValidate={[Function]}
step={1}
styles={
Object {
"arrowButtonsContainer": Object {},
"icon": Object {},
"input": Object {},
"label": Object {
"fontSize": 12,
"fontWeight": 400,
},
"labelWrapper": Object {},
"root": Object {
"paddingBottom": 10,
},
"spinButtonWrapper": Object {},
}
}
value="9"
/>
<div>
<legend
className="settingsSectionLabel legendLabel"
id="queryRetryAttemptsLabel"
>
Fixed retry interval (ms)
</legend>
<InfoTooltip>
Fixed retry interval in milliseconds to wait between each retry ignoring the retryAfter returned as part of the response. Default value is 0 milliseconds.
</InfoTooltip>
</div>
<StyledSpinButton
decrementButtonAriaLabel="Decrease value by 1000"
incrementButtonAriaLabel="Increase value by 1000"
labelPosition={0}
min={1000}
onChange={[Function]}
onDecrement={[Function]}
onIncrement={[Function]}
onValidate={[Function]}
step={1000}
styles={
Object {
"arrowButtonsContainer": Object {},
"icon": Object {},
"input": Object {},
"label": Object {
"fontSize": 12,
"fontWeight": 400,
},
"labelWrapper": Object {},
"root": Object {
"paddingBottom": 10,
},
"spinButtonWrapper": Object {},
}
}
value="0"
/>
<div>
<legend
className="settingsSectionLabel legendLabel"
id="queryRetryAttemptsLabel"
>
Max wait time (s)
</legend>
<InfoTooltip>
Max wait time in seconds to wait for a request while the retries are happening. Default value 30 seconds.
</InfoTooltip>
</div>
<StyledSpinButton
decrementButtonAriaLabel="Decrease value by 1"
incrementButtonAriaLabel="Increase value by 1"
labelPosition={0}
min={1}
onChange={[Function]}
onDecrement={[Function]}
onIncrement={[Function]}
onValidate={[Function]}
step={1}
styles={
Object {
"arrowButtonsContainer": Object {},
"icon": Object {},
"input": Object {},
"label": Object {
"fontSize": 12,
"fontWeight": 400,
},
"labelWrapper": Object {},
"root": Object {
"paddingBottom": 10,
},
"spinButtonWrapper": Object {},
}
}
value="30"
/>
</div>
</div>
<div
className="settingsSection"
>
<div
className="settingsSectionPart settingsSectionInlineCheckbox"
> >
<div <div
className="settingsSectionLabel" className="settingsSectionLabel"
@@ -170,7 +303,7 @@ exports[`Settings Pane should render Default properly 1`] = `
className="settingsSection" className="settingsSection"
> >
<div <div
className="settingsSectionPart" className="settingsSectionPart settingsSectionInlineCheckbox"
> >
<div <div
className="settingsSectionLabel" className="settingsSectionLabel"
@@ -256,6 +389,139 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
> >
<div <div
className="settingsSectionPart" className="settingsSectionPart"
>
<div
className="settingsSectionLabel"
>
Retry Settings
<InfoTooltip>
Retry policy associated with throttled requests during CosmosDB queries.
</InfoTooltip>
</div>
<div>
<legend
className="settingsSectionLabel legendLabel"
id="queryRetryAttemptsLabel"
>
Max retry attempts
</legend>
<InfoTooltip>
Max number of retries to be performed for a request. Default value 9.
</InfoTooltip>
</div>
<StyledSpinButton
decrementButtonAriaLabel="Decrease value by 1"
incrementButtonAriaLabel="Increase value by 1"
labelPosition={0}
min={1}
onChange={[Function]}
onDecrement={[Function]}
onIncrement={[Function]}
onValidate={[Function]}
step={1}
styles={
Object {
"arrowButtonsContainer": Object {},
"icon": Object {},
"input": Object {},
"label": Object {
"fontSize": 12,
"fontWeight": 400,
},
"labelWrapper": Object {},
"root": Object {
"paddingBottom": 10,
},
"spinButtonWrapper": Object {},
}
}
value="9"
/>
<div>
<legend
className="settingsSectionLabel legendLabel"
id="queryRetryAttemptsLabel"
>
Fixed retry interval (ms)
</legend>
<InfoTooltip>
Fixed retry interval in milliseconds to wait between each retry ignoring the retryAfter returned as part of the response. Default value is 0 milliseconds.
</InfoTooltip>
</div>
<StyledSpinButton
decrementButtonAriaLabel="Decrease value by 1000"
incrementButtonAriaLabel="Increase value by 1000"
labelPosition={0}
min={1000}
onChange={[Function]}
onDecrement={[Function]}
onIncrement={[Function]}
onValidate={[Function]}
step={1000}
styles={
Object {
"arrowButtonsContainer": Object {},
"icon": Object {},
"input": Object {},
"label": Object {
"fontSize": 12,
"fontWeight": 400,
},
"labelWrapper": Object {},
"root": Object {
"paddingBottom": 10,
},
"spinButtonWrapper": Object {},
}
}
value="0"
/>
<div>
<legend
className="settingsSectionLabel legendLabel"
id="queryRetryAttemptsLabel"
>
Max wait time (s)
</legend>
<InfoTooltip>
Max wait time in seconds to wait for a request while the retries are happening. Default value 30 seconds.
</InfoTooltip>
</div>
<StyledSpinButton
decrementButtonAriaLabel="Decrease value by 1"
incrementButtonAriaLabel="Increase value by 1"
labelPosition={0}
min={1}
onChange={[Function]}
onDecrement={[Function]}
onIncrement={[Function]}
onValidate={[Function]}
step={1}
styles={
Object {
"arrowButtonsContainer": Object {},
"icon": Object {},
"input": Object {},
"label": Object {
"fontSize": 12,
"fontWeight": 400,
},
"labelWrapper": Object {},
"root": Object {
"paddingBottom": 10,
},
"spinButtonWrapper": Object {},
}
}
value="30"
/>
</div>
</div>
<div
className="settingsSection"
>
<div
className="settingsSectionPart settingsSectionInlineCheckbox"
> >
<div <div
className="settingsSectionLabel" className="settingsSectionLabel"

View File

@@ -357,7 +357,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
value="" value=""
> >
<div <div
className="ms-TextField is-required root-54" className="ms-TextField is-required root-110"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
@@ -648,7 +648,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
} }
> >
<label <label
className="ms-Label root-65" className="ms-Label root-121"
htmlFor="TextField0" htmlFor="TextField0"
id="TextFieldLabel2" id="TextFieldLabel2"
> >
@@ -657,13 +657,13 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
</LabelBase> </LabelBase>
</StyledLabelBase> </StyledLabelBase>
<div <div
className="ms-TextField-fieldGroup fieldGroup-55" className="ms-TextField-fieldGroup fieldGroup-111"
> >
<input <input
aria-invalid={false} aria-invalid={false}
aria-labelledby="TextFieldLabel2" aria-labelledby="TextFieldLabel2"
autoFocus={true} autoFocus={true}
className="ms-TextField-field field-56" className="ms-TextField-field field-112"
id="TextField0" id="TextField0"
name="collectionIdConfirmation" name="collectionIdConfirmation"
onBlur={[Function]} onBlur={[Function]}
@@ -1569,7 +1569,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1595,7 +1595,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1607,14 +1607,16 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1645,7 +1647,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -1672,7 +1674,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1697,14 +1699,16 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1738,7 +1742,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1755,7 +1759,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -1767,7 +1771,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1783,12 +1787,13 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -1799,14 +1804,16 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1829,13 +1836,21 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -1848,7 +1863,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -1861,7 +1876,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1875,7 +1890,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1889,7 +1904,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -1905,7 +1920,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -1914,7 +1929,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1930,7 +1945,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -1942,7 +1957,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -1955,7 +1970,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -1977,18 +1992,18 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -2038,7 +2053,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2047,7 +2062,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2055,7 +2070,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2077,14 +2092,16 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -2106,7 +2123,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2396,7 +2413,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
> >
<button <button
aria-label="Create" aria-label="Create"
className="ms-Button ms-Button--primary root-66" className="ms-Button ms-Button--primary root-122"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -2408,16 +2425,16 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-67" className="ms-Button-flexContainer flexContainer-123"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-68" className="ms-Button-textContainer textContainer-124"
> >
<span <span
className="ms-Button-label label-70" className="ms-Button-label label-126"
id="id__3" id="id__5"
key="id__3" key="id__5"
> >
Create Create
</span> </span>

View File

@@ -213,12 +213,24 @@ export const AddTableEntityPanel: FunctionComponent<AddTableEntityPanelProps> =
setSelectedRow(rowEndex); setSelectedRow(rowEndex);
setIsEntityValuePanelTrue(); setIsEntityValuePanelTrue();
}; };
const handlePress = (event: React.KeyboardEvent<HTMLElement>): void => {
if (event.key === "Enter" || event.key === "Space") {
setIsEntityValuePanelFalse();
}
};
if (isEntityValuePanelOpen) { if (isEntityValuePanelOpen) {
return ( return (
<Stack style={{ padding: "20px 34px" }}> <Stack style={{ padding: "20px 34px" }}>
<Stack horizontal {...columnProps}> <Stack horizontal {...columnProps}>
<Image {...backImageProps} src={RevertBackIcon} alt="back" onClick={() => setIsEntityValuePanelFalse()} /> <Image
{...backImageProps}
src={RevertBackIcon}
alt="back"
tabIndex={0}
onClick={setIsEntityValuePanelFalse}
onKeyPress={handlePress}
/>
<Label>{entityAttributeProperty}</Label> <Label>{entityAttributeProperty}</Label>
</Stack> </Stack>
<TextField <TextField

View File

@@ -390,6 +390,9 @@ export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps>
</Stack> </Stack>
)} )}
</div> </div>
<div className="panelNullWarning" style={{ padding: "20px", color: "red" }}>
Warning: Null fields will not be displayed for editing.
</div>
</RightPaneForm> </RightPaneForm>
); );
}; };

View File

@@ -29,7 +29,6 @@ describe("Table query select Panel", () => {
it("Should checked availableCheckbox by default", () => { it("Should checked availableCheckbox by default", () => {
const wrapper = mount(<TableQuerySelectPanel {...props} />); const wrapper = mount(<TableQuerySelectPanel {...props} />);
expect(wrapper.find("#availableCheckbox").first().props()).toEqual({ expect(wrapper.find("#availableCheckbox").first().props()).toEqual({
ariaPositionInSet: 0,
id: "availableCheckbox", id: "availableCheckbox",
label: "Available Columns", label: "Available Columns",
checked: true, checked: true,

View File

@@ -1,7 +1,7 @@
import { Checkbox, Text } from "@fluentui/react"; import { Checkbox, Text } from "@fluentui/react";
import React, { FunctionComponent, useEffect, useState } from "react"; import React, { FunctionComponent, useEffect, useState } from "react";
import { useSidePanel } from "../../../../hooks/useSidePanel";
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { useSidePanel } from "../../../../hooks/useSidePanel";
import * as Constants from "../../../Tables/Constants"; import * as Constants from "../../../Tables/Constants";
import QueryViewModel from "../../../Tables/QueryBuilder/QueryViewModel"; import QueryViewModel from "../../../Tables/QueryBuilder/QueryViewModel";
import { RightPaneForm, RightPaneFormProps } from "../../RightPaneForm/RightPaneForm"; import { RightPaneForm, RightPaneFormProps } from "../../RightPaneForm/RightPaneForm";
@@ -128,9 +128,8 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
label="Available Columns" label="Available Columns"
checked={isAvailableColumnChecked} checked={isAvailableColumnChecked}
onChange={availableColumnsCheckboxClick} onChange={availableColumnsCheckboxClick}
ariaPositionInSet={0}
/> />
{columnOptions.map((column, index) => { {columnOptions.map((column) => {
return ( return (
<Checkbox <Checkbox
label={column.columnName} label={column.columnName}
@@ -138,7 +137,6 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
key={column.columnName} key={column.columnName}
checked={column.selected} checked={column.selected}
disabled={!column.editable} disabled={!column.editable}
ariaPositionInSet={index + 1}
/> />
); );
})} })}

View File

@@ -28,7 +28,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
> >
<Text> <Text>
<span <span
className="css-53" className="css-109"
> >
Select the columns that you want to query. Select the columns that you want to query.
</span> </span>
@@ -37,14 +37,12 @@ exports[`Table query select Panel should render Default properly 1`] = `
className="column-select-view" className="column-select-view"
> >
<StyledCheckboxBase <StyledCheckboxBase
ariaPositionInSet={0}
checked={true} checked={true}
id="availableCheckbox" id="availableCheckbox"
label="Available Columns" label="Available Columns"
onChange={[Function]} onChange={[Function]}
> >
<CheckboxBase <CheckboxBase
ariaPositionInSet={0}
checked={true} checked={true}
id="availableCheckbox" id="availableCheckbox"
label="Available Columns" label="Available Columns"
@@ -325,33 +323,30 @@ exports[`Table query select Panel should render Default properly 1`] = `
} }
> >
<div <div
className="ms-Checkbox is-checked is-enabled root-54" className="ms-Checkbox is-checked is-enabled root-110"
> >
<input <input
aria-checked="true"
aria-label="Available Columns"
aria-posinset={0}
checked={true} checked={true}
className="input-55" className="input-111"
data-ktp-execute-target={true} data-ktp-execute-target={true}
id="availableCheckbox" id="availableCheckbox"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<label <label
className="ms-Checkbox-label label-56" className="ms-Checkbox-label label-112"
htmlFor="availableCheckbox" htmlFor="availableCheckbox"
> >
<div <div
className="ms-Checkbox-checkbox checkbox-57" className="ms-Checkbox-checkbox checkbox-113"
data-ktp-target={true} data-ktp-target={true}
> >
<StyledIconBase <StyledIconBase
className="ms-Checkbox-checkmark checkmark-58" className="ms-Checkbox-checkmark checkmark-114"
iconName="CheckMark" iconName="CheckMark"
> >
<IconBase <IconBase
className="ms-Checkbox-checkmark checkmark-58" className="ms-Checkbox-checkmark checkmark-114"
iconName="CheckMark" iconName="CheckMark"
styles={[Function]} styles={[Function]}
theme={ theme={
@@ -630,7 +625,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
> >
<i <i
aria-hidden={true} aria-hidden={true}
className="ms-Checkbox-checkmark checkmark-61" className="ms-Checkbox-checkmark checkmark-118"
data-icon-name="CheckMark" data-icon-name="CheckMark"
> >
@@ -639,8 +634,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
</StyledIconBase> </StyledIconBase>
</div> </div>
<span <span
aria-hidden="true" className="ms-Checkbox-text text-115"
className="ms-Checkbox-text text-59"
> >
Available Columns Available Columns
</span> </span>
@@ -649,7 +643,6 @@ exports[`Table query select Panel should render Default properly 1`] = `
</CheckboxBase> </CheckboxBase>
</StyledCheckboxBase> </StyledCheckboxBase>
<StyledCheckboxBase <StyledCheckboxBase
ariaPositionInSet={1}
checked={true} checked={true}
disabled={false} disabled={false}
key="" key=""
@@ -657,7 +650,6 @@ exports[`Table query select Panel should render Default properly 1`] = `
onChange={[Function]} onChange={[Function]}
> >
<CheckboxBase <CheckboxBase
ariaPositionInSet={1}
checked={true} checked={true}
disabled={false} disabled={false}
label="" label=""
@@ -938,15 +930,12 @@ exports[`Table query select Panel should render Default properly 1`] = `
} }
> >
<div <div
className="ms-Checkbox is-checked is-enabled root-54" className="ms-Checkbox is-checked is-enabled root-110"
> >
<input <input
aria-checked="true"
aria-disabled={false} aria-disabled={false}
aria-label=""
aria-posinset={1}
checked={true} checked={true}
className="input-55" className="input-111"
data-ktp-execute-target={true} data-ktp-execute-target={true}
disabled={false} disabled={false}
id="checkbox-0" id="checkbox-0"
@@ -954,19 +943,19 @@ exports[`Table query select Panel should render Default properly 1`] = `
type="checkbox" type="checkbox"
/> />
<label <label
className="ms-Checkbox-label label-56" className="ms-Checkbox-label label-112"
htmlFor="checkbox-0" htmlFor="checkbox-0"
> >
<div <div
className="ms-Checkbox-checkbox checkbox-57" className="ms-Checkbox-checkbox checkbox-113"
data-ktp-target={true} data-ktp-target={true}
> >
<StyledIconBase <StyledIconBase
className="ms-Checkbox-checkmark checkmark-58" className="ms-Checkbox-checkmark checkmark-114"
iconName="CheckMark" iconName="CheckMark"
> >
<IconBase <IconBase
className="ms-Checkbox-checkmark checkmark-58" className="ms-Checkbox-checkmark checkmark-114"
iconName="CheckMark" iconName="CheckMark"
styles={[Function]} styles={[Function]}
theme={ theme={
@@ -1245,7 +1234,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
> >
<i <i
aria-hidden={true} aria-hidden={true}
className="ms-Checkbox-checkmark checkmark-61" className="ms-Checkbox-checkmark checkmark-118"
data-icon-name="CheckMark" data-icon-name="CheckMark"
> >
@@ -2149,7 +2138,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2175,7 +2164,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2187,14 +2176,16 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -2225,7 +2216,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -2252,7 +2243,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -2277,14 +2268,16 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -2318,7 +2311,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2335,7 +2328,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -2347,7 +2340,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -2363,12 +2356,13 @@ exports[`Table query select Panel should render Default properly 1`] = `
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -2379,14 +2373,16 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -2409,13 +2405,21 @@ exports[`Table query select Panel should render Default properly 1`] = `
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -2428,7 +2432,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -2441,7 +2445,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -2455,7 +2459,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -2469,7 +2473,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -2485,7 +2489,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -2494,7 +2498,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2510,7 +2514,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -2522,7 +2526,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -2535,7 +2539,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -2557,18 +2561,18 @@ exports[`Table query select Panel should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -2618,7 +2622,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2627,7 +2631,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2635,7 +2639,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2657,14 +2661,16 @@ exports[`Table query select Panel should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -2686,7 +2692,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2976,7 +2982,7 @@ exports[`Table query select Panel should render Default properly 1`] = `
> >
<button <button
aria-label="OK" aria-label="OK"
className="ms-Button ms-Button--primary root-68" className="ms-Button ms-Button--primary root-125"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -2988,14 +2994,14 @@ exports[`Table query select Panel should render Default properly 1`] = `
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-69" className="ms-Button-flexContainer flexContainer-126"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-70" className="ms-Button-textContainer textContainer-127"
> >
<span <span
className="ms-Button-label label-72" className="ms-Button-label label-129"
id="id__1" id="id__1"
key="id__1" key="id__1"
> >

View File

@@ -35,7 +35,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
> >
<div <div
aria-label="Add Property" aria-label="Add Property"
className="ms-Stack addButtonEntiy css-53" className="ms-Stack addButtonEntiy css-109"
onClick={[Function]} onClick={[Function]}
onKeyPress={[Function]} onKeyPress={[Function]}
tabIndex={0} tabIndex={0}
@@ -43,7 +43,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
<StyledImageBase <StyledImageBase
alt="Add Property" alt="Add Property"
height={30} height={30}
key=".0:$.0" key=".0:$.$.0"
src={Object {}} src={Object {}}
width={16} width={16}
> >
@@ -328,7 +328,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
width={16} width={16}
> >
<div <div
className="ms-Image root-54" className="ms-Image root-110"
style={ style={
Object { Object {
"height": 30, "height": 30,
@@ -338,7 +338,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
> >
<img <img
alt="Add Property" alt="Add Property"
className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-55" className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-111"
key="fabricImage[object Object]" key="fabricImage[object Object]"
onError={[Function]} onError={[Function]}
onLoad={[Function]} onLoad={[Function]}
@@ -349,10 +349,10 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
</StyledImageBase> </StyledImageBase>
<Text <Text
className="addNewParamStyle" className="addNewParamStyle"
key=".0:$.1" key=".0:$.$.1"
> >
<span <span
className="addNewParamStyle css-56" className="addNewParamStyle css-112"
> >
Add Property Add Property
</span> </span>
@@ -1249,7 +1249,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1275,7 +1275,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1287,14 +1287,16 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1325,7 +1327,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -1352,7 +1354,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1377,14 +1379,16 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1418,7 +1422,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1435,7 +1439,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -1447,7 +1451,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1463,12 +1467,13 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -1479,14 +1484,16 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1509,13 +1516,21 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -1528,7 +1543,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -1541,7 +1556,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1555,7 +1570,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1569,7 +1584,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -1585,7 +1600,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -1594,7 +1609,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1610,7 +1625,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -1622,7 +1637,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -1635,7 +1650,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -1657,18 +1672,18 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -1718,7 +1733,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1727,7 +1742,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1735,7 +1750,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1757,14 +1772,16 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1786,7 +1803,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2076,7 +2093,7 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
> >
<button <button
aria-label="Add Entity" aria-label="Add Entity"
className="ms-Button ms-Button--primary root-57" className="ms-Button ms-Button--primary root-113"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -2088,14 +2105,14 @@ exports[`Excute Add Table Entity Pane should render Default properly 1`] = `
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-58" className="ms-Button-flexContainer flexContainer-114"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-59" className="ms-Button-textContainer textContainer-115"
> >
<span <span
className="ms-Button-label label-61" className="ms-Button-label label-117"
id="id__0" id="id__0"
key="id__0" key="id__0"
> >

View File

@@ -32,13 +32,13 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
onClick={[Function]} onClick={[Function]}
> >
<div <div
className="ms-Stack addButtonEntiy css-53" className="ms-Stack addButtonEntiy css-109"
onClick={[Function]} onClick={[Function]}
> >
<StyledImageBase <StyledImageBase
alt="Add Entity" alt="Add Entity"
height={30} height={30}
key=".0:$.0" key=".0:$.$.0"
src={Object {}} src={Object {}}
width={16} width={16}
> >
@@ -323,7 +323,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
width={16} width={16}
> >
<div <div
className="ms-Image root-54" className="ms-Image root-110"
style={ style={
Object { Object {
"height": 30, "height": 30,
@@ -333,7 +333,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
> >
<img <img
alt="Add Entity" alt="Add Entity"
className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-55" className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-111"
key="fabricImage[object Object]" key="fabricImage[object Object]"
onError={[Function]} onError={[Function]}
onLoad={[Function]} onLoad={[Function]}
@@ -344,10 +344,10 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
</StyledImageBase> </StyledImageBase>
<Text <Text
className="addNewParamStyle" className="addNewParamStyle"
key=".0:$.1" key=".0:$.$.1"
> >
<span <span
className="addNewParamStyle css-56" className="addNewParamStyle css-112"
> >
Add Property Add Property
</span> </span>
@@ -355,6 +355,17 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
</div> </div>
</Stack> </Stack>
</div> </div>
<div
className="panelNullWarning"
style={
Object {
"color": "red",
"padding": "20px",
}
}
>
Warning: Null fields will not be displayed for editing.
</div>
<PanelFooterComponent <PanelFooterComponent
buttonLabel="Update" buttonLabel="Update"
isButtonDisabled={false} isButtonDisabled={false}
@@ -1244,7 +1255,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1270,7 +1281,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1282,14 +1293,16 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1320,7 +1333,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -1347,7 +1360,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1372,14 +1385,16 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -1413,7 +1428,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1430,7 +1445,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -1442,7 +1457,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -1458,12 +1473,13 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -1474,14 +1490,16 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1504,13 +1522,21 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -1523,7 +1549,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -1536,7 +1562,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1550,7 +1576,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -1564,7 +1590,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -1580,7 +1606,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -1589,7 +1615,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1605,7 +1631,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -1617,7 +1643,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -1630,7 +1656,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -1652,18 +1678,18 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -1713,7 +1739,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1722,7 +1748,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1730,7 +1756,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -1752,14 +1778,16 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -1781,7 +1809,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2071,7 +2099,7 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
> >
<button <button
aria-label="Update" aria-label="Update"
className="ms-Button ms-Button--primary root-57" className="ms-Button ms-Button--primary root-113"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -2083,14 +2111,14 @@ exports[`Excute Edit Table Entity Pane should render Default properly 1`] = `
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-58" className="ms-Button-flexContainer flexContainer-114"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-59" className="ms-Button-textContainer textContainer-115"
> >
<span <span
className="ms-Button-label label-61" className="ms-Button-label label-117"
id="id__0" id="id__0"
key="id__0" key="id__0"
> >

View File

@@ -25,13 +25,13 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
verticalAlign="center" verticalAlign="center"
> >
<div <div
className="ms-Stack panelInfoErrorContainer css-53" className="ms-Stack panelInfoErrorContainer css-109"
> >
<StyledIconBase <StyledIconBase
aria-label="warning" aria-label="warning"
className="panelWarningIcon" className="panelWarningIcon"
iconName="WarningSolid" iconName="WarningSolid"
key=".0:$.0" key=".0:$.$.0"
> >
<IconBase <IconBase
aria-label="warning" aria-label="warning"
@@ -314,7 +314,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
> >
<i <i
aria-label="warning" aria-label="warning"
className="panelWarningIcon root-55" className="panelWarningIcon root-112"
data-icon-name="WarningSolid" data-icon-name="WarningSolid"
role="img" role="img"
> >
@@ -323,21 +323,19 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
</IconBase> </IconBase>
</StyledIconBase> </StyledIconBase>
<span <span
aria-live="assertive"
className="panelWarningErrorDetailsLinkContainer" className="panelWarningErrorDetailsLinkContainer"
key=".0:$.1" key=".0:$.$.1"
role="alert"
> >
<Text <Text
aria-label="Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources." aria-label="Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources."
aria-live="assertive"
className="panelWarningErrorMessage" className="panelWarningErrorMessage"
role="alert"
variant="small" variant="small"
> >
<span <span
aria-label="Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources." aria-label="Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources."
aria-live="assertive" className="panelWarningErrorMessage css-113"
className="panelWarningErrorMessage css-56"
role="alert"
> >
Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources. Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources.
</span> </span>
@@ -361,7 +359,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
variant="small" variant="small"
> >
<span <span
className="css-56" className="css-113"
> >
Confirm by typing the database id Confirm by typing the database id
</span> </span>
@@ -665,19 +663,19 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
validateOnLoad={true} validateOnLoad={true}
> >
<div <div
className="ms-TextField is-required root-58" className="ms-TextField is-required root-115"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
> >
<div <div
className="ms-TextField-fieldGroup fieldGroup-59" className="ms-TextField-fieldGroup fieldGroup-116"
> >
<input <input
aria-invalid={false} aria-invalid={false}
aria-label="Confirm by typing the database id" aria-label="Confirm by typing the database id"
autoFocus={true} autoFocus={true}
className="ms-TextField-field field-60" className="ms-TextField-field field-117"
id="confirmDatabaseId" id="confirmDatabaseId"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@@ -701,7 +699,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
variant="small" variant="small"
> >
<span <span
className="css-69" className="css-126"
> >
Help us improve Azure Cosmos DB! Help us improve Azure Cosmos DB!
</span> </span>
@@ -711,7 +709,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
variant="small" variant="small"
> >
<span <span
className="css-69" className="css-126"
> >
What is the reason why you are deleting this database? What is the reason why you are deleting this database?
</span> </span>
@@ -1015,18 +1013,18 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
validateOnLoad={true} validateOnLoad={true}
> >
<div <div
className="ms-TextField ms-TextField--multiline root-58" className="ms-TextField ms-TextField--multiline root-115"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
> >
<div <div
className="ms-TextField-fieldGroup fieldGroup-70" className="ms-TextField-fieldGroup fieldGroup-127"
> >
<textarea <textarea
aria-invalid={false} aria-invalid={false}
aria-label="Help us improve Azure Cosmos DB! What is the reason why you are deleting this database?" aria-label="Help us improve Azure Cosmos DB! What is the reason why you are deleting this database?"
className="ms-TextField-field field-71" className="ms-TextField-field field-128"
id="deleteDatabaseFeedbackInput" id="deleteDatabaseFeedbackInput"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@@ -1931,7 +1929,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"iconDisabled": Object { "iconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1957,7 +1955,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"menuIconDisabled": Object { "menuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -1969,14 +1967,16 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -2007,7 +2007,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"display": "inline-block", "display": "inline-block",
"padding": "0 16px", "padding": "0 16px",
"selectors": Object { "selectors": Object {
":active > *": Object { ":active > span": Object {
"left": 0, "left": 0,
"position": "relative", "position": "relative",
"top": 0, "top": 0,
@@ -2034,7 +2034,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -2059,14 +2059,16 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid transparent", "border": "1px solid transparent",
"borderRadius": undefined,
"bottom": 2, "bottom": 2,
"content": "\\"\\"", "content": "\\"\\"",
"left": 2, "left": 2,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 2, "right": 2,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
"outlineColor": "ButtonText", "outlineColor": "ButtonText",
@@ -2100,7 +2102,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"backgroundColor": "#f3f2f1", "backgroundColor": "#f3f2f1",
"color": "#d2d0ce", "color": "#d2d0ce",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2117,7 +2119,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"border": "1px solid #106ebe", "border": "1px solid #106ebe",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"borderColor": "Highlight", "borderColor": "Highlight",
"color": "Window", "color": "Window",
@@ -2129,7 +2131,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"border": "1px solid #005a9e", "border": "1px solid #005a9e",
"color": "#ffffff", "color": "#ffffff",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"borderColor": "WindowText", "borderColor": "WindowText",
@@ -2145,12 +2147,13 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"overflow": "hidden", "overflow": "hidden",
"padding": 0, "padding": 0,
"position": "absolute", "position": "absolute",
"whiteSpace": "nowrap",
"width": 1, "width": 1,
}, },
"splitButtonContainer": Array [ "splitButtonContainer": Array [
Object { Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
}, },
}, },
@@ -2161,14 +2164,16 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": "none",
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -2191,13 +2196,21 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderRight": "none", "borderRight": "none",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
}, },
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"border": "none", "border": "none",
"borderBottomRightRadius": "0", "borderBottomRightRadius": "0",
"borderTopRightRadius": "0", "borderTopRightRadius": "0",
"flexGrow": "1",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { ":active": Object {
"border": "none",
},
":hover": Object {
"border": "none",
},
"@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid WindowText", "border": "1px solid WindowText",
@@ -2210,7 +2223,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
".ms-Button--primary + .ms-Button": Object { ".ms-Button--primary + .ms-Button": Object {
"border": "none", "border": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "1px solid WindowText", "border": "1px solid WindowText",
"borderLeftWidth": "0", "borderLeftWidth": "0",
}, },
@@ -2223,7 +2236,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -2237,7 +2250,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
"color": "Window", "color": "Window",
@@ -2251,7 +2264,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"border": "none", "border": "none",
"outline": "none", "outline": "none",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"MsHighContrastAdjust": "none", "MsHighContrastAdjust": "none",
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
@@ -2267,7 +2280,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Highlight", "backgroundColor": "Highlight",
"color": "Window", "color": "Window",
}, },
@@ -2276,7 +2289,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
".ms-Button.is-disabled": Object { ".ms-Button.is-disabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2292,7 +2305,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
}, },
}, },
@@ -2304,7 +2317,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "WindowText",
}, },
}, },
@@ -2317,7 +2330,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"position": "absolute", "position": "absolute",
"right": 31, "right": 31,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "GrayText", "backgroundColor": "GrayText",
}, },
}, },
@@ -2339,18 +2352,18 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
":hover": Object { ":hover": Object {
"backgroundColor": "#106ebe", "backgroundColor": "#106ebe",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "Highlight", "color": "Highlight",
}, },
}, },
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "WindowText", "backgroundColor": "Canvas",
}, },
}, },
}, },
Object { Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"color": "WindowText", "color": "WindowText",
}, },
@@ -2400,7 +2413,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Button--primary": Object { ".ms-Button--primary": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"borderColor": "GrayText", "borderColor": "GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2409,7 +2422,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
}, },
".ms-Button-menuIcon": Object { ".ms-Button-menuIcon": Object {
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2417,7 +2430,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
":hover": Object { ":hover": Object {
"cursor": "default", "cursor": "default",
}, },
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"backgroundColor": "Window", "backgroundColor": "Window",
"border": "1px solid GrayText", "border": "1px solid GrayText",
"color": "GrayText", "color": "GrayText",
@@ -2439,14 +2452,16 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"selectors": Object { "selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object { ".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff", "border": "1px solid #ffffff",
"borderRadius": undefined,
"bottom": 3, "bottom": 3,
"content": "\\"\\"", "content": "\\"\\"",
"left": 3, "left": 3,
"outline": "1px solid #605e5c", "outline": "1px solid #605e5c",
"pointerEvents": undefined,
"position": "absolute", "position": "absolute",
"right": 3, "right": 3,
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"border": "none", "border": "none",
"bottom": -2, "bottom": -2,
"left": -2, "left": -2,
@@ -2468,7 +2483,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
"splitButtonMenuIconDisabled": Object { "splitButtonMenuIconDisabled": Object {
"color": "#a19f9d", "color": "#a19f9d",
"selectors": Object { "selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object { "@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)": Object {
"color": "GrayText", "color": "GrayText",
}, },
}, },
@@ -2758,7 +2773,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
> >
<button <button
aria-label="OK" aria-label="OK"
className="ms-Button ms-Button--primary root-73" className="ms-Button ms-Button--primary root-130"
data-is-focusable={true} data-is-focusable={true}
id="sidePanelOkButton" id="sidePanelOkButton"
onClick={[Function]} onClick={[Function]}
@@ -2770,16 +2785,16 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
type="submit" type="submit"
> >
<span <span
className="ms-Button-flexContainer flexContainer-74" className="ms-Button-flexContainer flexContainer-131"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<span <span
className="ms-Button-textContainer textContainer-75" className="ms-Button-textContainer textContainer-132"
> >
<span <span
className="ms-Button-label label-77" className="ms-Button-label label-134"
id="id__6" id="id__10"
key="id__6" key="id__10"
> >
OK OK
</span> </span>

View File

@@ -6,6 +6,7 @@ exports[`PaneContainerComponent test should be resize if notification console is
customWidth="440px" customWidth="440px"
headerClassName="panelHeader" headerClassName="panelHeader"
headerText="test" headerText="test"
isFooterAtBottom={true}
isLightDismiss={true} isLightDismiss={true}
isOpen={true} isOpen={true}
onDismiss={[Function]} onDismiss={[Function]}
@@ -18,9 +19,9 @@ exports[`PaneContainerComponent test should be resize if notification console is
Object { Object {
"commands": Object { "commands": Object {
"marginTop": 8, "marginTop": 8,
"paddingTop": 0,
}, },
"content": Object { "content": Object {
"height": "100%",
"padding": 0, "padding": 0,
}, },
"header": Object { "header": Object {
@@ -29,9 +30,6 @@ exports[`PaneContainerComponent test should be resize if notification console is
"navigation": Object { "navigation": Object {
"borderBottom": "1px solid #cccccc", "borderBottom": "1px solid #cccccc",
}, },
"scrollableContent": Object {
"height": "100%",
},
} }
} }
type={7} type={7}
@@ -48,6 +46,7 @@ exports[`PaneContainerComponent test should render with panel content and header
customWidth="440px" customWidth="440px"
headerClassName="panelHeader" headerClassName="panelHeader"
headerText="test" headerText="test"
isFooterAtBottom={true}
isLightDismiss={true} isLightDismiss={true}
isOpen={true} isOpen={true}
onDismiss={[Function]} onDismiss={[Function]}
@@ -60,9 +59,9 @@ exports[`PaneContainerComponent test should render with panel content and header
Object { Object {
"commands": Object { "commands": Object {
"marginTop": 8, "marginTop": 8,
"paddingTop": 0,
}, },
"content": Object { "content": Object {
"height": "100%",
"padding": 0, "padding": 0,
}, },
"header": Object { "header": Object {
@@ -71,9 +70,6 @@ exports[`PaneContainerComponent test should render with panel content and header
"navigation": Object { "navigation": Object {
"borderBottom": "1px solid #cccccc", "borderBottom": "1px solid #cccccc",
}, },
"scrollableContent": Object {
"height": "100%",
},
} }
} }
type={7} type={7}

View File

@@ -1,10 +1,10 @@
import { Checkbox, ChoiceGroup, DefaultButton, IconButton, PrimaryButton, TextField } from "@fluentui/react"; import { Checkbox, DefaultButton, IconButton, PrimaryButton, TextField } from "@fluentui/react";
import Explorer from "Explorer/Explorer"; import Explorer from "Explorer/Explorer";
import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal"; import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
import { SubmitFeedback } from "Explorer/QueryCopilot/Shared/QueryCopilotClient"; import { SubmitFeedback } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
import { getUserEmail } from "Utils/UserUtils"; import { getUserEmail } from "Utils/UserUtils";
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react"; import React from "react";
jest.mock("Utils/UserUtils"); jest.mock("Utils/UserUtils");
@@ -13,21 +13,49 @@ jest.mock("Utils/UserUtils");
jest.mock("Explorer/QueryCopilot/Shared/QueryCopilotClient"); jest.mock("Explorer/QueryCopilot/Shared/QueryCopilotClient");
SubmitFeedback as jest.Mock; SubmitFeedback as jest.Mock;
jest.mock("Explorer/QueryCopilot/QueryCopilotContext");
const mockUseCopilotStore = useCopilotStore as jest.Mock;
const mockReturnValue = {
generatedQuery: "test query",
userPrompt: "test prompt",
likeQuery: false,
showFeedbackModal: false,
closeFeedbackModal: jest.fn,
setHideFeedbackModalForLikedQueries: jest.fn,
};
describe("Query Copilot Feedback Modal snapshot test", () => { describe("Query Copilot Feedback Modal snapshot test", () => {
beforeEach(() => { beforeEach(() => {
mockUseCopilotStore.mockReturnValue(mockReturnValue);
jest.clearAllMocks(); jest.clearAllMocks();
}); });
it("shoud render and match snapshot", () => { it("shoud render and match snapshot", () => {
useQueryCopilot.getState().openFeedbackModal("test query", false, "test prompt"); mockUseCopilotStore.mockReturnValue({
...mockReturnValue,
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />); showFeedbackModal: true,
});
const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
expect(wrapper.props().isOpen).toBeTruthy(); expect(wrapper.props().isOpen).toBeTruthy();
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it("should close on cancel click", () => { it("should close on cancel click", () => {
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />); const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const cancelButton = wrapper.find(IconButton); const cancelButton = wrapper.find(IconButton);
cancelButton.simulate("click"); cancelButton.simulate("click");
@@ -38,7 +66,14 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
}); });
it("should get user unput", () => { it("should get user unput", () => {
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />); const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const testUserInput = "test user input"; const testUserInput = "test user input";
const userInput = wrapper.find(TextField).first(); const userInput = wrapper.find(TextField).first();
@@ -48,30 +83,15 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it("should record user contact choice no", () => {
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />);
const contactAllowed = wrapper.find(ChoiceGroup);
contactAllowed.simulate("change", {}, { key: "no" });
expect(getUserEmail).toHaveBeenCalledTimes(3);
expect(wrapper.find(ChoiceGroup).props().selectedKey).toEqual("no");
expect(wrapper).toMatchSnapshot();
});
it("should record user contact choice yes", () => {
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />);
const contactAllowed = wrapper.find(ChoiceGroup);
contactAllowed.simulate("change", {}, { key: "yes" });
expect(getUserEmail).toHaveBeenCalledTimes(4);
expect(wrapper.find(ChoiceGroup).props().selectedKey).toEqual("yes");
expect(wrapper).toMatchSnapshot();
});
it("should not render dont show again button", () => { it("should not render dont show again button", () => {
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />); const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const dontShowAgain = wrapper.find(Checkbox); const dontShowAgain = wrapper.find(Checkbox);
@@ -79,9 +99,20 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it("should render dont show again button and check it ", () => { it("should render dont show again button and check it", () => {
useQueryCopilot.getState().openFeedbackModal("test query", true, "test prompt"); mockUseCopilotStore.mockReturnValue({
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />); ...mockReturnValue,
showFeedbackModal: true,
likeQuery: true,
});
const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const dontShowAgain = wrapper.find(Checkbox); const dontShowAgain = wrapper.find(Checkbox);
dontShowAgain.simulate("change", {}, true); dontShowAgain.simulate("change", {}, true);
@@ -92,7 +123,14 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
}); });
it("should cancel submission", () => { it("should cancel submission", () => {
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={new Explorer()} />); const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const cancelButton = wrapper.find(DefaultButton); const cancelButton = wrapper.find(DefaultButton);
cancelButton.simulate("click"); cancelButton.simulate("click");
@@ -104,7 +142,14 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
it("should not submit submission if required description field is null", () => { it("should not submit submission if required description field is null", () => {
const explorer = new Explorer(); const explorer = new Explorer();
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={explorer} />); const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={explorer}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const submitButton = wrapper.find(PrimaryButton); const submitButton = wrapper.find(PrimaryButton);
submitButton.simulate("click"); submitButton.simulate("click");
@@ -114,9 +159,15 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
}); });
it("should submit submission", () => { it("should submit submission", () => {
useQueryCopilot.getState().openFeedbackModal("test query", false, "test prompt");
const explorer = new Explorer(); const explorer = new Explorer();
const wrapper = shallow(<QueryCopilotFeedbackModal explorer={explorer} />); const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={explorer}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const submitButton = wrapper.find("form"); const submitButton = wrapper.find("form");
submitButton.simulate("submit"); submitButton.simulate("submit");
@@ -124,12 +175,14 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
expect(SubmitFeedback).toHaveBeenCalledTimes(1); expect(SubmitFeedback).toHaveBeenCalledTimes(1);
expect(SubmitFeedback).toHaveBeenCalledWith({ expect(SubmitFeedback).toHaveBeenCalledWith({
containerId: "CopilotUserContainer",
databaseId: "CopilotUserDb",
mode: "User",
params: { params: {
likeQuery: false, likeQuery: false,
generatedQuery: "test query", generatedQuery: "test query",
userPrompt: "test prompt", userPrompt: "test prompt",
description: "", description: "",
contact: getUserEmail(),
}, },
explorer: explorer, explorer: explorer,
}); });

View File

@@ -1,6 +1,5 @@
import { import {
Checkbox, Checkbox,
ChoiceGroup,
DefaultButton, DefaultButton,
IconButton, IconButton,
Link, Link,
@@ -11,12 +10,21 @@ import {
TextField, TextField,
} from "@fluentui/react"; } from "@fluentui/react";
import Explorer from "Explorer/Explorer"; import Explorer from "Explorer/Explorer";
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
import { SubmitFeedback } from "Explorer/QueryCopilot/Shared/QueryCopilotClient"; import { SubmitFeedback } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react"; import React from "react";
import { getUserEmail } from "../../../Utils/UserUtils";
export const QueryCopilotFeedbackModal = ({ explorer }: { explorer: Explorer }): JSX.Element => { export const QueryCopilotFeedbackModal = ({
explorer,
databaseId,
containerId,
mode,
}: {
explorer: Explorer;
databaseId: string;
containerId: string;
mode: string;
}): JSX.Element => {
const { const {
generatedQuery, generatedQuery,
userPrompt, userPrompt,
@@ -24,18 +32,19 @@ export const QueryCopilotFeedbackModal = ({ explorer }: { explorer: Explorer }):
showFeedbackModal, showFeedbackModal,
closeFeedbackModal, closeFeedbackModal,
setHideFeedbackModalForLikedQueries, setHideFeedbackModalForLikedQueries,
} = useQueryCopilot(); } = useCopilotStore();
const [isContactAllowed, setIsContactAllowed] = React.useState<boolean>(false);
const [description, setDescription] = React.useState<string>(""); const [description, setDescription] = React.useState<string>("");
const [doNotShowAgainChecked, setDoNotShowAgainChecked] = React.useState<boolean>(false); const [doNotShowAgainChecked, setDoNotShowAgainChecked] = React.useState<boolean>(false);
const [contact, setContact] = React.useState<string>(getUserEmail());
const handleSubmit = () => { const handleSubmit = () => {
closeFeedbackModal(); closeFeedbackModal();
setHideFeedbackModalForLikedQueries(doNotShowAgainChecked); setHideFeedbackModalForLikedQueries(doNotShowAgainChecked);
SubmitFeedback({ SubmitFeedback({
params: { generatedQuery, likeQuery, description, userPrompt, contact }, params: { generatedQuery, likeQuery, description, userPrompt },
explorer: explorer, explorer,
databaseId,
containerId,
mode: mode,
}); });
}; };
@@ -64,30 +73,6 @@ export const QueryCopilotFeedbackModal = ({ explorer }: { explorer: Explorer }):
defaultValue={generatedQuery} defaultValue={generatedQuery}
readOnly readOnly
/> />
<ChoiceGroup
styles={{
root: {
marginBottom: 14,
},
flexContainer: {
selectors: {
".ms-ChoiceField-field::before": { marginTop: 4 },
".ms-ChoiceField-field::after": { marginTop: 4 },
".ms-ChoiceFieldLabel": { paddingLeft: 6 },
},
},
}}
label="May we contact you about your feedback?"
options={[
{ key: "yes", text: "Yes, you may contact me." },
{ key: "no", text: "No, do not contact me." },
]}
selectedKey={isContactAllowed ? "yes" : "no"}
onChange={(_, option) => {
setIsContactAllowed(option.key === "yes");
setContact(option.key === "yes" ? getUserEmail() : "");
}}
></ChoiceGroup>
<Text style={{ fontSize: 12, marginBottom: 14 }}> <Text style={{ fontSize: 12, marginBottom: 14 }}>
By pressing submit, your feedback will be used to improve Microsoft products and services. Please see the{" "} By pressing submit, your feedback will be used to improve Microsoft products and services. Please see the{" "}
{ {

View File

@@ -1,7 +1,6 @@
.modalContentPadding { .modalContentPadding {
padding-top: 15px; padding-top: 15px;
width: 513px; width: 513px;
height: 638px;
} }
.exitPadding { .exitPadding {
@@ -39,7 +38,7 @@
} }
.buttonPadding { .buttonPadding {
padding: 15px 0px 0px 0px; padding: 15px 0px 15px 0px;
} }
.tryButton { .tryButton {

View File

@@ -1,7 +1,6 @@
import { IconButton, Image, Link, Modal, PrimaryButton, Stack, StackItem, Text } from "@fluentui/react"; import { IconButton, Image, Link, Modal, PrimaryButton, Stack, StackItem, Text } from "@fluentui/react";
import { useBoolean } from "@fluentui/react-hooks"; import { useBoolean } from "@fluentui/react-hooks";
import React from "react"; import React from "react";
import Database from "../../../../images/CopilotDatabase.svg";
import Flash from "../../../../images/CopilotFlash.svg"; import Flash from "../../../../images/CopilotFlash.svg";
import Thumb from "../../../../images/CopilotThumb.svg"; import Thumb from "../../../../images/CopilotThumb.svg";
import CoplilotWelcomeIllustration from "../../../../images/CopliotWelcomeIllustration.svg"; import CoplilotWelcomeIllustration from "../../../../images/CopliotWelcomeIllustration.svg";
@@ -23,8 +22,10 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
onDismiss={hideModal} onDismiss={hideModal}
isBlocking={false} isBlocking={false}
styles={{ styles={{
scrollableContent: { main: {
minHeight: 680, maxHeight: 600,
borderRadius: 10,
overflow: "hidden",
}, },
}} }}
> >
@@ -36,9 +37,6 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
</Stack.Item> </Stack.Item>
</Stack> </Stack>
<Stack horizontal grow={1} horizontalAlign="end" verticalAlign="start" className="exitPadding"> <Stack horizontal grow={1} horizontalAlign="end" verticalAlign="start" className="exitPadding">
<Stack.Item className="previewMargin">
<Text className="preview">Preview</Text>
</Stack.Item>
<Stack.Item> <Stack.Item>
<IconButton <IconButton
onClick={hideModal} onClick={hideModal}
@@ -52,7 +50,7 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
</Stack> </Stack>
<Stack horizontalAlign="center"> <Stack horizontalAlign="center">
<Stack.Item align="center" style={{ textAlign: "center" }}> <Stack.Item align="center" style={{ textAlign: "center" }}>
<Text className="title bold">Welcome to Copilot in Azure Cosmos DB (Private Preview)</Text> <Text className="title bold">Welcome to Microsoft Copilot for Azure in Cosmos DB</Text>
</Stack.Item> </Stack.Item>
<Stack.Item align="center" className="text"> <Stack.Item align="center" className="text">
<Stack horizontal> <Stack horizontal>
@@ -69,7 +67,7 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
<Text> <Text>
Ask Copilot to generate a query by describing the query in your words. Ask Copilot to generate a query by describing the query in your words.
<br /> <br />
<Link target="_blank" href="https://aka.ms/cdb-copilot-learn-more"> <Link target="_blank" href="https://aka.ms/MicrosoftCopilotForAzureInCDBHowTo">
Learn more Learn more
</Link> </Link>
</Text> </Text>
@@ -87,31 +85,11 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
</StackItem> </StackItem>
</Stack> </Stack>
<Text> <Text>
AI-generated content can have mistakes. Make sure its accurate and appropriate before using it. AI-generated content can have mistakes. Make sure it is accurate and appropriate before executing the
query.
<br /> <br />
<Link target="_blank" href="https://aka.ms/cdb-copilot-preview-terms"> <Link target="_blank" href="https://aka.ms/cdb-copilot-preview-terms">
Read preview terms Read our preview terms here
</Link>
</Text>
</Stack.Item>
<Stack.Item align="center" className="text">
<Stack horizontal>
<StackItem align="start" className="imageTextPadding">
<Image src={Database} />
</StackItem>
<StackItem align="start">
<Text className="bold">
Query Copilot works on a sample database.
<br />
</Text>
</StackItem>
</Stack>
<Text>
While in Private Preview, Query Copilot is setup to work on sample database we have configured for you
at no cost.
<br />
<Link target="_blank" href="https://aka.ms/cdb-copilot-learn-more">
Learn more
</Link> </Link>
</Text> </Text>
</Stack.Item> </Stack.Item>

View File

@@ -76,43 +76,6 @@ exports[`Query Copilot Feedback Modal snapshot test shoud render and match snaps
} }
} }
/> />
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text <Text
style={ style={
Object { Object {
@@ -235,43 +198,6 @@ exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`]
} }
} }
/> />
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text <Text
style={ style={
Object { Object {
@@ -291,21 +217,6 @@ exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`]
for more information. for more information.
</Text> </Text>
<StyledCheckboxBase
checked={false}
label="Don't show me this next time"
onChange={[Function]}
styles={
Object {
"label": Object {
"paddingLeft": 0,
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Stack <Stack
horizontal={true} horizontal={true}
horizontalAlign="end" horizontalAlign="end"
@@ -409,43 +320,6 @@ exports[`Query Copilot Feedback Modal snapshot test should close on cancel click
} }
} }
/> />
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text <Text
style={ style={
Object { Object {
@@ -568,43 +442,6 @@ exports[`Query Copilot Feedback Modal snapshot test should get user unput 1`] =
} }
} }
/> />
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text <Text
style={ style={
Object { Object {
@@ -727,43 +564,6 @@ exports[`Query Copilot Feedback Modal snapshot test should not render dont show
} }
} }
/> />
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text <Text
style={ style={
Object { Object {
@@ -810,325 +610,7 @@ exports[`Query Copilot Feedback Modal snapshot test should not render dont show
</Modal> </Modal>
`; `;
exports[`Query Copilot Feedback Modal snapshot test should record user contact choice no 1`] = ` exports[`Query Copilot Feedback Modal snapshot test should render dont show again button and check it 1`] = `
<Modal
isOpen={false}
>
<form
onSubmit={[Function]}
>
<Stack
style={
Object {
"padding": 24,
}
}
>
<Stack
horizontal={true}
horizontalAlign="space-between"
>
<Text
style={
Object {
"fontSize": 20,
"fontWeight": 600,
"marginBottom": 20,
}
}
>
Send feedback to Microsoft
</Text>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Cancel",
}
}
onClick={[Function]}
/>
</Stack>
<Text
style={
Object {
"fontSize": 14,
"marginBottom": 14,
}
}
>
Your feedback will help improve the experience.
</Text>
<StyledTextFieldBase
label="Description"
multiline={true}
onChange={[Function]}
placeholder="Provide more details"
required={true}
rows={3}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
value=""
/>
<StyledTextFieldBase
defaultValue="test query"
label="Query generated"
readOnly={true}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
"fontSize": 12,
"marginBottom": 14,
}
}
>
By pressing submit, your feedback will be used to improve Microsoft products and services. Please see the
<StyledLinkBase
href="https://privacy.microsoft.com/privacystatement"
target="_blank"
>
Privacy statement
</StyledLinkBase>
for more information.
</Text>
<Stack
horizontal={true}
horizontalAlign="end"
>
<CustomizedPrimaryButton
styles={
Object {
"root": Object {
"marginRight": 8,
},
}
}
type="submit"
>
Submit
</CustomizedPrimaryButton>
<CustomizedDefaultButton
onClick={[Function]}
>
Cancel
</CustomizedDefaultButton>
</Stack>
</Stack>
</form>
</Modal>
`;
exports[`Query Copilot Feedback Modal snapshot test should record user contact choice yes 1`] = `
<Modal
isOpen={false}
>
<form
onSubmit={[Function]}
>
<Stack
style={
Object {
"padding": 24,
}
}
>
<Stack
horizontal={true}
horizontalAlign="space-between"
>
<Text
style={
Object {
"fontSize": 20,
"fontWeight": 600,
"marginBottom": 20,
}
}
>
Send feedback to Microsoft
</Text>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Cancel",
}
}
onClick={[Function]}
/>
</Stack>
<Text
style={
Object {
"fontSize": 14,
"marginBottom": 14,
}
}
>
Your feedback will help improve the experience.
</Text>
<StyledTextFieldBase
label="Description"
multiline={true}
onChange={[Function]}
placeholder="Provide more details"
required={true}
rows={3}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
value=""
/>
<StyledTextFieldBase
defaultValue="test query"
label="Query generated"
readOnly={true}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="yes"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
"fontSize": 12,
"marginBottom": 14,
}
}
>
By pressing submit, your feedback will be used to improve Microsoft products and services. Please see the
<StyledLinkBase
href="https://privacy.microsoft.com/privacystatement"
target="_blank"
>
Privacy statement
</StyledLinkBase>
for more information.
</Text>
<Stack
horizontal={true}
horizontalAlign="end"
>
<CustomizedPrimaryButton
styles={
Object {
"root": Object {
"marginRight": 8,
},
}
}
type="submit"
>
Submit
</CustomizedPrimaryButton>
<CustomizedDefaultButton
onClick={[Function]}
>
Cancel
</CustomizedDefaultButton>
</Stack>
</Stack>
</form>
</Modal>
`;
exports[`Query Copilot Feedback Modal snapshot test should render dont show again button and check it 1`] = `
<Modal <Modal
isOpen={true} isOpen={true}
> >
@@ -1204,43 +686,6 @@ exports[`Query Copilot Feedback Modal snapshot test should render dont show agai
} }
} }
/> />
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text <Text
style={ style={
Object { Object {
@@ -1378,43 +823,6 @@ exports[`Query Copilot Feedback Modal snapshot test should submit submission 1`]
} }
} }
/> />
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text <Text
style={ style={
Object { Object {

View File

@@ -8,8 +8,10 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
onDismiss={[Function]} onDismiss={[Function]}
styles={ styles={
Object { Object {
"scrollableContent": Object { "main": Object {
"minHeight": 680, "borderRadius": 10,
"maxHeight": 600,
"overflow": "hidden",
}, },
} }
} }
@@ -38,15 +40,6 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
horizontalAlign="end" horizontalAlign="end"
verticalAlign="start" verticalAlign="start"
> >
<StackItem
className="previewMargin"
>
<Text
className="preview"
>
Preview
</Text>
</StackItem>
<StackItem> <StackItem>
<CustomizedIconButton <CustomizedIconButton
ariaLabel="Exit" ariaLabel="Exit"
@@ -76,7 +69,7 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
<Text <Text
className="title bold" className="title bold"
> >
Welcome to Copilot in Azure Cosmos DB (Private Preview) Welcome to Microsoft Copilot for Azure in Cosmos DB
</Text> </Text>
</StackItem> </StackItem>
<StackItem <StackItem
@@ -109,7 +102,7 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
Ask Copilot to generate a query by describing the query in your words. Ask Copilot to generate a query by describing the query in your words.
<br /> <br />
<StyledLinkBase <StyledLinkBase
href="https://aka.ms/cdb-copilot-learn-more" href="https://aka.ms/MicrosoftCopilotForAzureInCDBHowTo"
target="_blank" target="_blank"
> >
Learn more Learn more
@@ -143,50 +136,13 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
</StackItem> </StackItem>
</Stack> </Stack>
<Text> <Text>
AI-generated content can have mistakes. Make sure its accurate and appropriate before using it. AI-generated content can have mistakes. Make sure it is accurate and appropriate before executing the query.
<br /> <br />
<StyledLinkBase <StyledLinkBase
href="https://aka.ms/cdb-copilot-preview-terms" href="https://aka.ms/cdb-copilot-preview-terms"
target="_blank" target="_blank"
> >
Read preview terms Read our preview terms here
</StyledLinkBase>
</Text>
</StackItem>
<StackItem
align="center"
className="text"
>
<Stack
horizontal={true}
>
<StackItem
align="start"
className="imageTextPadding"
>
<Image
src={Object {}}
/>
</StackItem>
<StackItem
align="start"
>
<Text
className="bold"
>
Query Copilot works on a sample database.
<br />
</Text>
</StackItem>
</Stack>
<Text>
While in Private Preview, Query Copilot is setup to work on sample database we have configured for you at no cost.
<br />
<StyledLinkBase
href="https://aka.ms/cdb-copilot-learn-more"
target="_blank"
>
Learn more
</StyledLinkBase> </StyledLinkBase>
</Text> </Text>
</StackItem> </StackItem>

View File

@@ -15,6 +15,7 @@ export const CopyPopup = ({
return showCopyPopup ? ( return showCopyPopup ? (
<Stack <Stack
role="status"
style={{ style={{
position: "fixed", position: "fixed",
width: 345, width: 345,

View File

@@ -4,6 +4,7 @@ exports[`Copy Popup snapshot test should render when showCopyPopup is false 1`]
exports[`Copy Popup snapshot test should render when showCopyPopup is true 1`] = ` exports[`Copy Popup snapshot test should render when showCopyPopup is true 1`] = `
<Stack <Stack
role="status"
style={ style={
Object { Object {
"background": "#FFFFFF", "background": "#FFFFFF",

View File

@@ -0,0 +1,138 @@
import { MinimalQueryIterator } from "Common/IteratorUtilities";
import { QueryResults } from "Contracts/ViewModels";
import { CopilotMessage } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces";
import { guid } from "Explorer/Tables/Utilities";
import { QueryCopilotState } from "hooks/useQueryCopilot";
import React, { createContext, useContext, useState } from "react";
import create from "zustand";
const context = createContext(null);
const useCopilotStore = (): Partial<QueryCopilotState> => useContext(context);
const CopilotProvider = ({ children }: { children: React.ReactNode }): JSX.Element => {
const [useStore] = useState(() =>
create((set, get) => ({
generatedQuery: "",
likeQuery: false,
userPrompt: "",
showFeedbackModal: false,
hideFeedbackModalForLikedQueries: false,
correlationId: "",
query: "SELECT * FROM c",
selectedQuery: "",
isGeneratingQuery: false,
isGeneratingExplanation: false,
isExecuting: false,
dislikeQuery: undefined,
showCallout: false,
showSamplePrompts: false,
queryIterator: undefined,
queryResults: undefined,
errorMessage: "",
isSamplePromptsOpen: false,
showPromptTeachingBubble: true,
showDeletePopup: false,
showFeedbackBar: false,
showCopyPopup: false,
showErrorMessageBar: false,
showInvalidQueryMessageBar: false,
generatedQueryComments: "",
wasCopilotUsed: false,
showWelcomeSidebar: true,
showCopilotSidebar: false,
chatMessages: [],
shouldIncludeInMessages: true,
showExplanationBubble: false,
isAllocatingContainer: false,
openFeedbackModal: (generatedQuery: string, likeQuery: boolean, userPrompt: string) =>
set({ generatedQuery, likeQuery, userPrompt, showFeedbackModal: true }),
closeFeedbackModal: () => set({ showFeedbackModal: false }),
setHideFeedbackModalForLikedQueries: (hideFeedbackModalForLikedQueries: boolean) =>
set({ hideFeedbackModalForLikedQueries }),
refreshCorrelationId: () => set({ correlationId: guid() }),
setUserPrompt: (userPrompt: string) => set({ userPrompt }),
setQuery: (query: string) => set({ query }),
setGeneratedQuery: (generatedQuery: string) => set({ generatedQuery }),
setSelectedQuery: (selectedQuery: string) => set({ selectedQuery }),
setIsGeneratingQuery: (isGeneratingQuery: boolean) => set({ isGeneratingQuery }),
setIsGeneratingExplanation: (isGeneratingExplanation: boolean) => set({ isGeneratingExplanation }),
setIsExecuting: (isExecuting: boolean) => set({ isExecuting }),
setLikeQuery: (likeQuery: boolean) => set({ likeQuery }),
setDislikeQuery: (dislikeQuery: boolean | undefined) => set({ dislikeQuery }),
setShowCallout: (showCallout: boolean) => set({ showCallout }),
setShowSamplePrompts: (showSamplePrompts: boolean) => set({ showSamplePrompts }),
setQueryIterator: (queryIterator: MinimalQueryIterator | undefined) => set({ queryIterator }),
setQueryResults: (queryResults: QueryResults | undefined) => set({ queryResults }),
setErrorMessage: (errorMessage: string) => set({ errorMessage }),
setIsSamplePromptsOpen: (isSamplePromptsOpen: boolean) => set({ isSamplePromptsOpen }),
setShowPromptTeachingBubble: (showPromptTeachingBubble: boolean) => set({ showPromptTeachingBubble }),
setShowDeletePopup: (showDeletePopup: boolean) => set({ showDeletePopup }),
setShowFeedbackBar: (showFeedbackBar: boolean) => set({ showFeedbackBar }),
setshowCopyPopup: (showCopyPopup: boolean) => set({ showCopyPopup }),
setShowErrorMessageBar: (showErrorMessageBar: boolean) => set({ showErrorMessageBar }),
setShowInvalidQueryMessageBar: (showInvalidQueryMessageBar: boolean) => set({ showInvalidQueryMessageBar }),
setGeneratedQueryComments: (generatedQueryComments: string) => set({ generatedQueryComments }),
setWasCopilotUsed: (wasCopilotUsed: boolean) => set({ wasCopilotUsed }),
setShowWelcomeSidebar: (showWelcomeSidebar: boolean) => set({ showWelcomeSidebar }),
setShowCopilotSidebar: (showCopilotSidebar: boolean) => set({ showCopilotSidebar }),
setChatMessages: (chatMessages: CopilotMessage[]) => set({ chatMessages }),
setShouldIncludeInMessages: (shouldIncludeInMessages: boolean) => set({ shouldIncludeInMessages }),
setShowExplanationBubble: (showExplanationBubble: boolean) => set({ showExplanationBubble }),
getState: () => {
return get();
},
resetQueryCopilotStates: () => {
set((state) => ({
...state,
generatedQuery: "",
likeQuery: false,
userPrompt: "",
showFeedbackModal: false,
hideFeedbackModalForLikedQueries: false,
correlationId: "",
query: "SELECT * FROM c",
selectedQuery: "",
isGeneratingQuery: false,
isGeneratingExplanation: false,
isExecuting: false,
dislikeQuery: undefined,
showCallout: false,
showSamplePrompts: false,
queryIterator: undefined,
queryResults: undefined,
errorMessage: "",
isSamplePromptsOpen: false,
showPromptTeachingBubble: true,
showDeletePopup: false,
showFeedbackBar: false,
showCopyPopup: false,
showErrorMessageBar: false,
showInvalidQueryMessageBar: false,
generatedQueryComments: "",
wasCopilotUsed: false,
showCopilotSidebar: false,
chatMessages: [],
shouldIncludeInMessages: true,
showExplanationBubble: false,
notebookServerInfo: {
notebookServerEndpoint: undefined,
authToken: undefined,
forwardingId: undefined,
},
containerStatus: {
status: undefined,
durationLeftInMinutes: undefined,
phoenixServerInfo: undefined,
},
isAllocatingContainer: false,
}));
},
})),
);
return <context.Provider value={useStore()}>{children}</context.Provider>;
};
export { CopilotProvider, useCopilotStore };

View File

@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-console */
import { import {
Callout, Callout,
CommandBarButton, CommandBarButton,
@@ -16,21 +18,21 @@ import {
Text, Text,
TextField, TextField,
} from "@fluentui/react"; } from "@fluentui/react";
import { useBoolean } from "@fluentui/react-hooks"; import { HttpStatusCodes } from "Common/Constants";
import {
ContainerStatusType,
PoolIdType,
QueryCopilotSampleContainerSchema,
ShortenedQueryCopilotSampleContainerSchema,
} from "Common/Constants";
import { handleError } from "Common/ErrorHandlingUtils"; import { handleError } from "Common/ErrorHandlingUtils";
import { createUri } from "Common/UrlUtility"; import { createUri } from "Common/UrlUtility";
import { WelcomeModal } from "Explorer/QueryCopilot/Modal/WelcomeModal"; import { WelcomeModal } from "Explorer/QueryCopilot/Modal/WelcomeModal";
import { CopyPopup } from "Explorer/QueryCopilot/Popup/CopyPopup"; import { CopyPopup } from "Explorer/QueryCopilot/Popup/CopyPopup";
import { DeletePopup } from "Explorer/QueryCopilot/Popup/DeletePopup"; import { DeletePopup } from "Explorer/QueryCopilot/Popup/DeletePopup";
import { SubmitFeedback } from "Explorer/QueryCopilot/Shared/QueryCopilotClient"; import {
SuggestedPrompt,
getSampleDatabaseSuggestedPrompts,
getSuggestedPrompts,
} from "Explorer/QueryCopilot/QueryCopilotUtilities";
import { SubmitFeedback, allocatePhoenixContainer } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
import { GenerateSQLQueryResponse, QueryCopilotProps } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces"; import { GenerateSQLQueryResponse, QueryCopilotProps } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces";
import { SamplePrompts, SamplePromptsProps } from "Explorer/QueryCopilot/Shared/SamplePrompts/SamplePrompts"; import { SamplePrompts, SamplePromptsProps } from "Explorer/QueryCopilot/Shared/SamplePrompts/SamplePrompts";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { userContext } from "UserContext"; import { userContext } from "UserContext";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useQueryCopilot } from "hooks/useQueryCopilot";
import React, { useRef, useState } from "react"; import React, { useRef, useState } from "react";
@@ -38,29 +40,40 @@ import HintIcon from "../../../images/Hint.svg";
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg"; import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
import RecentIcon from "../../../images/Recent.svg"; import RecentIcon from "../../../images/Recent.svg";
import errorIcon from "../../../images/close-black.svg"; import errorIcon from "../../../images/close-black.svg";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { useTabs } from "../../hooks/useTabs"; import { useTabs } from "../../hooks/useTabs";
import { useCopilotStore } from "../QueryCopilot/QueryCopilotContext";
import { useSelectedNode } from "../useSelectedNode";
type QueryCopilotPromptProps = QueryCopilotProps & { type QueryCopilotPromptProps = QueryCopilotProps & {
databaseId: string;
containerId: string;
toggleCopilot: (toggle: boolean) => void; toggleCopilot: (toggle: boolean) => void;
}; };
interface SuggestedPrompt {
id: number;
text: string;
}
const promptStyles: IButtonStyles = { const promptStyles: IButtonStyles = {
root: { border: 0, selectors: { ":hover": { outline: "1px dashed #605e5c" } } }, root: { border: 0, selectors: { ":hover": { outline: "1px dashed #605e5c" } } },
label: { fontWeight: 400, textAlign: "left", paddingLeft: 8 }, label: {
fontWeight: 400,
textAlign: "left",
paddingLeft: 8,
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
},
textContainer: { overflow: "hidden" },
}; };
export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
explorer, explorer,
toggleCopilot, toggleCopilot,
databaseId,
containerId,
}: QueryCopilotPromptProps): JSX.Element => { }: QueryCopilotPromptProps): JSX.Element => {
const [copilotTeachingBubbleVisible, { toggle: toggleCopilotTeachingBubbleVisible }] = useBoolean(false); const [copilotTeachingBubbleVisible, setCopilotTeachingBubbleVisible] = useState<boolean>(false);
const inputEdited = useRef(false); const inputEdited = useRef(false);
const { const {
openFeedbackModal,
hideFeedbackModalForLikedQueries, hideFeedbackModalForLikedQueries,
userPrompt, userPrompt,
setUserPrompt, setUserPrompt,
@@ -80,6 +93,8 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setIsSamplePromptsOpen, setIsSamplePromptsOpen,
showSamplePrompts, showSamplePrompts,
setShowSamplePrompts, setShowSamplePrompts,
showPromptTeachingBubble,
setShowPromptTeachingBubble,
showDeletePopup, showDeletePopup,
setShowDeletePopup, setShowDeletePopup,
showFeedbackBar, showFeedbackBar,
@@ -93,7 +108,8 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setGeneratedQueryComments, setGeneratedQueryComments,
setQueryResults, setQueryResults,
setErrorMessage, setErrorMessage,
} = useQueryCopilot(); errorMessage,
} = useCopilotStore();
const sampleProps: SamplePromptsProps = { const sampleProps: SamplePromptsProps = {
isSamplePromptsOpen: isSamplePromptsOpen, isSamplePromptsOpen: isSamplePromptsOpen,
@@ -118,14 +134,13 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}, 6000); }, 6000);
}; };
const isSampleCopilotActive = useSelectedNode.getState().isQueryCopilotCollectionSelected();
const cachedHistoriesString = localStorage.getItem(`${userContext.databaseAccount?.id}-queryCopilotHistories`); const cachedHistoriesString = localStorage.getItem(`${userContext.databaseAccount?.id}-queryCopilotHistories`);
const cachedHistories = cachedHistoriesString?.split("|"); const cachedHistories = cachedHistoriesString?.split("|");
const [histories, setHistories] = useState<string[]>(cachedHistories || []); const [histories, setHistories] = useState<string[]>(cachedHistories || []);
const suggestedPrompts: SuggestedPrompt[] = [ const suggestedPrompts: SuggestedPrompt[] = isSampleCopilotActive
{ id: 1, text: 'Show all products that have the word "ultra" in the name or description' }, ? getSampleDatabaseSuggestedPrompts()
{ id: 2, text: "What are all of the possible categories for the products, and their counts?" }, : getSuggestedPrompts();
{ id: 3, text: 'Show me all products that have been reviewed by someone with a username that contains "bob"' },
];
const [filteredHistories, setFilteredHistories] = useState<string[]>(histories); const [filteredHistories, setFilteredHistories] = useState<string[]>(histories);
const [filteredSuggestedPrompts, setFilteredSuggestedPrompts] = useState<SuggestedPrompt[]>(suggestedPrompts); const [filteredSuggestedPrompts, setFilteredSuggestedPrompts] = useState<SuggestedPrompt[]>(suggestedPrompts);
@@ -176,28 +191,24 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setShowDeletePopup(false); setShowDeletePopup(false);
useTabs.getState().setIsTabExecuting(true); useTabs.getState().setIsTabExecuting(true);
useTabs.getState().setIsQueryErrorThrown(false); useTabs.getState().setIsQueryErrorThrown(false);
if ( const mode: string = isSampleCopilotActive ? "Sample" : "User";
useQueryCopilot.getState().containerStatus.status !== ContainerStatusType.Active &&
!userContext.features.disableCopilotPhoenixGateaway await allocatePhoenixContainer({ explorer, databaseId, containerId, mode });
) {
await explorer.allocateContainer(PoolIdType.QueryCopilot);
}
const payload = { const payload = {
containerSchema: userContext.features.enableCopilotFullSchema
? QueryCopilotSampleContainerSchema
: ShortenedQueryCopilotSampleContainerSchema,
userPrompt: userPrompt, userPrompt: userPrompt,
}; };
useQueryCopilot.getState().refreshCorrelationId(); useQueryCopilot.getState().refreshCorrelationId();
const serverInfo = useQueryCopilot.getState().notebookServerInfo; const serverInfo = useQueryCopilot.getState().notebookServerInfo;
const queryUri = userContext.features.disableCopilotPhoenixGateaway const queryUri = userContext.features.disableCopilotPhoenixGateaway
? createUri("https://copilotorchestrater.azurewebsites.net/", "generateSQLQuery") ? createUri("https://copilotorchestrater.azurewebsites.net/", "generateSQLQuery")
: createUri(serverInfo.notebookServerEndpoint, "generateSQLQuery"); : createUri(serverInfo.notebookServerEndpoint, "public/generateSQLQuery");
const response = await fetch(queryUri, { const response = await fetch(queryUri, {
method: "POST", method: "POST",
headers: { headers: {
"content-type": "application/json", "content-type": "application/json",
"x-ms-correlationid": useQueryCopilot.getState().correlationId, "x-ms-correlationid": useQueryCopilot.getState().correlationId,
Authorization: `token ${useQueryCopilot.getState().notebookServerInfo.authToken}`,
}, },
body: JSON.stringify(payload), body: JSON.stringify(payload),
}); });
@@ -215,13 +226,40 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setGeneratedQueryComments(generateSQLQueryResponse.explanation); setGeneratedQueryComments(generateSQLQueryResponse.explanation);
setShowFeedbackBar(true); setShowFeedbackBar(true);
resetQueryResults(); resetQueryResults();
TelemetryProcessor.traceSuccess(Action.QueryGenerationFromCopilotPrompt, {
databaseName: databaseId,
collectionId: containerId,
copilotLatency:
Date.parse(generateSQLQueryResponse?.generateEnd) - Date.parse(generateSQLQueryResponse?.generateStart),
responseCode: response.status,
});
} else { } else {
setShowInvalidQueryMessageBar(true); setShowInvalidQueryMessageBar(true);
TelemetryProcessor.traceFailure(Action.QueryGenerationFromCopilotPrompt, {
databaseName: databaseId,
collectionId: containerId,
responseCode: response.status,
});
} }
} else if (response?.status === HttpStatusCodes.TooManyRequests) {
handleError(JSON.stringify(generateSQLQueryResponse), "copilotTooManyRequestError");
useTabs.getState().setIsQueryErrorThrown(true);
setShowErrorMessageBar(true);
setErrorMessage("Ratelimit exceeded 5 per 1 minute. Please try again after sometime");
TelemetryProcessor.traceFailure(Action.QueryGenerationFromCopilotPrompt, {
databaseName: databaseId,
collectionId: containerId,
responseCode: response.status,
});
} else { } else {
handleError(JSON.stringify(generateSQLQueryResponse), "copilotInternalServerError"); handleError(JSON.stringify(generateSQLQueryResponse), "copilotInternalServerError");
useTabs.getState().setIsQueryErrorThrown(true); useTabs.getState().setIsQueryErrorThrown(true);
setShowErrorMessageBar(true); setShowErrorMessageBar(true);
TelemetryProcessor.traceFailure(Action.QueryGenerationFromCopilotPrompt, {
databaseName: databaseId,
collectionId: containerId,
responseCode: response.status,
});
} }
} catch (error) { } catch (error) {
handleError(error, "executeNaturalLanguageQuery"); handleError(error, "executeNaturalLanguageQuery");
@@ -235,16 +273,23 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}; };
const showTeachingBubble = (): void => { const showTeachingBubble = (): void => {
if (!inputEdited.current) { if (showPromptTeachingBubble && !inputEdited.current) {
setTimeout(() => { setTimeout(() => {
if (!inputEdited.current && !isWelcomModalVisible()) { if (!inputEdited.current && !isWelcomModalVisible()) {
toggleCopilotTeachingBubbleVisible(); setCopilotTeachingBubbleVisible(true);
inputEdited.current = true; inputEdited.current = true;
} }
}, 30000); }, 30000);
} else {
toggleCopilotTeachingBubbleVisible(false);
} }
}; };
const toggleCopilotTeachingBubbleVisible = (visible: boolean): void => {
setCopilotTeachingBubbleVisible(visible);
setShowPromptTeachingBubble(visible);
};
const isWelcomModalVisible = (): boolean => { const isWelcomModalVisible = (): boolean => {
return localStorage.getItem("hideWelcomeModal") !== "true"; return localStorage.getItem("hideWelcomeModal") !== "true";
}; };
@@ -266,15 +311,29 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
resetButtonState(); resetButtonState();
}; };
const getAriaLabel = () => {
if (isGeneratingQuery === null) {
return " ";
} else if (isGeneratingQuery) {
return "Content is loading";
} else {
return "Content is updated";
}
};
React.useEffect(() => { React.useEffect(() => {
showTeachingBubble(); showTeachingBubble();
useTabs.getState().setIsQueryErrorThrown(false); useTabs.getState().setIsQueryErrorThrown(false);
}, []); }, []);
return ( return (
<Stack className="copilot-prompt-pane" styles={{ root: { backgroundColor: "#FAFAFA", padding: "16px 24px 0px" } }}> <Stack
className="copilot-prompt-pane"
styles={{ root: { backgroundColor: "#FAFAFA", padding: "16px 24px 0px" } }}
id="copilot-textfield-label"
>
<Stack horizontal> <Stack horizontal>
<Image src={CopilotIcon} style={{ width: 24, height: 24 }} /> <Image src={CopilotIcon} style={{ width: 24, height: 24 }} alt="Copilot" role="none" />
<Text style={{ marginLeft: 8, fontWeight: 600, fontSize: 16 }}>Copilot</Text> <Text style={{ marginLeft: 8, fontWeight: 600, fontSize: 16 }}>Copilot</Text>
<IconButton <IconButton
iconProps={{ imageProps: { src: errorIcon } }} iconProps={{ imageProps: { src: errorIcon } }}
@@ -310,14 +369,16 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
styles={{ root: { width: "95%" }, fieldGroup: { borderRadius: 6 } }} styles={{ root: { width: "95%" }, fieldGroup: { borderRadius: 6 } }}
disabled={isGeneratingQuery} disabled={isGeneratingQuery}
autoComplete="off" autoComplete="off"
placeholder="Ask a question in natural language and well generate the query for you."
aria-labelledby="copilot-textfield-label"
/> />
{copilotTeachingBubbleVisible && ( {showPromptTeachingBubble && copilotTeachingBubbleVisible && (
<TeachingBubble <TeachingBubble
calloutProps={{ directionalHint: DirectionalHint.bottomCenter }} calloutProps={{ directionalHint: DirectionalHint.bottomCenter }}
target="#naturalLanguageInput" target="#naturalLanguageInput"
hasCloseButton={true} hasCloseButton={true}
closeButtonAriaLabel="Close" closeButtonAriaLabel="Close"
onDismiss={toggleCopilotTeachingBubbleVisible} onDismiss={() => toggleCopilotTeachingBubbleVisible(false)}
hasSmallHeadline={true} hasSmallHeadline={true}
headline="Write a prompt" headline="Write a prompt"
> >
@@ -325,7 +386,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
<Link <Link
onClick={() => { onClick={() => {
setShowSamplePrompts(true); setShowSamplePrompts(true);
toggleCopilotTeachingBubbleVisible(); toggleCopilotTeachingBubbleVisible(false);
}} }}
style={{ color: "white", fontWeight: 600 }} style={{ color: "white", fontWeight: 600 }}
> >
@@ -339,11 +400,14 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
disabled={isGeneratingQuery || !userPrompt.trim()} disabled={isGeneratingQuery || !userPrompt.trim()}
style={{ marginLeft: 8 }} style={{ marginLeft: 8 }}
onClick={() => startGenerateQueryProcess()} onClick={() => startGenerateQueryProcess()}
aria-label="Send"
/> />
{isGeneratingQuery && <Spinner style={{ marginLeft: 8 }} />} <div role="alert" aria-label={getAriaLabel()}>
{isGeneratingQuery && <Spinner style={{ marginLeft: 8 }} />}
</div>
{showSamplePrompts && ( {showSamplePrompts && (
<Callout <Callout
styles={{ root: { minWidth: 400 } }} styles={{ root: { minWidth: 400, maxWidth: "70vw" } }}
target="#naturalLanguageInput" target="#naturalLanguageInput"
isBeakVisible={false} isBeakVisible={false}
onDismiss={() => setShowSamplePrompts(false)} onDismiss={() => setShowSamplePrompts(false)}
@@ -375,7 +439,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setShowSamplePrompts(false); setShowSamplePrompts(false);
inputEdited.current = true; inputEdited.current = true;
}} }}
onRenderIcon={() => <Image src={RecentIcon} />} onRenderIcon={() => <Image src={RecentIcon} styles={{ root: { overflow: "unset" } }} />}
styles={promptStyles} styles={promptStyles}
> >
{history} {history}
@@ -446,12 +510,12 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
<Stack style={{ margin: "8px 0" }}> <Stack style={{ margin: "8px 0" }}>
<Text style={{ fontSize: 12 }}> <Text style={{ fontSize: 12 }}>
AI-generated content can have mistakes. Make sure it&apos;s accurate and appropriate before using it.{" "} AI-generated content can have mistakes. Make sure it&apos;s accurate and appropriate before using it.{" "}
<Link href="https://aka.ms/cdb-copilot-preview-terms" target="_blank"> <Link href="https://aka.ms/cdb-copilot-preview-terms" target="_blank" style={{ color: "#0072c9" }}>
Read preview terms Read preview terms
</Link> </Link>
{showErrorMessageBar && ( {showErrorMessageBar && (
<MessageBar messageBarType={MessageBarType.error}> <MessageBar messageBarType={MessageBarType.error}>
We ran into an error and were not able to execute query. {errorMessage ? errorMessage : "We ran into an error and were not able to execute query."}
</MessageBar> </MessageBar>
)} )}
{showInvalidQueryMessageBar && ( {showInvalidQueryMessageBar && (
@@ -489,7 +553,10 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
description: "", description: "",
userPrompt: userPrompt, userPrompt: userPrompt,
}, },
explorer: explorer, explorer,
databaseId,
containerId,
mode: isSampleCopilotActive ? "Sample" : "User",
}); });
}} }}
directionalHint={DirectionalHint.topCenter} directionalHint={DirectionalHint.topCenter}
@@ -499,7 +566,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
<Link <Link
onClick={() => { onClick={() => {
setShowCallout(false); setShowCallout(false);
useQueryCopilot.getState().openFeedbackModal(generatedQuery, true, userPrompt); openFeedbackModal(generatedQuery, true, userPrompt);
}} }}
> >
more feedback? more feedback?
@@ -511,6 +578,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
id="likeBtn" id="likeBtn"
style={{ marginLeft: 20 }} style={{ marginLeft: 20 }}
iconProps={{ iconName: likeQuery === true ? "LikeSolid" : "Like" }} iconProps={{ iconName: likeQuery === true ? "LikeSolid" : "Like" }}
aria-label="Like"
onClick={() => { onClick={() => {
setShowCallout(!likeQuery); setShowCallout(!likeQuery);
setLikeQuery(!likeQuery); setLikeQuery(!likeQuery);
@@ -524,12 +592,13 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
iconProps={{ iconName: dislikeQuery === true ? "DislikeSolid" : "Dislike" }} iconProps={{ iconName: dislikeQuery === true ? "DislikeSolid" : "Dislike" }}
onClick={() => { onClick={() => {
if (!dislikeQuery) { if (!dislikeQuery) {
useQueryCopilot.getState().openFeedbackModal(generatedQuery, false, userPrompt); openFeedbackModal(generatedQuery, false, userPrompt);
setLikeQuery(false); setLikeQuery(false);
} }
setDislikeQuery(!dislikeQuery); setDislikeQuery(!dislikeQuery);
setShowCallout(false); setShowCallout(false);
}} }}
aria-label="Dislike"
/> />
<Separator vertical style={{ color: "#EDEBE9" }} /> <Separator vertical style={{ color: "#EDEBE9" }} />
<CommandBarButton <CommandBarButton

View File

@@ -1,5 +1,6 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import { Stack } from "@fluentui/react"; import { Stack } from "@fluentui/react";
import { QueryCopilotSampleContainerId, QueryCopilotSampleDatabaseId } from "Common/Constants";
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
import { EditorReact } from "Explorer/Controls/Editor/EditorReact"; import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter"; import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
@@ -11,6 +12,7 @@ import { QueryCopilotResults } from "Explorer/QueryCopilot/Shared/QueryCopilotRe
import { userContext } from "UserContext"; import { userContext } from "UserContext";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useQueryCopilot } from "hooks/useQueryCopilot";
import { useSidePanel } from "hooks/useSidePanel"; import { useSidePanel } from "hooks/useSidePanel";
import { ReactTabKind, TabsState, useTabs } from "hooks/useTabs";
import React, { useState } from "react"; import React, { useState } from "react";
import SplitterLayout from "react-splitter-layout"; import SplitterLayout from "react-splitter-layout";
import QueryCommandIcon from "../../../images/CopilotCommand.svg"; import QueryCommandIcon from "../../../images/CopilotCommand.svg";
@@ -28,13 +30,14 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
? StringUtility.toBoolean(cachedCopilotToggleStatus) ? StringUtility.toBoolean(cachedCopilotToggleStatus)
: true; : true;
const [copilotActive, setCopilotActive] = useState<boolean>(copilotInitialActive); const [copilotActive, setCopilotActive] = useState<boolean>(copilotInitialActive);
const [tabActive, setTabActive] = useState<boolean>(true);
const getCommandbarButtons = (): CommandButtonComponentProps[] => { const getCommandbarButtons = (): CommandButtonComponentProps[] => {
const executeQueryBtnLabel = selectedQuery ? "Execute Selection" : "Execute Query"; const executeQueryBtnLabel = selectedQuery ? "Execute Selection" : "Execute Query";
const executeQueryBtn = { const executeQueryBtn = {
iconSrc: ExecuteQueryIcon, iconSrc: ExecuteQueryIcon,
iconAlt: executeQueryBtnLabel, iconAlt: executeQueryBtnLabel,
onCommandClick: () => OnExecuteQueryClick(), onCommandClick: () => OnExecuteQueryClick(useQueryCopilot),
commandButtonLabel: executeQueryBtnLabel, commandButtonLabel: executeQueryBtnLabel,
ariaLabel: executeQueryBtnLabel, ariaLabel: executeQueryBtnLabel,
hasPopup: false, hasPopup: false,
@@ -73,10 +76,13 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
React.useEffect(() => { React.useEffect(() => {
return () => { return () => {
const commandbarButtons = getCommandbarButtons(); useTabs.subscribe((state: TabsState) => {
commandbarButtons.pop(); if (state.activeReactTab === ReactTabKind.QueryCopilot) {
commandbarButtons.map((props: CommandButtonComponentProps) => (props.disabled = true)); setTabActive(true);
useCommandBar.getState().setContextButtons(commandbarButtons); } else {
setTabActive(false);
}
});
}; };
}, []); }, []);
@@ -88,8 +94,13 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
return ( return (
<Stack className="tab-pane" style={{ width: "100%" }}> <Stack className="tab-pane" style={{ width: "100%" }}>
<div style={isGeneratingQuery ? { height: "100%" } : { overflowY: "auto", height: "100%" }}> <div style={isGeneratingQuery ? { height: "100%" } : { overflowY: "auto", height: "100%" }}>
{copilotActive && ( {tabActive && copilotActive && (
<QueryCopilotPromptbar explorer={explorer} toggleCopilot={toggleCopilot}></QueryCopilotPromptbar> <QueryCopilotPromptbar
explorer={explorer}
toggleCopilot={toggleCopilot}
databaseId={QueryCopilotSampleDatabaseId}
containerId={QueryCopilotSampleContainerId}
></QueryCopilotPromptbar>
)} )}
<Stack className="tabPaneContentContainer"> <Stack className="tabPaneContentContainer">
<SplitterLayout percentage={true} vertical={true} primaryIndex={0} primaryMinSize={30} secondaryMinSize={70}> <SplitterLayout percentage={true} vertical={true} primaryIndex={0} primaryMinSize={30} secondaryMinSize={70}>

View File

@@ -7,6 +7,11 @@ import { getCommonQueryOptions } from "Common/dataAccess/queryDocuments";
import DocumentId from "Explorer/Tree/DocumentId"; import DocumentId from "Explorer/Tree/DocumentId";
import { logConsoleProgress } from "Utils/NotificationConsoleUtils"; import { logConsoleProgress } from "Utils/NotificationConsoleUtils";
export interface SuggestedPrompt {
id: number;
text: string;
}
export const querySampleDocuments = (query: string, options: FeedOptions): QueryIterator<ItemDefinition & Resource> => { export const querySampleDocuments = (query: string, options: FeedOptions): QueryIterator<ItemDefinition & Resource> => {
options = getCommonQueryOptions(options); options = getCommonQueryOptions(options);
return sampleDataClient() return sampleDataClient()
@@ -33,3 +38,19 @@ export const readSampleDocument = async (documentId: DocumentId): Promise<Item>
clearMessage(); clearMessage();
} }
}; };
export const getSampleDatabaseSuggestedPrompts = (): SuggestedPrompt[] => {
return [
{ id: 1, text: 'Show all products that have the word "ultra" in the name or description' },
{ id: 2, text: "What are all of the possible categories for the products, and their counts?" },
{ id: 3, text: 'Show me all products that have been reviewed by someone with a username that contains "bob"' },
];
};
export const getSuggestedPrompts = (): SuggestedPrompt[] => {
return [
{ id: 1, text: "Show the first 10 items" },
{ id: 2, text: 'Count all the items in my data as "numItems"' },
{ id: 3, text: "Find the oldest item added to my collection" },
];
};

View File

@@ -1,4 +1,3 @@
import { QueryCopilotSampleContainerSchema, ShortenedQueryCopilotSampleContainerSchema } from "Common/Constants";
import { handleError } from "Common/ErrorHandlingUtils"; import { handleError } from "Common/ErrorHandlingUtils";
import { createUri } from "Common/UrlUtility"; import { createUri } from "Common/UrlUtility";
import Explorer from "Explorer/Explorer"; import Explorer from "Explorer/Explorer";
@@ -37,9 +36,6 @@ describe("Query Copilot Client", () => {
userPrompt: "UserPrompt", userPrompt: "UserPrompt",
description: "Description", description: "Description",
contact: "Contact", contact: "Contact",
containerSchema: userContext.features.enableCopilotFullSchema
? QueryCopilotSampleContainerSchema
: ShortenedQueryCopilotSampleContainerSchema,
}; };
const mockStore = useQueryCopilot.getState(); const mockStore = useQueryCopilot.getState();
@@ -52,13 +48,16 @@ describe("Query Copilot Client", () => {
const feedbackUri = userContext.features.disableCopilotPhoenixGateaway const feedbackUri = userContext.features.disableCopilotPhoenixGateaway
? createUri("https://copilotorchestrater.azurewebsites.net/", "feedback") ? createUri("https://copilotorchestrater.azurewebsites.net/", "feedback")
: createUri(useQueryCopilot.getState().notebookServerInfo.notebookServerEndpoint, "feedback"); : createUri(useQueryCopilot.getState().notebookServerInfo.notebookServerEndpoint, "public/feedback");
it("should call fetch with the payload with like", async () => { it("should call fetch with the payload with like", async () => {
const mockFetch = jest.fn().mockResolvedValueOnce({}); const mockFetch = jest.fn().mockResolvedValueOnce({});
globalThis.fetch = mockFetch; globalThis.fetch = mockFetch;
await SubmitFeedback({ await SubmitFeedback({
databaseId: "test",
containerId: "test",
mode: "User",
params: { params: {
likeQuery: true, likeQuery: true,
generatedQuery: "GeneratedQuery", generatedQuery: "GeneratedQuery",
@@ -91,6 +90,9 @@ describe("Query Copilot Client", () => {
globalThis.fetch = mockFetch; globalThis.fetch = mockFetch;
await SubmitFeedback({ await SubmitFeedback({
databaseId: "test",
containerId: "test",
mode: "User",
params: { params: {
likeQuery: false, likeQuery: false,
generatedQuery: "GeneratedQuery", generatedQuery: "GeneratedQuery",
@@ -108,6 +110,7 @@ describe("Query Copilot Client", () => {
headers: { headers: {
"content-type": "application/json", "content-type": "application/json",
"x-ms-correlationid": "mocked-correlation-id", "x-ms-correlationid": "mocked-correlation-id",
Authorization: "token mocked-token",
}, },
}), }),
); );
@@ -120,6 +123,9 @@ describe("Query Copilot Client", () => {
globalThis.fetch = jest.fn().mockRejectedValueOnce(new Error("Mock error")); globalThis.fetch = jest.fn().mockRejectedValueOnce(new Error("Mock error"));
await SubmitFeedback({ await SubmitFeedback({
databaseId: "test",
containerId: "test",
mode: "User",
params: { params: {
likeQuery: true, likeQuery: true,
generatedQuery: "GeneratedQuery", generatedQuery: "GeneratedQuery",
@@ -129,6 +135,7 @@ describe("Query Copilot Client", () => {
}, },
explorer: new Explorer(), explorer: new Explorer(),
}).catch((error) => { }).catch((error) => {
// eslint-disable-next-line jest/no-conditional-expect
expect(error.message).toEqual("Mock error"); expect(error.message).toEqual("Mock error");
}); });

View File

@@ -1,28 +1,192 @@
import { FeedOptions } from "@azure/cosmos"; import { FeedOptions } from "@azure/cosmos";
import { import {
Areas,
ConnectionStatusType,
ContainerStatusType, ContainerStatusType,
HttpStatusCodes,
PoolIdType, PoolIdType,
QueryCopilotSampleContainerId, QueryCopilotSampleContainerId,
QueryCopilotSampleContainerSchema, QueryCopilotSampleContainerSchema,
ShortenedQueryCopilotSampleContainerSchema, ShortenedQueryCopilotSampleContainerSchema,
} from "Common/Constants"; } from "Common/Constants";
import { getErrorMessage, handleError } from "Common/ErrorHandlingUtils"; import { getErrorMessage, getErrorStack, handleError } from "Common/ErrorHandlingUtils";
import { shouldEnableCrossPartitionKey } from "Common/HeadersUtility"; import { shouldEnableCrossPartitionKey } from "Common/HeadersUtility";
import { MinimalQueryIterator } from "Common/IteratorUtilities"; import { MinimalQueryIterator } from "Common/IteratorUtilities";
import { createUri } from "Common/UrlUtility"; import { createUri } from "Common/UrlUtility";
import { queryDocumentsPage } from "Common/dataAccess/queryDocumentsPage"; import { queryDocumentsPage } from "Common/dataAccess/queryDocumentsPage";
import { QueryResults } from "Contracts/ViewModels"; import { configContext } from "ConfigContext";
import {
ContainerConnectionInfo,
CopilotEnabledConfiguration,
FeatureRegistration,
IProvisionData,
} from "Contracts/DataModels";
import { AuthorizationTokenHeaderMetadata, QueryResults } from "Contracts/ViewModels";
import { useDialog } from "Explorer/Controls/Dialog";
import Explorer from "Explorer/Explorer"; import Explorer from "Explorer/Explorer";
import { querySampleDocuments } from "Explorer/QueryCopilot/QueryCopilotUtilities"; import { querySampleDocuments } from "Explorer/QueryCopilot/QueryCopilotUtilities";
import { FeedbackParams, GenerateSQLQueryResponse } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces"; import { FeedbackParams, GenerateSQLQueryResponse } from "Explorer/QueryCopilot/Shared/QueryCopilotInterfaces";
import { Action } from "Shared/Telemetry/TelemetryConstants"; import { Action } from "Shared/Telemetry/TelemetryConstants";
import { traceFailure, traceStart, traceSuccess } from "Shared/Telemetry/TelemetryProcessor"; import { traceFailure, traceStart, traceSuccess } from "Shared/Telemetry/TelemetryProcessor";
import { userContext } from "UserContext"; import { userContext } from "UserContext";
import { getAuthorizationHeader } from "Utils/AuthorizationUtils";
import { queryPagesUntilContentPresent } from "Utils/QueryUtils"; import { queryPagesUntilContentPresent } from "Utils/QueryUtils";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";
import { useTabs } from "hooks/useTabs"; import { useTabs } from "hooks/useTabs";
import * as StringUtility from "../../../Shared/StringUtility"; import * as StringUtility from "../../../Shared/StringUtility";
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;
}
export const isCopilotFeatureRegistered = async (subscriptionId: string): Promise<boolean> => {
const api_version = "2021-07-01";
const url = `${configContext.ARM_ENDPOINT}/subscriptions/${subscriptionId}/providers/Microsoft.Features/featureProviders/Microsoft.DocumentDB/subscriptionFeatureRegistrations/MicrosoftCopilotForAzureInCDB?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";
};
export const getCopilotEnabled = async (): Promise<boolean> => {
const url = `${configContext.BACKEND_ENDPOINT}/api/portalsettings/querycopilot`;
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 copilotPortalConfiguration = (await response?.json()) as CopilotEnabledConfiguration;
return copilotPortalConfiguration?.isEnabled;
};
export const allocatePhoenixContainer = async ({
explorer,
databaseId,
containerId,
mode,
}: {
explorer: Explorer;
databaseId: string;
containerId: string;
mode: string;
}): Promise<void> => {
try {
if (
useQueryCopilot.getState().containerStatus.status !== ContainerStatusType.Active &&
!userContext.features.disableCopilotPhoenixGateaway
) {
await explorer.allocateContainer(PoolIdType.QueryCopilot, mode);
} else {
const currentAllocatedSchemaInfo = useQueryCopilot.getState().schemaAllocationInfo;
if (
currentAllocatedSchemaInfo.databaseId !== databaseId ||
currentAllocatedSchemaInfo.containerId !== containerId
) {
await resetPhoenixContainerSchema({ explorer, databaseId, containerId, mode });
}
}
useQueryCopilot.getState().setSchemaAllocationInfo({
databaseId,
containerId,
});
} catch (error) {
traceFailure(Action.PhoenixConnection, {
dataExplorerArea: Areas.Copilot,
status: error.status,
error: getErrorMessage(error),
errorStack: getErrorStack(error),
});
useQueryCopilot.getState().resetContainerConnection();
if (error?.status === HttpStatusCodes.Forbidden && error.message) {
useDialog.getState().showOkModalDialog("Connection Failed", `${error.message}`);
} else {
useDialog
.getState()
.showOkModalDialog(
"Connection Failed",
"We are unable to connect to the temporary workspace. Please try again in a few minutes. If the error persists, file a support ticket.",
);
}
} finally {
useTabs.getState().setIsTabExecuting(false);
}
};
export const resetPhoenixContainerSchema = async ({
explorer,
databaseId,
containerId,
mode,
}: {
explorer: Explorer;
databaseId: string;
containerId: string;
mode: string;
}): Promise<void> => {
try {
const provisionData: IProvisionData = {
poolId: PoolIdType.QueryCopilot,
databaseId: databaseId,
containerId: containerId,
mode: mode,
};
const connectionInfo = await explorer.phoenixClient.allocateContainer(provisionData);
const connectionStatus: ContainerConnectionInfo = {
status: ConnectionStatusType.Connecting,
};
await explorer.setNotebookInfo(false, connectionInfo, connectionStatus);
} catch (error) {
traceFailure(Action.PhoenixConnection, {
dataExplorerArea: Areas.Copilot,
status: error.status,
error: getErrorMessage(error),
errorStack: getErrorStack(error),
});
throw error;
}
};
export const SendQueryRequest = async ({ export const SendQueryRequest = async ({
userPrompt, userPrompt,
explorer, explorer,
@@ -51,7 +215,7 @@ export const SendQueryRequest = async ({
const queryUri = userContext.features.disableCopilotPhoenixGateaway const queryUri = userContext.features.disableCopilotPhoenixGateaway
? createUri("https://copilotorchestrater.azurewebsites.net/", "generateSQLQuery") ? createUri("https://copilotorchestrater.azurewebsites.net/", "generateSQLQuery")
: createUri(serverInfo.notebookServerEndpoint, "generateSQLQuery"); : createUri(serverInfo.notebookServerEndpoint, "public/generateSQLQuery");
const payload = { const payload = {
containerSchema: userContext.features.enableCopilotFullSchema containerSchema: userContext.features.enableCopilotFullSchema
@@ -106,16 +270,19 @@ export const SendQueryRequest = async ({
export const SubmitFeedback = async ({ export const SubmitFeedback = async ({
params, params,
explorer, explorer,
databaseId,
containerId,
mode,
}: { }: {
params: FeedbackParams; params: FeedbackParams;
explorer: Explorer; explorer: Explorer;
databaseId: string;
containerId: string;
mode: string;
}): Promise<void> => { }): Promise<void> => {
try { try {
const { likeQuery, generatedQuery, userPrompt, description, contact } = params; const { likeQuery, generatedQuery, userPrompt, description, contact } = params;
const payload = { const payload = {
containerSchema: userContext.features.enableCopilotFullSchema
? QueryCopilotSampleContainerSchema
: ShortenedQueryCopilotSampleContainerSchema,
like: likeQuery ? "like" : "dislike", like: likeQuery ? "like" : "dislike",
generatedSql: generatedQuery, generatedSql: generatedQuery,
userPrompt, userPrompt,
@@ -126,17 +293,18 @@ export const SubmitFeedback = async ({
useQueryCopilot.getState().containerStatus.status !== ContainerStatusType.Active && useQueryCopilot.getState().containerStatus.status !== ContainerStatusType.Active &&
!userContext.features.disableCopilotPhoenixGateaway !userContext.features.disableCopilotPhoenixGateaway
) { ) {
await explorer.allocateContainer(PoolIdType.QueryCopilot); await allocatePhoenixContainer({ explorer, databaseId, containerId, mode });
} }
const serverInfo = useQueryCopilot.getState().notebookServerInfo; const serverInfo = useQueryCopilot.getState().notebookServerInfo;
const feedbackUri = userContext.features.disableCopilotPhoenixGateaway const feedbackUri = userContext.features.disableCopilotPhoenixGateaway
? createUri("https://copilotorchestrater.azurewebsites.net/", "feedback") ? createUri("https://copilotorchestrater.azurewebsites.net/", "feedback")
: createUri(serverInfo.notebookServerEndpoint, "feedback"); : createUri(serverInfo.notebookServerEndpoint, "public/feedback");
await fetch(feedbackUri, { await fetch(feedbackUri, {
method: "POST", method: "POST",
headers: { headers: {
"content-type": "application/json", "content-type": "application/json",
"x-ms-correlationid": useQueryCopilot.getState().correlationId, "x-ms-correlationid": useQueryCopilot.getState().correlationId,
Authorization: `token ${useQueryCopilot.getState().notebookServerInfo.authToken}`,
}, },
body: JSON.stringify(payload), body: JSON.stringify(payload),
}); });
@@ -145,7 +313,7 @@ export const SubmitFeedback = async ({
} }
}; };
export const OnExecuteQueryClick = async (): Promise<void> => { export const OnExecuteQueryClick = async (useQueryCopilot: Partial<QueryCopilotState>): Promise<void> => {
traceStart(Action.ExecuteQueryGeneratedFromQueryCopilot, { traceStart(Action.ExecuteQueryGeneratedFromQueryCopilot, {
correlationId: useQueryCopilot.getState().correlationId, correlationId: useQueryCopilot.getState().correlationId,
userPrompt: useQueryCopilot.getState().userPrompt, userPrompt: useQueryCopilot.getState().userPrompt,
@@ -160,13 +328,14 @@ export const OnExecuteQueryClick = async (): Promise<void> => {
useQueryCopilot.getState().setQueryIterator(queryIterator); useQueryCopilot.getState().setQueryIterator(queryIterator);
setTimeout(async () => { setTimeout(async () => {
await QueryDocumentsPerPage(0, queryIterator); await QueryDocumentsPerPage(0, queryIterator, useQueryCopilot);
}, 100); }, 100);
}; };
export const QueryDocumentsPerPage = async ( export const QueryDocumentsPerPage = async (
firstItemIndex: number, firstItemIndex: number,
queryIterator: MinimalQueryIterator, queryIterator: MinimalQueryIterator,
useQueryCopilot: Partial<QueryCopilotState>,
): Promise<void> => { ): Promise<void> => {
try { try {
useQueryCopilot.getState().setIsExecuting(true); useQueryCopilot.getState().setIsExecuting(true);

Some files were not shown because too many files have changed in this diff Show More