Compare commits

...

19 Commits

Author SHA1 Message Date
Sakshi Gupta
8d576fa1c0 test fix 2026-01-07 14:48:47 +05:30
Sakshi Gupta
82219af14e fixed review comments 2026-01-07 14:43:45 +05:30
Sakshi Gupta
44f45a9e13 fixed the test suit 2026-01-06 23:07:13 +05:30
Sakshi Gupta
196b63b22d updated the conflicts 2026-01-06 22:58:38 +05:30
Sakshi Gupta
b17c54b973 updated the conflicts 2026-01-06 22:54:32 +05:30
Sakshi Gupta
eb72dfd61d updated the conflicts 2026-01-06 22:53:23 +05:30
Sakshi Gupta
450a81d3b6 rebased from master 2026-01-06 21:49:31 +05:30
BChoudhury-ms
53288dec6f feat: add test identifiers (data-test) to Container Copy components (#2306) 2026-01-06 21:19:58 +05:30
BChoudhury-ms
258a6286e7 refactor(dataTransfers): replace fetch with armRequest for pagination (#2305)
* refactor(dataTransfers): replace fetch with armRequest for pagination

* added comment for next link url parsing
2026-01-06 21:12:19 +05:30
sakshigupta12feb
c8ebca6da4 Fixed homepage UI for fabric (#2304)
* Fixed homePage UI for fabric


Co-authored-by: Sakshi Gupta <sakshig@microsoft.com>
2026-01-05 17:02:19 +05:30
Sakshi Gupta
ddbc789d75 updated infor icon , error icon and text on jobs details page 2026-01-02 17:52:22 +05:30
Sakshi Gupta
91cd61d387 Merge branch 'master' into users/sakshig/darkthemeCopyJobs-4050631 2025-12-29 21:51:37 +05:30
BChoudhury-ms
6167f94bc3 fix: restore SidePanel component for Container Copy feature (#2295) 2025-12-29 21:46:47 +05:30
BChoudhury-ms
be89c634f3 Add E2E tests for partition key change workflow (#2293) 2025-12-29 15:08:54 +05:30
Sakshi Gupta
e9151bcaf0 Fix formatting in Utils.test.ts 2025-12-29 13:13:23 +05:30
Sakshi Gupta
72debd0778 added a dark theme toggle button on Copyjobs next to refresh button and covered full feature 2025-12-29 12:57:26 +05:30
sakshigupta12feb
42e230b88b Few more UI observation (fixes) (#2283)
* fixed bottom border for fabric

* fixed scrollbar

* reverted last

* updated the review comments

* Fixed scroll , updated the home page UI box shadow, header font weight, margin between boxed , subtab underline for fabric fixed

---------

Co-authored-by: Sakshi Gupta <sakshig@microsoft.com>
2025-12-17 23:54:30 +05:30
sakshigupta12feb
6196ba4722 Fixed bottom border for fabric and small UI changes (#2282)
* fixed bottom border for fabric

* updated the review comments

---------

Co-authored-by: Sakshi Gupta <sakshig@microsoft.com>
2025-12-16 21:35:08 +05:30
sakshigupta12feb
2c31ec2a8d Dark theme for Explorer (#2185)
* First dark theme commits for command bar

* Updated theme on sidebar

* Updated tabs, sidebar, splash screen

* settings theme changes

* Dark theme applied to Monaco editor

* Dark theme to stored procedures

* Fixed sidebar scroll

* Updated scroll issue in sidebar

* Command bar items fixed

* Fixed lint errors

* fixed lint errors

* settings side panel fixed

* Second last iteration for css

* Fixed all the issues of css

* Updated the theme icon for now on DE to change the theme from portal/DE itself

* Formatting issue resolved

* Remove CloudShellTerminalComponent changes - revert to master version

* Fixed test issue

* Fixed formatting issue

* Fix tests: update snapshots and revert xterm imports for compatibility

* Fix xterm imports in CloudShellTerminalComponent to use @xterm packages

* Fix Cloud Shell component imports for compatibility

* Update test snapshots

* Fix xterm package consistency across all CloudShell components

* Fix TypeScript compilation errors in CloudShell components and query Documents

- Standardized xterm package imports across CloudShell components to use legacy 'xterm' package
- Fixed Terminal type compatibility issues in CommonUtils.tsx
- Added type casting for enableQueryControl property in queryDocuments.ts to handle Azure Cosmos SDK interface limitations
- Applied code formatting to ensure consistency

* Update failing snapshot tests

- Updated TreeNodeComponent snapshot tests for loading states
- Updated ThroughputInputAutoPilotV3Component snapshots for number formatting changes (10,00,000 -> 1,000,000)
- All snapshot tests now pass

* Fixed test issue

* Fixed test issue

* Updated the buttons for theme

* Updated the Theme changes based on portal theme changes

* Updated review comments

* Updated the duplicate code and fixed the fabric react error

* Few places styling added and resolving few comments

* Fixed errors

* Fixed comments

* Fixed comments

* Fixed comments

* Fixed full text policy issue for mongoru accounts

* Resolved comments for class Name and few others

* Added css for homepage in ru accounts

* Final commit with all the feedback issues resolved

* Lint error resolved

* Updated the review comments and few Ui issues

* Resolved review comments and changed header bg and active state color

* Moved svg code to different file and imported

* css fixed for the hpome page boxed for ru account

* Lint errors

* Fixed boxes issue in ru accounts

* Handled the initial theme from the portal

* Updated snap

* Update snapshots for TreeNodeComponent and CreateCopyJobScreensProvider tests

* Fix duplicate DataExplorerRoot test id causing Playwright strict mode violation

* Fix locale-dependent number formatting in ThroughputInputAutoPilotV3Component

---------

Co-authored-by: Sakshi Gupta <sakshig+microsoft@microsoft.com>
Co-authored-by: Sakshi Gupta <sakshig@microsoft.com>
2025-12-16 12:21:58 +05:30
153 changed files with 8110 additions and 2179 deletions

3
images/DocumentIcon.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
<path d="M4 4c0-1.1.9-2 2-2h3.59c.4 0 .78.16 1.06.44l3.91 3.91c.28.28.44.67.44 1.06V14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4Zm2-1a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V8h-3.5A1.5 1.5 0 0 1 9 6.5V3H6Zm4 .2v3.3c0 .28.22.5.5.5h3.3L10 3.2ZM17 9a1 1 0 0 0-1-1v6a3 3 0 0 1-3 3H6a1 1 0 0 0 1 1h6.06A3.94 3.94 0 0 0 17 14.06V9Z" />
</svg>

After

Width:  |  Height:  |  Size: 439 B

3
images/MoonIcon.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.85032 3.0153C10.4276 3.21621 12.4563 5.37119 12.4563 8C12.4563 10.7614 10.2177 13 7.45629 13C5.70158 13 4.15722 12.0961 3.26465 10.7271C4.66791 10.3479 6.58077 9.42526 7.42438 7.17555C7.97709 5.70162 8.00857 4.23763 7.85032 3.0153ZM13.4563 8C13.4563 4.68629 10.77 2 7.45629 2C7.38577 2 7.31552 2.00122 7.24555 2.00364C7.09984 2.00867 6.96358 2.07706 6.87247 2.19089C6.78136 2.30471 6.74447 2.45263 6.77147 2.59591C7.00024 3.81021 7.05064 5.32413 6.48805 6.82444C5.68804 8.95787 3.68609 9.66359 2.41062 9.89533C2.25698 9.92325 2.1252 10.0213 2.05438 10.1605C1.98356 10.2997 1.98182 10.4639 2.04969 10.6046C3.01873 12.6128 5.07502 14 7.45629 14C10.77 14 13.4563 11.3137 13.4563 8Z" fill="#0078d4" />
</svg>

After

Width:  |  Height:  |  Size: 814 B

3
images/SunIcon.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 1.33C8.276 1.33 8.5 1.554 8.5 1.83V2.83C8.5 3.106 8.276 3.33 8 3.33C7.724 3.33 7.5 3.106 7.5 2.83V1.83C7.5 1.554 7.724 1.33 8 1.33ZM8 11.33C9.841 11.33 11.33 9.841 11.33 8C11.33 6.159 9.841 4.67 8 4.67C6.159 4.67 4.67 6.159 4.67 8C4.67 9.841 6.159 11.33 8 11.33ZM8 10.33C6.711 10.33 5.67 9.289 5.67 8C5.67 6.711 6.711 5.67 8 5.67C9.289 5.67 10.33 6.711 10.33 8C10.33 9.289 9.289 10.33 8 10.33ZM14.17 8.5C14.446 8.5 14.67 8.276 14.67 8C14.67 7.724 14.446 7.5 14.17 7.5H13.17C12.894 7.5 12.67 7.724 12.67 8C12.67 8.276 12.894 8.5 13.17 8.5H14.17ZM8 12.67C8.276 12.67 8.5 12.894 8.5 13.17V14.17C8.5 14.446 8.276 14.67 8 14.67C7.724 14.67 7.5 14.446 7.5 14.17V13.17C7.5 12.894 7.724 12.67 8 12.67ZM2.83 8.5C3.106 8.5 3.33 8.276 3.33 8C3.33 7.724 3.106 7.5 2.83 7.5H1.83C1.554 7.5 1.33 7.724 1.33 8C1.33 8.276 1.554 8.5 1.83 8.5H2.83ZM2.813 2.813C3.009 2.617 3.325 2.617 3.521 2.813L4.521 3.813C4.717 4.009 4.717 4.325 4.521 4.521C4.325 4.717 4.009 4.717 3.813 4.521L2.813 3.521C2.617 3.325 2.617 3.009 2.813 2.813ZM3.521 13.187C3.325 13.383 3.009 13.383 2.813 13.187C2.617 12.991 2.617 12.675 2.813 12.479L3.813 11.479C4.009 11.283 4.325 11.283 4.521 11.479C4.717 11.675 4.717 11.991 4.521 12.187L3.521 13.187ZM13.187 2.813C12.991 2.617 12.675 2.617 12.479 2.813L11.479 3.813C11.283 4.009 11.283 4.325 11.479 4.521C11.675 4.717 11.991 4.717 12.187 4.521L13.187 3.521C13.383 3.325 13.383 3.009 13.187 2.813ZM12.479 13.187C12.675 13.383 12.991 13.383 13.187 13.187C13.383 12.991 13.383 12.675 13.187 12.479L12.187 11.479C11.991 11.283 11.675 11.283 11.479 11.479C11.283 11.675 11.283 11.991 11.479 12.187L12.479 13.187Z" fill="#0078d4" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

3
images/moon-blue.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 7.5C4 5.567 5.567 4 7.5 4C8.5 4 9.4 4.4 10 5.1C9.5 4.8 8.9 4.6 8.3 4.6C6.8 4.6 5.6 5.8 5.6 7.3C5.6 8.8 6.8 10 8.3 10C8.9 10 9.5 9.8 10 9.5C9.4 10.2 8.5 10.6 7.5 10.6C5.567 10.6 4 9.033 4 7.1V7.5Z" fill="#0078D4"/>
</svg>

After

Width:  |  Height:  |  Size: 328 B

11
images/sun-blue.svg Normal file
View File

@@ -0,0 +1,11 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 2C6 1.44772 6.44772 1 7 1C7.55228 1 8 1.44772 8 2C8 2.55228 7.55228 3 7 3C6.44772 3 6 2.55228 6 2Z" fill="#0078D4"/>
<path d="M6 13C6 12.4477 6.44772 12 7 12C7.55228 12 8 12.4477 8 13C8 13.5523 7.55228 14 7 14C6.44772 14 6 13.5523 6 13Z" fill="#0078D4"/>
<path d="M1 7C1 6.44772 1.44772 6 2 6C2.55228 6 3 6.44772 3 7C3 7.55228 2.55228 8 2 8C1.44772 8 1 7.55228 1 7Z" fill="#0078D4"/>
<path d="M12 7C12 6.44772 12.4477 6 13 6C13.5523 6 14 6.44772 14 7C14 7.55228 13.5523 8 13 8C12.4477 8 12 7.55228 12 7Z" fill="#0078D4"/>
<path d="M2.63604 3.63604C3.02656 3.24551 3.65973 3.24551 4.05025 3.63604C4.44078 4.02656 4.44078 4.65973 4.05025 5.05025C3.65973 5.44078 3.02656 5.44078 2.63604 5.05025C2.24551 4.65973 2.24551 4.02656 2.63604 3.63604Z" fill="#0078D4"/>
<path d="M10.9497 9.94975C11.3403 9.55922 11.9734 9.55922 12.364 9.94975C12.7545 10.3403 12.7545 10.9734 12.364 11.364C11.9734 11.7545 11.3403 11.7545 10.9497 11.364C10.5592 10.9734 10.5592 10.3403 10.9497 9.94975Z" fill="#0078D4"/>
<path d="M10.9497 5.05025C10.5592 4.65973 10.5592 4.02656 10.9497 3.63604C11.3403 3.24551 11.9734 3.24551 12.364 3.63604C12.7545 4.02656 12.7545 4.65973 12.364 5.05025C11.9734 5.44078 11.3403 5.44078 10.9497 5.05025Z" fill="#0078D4"/>
<path d="M2.63604 11.364C2.24551 10.9734 2.24551 10.3403 2.63604 9.94975C3.02656 9.55922 3.65973 9.55922 4.05025 9.94975C4.44078 10.3403 4.44078 10.9734 4.05025 11.364C3.65973 11.7545 3.02656 11.7545 2.63604 11.364Z" fill="#0078D4"/>
<circle cx="7.5" cy="7.5" r="2.5" fill="#0078D4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -128,7 +128,7 @@
@provisionDatabaseThroughputInfo: 200px; @provisionDatabaseThroughputInfo: 200px;
//tabs container //tabs container
@ActiveTabHeight: 31px; @ActiveTabHeight: 32px;
@ActiveTabWidth: 141px; @ActiveTabWidth: 141px;
@TabsHeight: 30px; @TabsHeight: 30px;
@TabsWidth: 140px; @TabsWidth: 140px;
@@ -237,11 +237,11 @@
*********************************************************************************************/ *********************************************************************************************/
.hover() { .hover() {
background-color: @AccentLight; background-color: var(--colorNeutralBackground1Hover);
} }
.active() { .active() {
background-color: @AccentExtra; background-color: var(--colorNeutralBackground1Hover);
} }
.focus() { .focus() {

View File

@@ -406,7 +406,11 @@ body {
width: 440px; width: 440px;
min-height: 565px; min-height: 565px;
} }
.dataExplorerLoaderforcopyJobs{
width: 100%;
min-height: 565px;
right: 0;
}
.dataExplorerTabLoaderContainer { .dataExplorerTabLoaderContainer {
left: initial; left: initial;
top: initial; top: initial;
@@ -1740,7 +1744,7 @@ input::-webkit-calendar-picker-indicator {
flex: 1; flex: 1;
padding-left: 34px; padding-left: 34px;
padding-right: 34px; padding-right: 34px;
color: @BaseDark; color: var(--colorNeutralForeground1);
overflow-y: auto; overflow-y: auto;
overflow-x: auto; overflow-x: auto;
margin: (2 * @MediumSpace) 0px; margin: (2 * @MediumSpace) 0px;
@@ -1749,7 +1753,6 @@ input::-webkit-calendar-picker-indicator {
.contextual-pane .panelMainContent { .contextual-pane .panelMainContent {
padding-left: 34px; padding-left: 34px;
padding-right: 34px; padding-right: 34px;
color: @BaseDark;
margin: (2 * @MediumSpace) 0px; margin: (2 * @MediumSpace) 0px;
} }
@@ -1914,7 +1917,8 @@ input::-webkit-calendar-picker-indicator::after {
} }
.nav-tabs-margin { .nav-tabs-margin {
background-color: #f2f2f2; background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
.nav-tabs { .nav-tabs {
display: flex; display: flex;
@@ -1922,11 +1926,19 @@ input::-webkit-calendar-picker-indicator::after {
align-items: flex-end; align-items: flex-end;
height: 100%; height: 100%;
margin-bottom: -0.5px; margin-bottom: -0.5px;
background-color: var(--colorNeutralBackground1Selected);
li { li {
// Override the bootstrap defaults here to align with our layout constants.
margin-bottom: 0px; margin-bottom: 0px;
height: 32px; height: 32px;
&:hover {
background-color: var(--colorNeutralBackground1Hover);
}
&:active {
background-color: var(--colorNeutralBackground1Pressed);
}
} }
} }
} }
@@ -1940,8 +1952,9 @@ input::-webkit-calendar-picker-indicator::after {
.nav.nav-tabs.qslevel > li > a:hover { .nav.nav-tabs.qslevel > li > a:hover {
border: none; border: none;
border-radius: 0; border-radius: 0;
background-color: transparent !important; background-color: var(--colorNeutralBackground1Selected);
border-color: transparent; border-color: transparent;
color: var(--colorNeutralForeground1);
} }
.numbersize { .numbersize {
@@ -2376,6 +2389,8 @@ a:link {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 0; // This prevents it to grow past the parent's width if its content is too wide min-width: 0; // This prevents it to grow past the parent's width if its content is too wide
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
} }
.tabs { .tabs {
@@ -2631,14 +2646,16 @@ a:link {
} }
.tabPanesContainer { .tabPanesContainer {
display: flex;
flex-grow: 1; flex-grow: 1;
overflow: hidden; overflow: hidden;
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
} }
.tabs-container { .tabs-container {
height: 100%; height: 100%;
width: 100%; width: 100%;
overflow-y: auto;
} }
.paddingspan4 { .paddingspan4 {
@@ -2655,24 +2672,18 @@ a:link {
.nav-tabs > li.active > .tabNavContentContainer, .nav-tabs > li.active > .tabNavContentContainer,
.nav-tabs > li.active > .tabNavContentContainer:focus, .nav-tabs > li.active > .tabNavContentContainer:focus,
.nav-tabs > li.active > .tabNavContentContainer:hover { .nav-tabs > li.active > .tabNavContentContainer:hover {
color: #555; color: var(--colorNeutralForeground1);
cursor: default; cursor: default;
background-color: @BaseLight; background-color: var(--colorNeutralBackground1);
border-color: @BaseMedium; border-color: var(--colorNeutralStroke1);
border-bottom-color: @BaseLight;
border-style: solid; border-style: solid;
border-width: 1px; border-width: 1px;
height: @ActiveTabHeight; height: @ActiveTabHeight;
width: @ActiveTabWidth; width: @ActiveTabWidth;
} }
.nav-tabs > li.active > .tabNavContentContainer > .tab_Content > .contentWrapper > .tabNavText { .nav-tabs > li.active .contentWrapper .tabNavText {
font-weight: bolder; border-bottom: 2px solid var(--colorCompoundBrandBackground);
border-bottom: 2px solid rgba(0, 120, 212, 1);
}
.nav-tabs > li.active:focus > .tabNavContentContainer {
.focus();
} }
.tabNavContentContainer { .tabNavContentContainer {
@@ -2681,7 +2692,7 @@ a:link {
justify-content: space-between; justify-content: space-between;
border-radius: 2px 2px 0 0; border-radius: 2px 2px 0 0;
padding: @DefaultSpace 0px @SmallSpace 0px; padding: @DefaultSpace 0px @SmallSpace 0px;
color: @BaseHigh; color: var(--colorNeutralForeground1);
width: @TabsWidth; width: @TabsWidth;
text-align: center; text-align: center;
position: relative; position: relative;
@@ -2689,19 +2700,21 @@ a:link {
&:hover { &:hover {
text-decoration: none; text-decoration: none;
background-color: @BaseMediumLow; background-color: var(--colorNeutralBackground1Hover);
border-color: @BaseMediumLow; border-color: transparent;
} }
&:active { &:active {
background-color: @BaseMediumLow; background-color: var(--colorNeutralBackground1Pressed);
} }
.tab_Content { .tab_Content {
.flex-display(); .flex-display();
width: @TabsWidth; width: @TabsWidth;
border-right: @ButtonBorderWidth solid @BaseMedium; border-right: @ButtonBorderWidth solid var(--colorNeutralStroke1);
white-space: nowrap; white-space: nowrap;
color: var(--colorNeutralForeground1);
.contentWrapper { .contentWrapper {
.flex-display(); .flex-display();
width: @ContentWrapper; width: @ContentWrapper;
@@ -2723,9 +2736,8 @@ a:link {
background-image: url(../images/error_no_outline.svg); background-image: url(../images/error_no_outline.svg);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
background-size: 3px;
display: block; display: block;
margin: 1px 0px 0px 6px; margin: 4px 0px 0px 6px;
} }
} }
@@ -2750,39 +2762,60 @@ a:link {
.loadingIcon { .loadingIcon {
width: @LoadingErrorIconSize; width: @LoadingErrorIconSize;
height: @LoadingErrorIconSize; height: @LoadingErrorIconSize;
margin: 0px 0px @SmallSpace @SmallSpace; margin-top: 1px;
}
.warningIconContainer {
width: @ErrorIconContainer;
height: @ErrorIconContainer;
margin-top: 1px;
} }
} }
.tabNavText { .tabNavText {
margin-left: @SmallSpace; margin-left: @SmallSpace;
margin-right: 2px; margin-right: 2px;
color: @BaseDark; color: var(--colorNeutralForeground1);
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
flex-grow: 1; flex-grow: 1;
font-size: 12px;
} }
} }
.tabIconSection { .tabIconSection {
width: 29px;
position: relative; position: relative;
padding-top: 2px;
.cancelButton { .cancelButton {
padding: 0px @SmallSpace 0px @SmallSpace; padding: 0px @SmallSpace 0px @SmallSpace;
color: var(--colorNeutralForeground1);
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover { &:hover {
.hover(); background-color: var(--colorNeutralBackground1Hover);
color: var(--colorNeutralForeground1);
} }
&:focus { &:focus {
.focus(); background-color: var(--colorNeutralBackground1Pressed);
color: var(--colorNeutralForeground1);
} }
&:active { &:active {
.active(); background-color: var(--colorNeutralBackground1Pressed);
color: var(--colorNeutralForeground1);
}
&::before {
content: "×";
font-size: 16px;
line-height: 1;
} }
} }
} }
@@ -3137,3 +3170,12 @@ a:link {
.sidebarContainer { .sidebarContainer {
height: 100%; height: 100%;
} }
.close-Icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
cursor: pointer;
}

View File

@@ -7,6 +7,7 @@ html {
body { body {
font-family: @FabricFont; font-family: @FabricFont;
background-color: #f5f5f5; background-color: #f5f5f5;
--colorCompoundBrandBackground: @FabricAccentMedium;
} }
a { a {
@@ -41,7 +42,7 @@ a:focus {
} }
.nav-tabs-margin { .nav-tabs-margin {
padding-top: 5px; padding-top: 0px;
background-color: #ffffff; background-color: #ffffff;
} }
@@ -68,17 +69,20 @@ a:focus {
} }
.nav-tabs > li > .tabNavContentContainer > .tab_Content:hover { .nav-tabs > li > .tabNavContentContainer > .tab_Content:hover {
border-bottom: 2px solid #e0e0e0; border-bottom: none;
} }
.nav-tabs > li.active > .tabNavContentContainer > .tab_Content, .nav-tabs > li.active > .tabNavContentContainer > .tab_Content,
.nav-tabs > li.active > .tabNavContentContainer > .tab_Content:hover { .nav-tabs > li.active > .tabNavContentContainer > .tab_Content:hover {
border-bottom: 2px solid @FabricAccentMedium; border-bottom: none;
} }
.nav-tabs > li.active > .tabNavContentContainer > .tab_Content > .contentWrapper > .tabNavText { .nav-tabs > li.active > .tabNavContentContainer > .tab_Content > .contentWrapper > .tabNavText {
border-bottom: 0px none transparent; border-bottom: 0px none transparent;
} }
.nav-tabs > li.active .contentWrapper .tabNavText {
border-bottom: 2px solid @FabricAccentMedium;
}
.tabNavContentContainer { .tabNavContentContainer {
padding: @SmallSpace 0px @SmallSpace 0px; padding: @SmallSpace 0px @SmallSpace 0px;
@@ -214,6 +218,7 @@ a:focus {
.tabPanesContainer { .tabPanesContainer {
overflow: auto !important; overflow: auto !important;
display: flex;
} }
.tabs-container { .tabs-container {

View File

@@ -1,211 +1,227 @@
@import "./Common/Constants"; @import "./Common/Constants";
.dirty { .dirty {
border: 1px solid #9b4f96; border: 1px solid #9b4f96;
} }
.dirty:focus { .dirty:focus {
outline: 1px solid #9b4f96; outline: 1px solid #9b4f96;
} }
.tabForm { .tabForm {
padding: 12px 20px 20px 20px; padding: 12px 20px 20px 20px;
margin-left: 3px; margin-left: 3px;
} }
.storedTabForm { .storedTabForm {
padding-top: @LargeSpace; padding-top: @LargeSpace;
} }
.scaleSettingScrollable { .scaleSettingScrollable {
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
height:100%; height: 100%;
} }
.disableFocusDefaults[tabindex] { .disableFocusDefaults[tabindex] {
&:focus { &:focus {
outline: none; outline: none;
} }
&:active { &:active {
outline: none; outline: none;
} }
} }
.indexingPolicyEditor { .indexingPolicyEditor {
width: 100%; width: 100%;
height: calc(~"100vh - 400px"); height: calc(~"100vh - 400px");
} }
.scaleDivison { .scaleDivison {
padding: @MediumSpace 0px @DefaultSpace 0px; padding: @MediumSpace 0px @DefaultSpace 0px;
} }
.scaleSettingTitle { .scaleSettingTitle {
font-size: 14px; font-size: 14px;
cursor: pointer; cursor: pointer;
} }
.autoScaleThroughputTitle { .autoScaleThroughputTitle {
margin-bottom: @SmallSpace; margin-bottom: @SmallSpace;
} }
.autoScaleDescription { .autoScaleDescription {
margin-top: 6px; margin-top: 6px;
margin-bottom: @SmallSpace; margin-bottom: @SmallSpace;
} }
.ssExpandCollapseIcon { .ssExpandCollapseIcon {
width: 10px; width: 10px;
height: 10px; height: 10px;
} }
.ssCollapseIcon { .ssCollapseIcon {
margin-bottom: 5px; margin-bottom: 5px;
} }
.ssTextAllignment { .ssTextAllignment {
padding-left: 19px; padding-left: 19px;
} }
.throughputStorageBlock { .throughputStorageBlock {
border-top: 1px solid #bbb; border-top: 1px solid #bbb;
border-bottom: 1px solid #bbb; border-bottom: 1px solid #bbb;
background-color: #ccc; background-color: #ccc;
padding-left: 10px; padding-left: 10px;
width: 315px; width: 315px;
} }
.storageCapacityTitle { .storageCapacityTitle {
padding: @LargeSpace 0px; padding: @LargeSpace 0px;
} }
.throughputStorageValue { .throughputStorageValue {
font-size: 12px; font-size: 12px;
} }
.estimatedCost, .largePartitionKeyEnabled { .estimatedCost,
padding: @SmallSpace 0px @LargeSpace; .largePartitionKeyEnabled {
padding: @SmallSpace 0px @LargeSpace;
} }
.storagePadding { .storagePadding {
padding-top: 6px; padding-top: 6px;
padding-bottom: 14px; padding-bottom: 14px;
} }
.dirtyTextbox { .dirtyTextbox {
width: 176px; width: 176px;
margin-top: 7px; margin-top: 7px;
padding-left: 5px; padding-left: 5px;
} }
.formTitleFirst { .formTitleFirst {
padding: @DefaultSpace (2 * @MediumSpace); padding: @DefaultSpace (2 * @MediumSpace);
} }
.formTitleTextbox { .formTitleTextbox {
padding: 0px 0px @DefaultSpace (2 * @MediumSpace); padding: 0px 0px @DefaultSpace (2 * @MediumSpace);
} }
.formTree { .formTree {
border: 1px solid #969696; border: 1px solid var(--colorNeutralStroke1);
color: #393939; color: var(--colorNeutralForeground1);
padding: 0px 12px 1px 8px; background-color: var(--colorNeutralBackground1);
padding: 0px 12px 1px 8px;
} }
.formTree:hover { .formTree:hover {
border: 1px solid #969696; border: 1px solid var(--colorNeutralStroke1Hover);
background-color: #e6f8fe; background-color: var(--colorNeutralBackground1Hover);
}
.formTree::placeholder {
color: var(--colorNeutralForeground2);
opacity: 1;
} }
.formTree:active { .formTree:active {
border: 1px solid #1ebbee; border: 1px solid var(--colorNeutralStroke1Pressed);
background-color: var(--colorNeutralBackground1Pressed);
} }
.scaleForm { .scaleForm {
padding-left: 8px; padding-left: 8px;
color: @BaseDark; color: @BaseDark;
border: 1px solid #969696; border: 1px solid #969696;
min-width: @ScaleFormWidth; min-width: @ScaleFormWidth;
&:hover { &:hover {
background-color: #e6f8fe; background-color: #e6f8fe;
} }
} }
.formTitle { .formTitle {
margin-top: 16px; margin-top: 16px;
margin-bottom: 4px; margin-bottom: 4px;
} }
.spUdfTriggerHeader { .spUdfTriggerHeader {
padding: @DefaultSpace 0px @SmallSpace (2 * @MediumSpace); padding: @DefaultSpace 0px @SmallSpace (2 * @MediumSpace);
} }
.storedUdfTriggerEditor { .storedUdfTriggerEditor {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.unselectedRadio { .unselectedRadio {
background-color: white; background-color: white;
border-color: #EEE!important; border-color: #eee !important;
color: black!important; color: black !important;
} }
.disabledRadio { .disabledRadio {
background-color: #A19F9D; background-color: #a19f9d;
border-color: #EEE!important; border-color: #eee !important;
color: white!important; color: white !important;
} }
.selectedRadio { .selectedRadio {
background-color: @AccentMediumHigh; background-color: @AccentMediumHigh;
border-color: #EEE!important; border-color: #eee !important;
color: white!important; color: white !important;
cursor: pointer; cursor: pointer;
} }
.selectedRadio:hover { .selectedRadio:hover {
background-color: @AccentMediumHigh; background-color: @AccentMediumHigh;
border-color: #EEE!important; border-color: #eee !important;
color: white!important; color: white !important;
cursor: pointer; cursor: pointer;
} }
.selectedRadio:active { .selectedRadio:active {
background-color: #0072c6; background-color: #0072c6;
border-color: #EEE!important; border-color: #eee !important;
color: white!important; color: white !important;
cursor: pointer; cursor: pointer;
border: 1px solid #0072c6; border: 1px solid #0072c6;
} }
.selectedRadio.dirty { .selectedRadio.dirty {
background-color: #9b4f96; background-color: #9b4f96;
} }
.tabs { .tabs {
margin: 0; margin: 0;
} }
.formReadOnly { .formReadOnly {
background-color: #ddd; background-color: #ddd;
border: 1px solid #969696; border: 1px solid #969696;
min-width: 184px; min-width: 184px;
padding-left: 8px; padding-left: 8px;
} }
.migration:disabled { .migration:disabled {
background-color: #ccc; background-color: #ccc;
} }
.trigger-field { .trigger-field {
width: 40%; width: 40%;
margin-top: 10px margin-top: 10px;
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
} }
.trigger-field input::placeholder {
color: var(--colorNeutralForeground3);
opacity: 1;
}
.trigger-form { .trigger-form {
padding: 10px 30px 10px 30px; background-color: var(--colorNeutralBackground1);
} color: var(--colorNeutralForeground1);
padding: 10px 30px;
}

View File

@@ -255,7 +255,7 @@ body {
flex: 1; flex: 1;
padding-left: 34px; padding-left: 34px;
padding-right: 34px; padding-right: 34px;
color: @BaseDark; color: var(--colorNeutralForeground1);
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
margin: (2 * @MediumSpace) 0px; margin: (2 * @MediumSpace) 0px;

View File

@@ -1,270 +0,0 @@
@import "./Common/Constants";
.resourceTree {
height: 100%;
flex: 0 0 auto;
.main {
height: 100%;
}
}
.resourceTreeScroll {
height: 100%;
display: flex;
overflow-y: auto;
overflow-x: hidden;
padding-right: 10px;
}
.userSelectNone {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.treeHovermargin {
margin-left: 16px;
}
.highlight {
padding: @SmallSpace 2px;
outline: 0;
&:hover {
.hover();
}
&:active {
.active();
}
&:focus {
.focus();
}
}
.contextmenushowing {
background-color: #eee;
}
.collectionstree {
width: 100%;
margin-top: @DefaultSpace;
.databaseList {
list-style-type: none;
padding-left: 0px;
.collectionList {
padding-left: (2 * @MediumSpace);
}
.collectionChildList {
padding-left: @LargeSpace;
}
.databaseDocuments {
padding-left: (5 * @MediumSpace);
}
}
}
.pointerCursor {
cursor: pointer;
}
.menuEllipsis {
padding-right: 6px;
font-weight: bold;
font-size: 18px;
position: relative;
top: -5px;
left: 0px;
float: right;
display: none;
padding-left: 6px !important;
line-height: @TreeLineHeight;
}
.databaseMenu {
.flex-display();
}
.databaseMenu:hover .menuEllipsis,
.databaseMenu:focus .menuEllipsis {
display: block;
}
.databaseCollChildTextOverflow {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
flex: 1;
}
.collectionMenu {
.flex-display();
}
.collectionMenu:hover .menuEllipsis,
.collectionMenu:focus .menuEllipsis {
display: block;
}
.documentsMenu:hover .menuEllipsis,
.documentsMenu:focus .menuEllipsis {
display: block;
}
.treeChildMenu {
display: flex;
}
.storedProcedureMenu:hover .menuEllipsis,
.storedProcedureMenu:focus .menuEllipsis {
display: block;
}
.childMenu {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-left: (6 * @MediumSpace);
width: 100%;
}
.storedChildMenu:hover .menuEllipsis,
.storedChildMenu:focus .menuEllipsis {
display: block;
}
.contextmenu6 {
top: -29px;
}
.userDefinedMenu:hover .contextmenu6 {
display: block;
}
.userDefinedchildMenu:hover .menuEllipsis,
.userDefinedchildMenu:focus .menuEllipsis {
display: block;
}
.triggersMenu:hover .menuEllipsis,
.triggersMenu:focus .menuEllipsis {
display: block;
}
.triggersChildMenu:hover .menuEllipsis,
.triggersChildMenu:focus .menuEllipsis {
display: block;
}
.databaseId {
font-size: 14px;
}
.storedUdfTriggerMenu {
padding-left: 0px;
}
.collectionstree img {
width: 16px;
height: 16px;
vertical-align: text-top;
}
img.collectionsTreeCollapseExpand {
width: 10px;
height: 10px;
vertical-align: middle;
margin-bottom: 5px;
}
.collapsed::before {
content: "\23F5";
margin-left: 0px;
font-size: 15px;
}
.expanded::before {
content: "\23F7";
margin-left: 0px;
font-size: 15px;
}
.collectionMenuChildren {
padding-left: 42px;
}
.main-nav {
width: 100vh;
height: 40px;
background: white;
transform-origin: left top;
-webkit-transform-origin: left top;
-ms-transform-origin: left top;
transform: rotate(-90deg) translateX(-100%);
-webkit-transform: rotate(-90deg) translateX(-100%);
-ms-transform: rotate(-90deg) translateX(-100%);
border-bottom: 1px solid #ccc;
}
.main-nav-img {
width: 16px;
height: 16px;
margin: -32px 0 0 0;
transform: rotate(-90deg) translateX(-100%);
-webkit-transform: rotate(-90deg) translateX(-100%);
-ms-transform: rotate(-90deg) translateX(-100%);
}
.main-nav-img.main-nav-sub-img {
width: 16px;
height: 16px;
margin: 0px 0px 0 0;
transform: rotate(180deg) translateX(0%);
-webkit-transform: rotate(180deg) translateX(0%);
-ms-transform: rotate(180deg) translateX(0%);
position: absolute;
right: -8px;
top: 16px;
}
ul.nav {
margin: 0 auto;
margin-top: 0px;
margin-left: 0px;
}
.mini ul.nav li {
float: right;
line-height: 25px;
height: auto;
margin-top: 3px;
}
.spancolchildstyle {
padding: 4px;
}
.contextmenubutton {
float: right;
display: none;
}
.highlight:hover > .contextmenubutton {
display: unset;
}
.highlight:hover > .contextmenubutton::after {
content: "\2026";
font-size: 12px;
}
.showEllipsis {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

View File

@@ -1,4 +1,5 @@
import { Overlay, Spinner, SpinnerSize } from "@fluentui/react"; import { Overlay, Spinner, SpinnerSize } from "@fluentui/react";
import { useThemeStore } from "hooks/useTheme";
import React from "react"; import React from "react";
interface LoadingOverlayProps { interface LoadingOverlayProps {
@@ -7,15 +8,17 @@ interface LoadingOverlayProps {
} }
const LoadingOverlay: React.FC<LoadingOverlayProps> = ({ isLoading, label }) => { const LoadingOverlay: React.FC<LoadingOverlayProps> = ({ isLoading, label }) => {
const isDarkMode = useThemeStore((state) => state.isDarkMode);
if (!isLoading) { if (!isLoading) {
return null; return null;
} }
return ( return (
<Overlay <Overlay
data-test="loading-overlay"
styles={{ styles={{
root: { root: {
backgroundColor: "rgba(255,255,255,0.9)", backgroundColor: isDarkMode ? "rgba(32, 31, 30, 0.9)" : "rgba(255,255,255,0.9)",
zIndex: 9999, zIndex: 9999,
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
@@ -23,7 +26,11 @@ const LoadingOverlay: React.FC<LoadingOverlayProps> = ({ isLoading, label }) =>
}, },
}} }}
> >
<Spinner size={SpinnerSize.large} label={label} styles={{ label: { fontWeight: 600 } }} /> <Spinner
size={SpinnerSize.large}
label={label}
styles={{ label: { fontWeight: 600, color: isDarkMode ? "#ffffff" : "#323130" } }}
/>
</Overlay> </Overlay>
); );
}; };

View File

@@ -11,3 +11,14 @@
gap: 8px; gap: 8px;
align-items: center; align-items: center;
} }
/* Override dark mode inherit for pagination icons */
body.isDarkMode .pager-container .ms-Button .ms-Button-icon,
body.isDarkMode .pager-container .ms-Button i {
color: var(--colorBrandForeground1);
}
body.isDarkMode .pager-container .ms-Button:disabled .ms-Button-icon,
body.isDarkMode .pager-container .ms-Button:disabled i {
color: var(--colorNeutralForegroundDisabled);
}

View File

@@ -59,7 +59,7 @@ const Pager: React.FC<PagerProps> = ({
return ( return (
<div className={className || "pager-container"}> <div className={className || "pager-container"}>
{showItemCount && ( {showItemCount && (
<Text> <Text className="themeText">
Showing {startIndex + 1} - {endIndex} of {totalCount} items Showing {startIndex + 1} - {endIndex} of {totalCount} items
</Text> </Text>
)} )}
@@ -82,7 +82,7 @@ const Pager: React.FC<PagerProps> = ({
disabled={disabled || currentPage === 1} disabled={disabled || currentPage === 1}
styles={iconButtonStyles} styles={iconButtonStyles}
/> />
<Text> <Text className="themeText">
Page {currentPage} of {totalPages} Page {currentPage} of {totalPages}
</Text> </Text>
<IconButton <IconButton

View File

@@ -50,10 +50,33 @@ export const Upload: FunctionComponent<UploadProps> = ({
const title = label + " to upload"; const title = label + " to upload";
return ( return (
<div> <div>
<span className="renewUploadItemsHeader">{label}</span> <span className="renewUploadItemsHeader" style={{ color: "var(--colorNeutralForeground1)" }}>
{label}
</span>
{tooltip && <InfoTooltip>{tooltip}</InfoTooltip>} {tooltip && <InfoTooltip>{tooltip}</InfoTooltip>}
<Stack horizontal> <Stack horizontal>
<TextField styles={{ fieldGroup: { width: 300 } }} readOnly value={selectedFilesTitle.toString()} /> <TextField
styles={{
fieldGroup: {
width: 300,
backgroundColor: "var(--colorNeutralBackground3)",
borderColor: "var(--colorNeutralStroke1)",
},
field: {
backgroundColor: "var(--colorNeutralBackground3)",
color: "var(--colorNeutralForeground1)",
},
subComponentStyles: {
label: {
root: {
color: "var(--colorNeutralForeground1)",
},
},
},
}}
readOnly
value={selectedFilesTitle.toString()}
/>
<input <input
type="file" type="file"
id="importFileInput" id="importFileInput"

View File

@@ -3,6 +3,7 @@
exports[`LoadingOverlay should handle long labels properly 1`] = ` exports[`LoadingOverlay should handle long labels properly 1`] = `
<div <div
class="ms-Overlay root-109" class="ms-Overlay root-109"
data-test="loading-overlay"
> >
<div <div
class="ms-Spinner root-111" class="ms-Spinner root-111"
@@ -22,6 +23,7 @@ exports[`LoadingOverlay should handle long labels properly 1`] = `
exports[`LoadingOverlay should render loading overlay when isLoading is true 1`] = ` exports[`LoadingOverlay should render loading overlay when isLoading is true 1`] = `
<div <div
class="ms-Overlay root-109" class="ms-Overlay root-109"
data-test="loading-overlay"
> >
<div <div
class="ms-Spinner root-111" class="ms-Spinner root-111"
@@ -41,6 +43,7 @@ exports[`LoadingOverlay should render loading overlay when isLoading is true 1`]
exports[`LoadingOverlay should render loading overlay with custom label 1`] = ` exports[`LoadingOverlay should render loading overlay with custom label 1`] = `
<div <div
class="ms-Overlay root-109" class="ms-Overlay root-109"
data-test="loading-overlay"
> >
<div <div
class="ms-Spinner root-111" class="ms-Spinner root-111"
@@ -60,6 +63,7 @@ exports[`LoadingOverlay should render loading overlay with custom label 1`] = `
exports[`LoadingOverlay should render loading overlay with empty label 1`] = ` exports[`LoadingOverlay should render loading overlay with empty label 1`] = `
<div <div
class="ms-Overlay root-109" class="ms-Overlay root-109"
data-test="loading-overlay"
> >
<div <div
class="ms-Spinner root-111" class="ms-Spinner root-111"

View File

@@ -1,3 +1,4 @@
import { configContext } from "ConfigContext";
import { ApiType, userContext } from "UserContext"; import { ApiType, userContext } from "UserContext";
import * as NotificationConsoleUtils from "Utils/NotificationConsoleUtils"; import * as NotificationConsoleUtils from "Utils/NotificationConsoleUtils";
import { import {
@@ -14,9 +15,12 @@ import {
DataTransferJobFeedResults, DataTransferJobFeedResults,
DataTransferJobGetResults, DataTransferJobGetResults,
} from "Utils/arm/generatedClients/dataTransferService/types"; } from "Utils/arm/generatedClients/dataTransferService/types";
import { armRequest } from "Utils/arm/request";
import { addToPolling, removeFromPolling, updateDataTransferJob, useDataTransferJobs } from "hooks/useDataTransferJobs"; import { addToPolling, removeFromPolling, updateDataTransferJob, useDataTransferJobs } from "hooks/useDataTransferJobs";
import promiseRetry, { AbortError, FailedAttemptError } from "p-retry"; import promiseRetry, { AbortError, FailedAttemptError } from "p-retry";
export const DATA_TRANSFER_JOB_API_VERSION = "2025-05-01-preview";
export interface DataTransferParams { export interface DataTransferParams {
jobName: string; jobName: string;
apiType: ApiType; apiType: ApiType;
@@ -33,26 +37,34 @@ export const getDataTransferJobs = async (
subscriptionId: string, subscriptionId: string,
resourceGroup: string, resourceGroup: string,
accountName: string, accountName: string,
signal?: AbortSignal,
): Promise<DataTransferJobGetResults[]> => { ): Promise<DataTransferJobGetResults[]> => {
let dataTransferJobs: DataTransferJobGetResults[] = []; let dataTransferJobs: DataTransferJobGetResults[] = [];
let dataTransferFeeds: DataTransferJobFeedResults = await listByDatabaseAccount( let dataTransferFeeds: DataTransferJobFeedResults = await listByDatabaseAccount(
subscriptionId, subscriptionId,
resourceGroup, resourceGroup,
accountName, accountName,
signal,
); );
dataTransferJobs = [...dataTransferJobs, ...(dataTransferFeeds?.value || [])]; dataTransferJobs = [...dataTransferJobs, ...(dataTransferFeeds?.value || [])];
while (dataTransferFeeds?.nextLink) { while (dataTransferFeeds?.nextLink) {
const nextResponse = await window.fetch(dataTransferFeeds.nextLink, { /**
headers: { * The `nextLink` URL returned by the Cosmos DB SQL API pointed to an incorrect endpoint, causing timeouts.
Authorization: userContext.authorizationToken, * (i.e: https://cdbmgmtprodby.documents.azure.com:450/subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.DocumentDB/databaseAccounts/{account}/sql/dataTransferJobs?$top=100&$skiptoken=...)
}, * We manipulate the URL by parsing it to extract the path and query parameters,
* then construct the correct URL for the Azure Resource Manager (ARM) API.
* This ensures that the request is made to the correct base URL (`configContext.ARM_ENDPOINT`),
* which is required for ARM operations.
*/
const parsedUrl = new URL(dataTransferFeeds.nextLink);
const nextUrlPath = parsedUrl.pathname + parsedUrl.search;
dataTransferFeeds = await armRequest({
host: configContext.ARM_ENDPOINT,
path: nextUrlPath,
method: "GET",
apiVersion: DATA_TRANSFER_JOB_API_VERSION,
}); });
if (nextResponse.ok) { dataTransferJobs.push(...(dataTransferFeeds?.value || []));
dataTransferFeeds = await nextResponse.json();
dataTransferJobs = [...dataTransferJobs, ...(dataTransferFeeds?.value || [])];
} else {
break;
}
} }
return dataTransferJobs; return dataTransferJobs;
}; };

View File

@@ -50,4 +50,5 @@ export enum MessageTypes {
OpenCESCVAFeedbackBlade, OpenCESCVAFeedbackBlade,
ActivateTab, ActivateTab,
OpenContainerCopyFeedbackBlade, OpenContainerCopyFeedbackBlade,
UpdateTheme,
} }

View File

@@ -7,7 +7,7 @@ import {
TriggerDefinition, TriggerDefinition,
UserDefinedFunctionDefinition, UserDefinedFunctionDefinition,
} from "@azure/cosmos"; } from "@azure/cosmos";
import Explorer from "../Explorer/Explorer"; import type Explorer from "../Explorer/Explorer";
import { ConsoleData } from "../Explorer/Menus/NotificationConsole/ConsoleData"; import { ConsoleData } from "../Explorer/Menus/NotificationConsole/ConsoleData";
import { CassandraTableKey, CassandraTableKeys } from "../Explorer/Tables/TableDataClient"; import { CassandraTableKey, CassandraTableKeys } from "../Explorer/Tables/TableDataClient";
import ConflictId from "../Explorer/Tree/ConflictId"; import ConflictId from "../Explorer/Tree/ConflictId";
@@ -447,6 +447,9 @@ export interface DataExplorerInputsFrame {
aadToken?: string; aadToken?: string;
containerCopyEnabled?: boolean; containerCopyEnabled?: boolean;
sessionId?: string; sessionId?: string;
theme?: {
mode: number;
};
} }
export interface SelfServeFrameInputs { export interface SelfServeFrameInputs {
@@ -480,3 +483,6 @@ export interface DropdownOption<T> {
value: T; value: T;
disable?: boolean; disable?: boolean;
} }
// Remove the duplicate Explorer interface and export the type
export type { Explorer };

View File

@@ -39,7 +39,7 @@ describe("CopyJobCommandBar", () => {
render(<CopyJobCommandBar explorer={mockExplorer} />); render(<CopyJobCommandBar explorer={mockExplorer} />);
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer); expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer, false);
expect(mockGetCommandBarButtons).toHaveBeenCalledTimes(1); expect(mockGetCommandBarButtons).toHaveBeenCalledTimes(1);
}); });
@@ -163,7 +163,7 @@ describe("CopyJobCommandBar", () => {
render(<CopyJobCommandBar explorer={mockExplorer} />); render(<CopyJobCommandBar explorer={mockExplorer} />);
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer); expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer, false);
expect(mockConvertButton.mock.calls[0][0]).toEqual(mockCommandButtonProps); expect(mockConvertButton.mock.calls[0][0]).toEqual(mockCommandButtonProps);
}); });
@@ -175,11 +175,11 @@ describe("CopyJobCommandBar", () => {
mockConvertButton.mockReturnValue([]); mockConvertButton.mockReturnValue([]);
const { rerender } = render(<CopyJobCommandBar explorer={mockExplorer1} />); const { rerender } = render(<CopyJobCommandBar explorer={mockExplorer1} />);
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer1); expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer1, false);
rerender(<CopyJobCommandBar explorer={mockExplorer2} />); rerender(<CopyJobCommandBar explorer={mockExplorer2} />);
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer2); expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer2, false);
expect(mockGetCommandBarButtons).toHaveBeenCalledTimes(2); expect(mockGetCommandBarButtons).toHaveBeenCalledTimes(2);
}); });
}); });

View File

@@ -1,24 +1,28 @@
import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react"; import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react";
import React from "react"; import React from "react";
import { StyleConstants } from "../../../Common/StyleConstants"; import { useThemeStore } from "../../../hooks/useTheme";
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
import * as CommandBarUtil from "../../Menus/CommandBar/CommandBarUtil"; import * as CommandBarUtil from "../../Menus/CommandBar/CommandBarUtil";
import { getThemeTokens } from "../../Theme/ThemeUtil";
import { ContainerCopyProps } from "../Types/CopyJobTypes"; import { ContainerCopyProps } from "../Types/CopyJobTypes";
import { getCommandBarButtons } from "./Utils"; import { getCommandBarButtons } from "./Utils";
const backgroundColor = StyleConstants.BaseLight;
const rootStyle = {
root: {
backgroundColor: backgroundColor,
},
};
const CopyJobCommandBar: React.FC<ContainerCopyProps> = ({ explorer }) => { const CopyJobCommandBar: React.FC<ContainerCopyProps> = ({ explorer }) => {
const commandBarItems: CommandButtonComponentProps[] = getCommandBarButtons(explorer); const isDarkMode = useThemeStore((state) => state.isDarkMode);
const themeTokens = getThemeTokens(isDarkMode);
const backgroundColor = themeTokens.colorNeutralBackground1;
const rootStyle = {
root: {
backgroundColor: backgroundColor,
},
};
const commandBarItems: CommandButtonComponentProps[] = getCommandBarButtons(explorer, isDarkMode);
const controlButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(commandBarItems, backgroundColor); const controlButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(commandBarItems, backgroundColor);
return ( return (
<div className="commandBarContainer"> <div className="commandBarContainer" style={{ backgroundColor }}>
<FluentCommandBar <FluentCommandBar
ariaLabel="Use left and right arrow keys to navigate between commands" ariaLabel="Use left and right arrow keys to navigate between commands"
styles={rootStyle} styles={rootStyle}

View File

@@ -50,7 +50,7 @@ describe("CommandBar Utils", () => {
describe("getCommandBarButtons", () => { describe("getCommandBarButtons", () => {
it("should return an array of command button props", () => { it("should return an array of command button props", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
expect(buttons).toBeDefined(); expect(buttons).toBeDefined();
expect(Array.isArray(buttons)).toBe(true); expect(Array.isArray(buttons)).toBe(true);
@@ -58,7 +58,7 @@ describe("CommandBar Utils", () => {
}); });
it("should include create copy job button", () => { it("should include create copy job button", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
const createButton = buttons[0]; const createButton = buttons[0];
expect(createButton).toBeDefined(); expect(createButton).toBeDefined();
@@ -70,7 +70,7 @@ describe("CommandBar Utils", () => {
}); });
it("should include refresh button", () => { it("should include refresh button", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
const refreshButton = buttons[1]; const refreshButton = buttons[1];
expect(refreshButton).toBeDefined(); expect(refreshButton).toBeDefined();
@@ -80,11 +80,11 @@ describe("CommandBar Utils", () => {
}); });
it("should include feedback button when platform is Portal", () => { it("should include feedback button when platform is Portal", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
expect(buttons.length).toBe(3); expect(buttons.length).toBe(4);
const feedbackButton = buttons[2]; const feedbackButton = buttons[3];
expect(feedbackButton).toBeDefined(); expect(feedbackButton).toBeDefined();
expect(feedbackButton.ariaLabel).toBe("Provide feedback on copy jobs"); expect(feedbackButton.ariaLabel).toBe("Provide feedback on copy jobs");
expect(feedbackButton.tooltipText).toBe("Feedback"); expect(feedbackButton.tooltipText).toBe("Feedback");
@@ -105,13 +105,13 @@ describe("CommandBar Utils", () => {
})); }));
const { getCommandBarButtons: getCommandBarButtonsEmulator } = await import("./Utils"); const { getCommandBarButtons: getCommandBarButtonsEmulator } = await import("./Utils");
const buttons = getCommandBarButtonsEmulator(mockExplorer); const buttons = getCommandBarButtonsEmulator(mockExplorer, false);
expect(buttons.length).toBe(2); expect(buttons.length).toBe(3);
}); });
it("should call openCreateCopyJobPanel when create button is clicked", () => { it("should call openCreateCopyJobPanel when create button is clicked", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
const createButton = buttons[0]; const createButton = buttons[0];
createButton.onCommandClick({} as React.SyntheticEvent); createButton.onCommandClick({} as React.SyntheticEvent);
@@ -121,7 +121,7 @@ describe("CommandBar Utils", () => {
}); });
it("should call refreshJobList when refresh button is clicked", () => { it("should call refreshJobList when refresh button is clicked", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
const refreshButton = buttons[1]; const refreshButton = buttons[1];
refreshButton.onCommandClick({} as React.SyntheticEvent); refreshButton.onCommandClick({} as React.SyntheticEvent);
@@ -130,8 +130,8 @@ describe("CommandBar Utils", () => {
}); });
it("should call openContainerCopyFeedbackBlade when feedback button is clicked", () => { it("should call openContainerCopyFeedbackBlade when feedback button is clicked", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
const feedbackButton = buttons[2]; const feedbackButton = buttons[3];
feedbackButton.onCommandClick({} as React.SyntheticEvent); feedbackButton.onCommandClick({} as React.SyntheticEvent);
@@ -139,7 +139,7 @@ describe("CommandBar Utils", () => {
}); });
it("should return buttons with correct icon sources", () => { it("should return buttons with correct icon sources", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
expect(buttons[0].iconSrc).toBeDefined(); expect(buttons[0].iconSrc).toBeDefined();
expect(buttons[0].iconAlt).toBe("Create Copy Job"); expect(buttons[0].iconAlt).toBe("Create Copy Job");
@@ -148,7 +148,10 @@ describe("CommandBar Utils", () => {
expect(buttons[1].iconAlt).toBe("Refresh"); expect(buttons[1].iconAlt).toBe("Refresh");
expect(buttons[2].iconSrc).toBeDefined(); expect(buttons[2].iconSrc).toBeDefined();
expect(buttons[2].iconAlt).toBe("Feedback"); expect(buttons[2].iconAlt).toBe("Dark Theme");
expect(buttons[3].iconSrc).toBeDefined();
expect(buttons[3].iconAlt).toBe("Feedback");
}); });
it("should handle null MonitorCopyJobsRefState ref gracefully", () => { it("should handle null MonitorCopyJobsRefState ref gracefully", () => {
@@ -157,14 +160,14 @@ describe("CommandBar Utils", () => {
return selector(state); return selector(state);
}); });
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
const refreshButton = buttons[1]; const refreshButton = buttons[1];
expect(() => refreshButton.onCommandClick({} as React.SyntheticEvent)).not.toThrow(); expect(() => refreshButton.onCommandClick({} as React.SyntheticEvent)).not.toThrow();
}); });
it("should set hasPopup to false for all buttons", () => { it("should set hasPopup to false for all buttons", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button) => { buttons.forEach((button) => {
expect(button.hasPopup).toBe(false); expect(button.hasPopup).toBe(false);
@@ -172,7 +175,7 @@ describe("CommandBar Utils", () => {
}); });
it("should set commandButtonLabel to undefined for all buttons", () => { it("should set commandButtonLabel to undefined for all buttons", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button) => { buttons.forEach((button) => {
expect(button.commandButtonLabel).toBeUndefined(); expect(button.commandButtonLabel).toBeUndefined();
@@ -180,7 +183,7 @@ describe("CommandBar Utils", () => {
}); });
it("should respect disabled state when provided", () => { it("should respect disabled state when provided", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button) => { buttons.forEach((button) => {
expect(button.disabled).toBe(false); expect(button.disabled).toBe(false);
@@ -188,7 +191,7 @@ describe("CommandBar Utils", () => {
}); });
it("should return CommandButtonComponentProps with all required properties", () => { it("should return CommandButtonComponentProps with all required properties", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button: CommandButtonComponentProps) => { buttons.forEach((button: CommandButtonComponentProps) => {
expect(button).toHaveProperty("iconSrc"); expect(button).toHaveProperty("iconSrc");
@@ -202,18 +205,19 @@ describe("CommandBar Utils", () => {
}); });
}); });
it("should maintain button order: create, refresh, feedback", () => { it("should maintain button order: create, refresh, themeToggle, feedback", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
expect(buttons[0].tooltipText).toBe("Create Copy Job"); expect(buttons[0].tooltipText).toBe("Create Copy Job");
expect(buttons[1].tooltipText).toBe("Refresh"); expect(buttons[1].tooltipText).toBe("Refresh");
expect(buttons[2].tooltipText).toBe("Feedback"); expect(buttons[2].tooltipText).toBe("Dark Theme");
expect(buttons[3].tooltipText).toBe("Feedback");
}); });
}); });
describe("Button click handlers", () => { describe("Button click handlers", () => {
it("should execute click handlers without errors", () => { it("should execute click handlers without errors", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button) => { buttons.forEach((button) => {
expect(() => button.onCommandClick({} as React.SyntheticEvent)).not.toThrow(); expect(() => button.onCommandClick({} as React.SyntheticEvent)).not.toThrow();
@@ -221,7 +225,7 @@ describe("CommandBar Utils", () => {
}); });
it("should call correct action for each button", () => { it("should call correct action for each button", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons[0].onCommandClick({} as React.SyntheticEvent); buttons[0].onCommandClick({} as React.SyntheticEvent);
expect(Actions.openCreateCopyJobPanel).toHaveBeenCalledWith(mockExplorer); expect(Actions.openCreateCopyJobPanel).toHaveBeenCalledWith(mockExplorer);
@@ -229,14 +233,14 @@ describe("CommandBar Utils", () => {
buttons[1].onCommandClick({} as React.SyntheticEvent); buttons[1].onCommandClick({} as React.SyntheticEvent);
expect(mockRefreshJobList).toHaveBeenCalled(); expect(mockRefreshJobList).toHaveBeenCalled();
buttons[2].onCommandClick({} as React.SyntheticEvent); buttons[3].onCommandClick({} as React.SyntheticEvent);
expect(mockOpenContainerCopyFeedbackBlade).toHaveBeenCalled(); expect(mockOpenContainerCopyFeedbackBlade).toHaveBeenCalled();
}); });
}); });
describe("Accessibility", () => { describe("Accessibility", () => {
it("should have aria labels for all buttons", () => { it("should have aria labels for all buttons", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button) => { buttons.forEach((button) => {
expect(button.ariaLabel).toBeDefined(); expect(button.ariaLabel).toBeDefined();
@@ -246,7 +250,7 @@ describe("CommandBar Utils", () => {
}); });
it("should have tooltip text for all buttons", () => { it("should have tooltip text for all buttons", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button) => { buttons.forEach((button) => {
expect(button.tooltipText).toBeDefined(); expect(button.tooltipText).toBeDefined();
@@ -256,7 +260,7 @@ describe("CommandBar Utils", () => {
}); });
it("should have icon alt text for all buttons", () => { it("should have icon alt text for all buttons", () => {
const buttons = getCommandBarButtons(mockExplorer); const buttons = getCommandBarButtons(mockExplorer, false);
buttons.forEach((button) => { buttons.forEach((button) => {
expect(button.iconAlt).toBeDefined(); expect(button.iconAlt).toBeDefined();

View File

@@ -1,7 +1,10 @@
import AddIcon from "../../../../images/Add.svg"; import AddIcon from "../../../../images/Add.svg";
import FeedbackIcon from "../../../../images/Feedback-Command.svg"; import FeedbackIcon from "../../../../images/Feedback-Command.svg";
import MoonIcon from "../../../../images/MoonIcon.svg";
import RefreshIcon from "../../../../images/refresh-cosmos.svg"; import RefreshIcon from "../../../../images/refresh-cosmos.svg";
import SunIcon from "../../../../images/SunIcon.svg";
import { configContext, Platform } from "../../../ConfigContext"; import { configContext, Platform } from "../../../ConfigContext";
import { useThemeStore } from "../../../hooks/useTheme";
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
import Explorer from "../../Explorer"; import Explorer from "../../Explorer";
import * as Actions from "../Actions/CopyJobActions"; import * as Actions from "../Actions/CopyJobActions";
@@ -9,7 +12,7 @@ import ContainerCopyMessages from "../ContainerCopyMessages";
import { MonitorCopyJobsRefState } from "../MonitorCopyJobs/MonitorCopyJobRefState"; import { MonitorCopyJobsRefState } from "../MonitorCopyJobs/MonitorCopyJobRefState";
import { CopyJobCommandBarBtnType } from "../Types/CopyJobTypes"; import { CopyJobCommandBarBtnType } from "../Types/CopyJobTypes";
function getCopyJobBtns(explorer: Explorer): CopyJobCommandBarBtnType[] { function getCopyJobBtns(explorer: Explorer, isDarkMode: boolean): CopyJobCommandBarBtnType[] {
const monitorCopyJobsRef = MonitorCopyJobsRefState((state) => state.ref); const monitorCopyJobsRef = MonitorCopyJobsRefState((state) => state.ref);
const buttons: CopyJobCommandBarBtnType[] = [ const buttons: CopyJobCommandBarBtnType[] = [
{ {
@@ -26,7 +29,15 @@ function getCopyJobBtns(explorer: Explorer): CopyJobCommandBarBtnType[] {
ariaLabel: ContainerCopyMessages.refreshButtonAriaLabel, ariaLabel: ContainerCopyMessages.refreshButtonAriaLabel,
onClick: () => monitorCopyJobsRef?.refreshJobList(), onClick: () => monitorCopyJobsRef?.refreshJobList(),
}, },
{
key: "themeToggle",
iconSrc: isDarkMode ? SunIcon : MoonIcon,
label: isDarkMode ? "Light Theme" : "Dark Theme",
ariaLabel: isDarkMode ? "Switch to Light Theme" : "Switch to Dark Theme",
onClick: () => useThemeStore.getState().toggleTheme(),
},
]; ];
if (configContext.platform === Platform.Portal) { if (configContext.platform === Platform.Portal) {
buttons.push({ buttons.push({
key: "feedback", key: "feedback",
@@ -54,6 +65,6 @@ function btnMapper(config: CopyJobCommandBarBtnType): CommandButtonComponentProp
}; };
} }
export function getCommandBarButtons(explorer: Explorer): CommandButtonComponentProps[] { export function getCommandBarButtons(explorer: Explorer, isDarkMode: boolean): CommandButtonComponentProps[] {
return getCopyJobBtns(explorer).map(btnMapper); return getCopyJobBtns(explorer, isDarkMode).map(btnMapper);
} }

View File

@@ -12,7 +12,12 @@ import useToggle from "./hooks/useToggle";
const managedIdentityTooltip = ( const managedIdentityTooltip = (
<Text> <Text>
{ContainerCopyMessages.addManagedIdentity.tooltip.content} &nbsp; {ContainerCopyMessages.addManagedIdentity.tooltip.content} &nbsp;
<Link href={ContainerCopyMessages.addManagedIdentity.tooltip.href} target="_blank" rel="noopener noreferrer"> <Link
style={{ color: "var(--colorBrandForeground1)" }}
href={ContainerCopyMessages.addManagedIdentity.tooltip.href}
target="_blank"
rel="noopener noreferrer"
>
{ContainerCopyMessages.addManagedIdentity.tooltip.hrefText} {ContainerCopyMessages.addManagedIdentity.tooltip.hrefText}
</Link> </Link>
</Text> </Text>
@@ -26,7 +31,7 @@ const AddManagedIdentity: React.FC<AddManagedIdentityProps> = () => {
return ( return (
<Stack className="addManagedIdentityContainer" tokens={{ childrenGap: 15, padding: "0 0 0 20px" }}> <Stack className="addManagedIdentityContainer" tokens={{ childrenGap: 15, padding: "0 0 0 20px" }}>
<Text> <Text className="themeText">
{ContainerCopyMessages.addManagedIdentity.description}&ensp; {ContainerCopyMessages.addManagedIdentity.description}&ensp;
<Link href={ContainerCopyMessages.addManagedIdentity.descriptionHref} target="_blank" rel="noopener noreferrer"> <Link href={ContainerCopyMessages.addManagedIdentity.descriptionHref} target="_blank" rel="noopener noreferrer">
{ContainerCopyMessages.addManagedIdentity.descriptionHrefText} {ContainerCopyMessages.addManagedIdentity.descriptionHrefText}
@@ -35,6 +40,7 @@ const AddManagedIdentity: React.FC<AddManagedIdentityProps> = () => {
<InfoTooltip content={managedIdentityTooltip} /> <InfoTooltip content={managedIdentityTooltip} />
</Text> </Text>
<Toggle <Toggle
data-test="btn-toggle"
checked={systemAssigned} checked={systemAssigned}
onText={ContainerCopyMessages.toggleBtn.onText} onText={ContainerCopyMessages.toggleBtn.onText}
offText={ContainerCopyMessages.toggleBtn.offText} offText={ContainerCopyMessages.toggleBtn.offText}

View File

@@ -13,7 +13,12 @@ import useToggle from "./hooks/useToggle";
const TooltipContent = ( const TooltipContent = (
<Text> <Text>
{ContainerCopyMessages.readPermissionAssigned.tooltip.content} &nbsp; {ContainerCopyMessages.readPermissionAssigned.tooltip.content} &nbsp;
<Link href={ContainerCopyMessages.readPermissionAssigned.tooltip.href} target="_blank" rel="noopener noreferrer"> <Link
style={{ color: "var(--colorBrandForeground1)" }}
href={ContainerCopyMessages.readPermissionAssigned.tooltip.href}
target="_blank"
rel="noopener noreferrer"
>
{ContainerCopyMessages.readPermissionAssigned.tooltip.hrefText} {ContainerCopyMessages.readPermissionAssigned.tooltip.hrefText}
</Link> </Link>
</Text> </Text>
@@ -65,6 +70,7 @@ const AddReadPermissionToDefaultIdentity: React.FC<AddReadPermissionToDefaultIde
<InfoTooltip content={TooltipContent} /> <InfoTooltip content={TooltipContent} />
</Text> </Text>
<Toggle <Toggle
data-test="btn-toggle"
checked={readPermissionAssigned} checked={readPermissionAssigned}
onText={ContainerCopyMessages.toggleBtn.onText} onText={ContainerCopyMessages.toggleBtn.onText}
offText={ContainerCopyMessages.toggleBtn.offText} offText={ContainerCopyMessages.toggleBtn.offText}

View File

@@ -12,7 +12,7 @@ import { useCopyJobPrerequisitesCache } from "../../Utils/useCopyJobPrerequisite
import usePermissionSections, { PermissionGroupConfig, PermissionSectionConfig } from "./hooks/usePermissionsSection"; import usePermissionSections, { PermissionGroupConfig, PermissionSectionConfig } from "./hooks/usePermissionsSection";
const PermissionSection: React.FC<PermissionSectionConfig> = ({ id, title, Component, completed, disabled }) => ( const PermissionSection: React.FC<PermissionSectionConfig> = ({ id, title, Component, completed, disabled }) => (
<AccordionItem key={id} value={id} disabled={disabled}> <AccordionItem key={id} value={id} disabled={disabled} data-test="accordion-item">
<AccordionHeader className="accordionHeader"> <AccordionHeader className="accordionHeader">
<Text className="accordionHeaderText" variant="medium"> <Text className="accordionHeaderText" variant="medium">
{title} {title}
@@ -25,13 +25,13 @@ const PermissionSection: React.FC<PermissionSectionConfig> = ({ id, title, Compo
height={completed ? 20 : 24} height={completed ? 20 : 24}
/> />
</AccordionHeader> </AccordionHeader>
<AccordionPanel aria-disabled={disabled} className="accordionPanel"> <AccordionPanel aria-disabled={disabled} className="accordionPanel" data-test="accordion-panel">
<Component /> <Component />
</AccordionPanel> </AccordionPanel>
</AccordionItem> </AccordionItem>
); );
const PermissionGroup: React.FC<PermissionGroupConfig> = ({ title, description, sections }) => { const PermissionGroup: React.FC<PermissionGroupConfig> = ({ id, title, description, sections }) => {
const [openItems, setOpenItems] = React.useState<string[]>([]); const [openItems, setOpenItems] = React.useState<string[]>([]);
useEffect(() => { useEffect(() => {
@@ -44,11 +44,12 @@ const PermissionGroup: React.FC<PermissionGroupConfig> = ({ title, description,
return ( return (
<Stack <Stack
data-test={`permission-group-container-${id}`}
tokens={{ childrenGap: 15 }} tokens={{ childrenGap: 15 }}
styles={{ styles={{
root: { root: {
background: "#fafafa", background: "var(--colorNeutralBackground2)",
border: "1px solid #e1e1e1", border: "1px solid var(--colorNeutralStroke1)",
borderRadius: 8, borderRadius: 8,
padding: 16, padding: 16,
boxShadow: "0 1px 3px rgba(0,0,0,0.1)", boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
@@ -56,11 +57,11 @@ const PermissionGroup: React.FC<PermissionGroupConfig> = ({ title, description,
}} }}
> >
<Stack tokens={{ childrenGap: 5 }}> <Stack tokens={{ childrenGap: 5 }}>
<Text variant="medium" style={{ fontWeight: 600 }}> <Text variant="medium" style={{ fontWeight: 600, color: "var(--colorNeutralForeground1)" }}>
{title} {title}
</Text> </Text>
{description && ( {description && (
<Text variant="small" styles={{ root: { color: "#605E5C" } }}> <Text variant="small" styles={{ root: { color: "var(--colorNeutralForeground2)" } }}>
{description} {description}
</Text> </Text>
)} )}
@@ -99,8 +100,12 @@ const AssignPermissions = () => {
}, []); }, []);
return ( return (
<Stack className="assignPermissionsContainer" tokens={{ childrenGap: 20 }}> <Stack
<Text variant="medium"> data-test="Panel:AssignPermissionsContainer"
className="assignPermissionsContainer"
tokens={{ childrenGap: 20 }}
>
<Text variant="medium" style={{ color: "var(--colorNeutralForeground1)" }}>
{isSameAccount && copyJobState.migrationType === CopyJobMigrationType.Online {isSameAccount && copyJobState.migrationType === CopyJobMigrationType.Online
? ContainerCopyMessages.assignPermissions.intraAccountOnlineDescription( ? ContainerCopyMessages.assignPermissions.intraAccountOnlineDescription(
copyJobState?.source?.account?.name || "", copyJobState?.source?.account?.name || "",

View File

@@ -12,7 +12,12 @@ import useToggle from "./hooks/useToggle";
const managedIdentityTooltip = ( const managedIdentityTooltip = (
<Text> <Text>
{ContainerCopyMessages.defaultManagedIdentity.tooltip.content} &nbsp; {ContainerCopyMessages.defaultManagedIdentity.tooltip.content} &nbsp;
<Link href={ContainerCopyMessages.defaultManagedIdentity.tooltip.href} target="_blank" rel="noopener noreferrer"> <Link
style={{ color: "var(--colorBrandForeground1)" }}
href={ContainerCopyMessages.defaultManagedIdentity.tooltip.href}
target="_blank"
rel="noopener noreferrer"
>
{ContainerCopyMessages.defaultManagedIdentity.tooltip.hrefText} {ContainerCopyMessages.defaultManagedIdentity.tooltip.hrefText}
</Link> </Link>
</Text> </Text>
@@ -31,6 +36,7 @@ const DefaultManagedIdentity: React.FC<AddManagedIdentityProps> = () => {
<InfoTooltip content={managedIdentityTooltip} /> <InfoTooltip content={managedIdentityTooltip} />
</div> </div>
<Toggle <Toggle
data-test="btn-toggle"
checked={defaultSystemAssigned} checked={defaultSystemAssigned}
onText={ContainerCopyMessages.toggleBtn.onText} onText={ContainerCopyMessages.toggleBtn.onText}
offText={ContainerCopyMessages.toggleBtn.offText} offText={ContainerCopyMessages.toggleBtn.offText}

View File

@@ -13,7 +13,12 @@ import InfoTooltip from "../Components/InfoTooltip";
const tooltipContent = ( const tooltipContent = (
<Text> <Text>
{ContainerCopyMessages.pointInTimeRestore.tooltip.content} &nbsp; {ContainerCopyMessages.pointInTimeRestore.tooltip.content} &nbsp;
<Link href={ContainerCopyMessages.pointInTimeRestore.tooltip.href} target="_blank" rel="noopener noreferrer"> <Link
style={{ color: "var(--colorBrandForeground1)" }}
href={ContainerCopyMessages.pointInTimeRestore.tooltip.href}
target="_blank"
rel="noopener noreferrer"
>
{ContainerCopyMessages.pointInTimeRestore.tooltip.hrefText} {ContainerCopyMessages.pointInTimeRestore.tooltip.hrefText}
</Link> </Link>
</Text> </Text>
@@ -127,6 +132,7 @@ const PointInTimeRestore: React.FC = () => {
<Stack.Item> <Stack.Item>
{showRefreshButton ? ( {showRefreshButton ? (
<PrimaryButton <PrimaryButton
data-test="pointInTimeRestore:RefreshBtn"
className="fullWidth" className="fullWidth"
text={ContainerCopyMessages.refreshButtonLabel} text={ContainerCopyMessages.refreshButtonLabel}
iconProps={{ iconName: "Refresh" }} iconProps={{ iconName: "Refresh" }}
@@ -134,6 +140,7 @@ const PointInTimeRestore: React.FC = () => {
/> />
) : ( ) : (
<PrimaryButton <PrimaryButton
data-test="pointInTimeRestore:PrimaryBtn"
className="fullWidth" className="fullWidth"
text={loading ? "" : ContainerCopyMessages.pointInTimeRestore.buttonText} text={loading ? "" : ContainerCopyMessages.pointInTimeRestore.buttonText}
{...(loading ? { iconProps: { iconName: "SyncStatusSolid" } } : {})} {...(loading ? { iconProps: { iconName: "SyncStatusSolid" } } : {})}

View File

@@ -5,7 +5,7 @@ exports[`AddManagedIdentity Snapshot Tests renders initial state correctly 1`] =
class="ms-Stack addManagedIdentityContainer css-109" class="ms-Stack addManagedIdentityContainer css-109"
> >
<span <span
class="css-110" class="themeText css-110"
> >
A system-assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. Once enabled, you can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Microsoft Entra ID, so you dont have to store any credentials in code. A system-assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. Once enabled, you can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Microsoft Entra ID, so you dont have to store any credentials in code.
@@ -67,6 +67,7 @@ exports[`AddManagedIdentity Snapshot Tests renders initial state correctly 1`] =
class="ms-Toggle-background pill-117" class="ms-Toggle-background pill-117"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle1" id="Toggle1"
role="switch" role="switch"
type="button" type="button"
@@ -92,7 +93,7 @@ exports[`AddManagedIdentity Snapshot Tests renders loading state 1`] = `
class="ms-Stack addManagedIdentityContainer css-109" class="ms-Stack addManagedIdentityContainer css-109"
> >
<span <span
class="css-110" class="themeText css-110"
> >
A system-assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. Once enabled, you can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Microsoft Entra ID, so you dont have to store any credentials in code. A system-assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. Once enabled, you can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Microsoft Entra ID, so you dont have to store any credentials in code.
@@ -154,6 +155,7 @@ exports[`AddManagedIdentity Snapshot Tests renders loading state 1`] = `
class="ms-Toggle-background pill-121" class="ms-Toggle-background pill-121"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle11" id="Toggle11"
role="switch" role="switch"
type="button" type="button"
@@ -173,10 +175,12 @@ exports[`AddManagedIdentity Snapshot Tests renders loading state 1`] = `
</div> </div>
<div <div
class="ms-Stack popover-container foreground loading css-123" class="ms-Stack popover-container foreground loading css-123"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<div <div
class="ms-Overlay root-135" class="ms-Overlay root-135"
data-test="loading-overlay"
> >
<div <div
class="ms-Spinner root-137" class="ms-Spinner root-137"
@@ -192,13 +196,13 @@ exports[`AddManagedIdentity Snapshot Tests renders loading state 1`] = `
</div> </div>
</div> </div>
<span <span
class="css-124" class="themeText css-124"
style="font-weight: 600;" style="font-weight: 600;"
> >
Enable system assigned managed identity Enable system assigned managed identity
</span> </span>
<span <span
class="css-110" class="themeText css-110"
> >
Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button. Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button.
</span> </span>
@@ -261,7 +265,7 @@ exports[`AddManagedIdentity Snapshot Tests renders with toggle on and popover vi
class="ms-Stack addManagedIdentityContainer css-109" class="ms-Stack addManagedIdentityContainer css-109"
> >
<span <span
class="css-110" class="themeText css-110"
> >
A system-assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. Once enabled, you can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Microsoft Entra ID, so you dont have to store any credentials in code. A system-assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. Once enabled, you can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Microsoft Entra ID, so you dont have to store any credentials in code.
@@ -323,6 +327,7 @@ exports[`AddManagedIdentity Snapshot Tests renders with toggle on and popover vi
class="ms-Toggle-background pill-121" class="ms-Toggle-background pill-121"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle3" id="Toggle3"
role="switch" role="switch"
type="button" type="button"
@@ -342,16 +347,17 @@ exports[`AddManagedIdentity Snapshot Tests renders with toggle on and popover vi
</div> </div>
<div <div
class="ms-Stack popover-container foreground css-123" class="ms-Stack popover-container foreground css-123"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-124" class="themeText css-124"
style="font-weight: 600;" style="font-weight: 600;"
> >
Enable system assigned managed identity Enable system assigned managed identity
</span> </span>
<span <span
class="css-110" class="themeText css-110"
> >
Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button. Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button.
</span> </span>

View File

@@ -41,6 +41,7 @@ exports[`AddReadPermissionToDefaultIdentity Component Edge Cases should handle m
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle17" id="Toggle17"
role="switch" role="switch"
type="button" type="button"
@@ -103,6 +104,7 @@ exports[`AddReadPermissionToDefaultIdentity Component Edge Cases should handle m
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle16" id="Toggle16"
role="switch" role="switch"
type="button" type="button"
@@ -165,6 +167,7 @@ exports[`AddReadPermissionToDefaultIdentity Component Rendering should render co
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle3" id="Toggle3"
role="switch" role="switch"
type="button" type="button"
@@ -227,6 +230,7 @@ exports[`AddReadPermissionToDefaultIdentity Component Rendering should render co
class="ms-Toggle-background pill-119" class="ms-Toggle-background pill-119"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle1" id="Toggle1"
role="switch" role="switch"
type="button" type="button"
@@ -314,6 +318,7 @@ exports[`AddReadPermissionToDefaultIdentity Component Rendering should render co
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle0" id="Toggle0"
role="switch" role="switch"
type="button" type="button"
@@ -376,6 +381,7 @@ exports[`AddReadPermissionToDefaultIdentity Component Rendering should render co
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle2" id="Toggle2"
role="switch" role="switch"
type="button" type="button"

View File

@@ -4,6 +4,7 @@ exports[`AssignPermissions Component Accordion Behavior should render accordion
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -15,6 +16,7 @@ exports[`AssignPermissions Component Accordion Behavior should render accordion
> >
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-testGroup"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -36,6 +38,7 @@ exports[`AssignPermissions Component Accordion Behavior should render accordion
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -85,6 +88,7 @@ exports[`AssignPermissions Component Accordion Behavior should render accordion
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -134,6 +138,7 @@ exports[`AssignPermissions Component Accordion Behavior should render accordion
<div <div
aria-disabled="false" aria-disabled="false"
class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu" class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu"
data-test="accordion-panel"
> >
<div> <div>
Incomplete Component Incomplete Component
@@ -142,6 +147,7 @@ exports[`AssignPermissions Component Accordion Behavior should render accordion
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw" class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw"
@@ -201,6 +207,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -212,6 +219,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
> >
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-testGroup"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -233,6 +241,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -282,6 +291,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -331,6 +341,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
<div <div
aria-disabled="false" aria-disabled="false"
class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu" class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu"
data-test="accordion-panel"
> >
<div> <div>
Incomplete Component Incomplete Component
@@ -339,6 +350,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw" class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw"
@@ -398,6 +410,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -409,6 +422,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
> >
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-testGroup"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -430,6 +444,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -479,6 +494,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -528,6 +544,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
<div <div
aria-disabled="false" aria-disabled="false"
class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu" class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu"
data-test="accordion-panel"
> >
<div> <div>
Incomplete Component Incomplete Component
@@ -536,6 +553,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw" class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw"
@@ -595,6 +613,7 @@ exports[`AssignPermissions Component Edge Cases should handle missing account na
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -606,6 +625,7 @@ exports[`AssignPermissions Component Edge Cases should handle missing account na
> >
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-testGroup"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -627,6 +647,7 @@ exports[`AssignPermissions Component Edge Cases should handle missing account na
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -676,6 +697,7 @@ exports[`AssignPermissions Component Edge Cases should handle missing account na
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -725,6 +747,7 @@ exports[`AssignPermissions Component Edge Cases should handle missing account na
<div <div
aria-disabled="false" aria-disabled="false"
class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu" class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu"
data-test="accordion-panel"
> >
<div> <div>
Incomplete Component Incomplete Component
@@ -733,6 +756,7 @@ exports[`AssignPermissions Component Edge Cases should handle missing account na
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw" class="fui-AccordionHeader accordionHeader ___lyghz50_53x5ri0 f1s2aq7o f1c21dwh f1s184ao ft85np5 fwrgwhw"
@@ -792,6 +816,7 @@ exports[`AssignPermissions Component Permission Groups should render multiple pe
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -803,6 +828,7 @@ exports[`AssignPermissions Component Permission Groups should render multiple pe
> >
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-crossAccountConfigs"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -824,6 +850,7 @@ exports[`AssignPermissions Component Permission Groups should render multiple pe
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -875,6 +902,7 @@ exports[`AssignPermissions Component Permission Groups should render multiple pe
</div> </div>
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-onlineConfigs"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -896,6 +924,7 @@ exports[`AssignPermissions Component Permission Groups should render multiple pe
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -945,6 +974,7 @@ exports[`AssignPermissions Component Permission Groups should render multiple pe
<div <div
aria-disabled="false" aria-disabled="false"
class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu" class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu"
data-test="accordion-panel"
> >
<div <div
data-testid="online-copy-enabled" data-testid="online-copy-enabled"
@@ -964,6 +994,7 @@ exports[`AssignPermissions Component Permission Groups should render online migr
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -975,6 +1006,7 @@ exports[`AssignPermissions Component Permission Groups should render online migr
> >
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-onlineConfigs"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -996,6 +1028,7 @@ exports[`AssignPermissions Component Permission Groups should render online migr
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -1045,6 +1078,7 @@ exports[`AssignPermissions Component Permission Groups should render online migr
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -1094,6 +1128,7 @@ exports[`AssignPermissions Component Permission Groups should render online migr
<div <div
aria-disabled="false" aria-disabled="false"
class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu" class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu"
data-test="accordion-panel"
> >
<div <div
data-testid="online-copy-enabled" data-testid="online-copy-enabled"
@@ -1113,6 +1148,7 @@ exports[`AssignPermissions Component Permission Groups should render permission
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -1124,6 +1160,7 @@ exports[`AssignPermissions Component Permission Groups should render permission
> >
<div <div
class="ms-Stack css-112" class="ms-Stack css-112"
data-test="permission-group-container-crossAccountConfigs"
> >
<div <div
class="ms-Stack css-113" class="ms-Stack css-113"
@@ -1145,6 +1182,7 @@ exports[`AssignPermissions Component Permission Groups should render permission
> >
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -1194,6 +1232,7 @@ exports[`AssignPermissions Component Permission Groups should render permission
</div> </div>
<div <div
class="fui-AccordionItem" class="fui-AccordionItem"
data-test="accordion-item"
> >
<div <div
class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5" class="fui-AccordionHeader accordionHeader ___kex8dp0_1udlp87 f19n0e5 f1c21dwh f1s184ao ft85np5"
@@ -1243,6 +1282,7 @@ exports[`AssignPermissions Component Permission Groups should render permission
<div <div
aria-disabled="false" aria-disabled="false"
class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu" class="fui-AccordionPanel accordionPanel ___1rufncu_1hx1scr f1axvtxu"
data-test="accordion-panel"
> >
<div <div
data-testid="add-read-permission" data-testid="add-read-permission"
@@ -1262,6 +1302,7 @@ exports[`AssignPermissions Component Rendering should render without crashing wi
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"
@@ -1283,6 +1324,7 @@ exports[`AssignPermissions Component Rendering should render without crashing wi
<div> <div>
<div <div
class="ms-Stack assignPermissionsContainer css-109" class="ms-Stack assignPermissionsContainer css-109"
data-test="Panel:AssignPermissionsContainer"
> >
<span <span
class="css-110" class="css-110"

View File

@@ -41,6 +41,7 @@ exports[`DefaultManagedIdentity Edge Cases should handle missing account name gr
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle14" id="Toggle14"
role="switch" role="switch"
type="button" type="button"
@@ -103,6 +104,7 @@ exports[`DefaultManagedIdentity Edge Cases should handle null account 1`] = `
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle15" id="Toggle15"
role="switch" role="switch"
type="button" type="button"
@@ -165,6 +167,7 @@ exports[`DefaultManagedIdentity Loading States should render loading state snaps
class="ms-Toggle-background pill-119" class="ms-Toggle-background pill-119"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle10" id="Toggle10"
role="switch" role="switch"
type="button" type="button"
@@ -256,6 +259,7 @@ exports[`DefaultManagedIdentity Rendering should render correctly with default s
class="ms-Toggle-background pill-115" class="ms-Toggle-background pill-115"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle0" id="Toggle0"
role="switch" role="switch"
type="button" type="button"
@@ -318,6 +322,7 @@ exports[`DefaultManagedIdentity Toggle Interactions should render toggle with ch
class="ms-Toggle-background pill-119" class="ms-Toggle-background pill-119"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="btn-toggle"
id="Toggle7" id="Toggle7"
role="switch" role="switch"
type="button" type="button"

View File

@@ -56,6 +56,7 @@ exports[`PointInTimeRestore Initial Render should render correctly with default
<button <button
class="ms-Button ms-Button--primary fullWidth root-115" class="ms-Button ms-Button--primary fullWidth root-115"
data-is-focusable="true" data-is-focusable="true"
data-test="pointInTimeRestore:PrimaryBtn"
type="button" type="button"
> >
<span <span
@@ -131,6 +132,7 @@ exports[`PointInTimeRestore Initial Render should render with empty account name
<button <button
class="ms-Button ms-Button--primary fullWidth root-115" class="ms-Button ms-Button--primary fullWidth root-115"
data-is-focusable="true" data-is-focusable="true"
data-test="pointInTimeRestore:PrimaryBtn"
type="button" type="button"
> >
<span <span
@@ -161,6 +163,7 @@ exports[`PointInTimeRestore Snapshots should match snapshot in loading state 1`]
> >
<div <div
class="ms-Overlay root-123" class="ms-Overlay root-123"
data-test="loading-overlay"
> >
<div <div
class="ms-Spinner root-125" class="ms-Spinner root-125"
@@ -223,6 +226,7 @@ exports[`PointInTimeRestore Snapshots should match snapshot in loading state 1`]
aria-disabled="true" aria-disabled="true"
class="ms-Button ms-Button--primary is-disabled fullWidth root-128" class="ms-Button ms-Button--primary is-disabled fullWidth root-128"
data-is-focusable="false" data-is-focusable="false"
data-test="pointInTimeRestore:PrimaryBtn"
disabled="" disabled=""
type="button" type="button"
> >
@@ -301,6 +305,7 @@ exports[`PointInTimeRestore Snapshots should match snapshot with refresh button
<button <button
class="ms-Button ms-Button--primary fullWidth root-115" class="ms-Button ms-Button--primary fullWidth root-115"
data-is-focusable="true" data-is-focusable="true"
data-test="pointInTimeRestore:RefreshBtn"
type="button" type="button"
> >
<span <span

View File

@@ -19,9 +19,21 @@ const NavigationControls: React.FC<NavigationControlsProps> = ({
isPreviousDisabled, isPreviousDisabled,
}) => ( }) => (
<Stack horizontal tokens={{ childrenGap: 20 }}> <Stack horizontal tokens={{ childrenGap: 20 }}>
<PrimaryButton text={primaryBtnText} onClick={onPrimary} allowDisabledFocus disabled={isPrimaryDisabled} /> <PrimaryButton
<DefaultButton text="Previous" onClick={onPrevious} allowDisabledFocus disabled={isPreviousDisabled} /> data-test="copy-job-primary"
<DefaultButton text="Cancel" onClick={onCancel} /> text={primaryBtnText}
onClick={onPrimary}
allowDisabledFocus
disabled={isPrimaryDisabled}
/>
<DefaultButton
data-test="copy-job-previous"
text="Previous"
onClick={onPrevious}
allowDisabledFocus
disabled={isPreviousDisabled}
/>
<DefaultButton data-test="copy-job-cancel" text="Cancel" onClick={onCancel} />
</Stack> </Stack>
); );

View File

@@ -17,15 +17,16 @@ const PopoverContainer: React.FC<PopoverContainerProps> = React.memo(
({ isLoading = false, title, children, onPrimary, onCancel }) => { ({ isLoading = false, title, children, onPrimary, onCancel }) => {
return ( return (
<Stack <Stack
data-test="popover-container"
className={`popover-container foreground ${isLoading ? "loading" : ""}`} className={`popover-container foreground ${isLoading ? "loading" : ""}`}
tokens={{ childrenGap: 20 }} tokens={{ childrenGap: 20 }}
style={{ maxWidth: 450 }} style={{ maxWidth: 450 }}
> >
<LoadingOverlay isLoading={isLoading} label={ContainerCopyMessages.popoverOverlaySpinnerLabel} /> <LoadingOverlay isLoading={isLoading} label={ContainerCopyMessages.popoverOverlaySpinnerLabel} />
<Text variant="mediumPlus" style={{ fontWeight: 600 }}> <Text variant="mediumPlus" className="themeText" style={{ fontWeight: 600 }}>
{title} {title}
</Text> </Text>
<Text>{children}</Text> <Text className="themeText">{children}</Text>
<Stack horizontal tokens={{ childrenGap: 20 }}> <Stack horizontal tokens={{ childrenGap: 20 }}>
<PrimaryButton text={"Yes"} onClick={onPrimary} disabled={isLoading} /> <PrimaryButton text={"Yes"} onClick={onPrimary} disabled={isLoading} />
<DefaultButton text="No" onClick={onCancel} disabled={isLoading} /> <DefaultButton text="No" onClick={onCancel} disabled={isLoading} />

View File

@@ -4,14 +4,15 @@ exports[`PopoverMessage Component Edge Cases should handle empty string title 1`
<div> <div>
<div <div
class="ms-Stack popover-container foreground css-109" class="ms-Stack popover-container foreground css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
/> />
<span <span
class="css-111" class="themeText css-111"
> >
<div> <div>
Test content Test content
@@ -71,10 +72,11 @@ exports[`PopoverMessage Component Edge Cases should handle null children 1`] = `
<div> <div>
<div <div
class="ms-Stack popover-container foreground css-109" class="ms-Stack popover-container foreground css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
> >
Test Title Test Title
@@ -133,10 +135,11 @@ exports[`PopoverMessage Component Edge Cases should handle undefined children 1`
<div> <div>
<div <div
class="ms-Stack popover-container foreground css-109" class="ms-Stack popover-container foreground css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
> >
Test Title Test Title
@@ -195,16 +198,17 @@ exports[`PopoverMessage Component Edge Cases should handle very long title 1`] =
<div> <div>
<div <div
class="ms-Stack popover-container foreground css-109" class="ms-Stack popover-container foreground css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
> >
This is a very long title that might cause layout issues or text wrapping in the popover component This is a very long title that might cause layout issues or text wrapping in the popover component
</span> </span>
<span <span
class="css-111" class="themeText css-111"
> >
<div> <div>
Test content Test content
@@ -266,16 +270,17 @@ exports[`PopoverMessage Component Rendering should render correctly when visible
<div> <div>
<div <div
class="ms-Stack popover-container foreground css-109" class="ms-Stack popover-container foreground css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
> >
Test Title Test Title
</span> </span>
<span <span
class="css-111" class="themeText css-111"
> >
<div> <div>
Test content Test content
@@ -335,16 +340,17 @@ exports[`PopoverMessage Component Rendering should render correctly with differe
<div> <div>
<div <div
class="ms-Stack popover-container foreground css-109" class="ms-Stack popover-container foreground css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
> >
Test Title Test Title
</span> </span>
<span <span
class="css-111" class="themeText css-111"
> >
<div> <div>
<p> <p>
@@ -409,16 +415,17 @@ exports[`PopoverMessage Component Rendering should render correctly with differe
<div> <div>
<div <div
class="ms-Stack popover-container foreground css-109" class="ms-Stack popover-container foreground css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
> >
Custom Title Custom Title
</span> </span>
<span <span
class="css-111" class="themeText css-111"
> >
<div> <div>
Test content Test content
@@ -478,6 +485,7 @@ exports[`PopoverMessage Component Rendering should render correctly with loading
<div> <div>
<div <div
class="ms-Stack popover-container foreground loading css-109" class="ms-Stack popover-container foreground loading css-109"
data-test="popover-container"
style="max-width: 450px;" style="max-width: 450px;"
> >
<div <div
@@ -485,13 +493,13 @@ exports[`PopoverMessage Component Rendering should render correctly with loading
data-testid="loading-overlay" data-testid="loading-overlay"
/> />
<span <span
class="css-110" class="themeText css-110"
style="font-weight: 600;" style="font-weight: 600;"
> >
Test Title Test Title
</span> </span>
<span <span
class="css-111" class="themeText css-111"
> >
<div> <div>
Test content Test content

View File

@@ -41,7 +41,7 @@ const AddCollectionPanelWrapper: React.FunctionComponent<AddCollectionPanelWrapp
return ( return (
<Stack className="addCollectionPanelWrapper"> <Stack className="addCollectionPanelWrapper">
<Stack.Item className="addCollectionPanelHeader"> <Stack.Item className="addCollectionPanelHeader">
<Text>{ContainerCopyMessages.createNewContainerSubHeading}</Text> <Text className="themeText">{ContainerCopyMessages.createNewContainerSubHeading}</Text>
</Stack.Item> </Stack.Item>
<Stack.Item className="addCollectionPanelBody"> <Stack.Item className="addCollectionPanelBody">
<AddCollectionPanel explorer={explorer} isCopyJobFlow={true} onSubmitSuccess={handleAddCollectionSuccess} /> <AddCollectionPanel explorer={explorer} isCopyJobFlow={true} onSubmitSuccess={handleAddCollectionSuccess} />

View File

@@ -9,7 +9,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot 1`]
class="ms-StackItem addCollectionPanelHeader css-110" class="ms-StackItem addCollectionPanelHeader css-110"
> >
<span <span
class="css-111" class="themeText css-111"
> >
Select the properties for your container. Select the properties for your container.
</span> </span>
@@ -50,7 +50,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot wit
class="ms-StackItem addCollectionPanelHeader css-110" class="ms-StackItem addCollectionPanelHeader css-110"
> >
<span <span
class="css-111" class="themeText css-111"
> >
Select the properties for your container. Select the properties for your container.
</span> </span>
@@ -91,7 +91,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot wit
class="ms-StackItem addCollectionPanelHeader css-110" class="ms-StackItem addCollectionPanelHeader css-110"
> >
<span <span
class="css-111" class="themeText css-111"
> >
Select the properties for your container. Select the properties for your container.
</span> </span>
@@ -132,7 +132,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot wit
class="ms-StackItem addCollectionPanelHeader css-110" class="ms-StackItem addCollectionPanelHeader css-110"
> >
<span <span
class="css-111" class="themeText css-111"
> >
Select the properties for your container. Select the properties for your container.
</span> </span>

View File

@@ -22,6 +22,7 @@ const CreateCopyJobScreens: React.FC = () => {
<Stack.Item className="createCopyJobScreensContent"> <Stack.Item className="createCopyJobScreensContent">
{contextError && ( {contextError && (
<MessageBar <MessageBar
data-test="Panel:ErrorContainer"
className="createCopyJobErrorMessageBar" className="createCopyJobErrorMessageBar"
messageBarType={MessageBarType.blocked} messageBarType={MessageBarType.blocked}
isMultiline={false} isMultiline={false}

View File

@@ -31,17 +31,21 @@ const PreviewCopyJob: React.FC = () => {
})); }));
}; };
return ( return (
<Stack tokens={{ childrenGap: 20 }} className="previewCopyJobContainer"> <Stack tokens={{ childrenGap: 20 }} className="previewCopyJobContainer" data-test="Panel:PreviewCopyJob">
<FieldRow label={ContainerCopyMessages.jobNameLabel}> <FieldRow label={ContainerCopyMessages.jobNameLabel}>
<TextField value={jobName} onChange={onJobNameChange} /> <TextField data-test="job-name-textfield" value={jobName} onChange={onJobNameChange} />
</FieldRow> </FieldRow>
<Stack> <Stack>
<Text className="bold">{ContainerCopyMessages.sourceSubscriptionLabel}</Text> <Text className="bold themeText">{ContainerCopyMessages.sourceSubscriptionLabel}</Text>
<Text>{copyJobState.source?.subscription?.displayName}</Text> <Text data-test="source-subscription-name" className="themeText">
{copyJobState.source?.subscription?.displayName}
</Text>
</Stack> </Stack>
<Stack> <Stack>
<Text className="bold">{ContainerCopyMessages.sourceAccountLabel}</Text> <Text className="bold themeText">{ContainerCopyMessages.sourceAccountLabel}</Text>
<Text>{copyJobState.source?.account?.name}</Text> <Text data-test="source-account-name" className="themeText">
{copyJobState.source?.account?.name}
</Text>
</Stack> </Stack>
<Stack> <Stack>
<DetailsList <DetailsList

View File

@@ -3,6 +3,7 @@
exports[`PreviewCopyJob should handle special characters in database and container names 1`] = ` exports[`PreviewCopyJob should handle special characters in database and container names 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -32,6 +33,7 @@ exports[`PreviewCopyJob should handle special characters in database and contain
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField84" id="TextField84"
type="text" type="text"
value="job-with@special#chars_123" value="job-with@special#chars_123"
@@ -45,12 +47,13 @@ exports[`PreviewCopyJob should handle special characters in database and contain
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
Test Subscription Test Subscription
</span> </span>
@@ -59,12 +62,13 @@ exports[`PreviewCopyJob should handle special characters in database and contain
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
test-account test-account
</span> </span>
@@ -321,6 +325,7 @@ exports[`PreviewCopyJob should handle special characters in database and contain
exports[`PreviewCopyJob should render component with cross-subscription setup 1`] = ` exports[`PreviewCopyJob should render component with cross-subscription setup 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -350,6 +355,7 @@ exports[`PreviewCopyJob should render component with cross-subscription setup 1`
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField96" id="TextField96"
type="text" type="text"
value="" value=""
@@ -363,12 +369,13 @@ exports[`PreviewCopyJob should render component with cross-subscription setup 1`
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
Test Subscription Test Subscription
</span> </span>
@@ -377,12 +384,13 @@ exports[`PreviewCopyJob should render component with cross-subscription setup 1`
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
test-account test-account
</span> </span>
@@ -639,6 +647,7 @@ exports[`PreviewCopyJob should render component with cross-subscription setup 1`
exports[`PreviewCopyJob should render with default state and empty job name 1`] = ` exports[`PreviewCopyJob should render with default state and empty job name 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -668,6 +677,7 @@ exports[`PreviewCopyJob should render with default state and empty job name 1`]
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField0" id="TextField0"
type="text" type="text"
value="" value=""
@@ -681,12 +691,13 @@ exports[`PreviewCopyJob should render with default state and empty job name 1`]
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
Test Subscription Test Subscription
</span> </span>
@@ -695,12 +706,13 @@ exports[`PreviewCopyJob should render with default state and empty job name 1`]
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
test-account test-account
</span> </span>
@@ -957,6 +969,7 @@ exports[`PreviewCopyJob should render with default state and empty job name 1`]
exports[`PreviewCopyJob should render with long subscription and account names 1`] = ` exports[`PreviewCopyJob should render with long subscription and account names 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -986,6 +999,7 @@ exports[`PreviewCopyJob should render with long subscription and account names 1
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField60" id="TextField60"
type="text" type="text"
value="" value=""
@@ -999,12 +1013,13 @@ exports[`PreviewCopyJob should render with long subscription and account names 1
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
This is a very long subscription name that might cause display issues if not handled properly This is a very long subscription name that might cause display issues if not handled properly
</span> </span>
@@ -1013,12 +1028,13 @@ exports[`PreviewCopyJob should render with long subscription and account names 1
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
this-is-a-very-long-database-account-name-that-might-cause-display-issues this-is-a-very-long-database-account-name-that-might-cause-display-issues
</span> </span>
@@ -1275,6 +1291,7 @@ exports[`PreviewCopyJob should render with long subscription and account names 1
exports[`PreviewCopyJob should render with missing source account information 1`] = ` exports[`PreviewCopyJob should render with missing source account information 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -1304,6 +1321,7 @@ exports[`PreviewCopyJob should render with missing source account information 1`
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField36" id="TextField36"
type="text" type="text"
value="" value=""
@@ -1317,12 +1335,13 @@ exports[`PreviewCopyJob should render with missing source account information 1`
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
Test Subscription Test Subscription
</span> </span>
@@ -1331,7 +1350,7 @@ exports[`PreviewCopyJob should render with missing source account information 1`
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
@@ -1588,6 +1607,7 @@ exports[`PreviewCopyJob should render with missing source account information 1`
exports[`PreviewCopyJob should render with missing source subscription information 1`] = ` exports[`PreviewCopyJob should render with missing source subscription information 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -1617,6 +1637,7 @@ exports[`PreviewCopyJob should render with missing source subscription informati
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField24" id="TextField24"
type="text" type="text"
value="" value=""
@@ -1630,7 +1651,7 @@ exports[`PreviewCopyJob should render with missing source subscription informati
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
@@ -1639,12 +1660,13 @@ exports[`PreviewCopyJob should render with missing source subscription informati
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
test-account test-account
</span> </span>
@@ -1901,6 +1923,7 @@ exports[`PreviewCopyJob should render with missing source subscription informati
exports[`PreviewCopyJob should render with online migration type 1`] = ` exports[`PreviewCopyJob should render with online migration type 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -1930,6 +1953,7 @@ exports[`PreviewCopyJob should render with online migration type 1`] = `
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField72" id="TextField72"
type="text" type="text"
value="online-migration-job" value="online-migration-job"
@@ -1943,12 +1967,13 @@ exports[`PreviewCopyJob should render with online migration type 1`] = `
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
Test Subscription Test Subscription
</span> </span>
@@ -1957,12 +1982,13 @@ exports[`PreviewCopyJob should render with online migration type 1`] = `
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
test-account test-account
</span> </span>
@@ -2219,6 +2245,7 @@ exports[`PreviewCopyJob should render with online migration type 1`] = `
exports[`PreviewCopyJob should render with pre-filled job name 1`] = ` exports[`PreviewCopyJob should render with pre-filled job name 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -2248,6 +2275,7 @@ exports[`PreviewCopyJob should render with pre-filled job name 1`] = `
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField12" id="TextField12"
type="text" type="text"
value="custom-job-name-123" value="custom-job-name-123"
@@ -2261,12 +2289,13 @@ exports[`PreviewCopyJob should render with pre-filled job name 1`] = `
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
Test Subscription Test Subscription
</span> </span>
@@ -2275,12 +2304,13 @@ exports[`PreviewCopyJob should render with pre-filled job name 1`] = `
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
test-account test-account
</span> </span>
@@ -2537,6 +2567,7 @@ exports[`PreviewCopyJob should render with pre-filled job name 1`] = `
exports[`PreviewCopyJob should render with undefined database and container names 1`] = ` exports[`PreviewCopyJob should render with undefined database and container names 1`] = `
<div <div
class="ms-Stack previewCopyJobContainer css-109" class="ms-Stack previewCopyJobContainer css-109"
data-test="Panel:PreviewCopyJob"
> >
<div <div
class="ms-Stack flex-row css-110" class="ms-Stack flex-row css-110"
@@ -2566,6 +2597,7 @@ exports[`PreviewCopyJob should render with undefined database and container name
<input <input
aria-invalid="false" aria-invalid="false"
class="ms-TextField-field field-115" class="ms-TextField-field field-115"
data-test="job-name-textfield"
id="TextField48" id="TextField48"
type="text" type="text"
value="" value=""
@@ -2579,12 +2611,13 @@ exports[`PreviewCopyJob should render with undefined database and container name
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source subscription Source subscription
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-subscription-name"
> >
Test Subscription Test Subscription
</span> </span>
@@ -2593,12 +2626,13 @@ exports[`PreviewCopyJob should render with undefined database and container name
class="ms-Stack css-124" class="ms-Stack css-124"
> >
<span <span
class="bold css-125" class="bold themeText css-125"
> >
Source account Source account
</span> </span>
<span <span
class="css-125" class="themeText css-125"
data-test="source-account-name"
> >
test-account test-account
</span> </span>

View File

@@ -9,7 +9,7 @@ import ContainerCopyMessages from "../../../../ContainerCopyMessages";
import { CopyJobContext } from "../../../../Context/CopyJobContext"; import { CopyJobContext } from "../../../../Context/CopyJobContext";
import { CopyJobMigrationType } from "../../../../Enums/CopyJobEnums"; import { CopyJobMigrationType } from "../../../../Enums/CopyJobEnums";
import { CopyJobContextProviderType, CopyJobContextState } from "../../../../Types/CopyJobTypes"; import { CopyJobContextProviderType, CopyJobContextState } from "../../../../Types/CopyJobTypes";
import { AccountDropdown } from "./AccountDropdown"; import { AccountDropdown, normalizeAccountId } from "./AccountDropdown";
jest.mock("../../../../../../hooks/useDatabaseAccounts"); jest.mock("../../../../../../hooks/useDatabaseAccounts");
jest.mock("../../../../../../UserContext", () => ({ jest.mock("../../../../../../UserContext", () => ({
@@ -202,13 +202,16 @@ describe("AccountDropdown", () => {
const stateUpdateFunction = mockSetCopyJobState.mock.calls[0][0]; const stateUpdateFunction = mockSetCopyJobState.mock.calls[0][0];
const newState = stateUpdateFunction(mockCopyJobState); const newState = stateUpdateFunction(mockCopyJobState);
expect(newState.source.account).toBe(mockDatabaseAccount1); expect(newState.source.account).toEqual({
...mockDatabaseAccount1,
id: normalizeAccountId(mockDatabaseAccount1.id),
});
}); });
it("should auto-select predefined account from userContext if available", async () => { it("should auto-select predefined account from userContext if available", async () => {
const userContextAccount = { const userContextAccount = {
...mockDatabaseAccount2, ...mockDatabaseAccount2,
id: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.DocumentDb/databaseAccounts/account2", id: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.DocumentDB/databaseAccounts/account2",
}; };
(userContext as any).databaseAccount = userContextAccount; (userContext as any).databaseAccount = userContextAccount;
@@ -223,7 +226,10 @@ describe("AccountDropdown", () => {
const stateUpdateFunction = mockSetCopyJobState.mock.calls[0][0]; const stateUpdateFunction = mockSetCopyJobState.mock.calls[0][0];
const newState = stateUpdateFunction(mockCopyJobState); const newState = stateUpdateFunction(mockCopyJobState);
expect(newState.source.account).toBe(mockDatabaseAccount2); expect(newState.source.account).toEqual({
...mockDatabaseAccount2,
id: normalizeAccountId(mockDatabaseAccount2.id),
});
}); });
it("should keep current account if it exists in the filtered list", async () => { it("should keep current account if it exists in the filtered list", async () => {
@@ -248,7 +254,16 @@ describe("AccountDropdown", () => {
const stateUpdateFunction = mockSetCopyJobState.mock.calls[0][0]; const stateUpdateFunction = mockSetCopyJobState.mock.calls[0][0];
const newState = stateUpdateFunction(contextWithSelectedAccount.copyJobState); const newState = stateUpdateFunction(contextWithSelectedAccount.copyJobState);
expect(newState).toBe(contextWithSelectedAccount.copyJobState); expect(newState).toEqual({
...contextWithSelectedAccount.copyJobState,
source: {
...contextWithSelectedAccount.copyJobState.source,
account: {
...mockDatabaseAccount1,
id: normalizeAccountId(mockDatabaseAccount1.id),
},
},
});
}); });
it("should handle account change when user selects different account", async () => { it("should handle account change when user selects different account", async () => {
@@ -272,7 +287,7 @@ describe("AccountDropdown", () => {
it("should normalize account ID for Portal platform", () => { it("should normalize account ID for Portal platform", () => {
const portalAccount = { const portalAccount = {
...mockDatabaseAccount1, ...mockDatabaseAccount1,
id: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.DocumentDb/databaseAccounts/account1", id: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.DocumentDB/databaseAccounts/account1",
}; };
(configContext as any).platform = Platform.Portal; (configContext as any).platform = Platform.Portal;

View File

@@ -12,7 +12,7 @@ import FieldRow from "../../Components/FieldRow";
interface AccountDropdownProps {} interface AccountDropdownProps {}
const normalizeAccountId = (id: string) => { export const normalizeAccountId = (id: string = "") => {
if (configContext.platform === Platform.Portal) { if (configContext.platform === Platform.Portal) {
return id.replace("/Microsoft.DocumentDb/", "/Microsoft.DocumentDB/"); return id.replace("/Microsoft.DocumentDb/", "/Microsoft.DocumentDB/");
} else if (configContext.platform === Platform.Hosted) { } else if (configContext.platform === Platform.Hosted) {
@@ -27,7 +27,12 @@ export const AccountDropdown: React.FC<AccountDropdownProps> = () => {
const selectedSubscriptionId = copyJobState?.source?.subscription?.subscriptionId; const selectedSubscriptionId = copyJobState?.source?.subscription?.subscriptionId;
const allAccounts: DatabaseAccount[] = useDatabaseAccounts(selectedSubscriptionId); const allAccounts: DatabaseAccount[] = useDatabaseAccounts(selectedSubscriptionId);
const sqlApiOnlyAccounts: DatabaseAccount[] = (allAccounts || []).filter((account) => apiType(account) === "SQL"); const sqlApiOnlyAccounts = (allAccounts || [])
.filter((account) => apiType(account) === "SQL")
.map((account) => ({
...account,
id: normalizeAccountId(account.id),
}));
const updateCopyJobState = (newAccount: DatabaseAccount) => { const updateCopyJobState = (newAccount: DatabaseAccount) => {
setCopyJobState((prevState) => { setCopyJobState((prevState) => {
@@ -47,7 +52,7 @@ export const AccountDropdown: React.FC<AccountDropdownProps> = () => {
useEffect(() => { useEffect(() => {
if (sqlApiOnlyAccounts && sqlApiOnlyAccounts.length > 0 && selectedSubscriptionId) { if (sqlApiOnlyAccounts && sqlApiOnlyAccounts.length > 0 && selectedSubscriptionId) {
const currentAccountId = copyJobState?.source?.account?.id; const currentAccountId = copyJobState?.source?.account?.id;
const predefinedAccountId = userContext.databaseAccount?.id; const predefinedAccountId = normalizeAccountId(userContext.databaseAccount?.id);
const selectedAccountId = currentAccountId || predefinedAccountId; const selectedAccountId = currentAccountId || predefinedAccountId;
const targetAccount: DatabaseAccount | null = const targetAccount: DatabaseAccount | null =
@@ -58,7 +63,7 @@ export const AccountDropdown: React.FC<AccountDropdownProps> = () => {
const accountOptions = const accountOptions =
sqlApiOnlyAccounts?.map((account) => ({ sqlApiOnlyAccounts?.map((account) => ({
key: normalizeAccountId(account.id), key: account.id,
text: account.name, text: account.name,
data: account, data: account,
})) || []; })) || [];

View File

@@ -1,6 +1,6 @@
/* eslint-disable react/prop-types */ /* eslint-disable react/prop-types */
/* eslint-disable react/display-name */ /* eslint-disable react/display-name */
import { Checkbox, Stack } from "@fluentui/react"; import { Checkbox, ICheckboxStyles, Stack } from "@fluentui/react";
import React from "react"; import React from "react";
import ContainerCopyMessages from "../../../../ContainerCopyMessages"; import ContainerCopyMessages from "../../../../ContainerCopyMessages";
@@ -9,8 +9,25 @@ interface MigrationTypeCheckboxProps {
onChange: (_ev?: React.FormEvent, checked?: boolean) => void; onChange: (_ev?: React.FormEvent, checked?: boolean) => void;
} }
export const MigrationTypeCheckbox: React.FC<MigrationTypeCheckboxProps> = React.memo(({ checked, onChange }) => ( const checkboxStyles: ICheckboxStyles = {
<Stack horizontal horizontalAlign="space-between" className="migrationTypeRow"> text: { color: "var(--colorNeutralForeground1)" },
<Checkbox label={ContainerCopyMessages.migrationTypeCheckboxLabel} checked={checked} onChange={onChange} /> checkbox: { borderColor: "var(--colorNeutralStroke1)" },
</Stack> root: {
)); selectors: {
":hover .ms-Checkbox-text": { color: "var(--colorNeutralForeground1)" },
},
},
};
export const MigrationTypeCheckbox: React.FC<MigrationTypeCheckboxProps> = React.memo(({ checked, onChange }) => {
return (
<Stack horizontal horizontalAlign="space-between" className="migrationTypeRow" data-test="migration-type-checkbox">
<Checkbox
label={ContainerCopyMessages.migrationTypeCheckboxLabel}
checked={checked}
onChange={onChange}
styles={checkboxStyles}
/>
</Stack>
);
});

View File

@@ -3,6 +3,7 @@
exports[`MigrationTypeCheckbox Component Rendering should render in checked state 1`] = ` exports[`MigrationTypeCheckbox Component Rendering should render in checked state 1`] = `
<div <div
class="ms-Stack migrationTypeRow css-109" class="ms-Stack migrationTypeRow css-109"
data-test="migration-type-checkbox"
> >
<div <div
class="ms-Checkbox is-checked is-enabled root-119" class="ms-Checkbox is-checked is-enabled root-119"
@@ -43,6 +44,7 @@ exports[`MigrationTypeCheckbox Component Rendering should render in checked stat
exports[`MigrationTypeCheckbox Component Rendering should render with default props (unchecked state) 1`] = ` exports[`MigrationTypeCheckbox Component Rendering should render with default props (unchecked state) 1`] = `
<div <div
class="ms-Stack migrationTypeRow css-109" class="ms-Stack migrationTypeRow css-109"
data-test="migration-type-checkbox"
> >
<div <div
class="ms-Checkbox is-enabled root-110" class="ms-Checkbox is-enabled root-110"

View File

@@ -21,7 +21,7 @@ const SelectAccount = React.memo(() => {
return ( return (
<Stack data-test="Panel:SelectAccountContainer" className="selectAccountContainer" tokens={{ childrenGap: 15 }}> <Stack data-test="Panel:SelectAccountContainer" className="selectAccountContainer" tokens={{ childrenGap: 15 }}>
<Text>{ContainerCopyMessages.selectAccountDescription}</Text> <Text className="themeText">{ContainerCopyMessages.selectAccountDescription}</Text>
<SubscriptionDropdown /> <SubscriptionDropdown />

View File

@@ -6,7 +6,7 @@ exports[`SelectAccount Component Rendering should render correctly with snapshot
data-test="Panel:SelectAccountContainer" data-test="Panel:SelectAccountContainer"
> >
<span <span
class="css-110" class="themeText css-110"
> >
Please select a source account from which to copy. Please select a source account from which to copy.
</span> </span>

View File

@@ -47,8 +47,12 @@ const SelectSourceAndTargetContainers = ({ showAddCollectionPanel }: SelectSourc
const onDropdownChange = dropDownChangeHandler(setCopyJobState); const onDropdownChange = dropDownChangeHandler(setCopyJobState);
return ( return (
<Stack className="selectSourceAndTargetContainers" tokens={{ childrenGap: 25 }}> <Stack
<span>{ContainerCopyMessages.selectSourceAndTargetContainersDescription}</span> data-test="Panel:SelectSourceAndTargetContainers"
className="selectSourceAndTargetContainers"
tokens={{ childrenGap: 25 }}
>
<span className="themeText">{ContainerCopyMessages.selectSourceAndTargetContainersDescription}</span>
<DatabaseContainerSection <DatabaseContainerSection
heading={ContainerCopyMessages.sourceContainerSubHeading} heading={ContainerCopyMessages.sourceContainerSubHeading}
databaseOptions={sourceDatabaseOptions} databaseOptions={sourceDatabaseOptions}
@@ -59,6 +63,7 @@ const SelectSourceAndTargetContainers = ({ showAddCollectionPanel }: SelectSourc
selectedContainer={source?.containerId} selectedContainer={source?.containerId}
containerDisabled={!source?.databaseId} containerDisabled={!source?.databaseId}
containerOnChange={onDropdownChange("sourceContainer")} containerOnChange={onDropdownChange("sourceContainer")}
sectionType="source"
/> />
<DatabaseContainerSection <DatabaseContainerSection
heading={ContainerCopyMessages.targetContainerSubHeading} heading={ContainerCopyMessages.targetContainerSubHeading}
@@ -71,6 +76,7 @@ const SelectSourceAndTargetContainers = ({ showAddCollectionPanel }: SelectSourc
containerDisabled={!target?.databaseId} containerDisabled={!target?.databaseId}
containerOnChange={onDropdownChange("targetContainer")} containerOnChange={onDropdownChange("targetContainer")}
handleOnDemandCreateContainer={showAddCollectionPanel} handleOnDemandCreateContainer={showAddCollectionPanel}
sectionType="target"
/> />
</Stack> </Stack>
); );

View File

@@ -32,6 +32,7 @@ describe("DatabaseContainerSection", () => {
selectedContainer: "container1", selectedContainer: "container1",
containerDisabled: false, containerDisabled: false,
containerOnChange: mockContainerOnChange, containerOnChange: mockContainerOnChange,
sectionType: "source",
}; };
beforeEach(() => { beforeEach(() => {
@@ -292,6 +293,7 @@ describe("DatabaseContainerSection", () => {
containerOptions: mockContainerOptions, containerOptions: mockContainerOptions,
selectedContainer: "container1", selectedContainer: "container1",
containerOnChange: mockContainerOnChange, containerOnChange: mockContainerOnChange,
sectionType: "source",
}; };
render(<DatabaseContainerSection {...minimalProps} />); render(<DatabaseContainerSection {...minimalProps} />);
@@ -393,6 +395,7 @@ describe("DatabaseContainerSection", () => {
containerOptions: [{ key: "c1", text: "Container 1", data: { id: "c1" } }], containerOptions: [{ key: "c1", text: "Container 1", data: { id: "c1" } }],
selectedContainer: "c1", selectedContainer: "c1",
containerOnChange: jest.fn(), containerOnChange: jest.fn(),
sectionType: "source",
}; };
const { container } = render(<DatabaseContainerSection {...minimalProps} />); const { container } = render(<DatabaseContainerSection {...minimalProps} />);
@@ -411,6 +414,7 @@ describe("DatabaseContainerSection", () => {
containerDisabled: false, containerDisabled: false,
containerOnChange: jest.fn(), containerOnChange: jest.fn(),
handleOnDemandCreateContainer: jest.fn(), handleOnDemandCreateContainer: jest.fn(),
sectionType: "target",
}; };
const { container } = render(<DatabaseContainerSection {...fullProps} />); const { container } = render(<DatabaseContainerSection {...fullProps} />);
@@ -428,6 +432,7 @@ describe("DatabaseContainerSection", () => {
selectedContainer: "container1", selectedContainer: "container1",
containerDisabled: true, containerDisabled: true,
containerOnChange: jest.fn(), containerOnChange: jest.fn(),
sectionType: "target",
}; };
const { container } = render(<DatabaseContainerSection {...disabledProps} />); const { container } = render(<DatabaseContainerSection {...disabledProps} />);
@@ -443,6 +448,7 @@ describe("DatabaseContainerSection", () => {
containerOptions: [], containerOptions: [],
selectedContainer: "", selectedContainer: "",
containerOnChange: jest.fn(), containerOnChange: jest.fn(),
sectionType: "target",
}; };
const { container } = render(<DatabaseContainerSection {...emptyOptionsProps} />); const { container } = render(<DatabaseContainerSection {...emptyOptionsProps} />);

View File

@@ -15,6 +15,7 @@ export const DatabaseContainerSection = ({
containerDisabled, containerDisabled,
containerOnChange, containerOnChange,
handleOnDemandCreateContainer, handleOnDemandCreateContainer,
sectionType,
}: DatabaseContainerSectionProps) => ( }: DatabaseContainerSectionProps) => (
<Stack tokens={{ childrenGap: 15 }} className="databaseContainerSection"> <Stack tokens={{ childrenGap: 15 }} className="databaseContainerSection">
<label className="subHeading">{heading}</label> <label className="subHeading">{heading}</label>
@@ -27,6 +28,7 @@ export const DatabaseContainerSection = ({
disabled={!!databaseDisabled} disabled={!!databaseDisabled}
selectedKey={selectedDatabase} selectedKey={selectedDatabase}
onChange={databaseOnChange} onChange={databaseOnChange}
data-test={`${sectionType}-databaseDropdown`}
/> />
</FieldRow> </FieldRow>
<FieldRow label={ContainerCopyMessages.containerDropdownLabel}> <FieldRow label={ContainerCopyMessages.containerDropdownLabel}>
@@ -39,9 +41,14 @@ export const DatabaseContainerSection = ({
disabled={!!containerDisabled} disabled={!!containerDisabled}
selectedKey={selectedContainer} selectedKey={selectedContainer}
onChange={containerOnChange} onChange={containerOnChange}
data-test={`${sectionType}-containerDropdown`}
/> />
{handleOnDemandCreateContainer && ( {handleOnDemandCreateContainer && (
<ActionButton className="create-container-link-btn" onClick={() => handleOnDemandCreateContainer()}> <ActionButton
className="create-container-link-btn"
style={{ color: "var(--colorBrandForeground1)" }}
onClick={() => handleOnDemandCreateContainer()}
>
{ContainerCopyMessages.createContainerButtonLabel} {ContainerCopyMessages.createContainerButtonLabel}
</ActionButton> </ActionButton>
)} )}

View File

@@ -37,6 +37,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with all pro
class="ms-Dropdown is-required dropdown-112" class="ms-Dropdown is-required dropdown-112"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="target-databaseDropdown"
id="Dropdown98" id="Dropdown98"
role="combobox" role="combobox"
tabindex="0" tabindex="0"
@@ -94,6 +95,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with all pro
class="ms-Dropdown is-required dropdown-112" class="ms-Dropdown is-required dropdown-112"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="target-containerDropdown"
id="Dropdown99" id="Dropdown99"
role="combobox" role="combobox"
tabindex="0" tabindex="0"
@@ -182,6 +184,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with disable
class="ms-Dropdown is-disabled is-required dropdown-143" class="ms-Dropdown is-disabled is-required dropdown-143"
data-is-focusable="false" data-is-focusable="false"
data-ktp-target="true" data-ktp-target="true"
data-test="target-databaseDropdown"
id="Dropdown103" id="Dropdown103"
role="combobox" role="combobox"
tabindex="-1" tabindex="-1"
@@ -239,6 +242,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with disable
class="ms-Dropdown is-disabled is-required dropdown-143" class="ms-Dropdown is-disabled is-required dropdown-143"
data-is-focusable="false" data-is-focusable="false"
data-ktp-target="true" data-ktp-target="true"
data-test="target-containerDropdown"
id="Dropdown104" id="Dropdown104"
role="combobox" role="combobox"
tabindex="-1" tabindex="-1"
@@ -306,6 +310,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with empty o
class="ms-Dropdown is-required dropdown-112" class="ms-Dropdown is-required dropdown-112"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="target-databaseDropdown"
id="Dropdown105" id="Dropdown105"
role="combobox" role="combobox"
tabindex="0" tabindex="0"
@@ -363,6 +368,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with empty o
class="ms-Dropdown is-required dropdown-112" class="ms-Dropdown is-required dropdown-112"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="target-containerDropdown"
id="Dropdown106" id="Dropdown106"
role="combobox" role="combobox"
tabindex="0" tabindex="0"
@@ -430,6 +436,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with minimal
class="ms-Dropdown is-required dropdown-112" class="ms-Dropdown is-required dropdown-112"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="source-databaseDropdown"
id="Dropdown96" id="Dropdown96"
role="combobox" role="combobox"
tabindex="0" tabindex="0"
@@ -487,6 +494,7 @@ exports[`DatabaseContainerSection Snapshot Testing matches snapshot with minimal
class="ms-Dropdown is-required dropdown-112" class="ms-Dropdown is-required dropdown-112"
data-is-focusable="true" data-is-focusable="true"
data-ktp-target="true" data-ktp-target="true"
data-test="source-containerDropdown"
id="Dropdown97" id="Dropdown97"
role="combobox" role="combobox"
tabindex="0" tabindex="0"

View File

@@ -83,6 +83,7 @@ const CopyJobActionMenu: React.FC<CopyJobActionMenuProps> = ({ job, handleClick
return ( return (
<IconButton <IconButton
data-test={`CopyJobActionMenu/Button:${job.Name}`}
role="button" role="button"
iconProps={{ iconName: "More", styles: { root: { fontSize: "20px", fontWeight: "bold" } } }} iconProps={{ iconName: "More", styles: { root: { fontSize: "20px", fontWeight: "bold" } } }}
menuProps={{ items: getMenuItems() }} menuProps={{ items: getMenuItems() }}

View File

@@ -1,5 +1,6 @@
import { DetailsList, DetailsListLayoutMode, IColumn, Stack, Text } from "@fluentui/react"; import { DetailsList, DetailsListLayoutMode, IColumn, Stack, Text } from "@fluentui/react";
import React, { memo } from "react"; import React, { memo } from "react";
import { useThemeStore } from "../../../../hooks/useTheme";
import ContainerCopyMessages from "../../ContainerCopyMessages"; import ContainerCopyMessages from "../../ContainerCopyMessages";
import { CopyJobStatusType } from "../../Enums/CopyJobEnums"; import { CopyJobStatusType } from "../../Enums/CopyJobEnums";
import { CopyJobType } from "../../Types/CopyJobTypes"; import { CopyJobType } from "../../Types/CopyJobTypes";
@@ -63,6 +64,19 @@ const getCopyJobDetailsListColumns = (): IColumn[] => {
}; };
const CopyJobDetails: React.FC<CopyJobDetailsProps> = ({ job }) => { const CopyJobDetails: React.FC<CopyJobDetailsProps> = ({ job }) => {
const isDarkMode = useThemeStore((state) => state.isDarkMode);
const errorMessageStyle: React.CSSProperties = {
whiteSpace: "pre-wrap",
...(isDarkMode && {
whiteSpace: "pre-wrap",
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
padding: "10px",
borderRadius: "4px",
}),
};
const selectedContainers = [ const selectedContainers = [
{ {
sourceContainerName: job?.Source?.containerName || "N/A", sourceContainerName: job?.Source?.containerName || "N/A",
@@ -77,10 +91,10 @@ const CopyJobDetails: React.FC<CopyJobDetailsProps> = ({ job }) => {
<Stack className="copyJobDetailsContainer" tokens={{ childrenGap: 15 }} data-testid="copy-job-details"> <Stack className="copyJobDetailsContainer" tokens={{ childrenGap: 15 }} data-testid="copy-job-details">
{job.Error ? ( {job.Error ? (
<Stack.Item data-testid="error-stack" style={sectionCss.verticalAlign}> <Stack.Item data-testid="error-stack" style={sectionCss.verticalAlign}>
<Text className="bold" style={sectionCss.headingText}> <Text className="bold themeText" style={sectionCss.headingText}>
{ContainerCopyMessages.errorTitle} {ContainerCopyMessages.errorTitle}
</Text> </Text>
<Text as="pre" style={{ whiteSpace: "pre-wrap" }}> <Text as="pre" style={errorMessageStyle}>
{job.Error.message} {job.Error.message}
</Text> </Text>
</Stack.Item> </Stack.Item>
@@ -88,16 +102,16 @@ const CopyJobDetails: React.FC<CopyJobDetailsProps> = ({ job }) => {
<Stack.Item data-testid="selectedcollection-stack"> <Stack.Item data-testid="selectedcollection-stack">
<Stack tokens={{ childrenGap: 15 }}> <Stack tokens={{ childrenGap: 15 }}>
<Stack.Item style={sectionCss.verticalAlign}> <Stack.Item style={sectionCss.verticalAlign}>
<Text className="bold">{ContainerCopyMessages.MonitorJobs.Columns.lastUpdatedTime}</Text> <Text className="bold themeText">{ContainerCopyMessages.MonitorJobs.Columns.lastUpdatedTime}</Text>
<Text>{job.LastUpdatedTime}</Text> <Text className="themeText">{job.LastUpdatedTime}</Text>
</Stack.Item> </Stack.Item>
<Stack.Item style={sectionCss.verticalAlign}> <Stack.Item style={sectionCss.verticalAlign}>
<Text className="bold">{ContainerCopyMessages.sourceAccountLabel}</Text> <Text className="bold themeText">{ContainerCopyMessages.sourceAccountLabel}</Text>
<Text>{job.Source?.remoteAccountName}</Text> <Text className="themeText">{job.Source?.remoteAccountName}</Text>
</Stack.Item> </Stack.Item>
<Stack.Item style={sectionCss.verticalAlign}> <Stack.Item style={sectionCss.verticalAlign}>
<Text className="bold">{ContainerCopyMessages.MonitorJobs.Columns.mode}</Text> <Text className="bold themeText">{ContainerCopyMessages.MonitorJobs.Columns.mode}</Text>
<Text>{job.Mode}</Text> <Text className="themeText">{job.Mode}</Text>
</Stack.Item> </Stack.Item>
</Stack> </Stack>
</Stack.Item> </Stack.Item>

View File

@@ -1,30 +1,14 @@
import { FontIcon, getTheme, mergeStyles, mergeStyleSets, Spinner, SpinnerSize, Stack, Text } from "@fluentui/react"; import { FontIcon, mergeStyles, Spinner, SpinnerSize, Stack, Text } from "@fluentui/react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import React from "react"; import React from "react";
import ContainerCopyMessages from "../../ContainerCopyMessages"; import ContainerCopyMessages from "../../ContainerCopyMessages";
import { CopyJobStatusType } from "../../Enums/CopyJobEnums"; import { CopyJobStatusType } from "../../Enums/CopyJobEnums";
const theme = getTheme();
const iconClass = mergeStyles({ const iconClass = mergeStyles({
fontSize: "16px", fontSize: "16px",
marginRight: "8px", marginRight: "8px",
}); });
const classNames = mergeStyleSets({
[CopyJobStatusType.Pending]: [{ color: theme.semanticColors.bodySubtext }, iconClass],
[CopyJobStatusType.InProgress]: [{ color: theme.palette.themePrimary }, iconClass],
[CopyJobStatusType.Running]: [{ color: theme.palette.themePrimary }, iconClass],
[CopyJobStatusType.Partitioning]: [{ color: theme.palette.themePrimary }, iconClass],
[CopyJobStatusType.Paused]: [{ color: theme.palette.themePrimary }, iconClass],
[CopyJobStatusType.Skipped]: [{ color: theme.semanticColors.bodySubtext }, iconClass],
[CopyJobStatusType.Cancelled]: [{ color: theme.semanticColors.bodySubtext }, iconClass],
[CopyJobStatusType.Failed]: [{ color: theme.semanticColors.errorIcon }, iconClass],
[CopyJobStatusType.Faulted]: [{ color: theme.semanticColors.errorIcon }, iconClass],
[CopyJobStatusType.Completed]: [{ color: theme.semanticColors.successIcon }, iconClass],
unknown: [{ color: theme.semanticColors.bodySubtext }, iconClass],
});
const iconMap: Partial<Record<CopyJobStatusType, string>> = { const iconMap: Partial<Record<CopyJobStatusType, string>> = {
[CopyJobStatusType.Pending]: "Clock", [CopyJobStatusType.Pending]: "Clock",
[CopyJobStatusType.Paused]: "CirclePause", [CopyJobStatusType.Paused]: "CirclePause",
@@ -35,6 +19,17 @@ const iconMap: Partial<Record<CopyJobStatusType, string>> = {
[CopyJobStatusType.Completed]: "CompletedSolid", [CopyJobStatusType.Completed]: "CompletedSolid",
}; };
// Icon colors for different statuses
const statusIconColors: Partial<Record<CopyJobStatusType, string>> = {
[CopyJobStatusType.Failed]: "var(--colorPaletteRedForeground1)",
[CopyJobStatusType.Faulted]: "var(--colorPaletteRedForeground1)",
[CopyJobStatusType.Completed]: "var(--colorSuccessGreen)",
[CopyJobStatusType.InProgress]: "var(--colorBrandForeground1)",
[CopyJobStatusType.Running]: "var(--colorBrandForeground1)",
[CopyJobStatusType.Partitioning]: "var(--colorBrandForeground1)",
[CopyJobStatusType.Paused]: "var(--colorBrandForeground1)",
};
export interface CopyJobStatusWithIconProps { export interface CopyJobStatusWithIconProps {
status: CopyJobStatusType; status: CopyJobStatusType;
} }
@@ -47,19 +42,17 @@ const CopyJobStatusWithIcon: React.FC<CopyJobStatusWithIconProps> = React.memo((
CopyJobStatusType.InProgress, CopyJobStatusType.InProgress,
CopyJobStatusType.Partitioning, CopyJobStatusType.Partitioning,
].includes(status); ].includes(status);
const iconColor = statusIconColors[status] || "var(--colorNeutralForeground2)";
const iconStyle = mergeStyles(iconClass, { color: iconColor });
return ( return (
<Stack horizontal verticalAlign="center"> <Stack horizontal verticalAlign="center">
{isSpinnerStatus ? ( {isSpinnerStatus ? (
<Spinner size={SpinnerSize.small} style={{ marginRight: "8px" }} /> <Spinner size={SpinnerSize.small} style={{ marginRight: "8px" }} />
) : ( ) : (
<FontIcon <FontIcon aria-label={status} iconName={iconMap[status] || "UnknownSolid"} className={iconStyle} />
aria-label={status}
iconName={iconMap[status] || "UnknownSolid"}
className={classNames[status] || classNames.unknown}
/>
)} )}
<Text>{statusText}</Text> <Text className="themeText">{statusText}</Text>
</Stack> </Stack>
); );
}); });

View File

@@ -15,6 +15,8 @@ import {
} from "@fluentui/react"; } from "@fluentui/react";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import Pager from "../../../../Common/Pager"; import Pager from "../../../../Common/Pager";
import { useThemeStore } from "../../../../hooks/useTheme";
import { getThemeTokens } from "../../../Theme/ThemeUtil";
import { openCopyJobDetailsPanel } from "../../Actions/CopyJobActions"; import { openCopyJobDetailsPanel } from "../../Actions/CopyJobActions";
import { CopyJobType, HandleJobActionClickType } from "../../Types/CopyJobTypes"; import { CopyJobType, HandleJobActionClickType } from "../../Types/CopyJobTypes";
import { getColumns } from "./CopyJobColumns"; import { getColumns } from "./CopyJobColumns";
@@ -26,13 +28,15 @@ interface CopyJobsListProps {
} }
const styles = { const styles = {
container: { height: "calc(100vh - 25em)" } as React.CSSProperties, container: { height: "100%" } as React.CSSProperties,
stackItem: { position: "relative", marginBottom: "20px" } as React.CSSProperties, stackItem: { position: "relative", marginBottom: "20px" } as React.CSSProperties,
}; };
const PAGE_SIZE = 10; const PAGE_SIZE = 10;
const CopyJobsList: React.FC<CopyJobsListProps> = ({ jobs, handleActionClick, pageSize = PAGE_SIZE }) => { const CopyJobsList: React.FC<CopyJobsListProps> = ({ jobs, handleActionClick, pageSize = PAGE_SIZE }) => {
const isDarkMode = useThemeStore((state) => state.isDarkMode);
const themeTokens = getThemeTokens(isDarkMode);
const [startIndex, setStartIndex] = React.useState(0); const [startIndex, setStartIndex] = React.useState(0);
const [sortedJobs, setSortedJobs] = React.useState<CopyJobType[]>(jobs); const [sortedJobs, setSortedJobs] = React.useState<CopyJobType[]>(jobs);
const [sortedColumnKey, setSortedColumnKey] = React.useState<string | undefined>(undefined); const [sortedColumnKey, setSortedColumnKey] = React.useState<string | undefined>(undefined);
@@ -80,6 +84,7 @@ const CopyJobsList: React.FC<CopyJobsListProps> = ({ jobs, handleActionClick, pa
<Stack.Item verticalFill={true} grow={1} shrink={1} style={styles.stackItem}> <Stack.Item verticalFill={true} grow={1} shrink={1} style={styles.stackItem}>
<ScrollablePane scrollbarVisibility={ScrollbarVisibility.auto}> <ScrollablePane scrollbarVisibility={ScrollbarVisibility.auto}>
<ShimmeredDetailsList <ShimmeredDetailsList
className="CopyJobListContainer"
onRenderRow={_onRenderRow} onRenderRow={_onRenderRow}
checkboxVisibility={2} checkboxVisibility={2}
columns={columns} columns={columns}
@@ -87,11 +92,28 @@ const CopyJobsList: React.FC<CopyJobsListProps> = ({ jobs, handleActionClick, pa
enableShimmer={false} enableShimmer={false}
constrainMode={ConstrainMode.unconstrained} constrainMode={ConstrainMode.unconstrained}
layoutMode={DetailsListLayoutMode.justified} layoutMode={DetailsListLayoutMode.justified}
onRenderDetailsHeader={(props, defaultRender) => ( onRenderDetailsHeader={(props, defaultRender) => {
<Sticky stickyPosition={StickyPositionType.Header} isScrollSynced> const bgColor = themeTokens.colorNeutralBackground3;
{defaultRender({ ...props })} const textColor = themeTokens.colorNeutralForeground1;
</Sticky> return (
)} <Sticky stickyPosition={StickyPositionType.Header} isScrollSynced stickyBackgroundColor={bgColor}>
<div style={{ backgroundColor: bgColor }}>
{defaultRender({
...props,
styles: {
root: {
backgroundColor: bgColor,
selectors: {
".ms-DetailsHeader-cellTitle": { color: textColor },
".ms-DetailsHeader-cellName": { color: textColor },
},
},
},
})}
</div>
</Sticky>
);
}}
/> />
</ScrollablePane> </ScrollablePane>
</Stack.Item> </Stack.Item>

View File

@@ -13,7 +13,7 @@ exports[`CopyJobStatusWithIcon Spinner Status Types renders InProgress with spin
/> />
</div> </div>
<span <span
class="css-112" class="themeText css-112"
> >
Running Running
</span> </span>
@@ -33,7 +33,7 @@ exports[`CopyJobStatusWithIcon Spinner Status Types renders Partitioning with sp
/> />
</div> </div>
<span <span
class="css-112" class="themeText css-112"
> >
Running Running
</span> </span>
@@ -53,7 +53,7 @@ exports[`CopyJobStatusWithIcon Spinner Status Types renders Running with spinner
/> />
</div> </div>
<span <span
class="css-112" class="themeText css-112"
> >
Running Running
</span> </span>
@@ -66,7 +66,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
> >
<i <i
aria-label="Cancelled" aria-label="Cancelled"
class="ms-Icon root-105 css-118 mocked-style-Cancelled" class="ms-Icon root-105 css-118 mocked-styles"
data-icon-name="StatusErrorFull" data-icon-name="StatusErrorFull"
role="img" role="img"
style="font-family: "FabricMDL2Icons-4";" style="font-family: "FabricMDL2Icons-4";"
@@ -74,7 +74,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
</i> </i>
<span <span
class="css-112" class="themeText css-112"
> >
Cancelled Cancelled
</span> </span>
@@ -87,7 +87,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
> >
<i <i
aria-label="Completed" aria-label="Completed"
class="ms-Icon root-105 css-120 mocked-style-Completed" class="ms-Icon root-105 css-120 mocked-styles"
data-icon-name="CompletedSolid" data-icon-name="CompletedSolid"
role="img" role="img"
style="font-family: "FabricMDL2Icons-5";" style="font-family: "FabricMDL2Icons-5";"
@@ -95,7 +95,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
</i> </i>
<span <span
class="css-112" class="themeText css-112"
> >
Completed Completed
</span> </span>
@@ -108,7 +108,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
> >
<i <i
aria-label="Failed" aria-label="Failed"
class="ms-Icon root-105 css-118 mocked-style-Failed" class="ms-Icon root-105 css-118 mocked-styles"
data-icon-name="StatusErrorFull" data-icon-name="StatusErrorFull"
role="img" role="img"
style="font-family: "FabricMDL2Icons-4";" style="font-family: "FabricMDL2Icons-4";"
@@ -116,7 +116,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
</i> </i>
<span <span
class="css-112" class="themeText css-112"
> >
Failed Failed
</span> </span>
@@ -129,7 +129,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
> >
<i <i
aria-label="Faulted" aria-label="Faulted"
class="ms-Icon root-105 css-118 mocked-style-Faulted" class="ms-Icon root-105 css-118 mocked-styles"
data-icon-name="StatusErrorFull" data-icon-name="StatusErrorFull"
role="img" role="img"
style="font-family: "FabricMDL2Icons-4";" style="font-family: "FabricMDL2Icons-4";"
@@ -137,7 +137,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
</i> </i>
<span <span
class="css-112" class="themeText css-112"
> >
Failed Failed
</span> </span>
@@ -150,7 +150,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
> >
<i <i
aria-label="Paused" aria-label="Paused"
class="ms-Icon root-105 css-114 mocked-style-Paused" class="ms-Icon root-105 css-114 mocked-styles"
data-icon-name="CirclePause" data-icon-name="CirclePause"
role="img" role="img"
style="font-family: "FabricMDL2Icons-11";" style="font-family: "FabricMDL2Icons-11";"
@@ -158,7 +158,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
</i> </i>
<span <span
class="css-112" class="themeText css-112"
> >
Paused Paused
</span> </span>
@@ -171,7 +171,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
> >
<i <i
aria-label="Pending" aria-label="Pending"
class="ms-Icon root-105 css-111 mocked-style-Pending" class="ms-Icon root-105 css-111 mocked-styles"
data-icon-name="Clock" data-icon-name="Clock"
role="img" role="img"
style="font-family: "FabricMDL2Icons-2";" style="font-family: "FabricMDL2Icons-2";"
@@ -179,7 +179,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
</i> </i>
<span <span
class="css-112" class="themeText css-112"
> >
Queued Queued
</span> </span>
@@ -192,7 +192,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
> >
<i <i
aria-label="Skipped" aria-label="Skipped"
class="ms-Icon root-105 css-116 mocked-style-Skipped" class="ms-Icon root-105 css-116 mocked-styles"
data-icon-name="StatusCircleBlock2" data-icon-name="StatusCircleBlock2"
role="img" role="img"
style="font-family: "FabricMDL2Icons-9";" style="font-family: "FabricMDL2Icons-9";"
@@ -200,7 +200,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders
</i> </i>
<span <span
class="css-112" class="themeText css-112"
> >
Cancelled Cancelled
</span> </span>

View File

@@ -49,6 +49,7 @@ export interface DatabaseContainerSectionProps {
containerDisabled?: boolean; containerDisabled?: boolean;
containerOnChange: (ev: React.FormEvent<HTMLDivElement>, option: DropdownOptionType) => void; containerOnChange: (ev: React.FormEvent<HTMLDivElement>, option: DropdownOptionType) => void;
handleOnDemandCreateContainer?: () => void; handleOnDemandCreateContainer?: () => void;
sectionType: "source" | "target";
} }
export interface CopyJobContextState { export interface CopyJobContextState {

View File

@@ -1,6 +1,30 @@
@import "../../../less/Common/Constants.less"; @import "../../../less/Common/Constants.less";
// Common theme-aware classes
.themeText {
color: var(--colorNeutralForeground1);
}
.themeTextSecondary {
color: var(--colorNeutralForeground2);
}
.themeLinkText {
color: var(--colorBrandForeground1);
}
.themeBackground {
background-color: var(--colorNeutralBackground1);
}
.themeBackgroundSecondary {
background-color: var(--colorNeutralBackground2);
}
#containerCopyWrapper { #containerCopyWrapper {
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
.centerContent { .centerContent {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@@ -9,20 +33,30 @@
.noCopyJobsMessage { .noCopyJobsMessage {
font-weight: 600; font-weight: 600;
margin: 0 auto; margin: 0 auto;
color: @FocusColor; color: var(--colorNeutralForeground2);
} }
button.createCopyJobButton { button.createCopyJobButton {
color: @LinkColor; color: var(--colorBrandForeground1);
} }
} }
} }
.createCopyJobScreensContainer { .createCopyJobScreensContainer {
height: 100%; height: 100%;
padding: 1em 1.5em; padding: 1em 1.5em;
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
.pointInTimeRestoreContainer, .onlineCopyContainer { .pointInTimeRestoreContainer, .onlineCopyContainer {
position: relative; position: relative;
} }
.toggle-label {
color: var(--colorNeutralForeground1);
}
.accordionHeaderText {
color: var(--colorNeutralForeground1);
}
label { label {
padding: 0; padding: 0;
@@ -71,7 +105,7 @@
} }
.foreground { .foreground {
z-index: 10; z-index: 10;
background-color: #f9f9f9; background-color: var(--colorNeutralBackground2);
padding: 20px; padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transform: translate(0%, -9%); transform: translate(0%, -9%);
@@ -80,14 +114,40 @@
.createCopyJobErrorMessageBar { .createCopyJobErrorMessageBar {
margin-bottom: 2em; margin-bottom: 2em;
} }
body.isDarkMode & {
.ms-TooltipHost .ms-Image {
filter: invert(1);
}
.ms-TextField {
.ms-TextField-fieldGroup {
background-color: var(--colorNeutralBackground1);
border-color: var(--colorNeutralStroke1);
}
.ms-TextField-field {
color: var(--colorNeutralForeground1);
background-color: var(--colorNeutralBackground1);
&::placeholder {
color: var(--colorNeutralForeground4);
}
}
.ms-Label {
color: var(--colorNeutralForeground1);
}
}
}
.create-container-link-btn { .create-container-link-btn {
padding: 0; padding: 0;
height: 25px; height: 25px;
color: @LinkColor; color: var(--colorBrandForeground1);
&:focus { &:focus {
outline: none; outline: none;
} }
} }
/* Create collection panel */ /* Create collection panel */
@@ -105,7 +165,6 @@
width: 100%; width: 100%;
max-width: 100%; max-width: 100%;
margin: 0 auto; margin: 0 auto;
.ms-DetailsList { .ms-DetailsList {
width: 100%; width: 100%;
@@ -114,33 +173,33 @@
padding: @DefaultSpace 20px; padding: @DefaultSpace 20px;
font-weight: 600; font-weight: 600;
font-size: @DefaultFontSize; font-size: @DefaultFontSize;
color: @BaseHigh; color: var(--colorNeutralForeground1);
background-color: @BaseLow; background-color: var(--colorNeutralBackground2);
border-bottom: @ButtonBorderWidth solid @BaseMedium; border-bottom: @ButtonBorderWidth solid var(--colorNeutralStroke1);
&:hover { &:hover {
background-color: @BaseMediumLow; background-color: var(--colorNeutralBackground3);
} }
} }
} }
.ms-DetailsRow { .ms-DetailsRow {
border-bottom: @ButtonBorderWidth solid @BaseMedium; border-bottom: @ButtonBorderWidth solid var(--colorNeutralStroke1);
&:hover { &:hover {
background-color: @BaseMediumLow; background-color: var(--colorNeutralBackground2);
} }
.ms-DetailsRow-cell { .ms-DetailsRow-cell {
padding: @MediumSpace 20px; padding: @MediumSpace 20px;
font-size: @DefaultFontSize; font-size: @DefaultFontSize;
color: @BaseHigh; color: var(--colorNeutralForeground1);
min-height: 48px; min-height: 48px;
display: flex; display: flex;
align-items: center; align-items: center;
.jobNameLink { .jobNameLink {
color: @LinkColor; color: var(--colorBrandForeground1);
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -168,7 +227,7 @@
} }
.ms-DetailsRow-cell { .ms-DetailsRow-cell {
font-size: @DefaultFontSize; font-size: @DefaultFontSize;
color: @BaseHigh; color: var(--colorNeutralForeground1);
} }
} }
} }

View File

@@ -58,7 +58,7 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
aria-expanded={this.state.isExpanded} aria-expanded={this.state.isExpanded}
> >
<Icon iconName={this.state.isExpanded ? "ChevronDown" : "ChevronRight"} /> <Icon iconName={this.state.isExpanded ? "ChevronDown" : "ChevronRight"} />
<Label>{this.props.title}</Label> <Label styles={{ root: { color: "var(--colorNeutralForeground1)" } }}>{this.props.title}</Label>
{this.props.tooltipContent && ( {this.props.tooltipContent && (
<TooltipHost <TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge} directionalHint={DirectionalHint.bottomLeftEdge}
@@ -79,6 +79,14 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
id={`delete-${this.props.title.split(" ").join("-")}`} id={`delete-${this.props.title.split(" ").join("-")}`}
iconProps={{ iconName: "Delete" }} iconProps={{ iconName: "Delete" }}
style={{ height: 27, marginRight: "20px" }} style={{ height: 27, marginRight: "20px" }}
styles={{
rootHovered: {
backgroundColor: "transparent",
},
rootPressed: {
backgroundColor: "transparent",
},
}}
onClick={(event) => { onClick={(event) => {
event.stopPropagation(); event.stopPropagation();
this.props.onDelete(); this.props.onDelete();

View File

@@ -20,7 +20,15 @@ exports[`CollapsibleSectionComponent renders 1`] = `
<Icon <Icon
iconName="ChevronDown" iconName="ChevronDown"
/> />
<StyledLabelBase> <StyledLabelBase
styles={
{
"root": {
"color": "var(--colorNeutralForeground1)",
},
}
}
>
Sample title Sample title
</StyledLabelBase> </StyledLabelBase>
</Stack> </Stack>

View File

@@ -58,6 +58,26 @@ export interface CommandButtonComponentProps {
*/ */
tooltipText?: string; tooltipText?: string;
/**
* Custom styles to apply to the button using Fluent UI theme tokens
*/
styles?: {
root?: {
backgroundColor?: string;
color?: string;
selectors?: {
":hover"?: {
backgroundColor?: string;
color?: string;
};
":active"?: {
backgroundColor?: string;
color?: string;
};
};
};
};
/** /**
* tabindex for the command button * tabindex for the command button
*/ */
@@ -250,6 +270,8 @@ export class CommandButtonComponent extends React.Component<CommandButtonCompone
contentClassName += " hasHiddenItems"; contentClassName += " hasHiddenItems";
} }
const style = this.props.styles?.root || {};
return ( return (
<div className="commandButtonReact"> <div className="commandButtonReact">
<span <span
@@ -262,6 +284,7 @@ export class CommandButtonComponent extends React.Component<CommandButtonCompone
aria-disabled={this.props.disabled} aria-disabled={this.props.disabled}
aria-haspopup={this.props.hasPopup} aria-haspopup={this.props.hasPopup}
aria-label={this.props.ariaLabel} aria-label={this.props.ariaLabel}
style={style}
onClick={(e: React.MouseEvent<HTMLSpanElement>) => this.commandClickCallback(e)} onClick={(e: React.MouseEvent<HTMLSpanElement>) => this.commandClickCallback(e)}
> >
<div className={contentClassName}> <div className={contentClassName}>

View File

@@ -179,8 +179,18 @@ export const Dialog: FC = () => {
title, title,
subText, subText,
styles: { styles: {
title: { fontSize: DIALOG_TITLE_FONT_SIZE, fontWeight: DIALOG_TITLE_FONT_WEIGHT }, title: {
subText: { fontSize: DIALOG_SUBTEXT_FONT_SIZE }, fontSize: DIALOG_TITLE_FONT_SIZE,
fontWeight: DIALOG_TITLE_FONT_WEIGHT,
},
subText: {
fontSize: DIALOG_SUBTEXT_FONT_SIZE,
color: "var(--colorNeutralForeground2)",
},
content: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
}, },
showCloseButton: showCloseButton || false, showCloseButton: showCloseButton || false,
onDismiss, onDismiss,
@@ -188,18 +198,60 @@ export const Dialog: FC = () => {
modalProps: { isBlocking: isModal, isDarkOverlay: false }, modalProps: { isBlocking: isModal, isDarkOverlay: false },
minWidth: DIALOG_MIN_WIDTH, minWidth: DIALOG_MIN_WIDTH,
maxWidth: DIALOG_MAX_WIDTH, maxWidth: DIALOG_MAX_WIDTH,
styles: {
main: {
backgroundColor: "var(--colorNeutralBackground1)",
selectors: {
".ms-Dialog-title": { color: "var(--colorNeutralForeground1)" },
},
},
},
}; };
const primaryButtonProps: IButtonProps = { const primaryButtonProps: IButtonProps = {
text: primaryButtonText, text: primaryButtonText,
disabled: primaryButtonDisabled || false, disabled: primaryButtonDisabled || false,
onClick: onPrimaryButtonClick, onClick: onPrimaryButtonClick,
styles: {
root: {
backgroundColor: "var(--colorBrandBackground)",
color: "var(--colorNeutralForegroundOnBrand)",
selectors: {
":hover": {
backgroundColor: "var(--colorBrandBackgroundHover)",
color: "var(--colorNeutralForegroundOnBrand)",
},
":active": {
backgroundColor: "var(--colorBrandBackgroundPressed)",
color: "var(--colorNeutralForegroundOnBrand)",
},
},
},
},
}; };
const secondaryButtonProps: IButtonProps = const secondaryButtonProps: IButtonProps =
secondaryButtonText && onSecondaryButtonClick secondaryButtonText && onSecondaryButtonClick
? { ? {
text: secondaryButtonText, text: secondaryButtonText,
onClick: onSecondaryButtonClick, onClick: onSecondaryButtonClick,
styles: {
root: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
borderColor: "var(--colorNeutralStroke1)",
selectors: {
":hover": {
backgroundColor: "var(--colorNeutralBackground3)",
color: "var(--colorNeutralForeground1)",
},
":active": {
backgroundColor: "var(--colorNeutralBackground3)",
color: "var(--colorNeutralForeground1)",
borderColor: "var(--colorCompoundBrandStroke1)",
},
},
},
},
} }
: undefined; : undefined;
return visible ? ( return visible ? (

View File

@@ -1,4 +1,5 @@
import { Spinner, SpinnerSize } from "@fluentui/react"; import { Spinner, SpinnerSize } from "@fluentui/react";
import { monacoTheme, useThemeStore } from "hooks/useTheme";
import * as React from "react"; import * as React from "react";
import { loadMonaco, monaco } from "../../LazyMonaco"; import { loadMonaco, monaco } from "../../LazyMonaco";
// import "./EditorReact.less"; // import "./EditorReact.less";
@@ -66,6 +67,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
private rootNode: HTMLElement; private rootNode: HTMLElement;
public editor: monaco.editor.IStandaloneCodeEditor; public editor: monaco.editor.IStandaloneCodeEditor;
private selectionListener: monaco.IDisposable; private selectionListener: monaco.IDisposable;
private themeUnsubscribe: () => void;
monacoApi: { monacoApi: {
default: typeof monaco; default: typeof monaco;
Emitter: typeof monaco.Emitter; Emitter: typeof monaco.Emitter;
@@ -94,6 +96,13 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
public componentDidMount(): void { public componentDidMount(): void {
this.createEditor(this.configureEditor.bind(this)); this.createEditor(this.configureEditor.bind(this));
this.themeUnsubscribe = useThemeStore.subscribe((state) => {
if (this.editor) {
const newTheme = state.isDarkMode ? "vs-dark" : "vs";
this.monacoApi?.editor.setTheme(newTheme);
}
});
setTimeout(() => { setTimeout(() => {
const suggestionWidget = this.editor?.getDomNode()?.querySelector(".suggest-widget") as HTMLElement; const suggestionWidget = this.editor?.getDomNode()?.querySelector(".suggest-widget") as HTMLElement;
if (suggestionWidget) { if (suggestionWidget) {
@@ -128,6 +137,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
public componentWillUnmount(): void { public componentWillUnmount(): void {
this.selectionListener && this.selectionListener.dispose(); this.selectionListener && this.selectionListener.dispose();
this.themeUnsubscribe && this.themeUnsubscribe();
} }
public render(): JSX.Element { public render(): JSX.Element {
@@ -211,7 +221,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
ariaLabel: this.props.ariaLabel, ariaLabel: this.props.ariaLabel,
fontSize: this.props.fontSize || 12, fontSize: this.props.fontSize || 12,
automaticLayout: true, automaticLayout: true,
theme: this.props.theme, theme: monacoTheme(),
wordWrap: this.props.wordWrap || "off", wordWrap: this.props.wordWrap || "off",
lineNumbers: this.props.lineNumbers || "off", lineNumbers: this.props.lineNumbers || "off",
lineNumbersMinChars: this.props.lineNumbersMinChars, lineNumbersMinChars: this.props.lineNumbersMinChars,

View File

@@ -2,6 +2,7 @@ import {
DefaultButton, DefaultButton,
Dropdown, Dropdown,
IDropdownOption, IDropdownOption,
IDropdownStyles,
IStyleFunctionOrObject, IStyleFunctionOrObject,
ITextFieldStyleProps, ITextFieldStyleProps,
ITextFieldStyles, ITextFieldStyles,
@@ -35,31 +36,167 @@ export interface FullTextPolicyData {
const labelStyles = { const labelStyles = {
root: { root: {
fontSize: 12, fontSize: 12,
color: "var(--colorNeutralForeground1)",
}, },
}; };
const textFieldStyles: IStyleFunctionOrObject<ITextFieldStyleProps, ITextFieldStyles> = { const textFieldStyles: IStyleFunctionOrObject<ITextFieldStyleProps, ITextFieldStyles> = {
fieldGroup: { fieldGroup: {
height: 27, height: 27,
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorNeutralStroke1)",
}, },
field: { field: {
fontSize: 12, fontSize: 12,
padding: "0 8px", padding: "0 8px",
color: "var(--colorNeutralForeground1)",
backgroundColor: "var(--colorNeutralBackground2)",
},
root: {
selectors: {
input: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
},
"input:hover": {
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorNeutralStroke1)",
},
"input:focus": {
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorBrandBackground)",
},
},
}, },
}; };
const dropdownStyles = { const dropdownStyles: Partial<IDropdownStyles> = {
title: { root: {
height: 27, width: "40%",
lineHeight: "24px", marginTop: "10px",
fontSize: 12, selectors: {
"&:hover .ms-Dropdown-title": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorNeutralStroke1)",
},
"&:hover span.ms-Dropdown-title": {
color: "var(--colorNeutralForeground1)",
},
"&:focus .ms-Dropdown-title": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "var(--colorNeutralBackground2)",
},
"&:focus span.ms-Dropdown-title": {
color: "var(--colorNeutralForeground1)",
},
},
},
label: {
color: "var(--colorNeutralForeground1)",
}, },
dropdown: { dropdown: {
height: 27, backgroundColor: "var(--colorNeutralBackground2)",
lineHeight: "24px", borderColor: "var(--colorNeutralStroke1)",
color: "var(--colorNeutralForeground1)",
},
title: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
borderColor: "var(--colorNeutralStroke1)",
selectors: {
"&:hover": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
},
"&:focus": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
},
"&:hover .ms-Dropdown-titleText": {
color: "var(--colorNeutralForeground1)",
},
"&:focus .ms-Dropdown-titleText": {
color: "var(--colorNeutralForeground1)",
},
"& .ms-Dropdown-titleText": {
color: "var(--colorNeutralForeground1)",
},
"&.ms-Dropdown-title--hasPlaceholder": {
color: "var(--colorNeutralForeground2)",
},
},
},
errorMessage: {
color: "var(--colorNeutralForeground1)",
},
caretDown: {
color: "var(--colorNeutralForeground1)",
},
callout: {
backgroundColor: "var(--colorNeutralBackground2)",
border: "1px solid var(--colorNeutralStroke1)",
},
dropdownItems: {
backgroundColor: "var(--colorNeutralBackground2)",
}, },
dropdownItem: { dropdownItem: {
fontSize: 12, backgroundColor: "transparent",
color: "var(--colorNeutralForeground1)",
minHeight: "36px",
lineHeight: "36px",
selectors: {
"&:hover": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
color: "var(--colorNeutralForeground1)",
},
"&:hover .ms-Dropdown-optionText": {
color: "var(--colorNeutralForeground1)",
},
"&:focus": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
color: "var(--colorNeutralForeground1)",
},
"&:active": {
backgroundColor: "rgba(255, 255, 255, 0.15)",
color: "var(--colorNeutralForeground1)",
},
"& .ms-Dropdown-optionText": {
color: "var(--colorNeutralForeground1)",
},
},
},
dropdownItemSelected: {
backgroundColor: "rgba(255, 255, 255, 0.08)",
color: "var(--colorNeutralForeground1)",
minHeight: "36px",
lineHeight: "36px",
selectors: {
"&:hover": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
color: "var(--colorNeutralForeground1)",
},
"&:hover .ms-Dropdown-optionText": {
color: "var(--colorNeutralForeground1)",
},
"&:focus": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
color: "var(--colorNeutralForeground1)",
},
"&:active": {
backgroundColor: "rgba(255, 255, 255, 0.15)",
color: "var(--colorNeutralForeground1)",
},
"& .ms-Dropdown-optionText": {
color: "var(--colorNeutralForeground1)",
},
},
},
dropdownOptionText: {
color: "var(--colorNeutralForeground1)",
},
dropdownItemHeader: {
color: "var(--colorNeutralForeground1)",
}, },
}; };
@@ -226,7 +363,32 @@ export const FullTextPoliciesComponent: React.FunctionComponent<FullTextPolicies
</Stack> </Stack>
</CollapsibleSectionComponent> </CollapsibleSectionComponent>
))} ))}
<DefaultButton id={`add-vector-policy`} styles={{ root: { maxWidth: 170, fontSize: 12 } }} onClick={onAdd}> <DefaultButton
id={`add-vector-policy`}
styles={{
root: {
maxWidth: 170,
fontSize: 12,
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
borderColor: "var(--colorNeutralStroke1)",
},
rootHovered: {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
borderColor: "var(--colorNeutralForeground1)",
},
rootPressed: {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
borderColor: "var(--colorNeutralForeground1)",
},
rootDisabled: {
backgroundColor: "transparent",
},
}}
onClick={onAdd}
>
Add full text path Add full text path
</DefaultButton> </DefaultButton>
</Stack> </Stack>

View File

@@ -4,6 +4,8 @@
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
width: 100%; width: 100%;
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
} }
.settingsV2ToolTip { .settingsV2ToolTip {
@@ -23,6 +25,8 @@
overflow-y: auto; overflow-y: auto;
width: 100%; width: 100%;
font-family: @DataExplorerFont; font-family: @DataExplorerFont;
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
} }
.settingsV2Editor { .settingsV2Editor {

View File

@@ -1,4 +1,4 @@
import { IPivotItemProps, IPivotProps, Pivot, PivotItem } from "@fluentui/react"; import { IPivotItemProps, IPivotProps, Pivot, PivotItem, Stack } from "@fluentui/react";
import { sendMessage } from "Common/MessageHandler"; import { sendMessage } from "Common/MessageHandler";
import { FabricMessageTypes } from "Contracts/FabricMessageTypes"; import { FabricMessageTypes } from "Contracts/FabricMessageTypes";
import { import {
@@ -1477,31 +1477,111 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
selectedKey: SettingsV2TabTypes[this.state.selectedTab], selectedKey: SettingsV2TabTypes[this.state.selectedTab],
}; };
const pivotItems = tabs.map((tab) => { const pivotStyles = {
const pivotItemProps: IPivotItemProps = { root: {
itemKey: SettingsV2TabTypes[tab.tab], backgroundColor: "var(--colorNeutralBackground1)",
style: { marginTop: 20 }, color: "var(--colorNeutralForeground1)",
headerText: getTabTitle(tab.tab), selectors: {
headerButtonProps: { "& .ms-Pivot-link": {
"data-test": `settings-tab-header/${SettingsV2TabTypes[tab.tab]}`, color: "var(--colorNeutralForeground1)",
},
"& .ms-Pivot-link.is-selected::before": {
backgroundColor: "var(--colorCompoundBrandBackground)",
},
}, },
}; },
link: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: {
"&:hover": {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
"&:active": {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
'&[aria-selected="true"]': {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: {
"&:hover": {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
"&:active": {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
},
},
},
},
return ( itemContainer: {
<PivotItem key={pivotItemProps.itemKey} {...pivotItemProps}> // padding: '20px 24px',
{tab.content} backgroundColor: "var(--colorNeutralBackground1)",
</PivotItem> color: "var(--colorNeutralForeground1)",
); },
}); };
const contentStyles = {
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
// padding: '20px 24px'
},
};
return ( return (
<div className="settingsV2MainContainer"> <div
className="settingsV2MainContainer"
style={
{
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
position: "relative",
} as React.CSSProperties
}
>
{this.shouldShowKeyspaceSharedThroughputMessage() && ( {this.shouldShowKeyspaceSharedThroughputMessage() && (
<div>This table shared throughput is configured at the keyspace</div> <div>This table shared throughput is configured at the keyspace</div>
)} )}
<div className="settingsV2TabsContainer"> <div
<Pivot {...pivotProps}>{pivotItems}</Pivot> className="settingsV2TabsContainer"
style={
{
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
position: "relative",
padding: "20px 24px",
} as React.CSSProperties
}
>
<Pivot {...pivotProps} styles={pivotStyles}>
{tabs.map((tab) => {
const pivotItemProps: IPivotItemProps = {
itemKey: SettingsV2TabTypes[tab.tab],
style: {
marginTop: 20,
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
headerText: getTabTitle(tab.tab),
headerButtonProps: {
"data-test": `settings-tab-header/${SettingsV2TabTypes[tab.tab]}`,
},
};
return (
<PivotItem key={pivotItemProps.itemKey} {...pivotItemProps}>
<Stack styles={contentStyles}>{tab.content}</Stack>
</PivotItem>
);
})}
</Pivot>
</div> </div>
</div> </div>
); );

View File

@@ -63,7 +63,7 @@ export interface PriceBreakdown {
export type editorType = "indexPolicy" | "computedProperties" | "dataMasking"; export type editorType = "indexPolicy" | "computedProperties" | "dataMasking";
export const infoAndToolTipTextStyle: ITextStyles = { root: { fontSize: 14, color: "windowtext" } }; export const infoAndToolTipTextStyle: ITextStyles = { root: { fontSize: 14, color: "var(--colorNeutralForeground1)" } };
export const noLeftPaddingCheckBoxStyle: ICheckboxStyles = { export const noLeftPaddingCheckBoxStyle: ICheckboxStyles = {
label: { label: {
@@ -119,15 +119,89 @@ export const addMongoIndexSubElementsTokens: IStackTokens = {
export const mediumWidthStackStyles: IStackStyles = { root: { width: 600 } }; export const mediumWidthStackStyles: IStackStyles = { root: { width: 600 } };
export const shortWidthTextFieldStyles: Partial<ITextFieldStyles> = { root: { paddingLeft: 10, width: 210 } }; export const shortWidthTextFieldStyles: Partial<ITextFieldStyles> = {
root: { paddingLeft: 10, width: 210 },
fieldGroup: {
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorNeutralStroke1)",
},
field: {
color: "var(--colorNeutralForeground1)",
backgroundColor: "var(--colorNeutralBackground2)",
},
};
export const shortWidthDropDownStyles: Partial<IDropdownStyles> = { dropdown: { paddingleft: 10, width: 202 } }; export const shortWidthDropDownStyles: Partial<IDropdownStyles> = {
dropdown: { paddingLeft: 10, width: 202 },
title: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
borderColor: "var(--colorNeutralStroke1)",
},
caretDown: {
color: "var(--colorNeutralForeground1)",
},
callout: {
backgroundColor: "var(--colorNeutralBackground2)",
border: "1px solid var(--colorNeutralStroke1)",
},
dropdownItems: {
backgroundColor: "var(--colorNeutralBackground2)",
},
dropdownItem: {
backgroundColor: "transparent",
color: "var(--colorNeutralForeground1)",
selectors: {
"&:hover": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
color: "var(--colorNeutralForeground1)",
},
"&:focus": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
color: "var(--colorNeutralForeground1)",
},
},
},
dropdownItemSelected: {
backgroundColor: "rgba(255, 255, 255, 0.08)",
color: "var(--colorNeutralForeground1)",
selectors: {
"&:hover": {
backgroundColor: "rgba(255, 255, 255, 0.1)",
color: "var(--colorNeutralForeground1)",
},
},
},
dropdownOptionText: {
color: "var(--colorNeutralForeground1)",
},
};
export const transparentDetailsRowStyles: Partial<IDetailsRowStyles> = { export const transparentDetailsRowStyles: Partial<IDetailsRowStyles> = {
root: { root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: { selectors: {
":hover": { ":hover": {
background: "transparent", backgroundColor: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1)",
},
":hover .ms-DetailsRow-cell": {
backgroundColor: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1)",
},
"&.ms-DetailsRow": {
backgroundColor: "var(--colorNeutralBackground1)",
},
},
},
cell: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: {
":hover": {
backgroundColor: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1)",
}, },
}, },
}, },
@@ -135,9 +209,11 @@ export const transparentDetailsRowStyles: Partial<IDetailsRowStyles> = {
export const transparentDetailsHeaderStyle: Partial<IDetailsColumnStyles> = { export const transparentDetailsHeaderStyle: Partial<IDetailsColumnStyles> = {
root: { root: {
color: "var(--colorNeutralForeground1)",
selectors: { selectors: {
":hover": { ":hover": {
background: "transparent", background: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1)",
}, },
}, },
}, },
@@ -149,6 +225,35 @@ export const customDetailsListStyles: Partial<IDetailsListStyles> = {
".ms-FocusZone": { ".ms-FocusZone": {
paddingTop: 0, paddingTop: 0,
}, },
".ms-DetailsHeader": {
backgroundColor: "var(--colorNeutralBackground1)",
},
".ms-DetailsHeader-cell": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "var(--colorNeutralBackground1)",
selectors: {
":hover": {
backgroundColor: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1)",
},
},
},
".ms-DetailsHeader-cellTitle": {
color: "var(--colorNeutralForeground1)",
},
".ms-DetailsRow": {
color: "var(--colorNeutralForeground1)",
},
".ms-DetailsRow-cell": {
color: "var(--colorNeutralForeground1)",
},
// Tooltip styling for cells
".ms-TooltipHost": {
color: "var(--colorNeutralForeground1)",
},
".ms-DetailsRow-cell .ms-TooltipHost": {
color: "var(--colorNeutralForeground1)",
},
}, },
}, },
}; };
@@ -166,7 +271,18 @@ export const separatorStyles: Partial<ISeparatorStyles> = {
}; };
export const messageBarStyles: Partial<IMessageBarStyles> = { export const messageBarStyles: Partial<IMessageBarStyles> = {
root: { marginTop: "5px", backgroundColor: "white" }, root: {
marginTop: "5px",
backgroundColor: "var(--colorNeutralBackground1)",
selectors: {
"&.ms-MessageBar--severeWarning": {
backgroundColor: "var(--colorNeutralBackground4)",
},
"&.ms-MessageBar--warning": {
backgroundColor: "var(--colorNeutralBackground3)",
},
},
},
text: { fontSize: 14 }, text: { fontSize: 14 },
}; };
@@ -222,9 +338,11 @@ export const getEstimatedSpendingElement = (
const ruRange: string = isAutoscale ? throughput / 10 + " RU/s - " : ""; const ruRange: string = isAutoscale ? throughput / 10 + " RU/s - " : "";
return ( return (
<Stack> <Stack>
<Text style={{ fontWeight: 600 }}>Cost estimate*</Text> <Text style={{ fontWeight: 600, color: "var(--colorNeutralForeground1)" }}>Cost estimate*</Text>
{costElement} {costElement}
<Text style={{ fontWeight: 600, marginTop: 15 }}>How we calculate this</Text> <Text style={{ fontWeight: 600, marginTop: 15, color: "var(--colorNeutralForeground1)" }}>
How we calculate this
</Text>
<Stack id="throughputSpendElement" style={{ marginTop: 5 }}> <Stack id="throughputSpendElement" style={{ marginTop: 5 }}>
<span> <span>
{numberOfRegions} region{numberOfRegions > 1 && <span>s</span>} {numberOfRegions} region{numberOfRegions > 1 && <span>s</span>}
@@ -238,7 +356,7 @@ export const getEstimatedSpendingElement = (
{priceBreakdown.pricePerRu}/RU {priceBreakdown.pricePerRu}/RU
</span> </span>
</Stack> </Stack>
<Text style={{ marginTop: 15 }}> <Text style={{ marginTop: 15, color: "var(--colorNeutralForeground1)" }}>
<em>*{estimatedCostDisclaimer}</em> <em>*{estimatedCostDisclaimer}</em>
</Text> </Text>
</Stack> </Stack>
@@ -285,7 +403,7 @@ export const updateThroughputDelayedApplyWarningMessage: JSX.Element = (
export const getUpdateThroughputBeyondInstantLimitMessage = (instantMaximumThroughput: number): JSX.Element => { export const getUpdateThroughputBeyondInstantLimitMessage = (instantMaximumThroughput: number): JSX.Element => {
return ( return (
<Text styles={infoAndToolTipTextStyle} id="updateThroughputDelayedApplyWarningMessage"> <Text id="updateThroughputDelayedApplyWarningMessage">
Scaling up will take 4-6 hours as it exceeds what Azure Cosmos DB can instantly support currently based on your Scaling up will take 4-6 hours as it exceeds what Azure Cosmos DB can instantly support currently based on your
number of physical partitions. You can increase your throughput to {instantMaximumThroughput} instantly or proceed number of physical partitions. You can increase your throughput to {instantMaximumThroughput} instantly or proceed
with this value and wait until the scale-up is completed. with this value and wait until the scale-up is completed.
@@ -303,7 +421,7 @@ export const getUpdateThroughputBeyondSupportLimitMessage = (
Your request to increase throughput exceeds the pre-allocated capacity which may take longer than expected. Your request to increase throughput exceeds the pre-allocated capacity which may take longer than expected.
There are three options you can choose from to proceed: There are three options you can choose from to proceed:
</Text> </Text>
<ol style={{ fontSize: 14, color: "windowtext", marginTop: "5px" }}> <ol style={{ fontSize: 14, color: "var(--colorNeutralForeground1)", marginTop: "5px" }}>
<li>You can instantly scale up to {instantMaximumThroughput} RU/s.</li> <li>You can instantly scale up to {instantMaximumThroughput} RU/s.</li>
{instantMaximumThroughput < maximumThroughput && ( {instantMaximumThroughput < maximumThroughput && (
<li>You can asynchronously scale up to any value under {maximumThroughput} RU/s in 4-6 hours.</li> <li>You can asynchronously scale up to any value under {maximumThroughput} RU/s in 4-6 hours.</li>
@@ -339,7 +457,7 @@ export const getUpdateThroughputBelowMinimumMessage = (minimum: number): JSX.Ele
}; };
export const saveThroughputWarningMessage: JSX.Element = ( export const saveThroughputWarningMessage: JSX.Element = (
<Text styles={infoAndToolTipTextStyle}> <Text>
Your bill will be affected as you update your throughput settings. Please review the updated cost estimate below Your bill will be affected as you update your throughput settings. Please review the updated cost estimate below
before saving your changes before saving your changes
</Text> </Text>
@@ -459,9 +577,13 @@ export const changeFeedPolicyToolTip: JSX.Element = (
); );
export const mongoIndexingPolicyDisclaimer: JSX.Element = ( export const mongoIndexingPolicyDisclaimer: JSX.Element = (
<Text> <Text style={{ color: "var(--colorNeutralForeground1)" }}>
For queries that filter on multiple properties, create multiple single field indexes instead of a compound index. For queries that filter on multiple properties, create multiple single field indexes instead of a compound index.
<Link href="https://docs.microsoft.com/azure/cosmos-db/mongodb-indexing#index-types" target="_blank"> <Link
href="https://docs.microsoft.com/azure/cosmos-db/mongodb-indexing#index-types"
target="_blank"
style={{ color: "var(--colorBrandForeground1)" }}
>
{` Compound indexes `} {` Compound indexes `}
</Link> </Link>
are only used for sorting query results. If you need to add a compound index, you can create one using the Mongo are only used for sorting query results. If you need to add a compound index, you can create one using the Mongo
@@ -470,7 +592,7 @@ export const mongoIndexingPolicyDisclaimer: JSX.Element = (
); );
export const mongoCompoundIndexNotSupportedMessage: JSX.Element = ( export const mongoCompoundIndexNotSupportedMessage: JSX.Element = (
<Text> <Text style={{ color: "var(--colorNeutralForeground1)" }}>
Collections with compound indexes are not yet supported in the indexing editor. To modify indexing policy for this Collections with compound indexes are not yet supported in the indexing editor. To modify indexing policy for this
collection, use the Mongo Shell. collection, use the Mongo Shell.
</Text> </Text>
@@ -519,14 +641,50 @@ export const getTextFieldStyles = (current: isDirtyTypes, baseline: isDirtyTypes
fieldGroup: { fieldGroup: {
height: 25, height: 25,
width: 300, width: 300,
borderColor: isDirty(current, baseline) ? StyleConstants.Dirty : "", backgroundColor: "var(--colorNeutralBackground2)",
borderColor: isDirty(current, baseline) ? StyleConstants.Dirty : "var(--colorNeutralStroke1)",
selectors: { selectors: {
":disabled": { ":disabled": {
backgroundColor: StyleConstants.BaseMedium, backgroundColor: "var(--colorNeutralBackground2)",
borderColor: StyleConstants.BaseMediumHigh, borderColor: "var(--colorNeutralStroke1)",
color: "var(--colorNeutralForeground2)",
},
input: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
},
"input:disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground2)",
},
"input#autopilotInput": {
backgroundColor: "var(--colorNeutralBackground4)",
color: "var(--colorNeutralForeground1)",
}, },
}, },
}, },
field: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
selectors: {
":disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground2)",
},
},
},
subComponentStyles: {
label: {
root: {
color: "var(--colorNeutralForeground1)",
},
},
},
suffix: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
border: "1px solid var(--colorNeutralStroke1)",
},
}); });
export const getChoiceGroupStyles = ( export const getChoiceGroupStyles = (
@@ -534,6 +692,28 @@ export const getChoiceGroupStyles = (
baseline: isDirtyTypes, baseline: isDirtyTypes,
isHorizontal?: boolean, isHorizontal?: boolean,
): Partial<IChoiceGroupStyles> => ({ ): Partial<IChoiceGroupStyles> => ({
label: {
color: "var(--colorNeutralForeground1)",
},
root: {
selectors: {
".ms-ChoiceFieldLabel": {
color: "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
color: "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceFieldLabel": {
color: "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceField-innerField": {
color: "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-innerField": {
color: "var(--colorNeutralForeground1)",
},
},
},
flexContainer: [ flexContainer: [
{ {
selectors: { selectors: {
@@ -548,6 +728,16 @@ export const getChoiceGroupStyles = (
fontSize: 14, fontSize: 14,
fontFamily: StyleConstants.DataExplorerFont, fontFamily: StyleConstants.DataExplorerFont,
padding: "2px 5px", padding: "2px 5px",
color: "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel": {
color: "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel:hover": {
color: "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
color: "var(--colorNeutralForeground1)",
}, },
}, },
display: isHorizontal ? "inline-flex" : "default", display: isHorizontal ? "inline-flex" : "default",

View File

@@ -1,11 +1,11 @@
import { FontIcon, Link, MessageBar, MessageBarType, Stack, Text } from "@fluentui/react"; import { FontIcon, IMessageBarStyles, Link, MessageBar, MessageBarType, Stack, Text } from "@fluentui/react";
import * as DataModels from "Contracts/DataModels"; import * as DataModels from "Contracts/DataModels";
import { titleAndInputStackProps, unsavedEditorWarningMessage } from "Explorer/Controls/Settings/SettingsRenderUtils"; import { titleAndInputStackProps, unsavedEditorWarningMessage } from "Explorer/Controls/Settings/SettingsRenderUtils";
import { isDirty } from "Explorer/Controls/Settings/SettingsUtils"; import { isDirty } from "Explorer/Controls/Settings/SettingsUtils";
import { loadMonaco } from "Explorer/LazyMonaco"; import { loadMonaco } from "Explorer/LazyMonaco";
import { monacoTheme, useThemeStore } from "hooks/useTheme";
import * as monaco from "monaco-editor"; import * as monaco from "monaco-editor";
import * as React from "react"; import * as React from "react";
export interface ComputedPropertiesComponentProps { export interface ComputedPropertiesComponentProps {
computedPropertiesContent: DataModels.ComputedProperties; computedPropertiesContent: DataModels.ComputedProperties;
computedPropertiesContentBaseline: DataModels.ComputedProperties; computedPropertiesContentBaseline: DataModels.ComputedProperties;
@@ -27,6 +27,24 @@ export class ComputedPropertiesComponent extends React.Component<
private shouldCheckComponentIsDirty = true; private shouldCheckComponentIsDirty = true;
private computedPropertiesDiv = React.createRef<HTMLDivElement>(); private computedPropertiesDiv = React.createRef<HTMLDivElement>();
private computedPropertiesEditor: monaco.editor.IStandaloneCodeEditor; private computedPropertiesEditor: monaco.editor.IStandaloneCodeEditor;
private themeUnsubscribe: () => void;
private darkThemeMessageBarStyles: Partial<IMessageBarStyles> = {
root: {
selectors: {
"&.ms-MessageBar--warning": {
backgroundColor: "var(--colorStatusWarningBackground1)",
border: "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
color: "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
color: "var(--colorNeutralForeground1)",
},
},
},
};
constructor(props: ComputedPropertiesComponentProps) { constructor(props: ComputedPropertiesComponentProps) {
super(props); super(props);
@@ -48,6 +66,10 @@ export class ComputedPropertiesComponent extends React.Component<
this.onComponentUpdate(); this.onComponentUpdate();
} }
componentWillUnmount(): void {
this.themeUnsubscribe && this.themeUnsubscribe();
}
public resetComputedPropertiesEditor = (): void => { public resetComputedPropertiesEditor = (): void => {
if (!this.computedPropertiesEditor) { if (!this.computedPropertiesEditor) {
this.createComputedPropertiesEditor(); this.createComputedPropertiesEditor();
@@ -86,8 +108,16 @@ export class ComputedPropertiesComponent extends React.Component<
value: value, value: value,
language: "json", language: "json",
ariaLabel: "Computed properties", ariaLabel: "Computed properties",
theme: monacoTheme(),
}); });
if (this.computedPropertiesEditor) { if (this.computedPropertiesEditor) {
// Subscribe to theme changes
this.themeUnsubscribe = useThemeStore.subscribe(() => {
if (this.computedPropertiesEditor) {
monaco.editor.setTheme(monacoTheme());
}
});
const computedPropertiesEditorModel = this.computedPropertiesEditor.getModel(); const computedPropertiesEditorModel = this.computedPropertiesEditor.getModel();
computedPropertiesEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this)); computedPropertiesEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this));
this.props.logComputedPropertiesSuccessMessage(); this.props.logComputedPropertiesSuccessMessage();
@@ -111,11 +141,15 @@ export class ComputedPropertiesComponent extends React.Component<
return ( return (
<Stack {...titleAndInputStackProps}> <Stack {...titleAndInputStackProps}>
{isDirty(this.props.computedPropertiesContent, this.props.computedPropertiesContentBaseline) && ( {isDirty(this.props.computedPropertiesContent, this.props.computedPropertiesContentBaseline) && (
<MessageBar messageBarType={MessageBarType.warning}> <MessageBar
messageBarType={MessageBarType.warning}
messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }}
styles={this.darkThemeMessageBarStyles}
>
{unsavedEditorWarningMessage("computedProperties")} {unsavedEditorWarningMessage("computedProperties")}
</MessageBar> </MessageBar>
)} )}
<Text style={{ marginLeft: "30px", marginBottom: "10px" }}> <Text style={{ marginLeft: "30px", marginBottom: "10px", color: "var(--colorNeutralForeground1)" }}>
<Link target="_blank" href="https://aka.ms/computed-properties-preview/"> <Link target="_blank" href="https://aka.ms/computed-properties-preview/">
{"Learn more"} <FontIcon iconName="NavigateExternalInline" /> {"Learn more"} <FontIcon iconName="NavigateExternalInline" />
</Link> </Link>

View File

@@ -6,7 +6,6 @@ import {
conflictResolutionCustomToolTip, conflictResolutionCustomToolTip,
conflictResolutionLwwTooltip, conflictResolutionLwwTooltip,
getChoiceGroupStyles, getChoiceGroupStyles,
getTextFieldStyles,
subComponentStackProps, subComponentStackProps,
} from "../SettingsRenderUtils"; } from "../SettingsRenderUtils";
import { isDirty } from "../SettingsUtils"; import { isDirty } from "../SettingsUtils";
@@ -106,10 +105,46 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
id="conflictResolutionLwwTextField" id="conflictResolutionLwwTextField"
label={"Conflict Resolver Property"} label={"Conflict Resolver Property"}
onRenderLabel={this.onRenderLwwComponentTextField} onRenderLabel={this.onRenderLwwComponentTextField}
styles={getTextFieldStyles( styles={{
this.props.conflictResolutionPolicyPath, fieldGroup: {
this.props.conflictResolutionPolicyPathBaseline, height: 25,
)} width: 300,
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorNeutralStroke1)",
selectors: {
":disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorNeutralStroke1)",
color: "var(--colorNeutralForeground2)",
},
input: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
},
"input:disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground2)",
},
},
},
field: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
selectors: {
":disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground2)",
},
},
},
subComponentStyles: {
label: {
root: {
color: "var(--colorNeutralForeground1)",
},
},
},
}}
value={this.props.conflictResolutionPolicyPath} value={this.props.conflictResolutionPolicyPath}
onChange={this.onConflictResolutionPolicyPathChange} onChange={this.onConflictResolutionPolicyPathChange}
/> />
@@ -119,19 +154,57 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
<ToolTipLabelComponent label={props.label} toolTipElement={conflictResolutionCustomToolTip} /> <ToolTipLabelComponent label={props.label} toolTipElement={conflictResolutionCustomToolTip} />
); );
private getConflictResolutionCustomComponent = (): JSX.Element => ( private getConflictResolutionCustomComponent = (): JSX.Element => {
<TextField return (
id="conflictResolutionCustomTextField" <TextField
label="Stored procedure" id="conflictResolutionCustomTextField"
onRenderLabel={this.onRenderCustomComponentTextField} label="Stored procedure"
styles={getTextFieldStyles( onRenderLabel={this.onRenderCustomComponentTextField}
this.props.conflictResolutionPolicyProcedure, styles={{
this.props.conflictResolutionPolicyProcedureBaseline, fieldGroup: {
)} height: 25,
value={this.props.conflictResolutionPolicyProcedure} width: 300,
onChange={this.onConflictResolutionPolicyProcedureChange} backgroundColor: "var(--colorNeutralBackground2)",
/> borderColor: "var(--colorNeutralStroke1)",
); selectors: {
":disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
borderColor: "var(--colorNeutralStroke1)",
color: "var(--colorNeutralForeground2)",
},
input: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
},
"input:disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground2)",
},
},
},
field: {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
selectors: {
":disabled": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground2)",
},
},
},
subComponentStyles: {
label: {
root: {
color: "var(--colorNeutralForeground1)",
},
},
},
}}
value={this.props.conflictResolutionPolicyProcedure}
onChange={this.onConflictResolutionPolicyProcedureChange}
/>
);
};
public render(): JSX.Element { public render(): JSX.Element {
return ( return (

View File

@@ -102,11 +102,57 @@ export const ContainerPolicyComponent: React.FC<ContainerPolicyComponentProps> =
return ( return (
<div> <div>
<Pivot onLinkClick={onPivotChange} selectedKey={ContainerPolicyTabTypes[selectedTab]}> <Pivot
onLinkClick={onPivotChange}
selectedKey={ContainerPolicyTabTypes[selectedTab]}
styles={{
root: {
color: "var(--colorNeutralForeground1)",
},
link: {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
selectors: {
":hover": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
},
":active": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
},
},
},
linkIsSelected: {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
selectors: {
":before": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "var(--colorBrandForeground1)",
},
":hover": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
},
":active": {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
},
},
},
linkContent: {
color: "inherit",
},
text: {
color: "inherit",
},
}}
>
{isVectorSearchEnabled && ( {isVectorSearchEnabled && (
<PivotItem <PivotItem
itemKey={ContainerPolicyTabTypes[ContainerPolicyTabTypes.VectorPolicyTab]} itemKey={ContainerPolicyTabTypes[ContainerPolicyTabTypes.VectorPolicyTab]}
style={{ marginTop: 20 }} style={{ marginTop: 20, color: "var(--colorNeutralForeground1)" }}
headerText="Vector Policy" headerText="Vector Policy"
> >
<Stack {...titleAndInputStackProps} styles={{ root: { position: "relative", maxWidth: "400px" } }}> <Stack {...titleAndInputStackProps} styles={{ root: { position: "relative", maxWidth: "400px" } }}>
@@ -128,7 +174,7 @@ export const ContainerPolicyComponent: React.FC<ContainerPolicyComponentProps> =
{isFullTextSearchEnabled && ( {isFullTextSearchEnabled && (
<PivotItem <PivotItem
itemKey={ContainerPolicyTabTypes[ContainerPolicyTabTypes.FullTextPolicyTab]} itemKey={ContainerPolicyTabTypes[ContainerPolicyTabTypes.FullTextPolicyTab]}
style={{ marginTop: 20 }} style={{ marginTop: 20, color: "var(--colorNeutralForeground1)" }}
headerText="Full Text Policy" headerText="Full Text Policy"
> >
<Stack {...titleAndInputStackProps} styles={{ root: { position: "relative", maxWidth: "400px" } }}> <Stack {...titleAndInputStackProps} styles={{ root: { position: "relative", maxWidth: "400px" } }}>
@@ -144,7 +190,27 @@ export const ContainerPolicyComponent: React.FC<ContainerPolicyComponentProps> =
) : ( ) : (
<DefaultButton <DefaultButton
id={"create-full-text-policy"} id={"create-full-text-policy"}
styles={{ root: { fontSize: 12 } }} styles={{
root: {
fontSize: 12,
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
borderColor: "var(--colorNeutralForeground1)",
},
rootHovered: {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
borderColor: "var(--colorNeutralForeground1)",
},
rootPressed: {
color: "var(--colorNeutralForeground1)",
backgroundColor: "transparent",
borderColor: "var(--colorNeutralForeground1)",
},
rootDisabled: {
backgroundColor: "transparent",
},
}}
onClick={() => { onClick={() => {
checkAndSendFullTextPolicyToSettings({ checkAndSendFullTextPolicyToSettings({
defaultLanguage: getFullTextLanguageOptions()[0].key as never, defaultLanguage: getFullTextLanguageOptions()[0].key as never,

View File

@@ -1,4 +1,5 @@
import { MessageBar, MessageBarType, Stack } from "@fluentui/react"; import { IMessageBarStyles, MessageBar, MessageBarType, Stack } from "@fluentui/react";
import { monacoTheme, useThemeStore } from "hooks/useTheme";
import * as monaco from "monaco-editor"; import * as monaco from "monaco-editor";
import * as React from "react"; import * as React from "react";
import * as DataModels from "../../../../Contracts/DataModels"; import * as DataModels from "../../../../Contracts/DataModels";
@@ -6,7 +7,6 @@ import { loadMonaco } from "../../../LazyMonaco";
import { titleAndInputStackProps, unsavedEditorWarningMessage } from "../SettingsRenderUtils"; import { titleAndInputStackProps, unsavedEditorWarningMessage } from "../SettingsRenderUtils";
import { isDirty, isIndexTransforming } from "../SettingsUtils"; import { isDirty, isIndexTransforming } from "../SettingsUtils";
import { IndexingPolicyRefreshComponent } from "./IndexingPolicyRefresh/IndexingPolicyRefreshComponent"; import { IndexingPolicyRefreshComponent } from "./IndexingPolicyRefresh/IndexingPolicyRefreshComponent";
export interface IndexingPolicyComponentProps { export interface IndexingPolicyComponentProps {
shouldDiscardIndexingPolicy: boolean; shouldDiscardIndexingPolicy: boolean;
resetShouldDiscardIndexingPolicy: () => void; resetShouldDiscardIndexingPolicy: () => void;
@@ -31,6 +31,24 @@ export class IndexingPolicyComponent extends React.Component<
private shouldCheckComponentIsDirty = true; private shouldCheckComponentIsDirty = true;
private indexingPolicyDiv = React.createRef<HTMLDivElement>(); private indexingPolicyDiv = React.createRef<HTMLDivElement>();
private indexingPolicyEditor: monaco.editor.IStandaloneCodeEditor; private indexingPolicyEditor: monaco.editor.IStandaloneCodeEditor;
private themeUnsubscribe: () => void;
private darkThemeMessageBarStyles: Partial<IMessageBarStyles> = {
root: {
selectors: {
"&.ms-MessageBar--warning": {
backgroundColor: "var(--colorStatusWarningBackground1)",
border: "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
color: "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
color: "var(--colorNeutralForeground1)",
},
},
},
};
constructor(props: IndexingPolicyComponentProps) { constructor(props: IndexingPolicyComponentProps) {
super(props); super(props);
@@ -52,6 +70,10 @@ export class IndexingPolicyComponent extends React.Component<
this.onComponentUpdate(); this.onComponentUpdate();
} }
componentWillUnmount(): void {
this.themeUnsubscribe && this.themeUnsubscribe();
}
public resetIndexingPolicyEditor = (): void => { public resetIndexingPolicyEditor = (): void => {
if (!this.indexingPolicyEditor) { if (!this.indexingPolicyEditor) {
this.createIndexingPolicyEditor(); this.createIndexingPolicyEditor();
@@ -87,18 +109,30 @@ export class IndexingPolicyComponent extends React.Component<
}; };
private async createIndexingPolicyEditor(): Promise<void> { private async createIndexingPolicyEditor(): Promise<void> {
if (!this.indexingPolicyDiv.current) {
return;
}
const value: string = JSON.stringify(this.props.indexingPolicyContent, undefined, 4); const value: string = JSON.stringify(this.props.indexingPolicyContent, undefined, 4);
const monaco = await loadMonaco(); const monaco = await loadMonaco();
this.indexingPolicyEditor = monaco.editor.create(this.indexingPolicyDiv.current, { if (this.indexingPolicyDiv.current) {
value: value, this.indexingPolicyEditor = monaco.editor.create(this.indexingPolicyDiv.current, {
language: "json", value: value,
readOnly: isIndexTransforming(this.props.indexTransformationProgress), language: "json",
ariaLabel: "Indexing Policy", readOnly: isIndexTransforming(this.props.indexTransformationProgress),
}); ariaLabel: "Indexing Policy",
if (this.indexingPolicyEditor) { theme: monacoTheme(),
const indexingPolicyEditorModel = this.indexingPolicyEditor.getModel(); });
indexingPolicyEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this)); if (this.indexingPolicyEditor) {
this.props.logIndexingPolicySuccessMessage(); this.themeUnsubscribe = useThemeStore.subscribe(() => {
if (this.indexingPolicyEditor) {
monaco.editor.setTheme(monacoTheme());
}
});
const indexingPolicyEditorModel = this.indexingPolicyEditor.getModel();
indexingPolicyEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this));
this.props.logIndexingPolicySuccessMessage();
}
} }
} }
@@ -121,7 +155,13 @@ export class IndexingPolicyComponent extends React.Component<
refreshIndexTransformationProgress={this.props.refreshIndexTransformationProgress} refreshIndexTransformationProgress={this.props.refreshIndexTransformationProgress}
/> />
{isDirty(this.props.indexingPolicyContent, this.props.indexingPolicyContentBaseline) && ( {isDirty(this.props.indexingPolicyContent, this.props.indexingPolicyContentBaseline) && (
<MessageBar messageBarType={MessageBarType.warning}>{unsavedEditorWarningMessage("indexPolicy")}</MessageBar> <MessageBar
messageBarType={MessageBarType.warning}
messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }}
styles={this.darkThemeMessageBarStyles}
>
{unsavedEditorWarningMessage("indexPolicy")}
</MessageBar>
)} )}
<div className="settingsV2Editor" tabIndex={0} ref={this.indexingPolicyDiv}></div> <div className="settingsV2Editor" tabIndex={0} ref={this.indexingPolicyDiv}></div>
</Stack> </Stack>

View File

@@ -8,7 +8,7 @@ exports[`IndexingPolicyRefreshComponent renders 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }

View File

@@ -3,6 +3,7 @@ import {
DetailsListLayoutMode, DetailsListLayoutMode,
IColumn, IColumn,
IconButton, IconButton,
IMessageBarStyles,
MessageBar, MessageBar,
MessageBarType, MessageBarType,
SelectionMode, SelectionMode,
@@ -30,12 +31,12 @@ import {
} from "../../SettingsRenderUtils"; } from "../../SettingsRenderUtils";
import { import {
AddMongoIndexProps, AddMongoIndexProps,
MongoIndexIdField,
MongoIndexTypes,
MongoNotificationType,
getMongoIndexType, getMongoIndexType,
getMongoIndexTypeText, getMongoIndexTypeText,
isIndexTransforming, isIndexTransforming,
MongoIndexIdField,
MongoIndexTypes,
MongoNotificationType,
} from "../../SettingsUtils"; } from "../../SettingsUtils";
import { IndexingPolicyRefreshComponent } from "../IndexingPolicyRefresh/IndexingPolicyRefreshComponent"; import { IndexingPolicyRefreshComponent } from "../IndexingPolicyRefresh/IndexingPolicyRefreshComponent";
import { AddMongoIndexComponent } from "./AddMongoIndexComponent"; import { AddMongoIndexComponent } from "./AddMongoIndexComponent";
@@ -63,6 +64,24 @@ interface MongoIndexDisplayProps {
export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingPolicyComponentProps> { export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingPolicyComponentProps> {
private shouldCheckComponentIsDirty = true; private shouldCheckComponentIsDirty = true;
private addMongoIndexComponentRefs: React.RefObject<AddMongoIndexComponent>[] = []; private addMongoIndexComponentRefs: React.RefObject<AddMongoIndexComponent>[] = [];
private darkThemeMessageBarStyles: Partial<IMessageBarStyles> = {
root: {
selectors: {
"&.ms-MessageBar--warning": {
backgroundColor: "var(--colorStatusWarningBackground1)",
border: "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
color: "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
color: "var(--colorNeutralForeground1)",
},
},
},
};
private initialIndexesColumns: IColumn[] = [ private initialIndexesColumns: IColumn[] = [
{ key: "definition", name: "Definition", fieldName: "definition", minWidth: 100, maxWidth: 200, isResizable: true }, { key: "definition", name: "Definition", fieldName: "definition", minWidth: 100, maxWidth: 200, isResizable: true },
{ key: "type", name: "Type", fieldName: "type", minWidth: 100, maxWidth: 200, isResizable: true }, { key: "type", name: "Type", fieldName: "type", minWidth: 100, maxWidth: 200, isResizable: true },
@@ -171,8 +190,8 @@ export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingP
let mongoIndexDisplayProps: MongoIndexDisplayProps; let mongoIndexDisplayProps: MongoIndexDisplayProps;
if (type) { if (type) {
mongoIndexDisplayProps = { mongoIndexDisplayProps = {
definition: <Text>{definition}</Text>, definition: <Text style={{ color: "var(--colorNeutralForeground1)" }}>{definition}</Text>,
type: <Text>{getMongoIndexTypeText(type)}</Text>, type: <Text style={{ color: "var(--colorNeutralForeground1)" }}>{getMongoIndexTypeText(type)}</Text>,
actionButton: definition === MongoIndexIdField ? <></> : this.getActionButton(arrayPosition, isCurrentIndex), actionButton: definition === MongoIndexIdField ? <></> : this.getActionButton(arrayPosition, isCurrentIndex),
}; };
} }
@@ -306,7 +325,15 @@ export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingP
indexTransformationProgress={this.props.indexTransformationProgress} indexTransformationProgress={this.props.indexTransformationProgress}
refreshIndexTransformationProgress={this.props.refreshIndexTransformationProgress} refreshIndexTransformationProgress={this.props.refreshIndexTransformationProgress}
/> />
{warningMessage && <MessageBar messageBarType={MessageBarType.warning}>{warningMessage}</MessageBar>} {warningMessage && (
<MessageBar
messageBarType={MessageBarType.warning}
messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }}
styles={this.darkThemeMessageBarStyles}
>
{warningMessage}
</MessageBar>
)}
</> </>
); );
}; };

View File

@@ -22,6 +22,14 @@ exports[`AddMongoIndexComponent renders 1`] = `
onChange={[Function]} onChange={[Function]}
styles={ styles={
{ {
"field": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
},
"fieldGroup": {
"backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": "var(--colorNeutralStroke1)",
},
"root": { "root": {
"paddingLeft": 10, "paddingLeft": 10,
"width": 210, "width": 210,
@@ -49,10 +57,52 @@ exports[`AddMongoIndexComponent renders 1`] = `
selectedKey="Single" selectedKey="Single"
styles={ styles={
{ {
"callout": {
"backgroundColor": "var(--colorNeutralBackground2)",
"border": "1px solid var(--colorNeutralStroke1)",
},
"caretDown": {
"color": "var(--colorNeutralForeground1)",
},
"dropdown": { "dropdown": {
"paddingleft": 10, "paddingLeft": 10,
"width": 202, "width": 202,
}, },
"dropdownItem": {
"backgroundColor": "transparent",
"color": "var(--colorNeutralForeground1)",
"selectors": {
"&:focus": {
"backgroundColor": "rgba(255, 255, 255, 0.1)",
"color": "var(--colorNeutralForeground1)",
},
"&:hover": {
"backgroundColor": "rgba(255, 255, 255, 0.1)",
"color": "var(--colorNeutralForeground1)",
},
},
},
"dropdownItemSelected": {
"backgroundColor": "rgba(255, 255, 255, 0.08)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
"&:hover": {
"backgroundColor": "rgba(255, 255, 255, 0.1)",
"color": "var(--colorNeutralForeground1)",
},
},
},
"dropdownItems": {
"backgroundColor": "var(--colorNeutralBackground2)",
},
"dropdownOptionText": {
"color": "var(--colorNeutralForeground1)",
},
"title": {
"backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": "var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground1)",
},
} }
} }
/> />

View File

@@ -1,7 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MongoIndexingPolicyComponent error shown for collection with compound indexes 1`] = ` exports[`MongoIndexingPolicyComponent error shown for collection with compound indexes 1`] = `
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Collections with compound indexes are not yet supported in the indexing editor. To modify indexing policy for this collection, use the Mongo Shell. Collections with compound indexes are not yet supported in the indexing editor. To modify indexing policy for this collection, use the Mongo Shell.
</Text> </Text>
`; `;
@@ -17,10 +23,21 @@ exports[`MongoIndexingPolicyComponent renders 1`] = `
<IndexingPolicyRefreshComponent <IndexingPolicyRefreshComponent
refreshIndexTransformationProgress={[Function]} refreshIndexTransformationProgress={[Function]}
/> />
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
For queries that filter on multiple properties, create multiple single field indexes instead of a compound index. For queries that filter on multiple properties, create multiple single field indexes instead of a compound index.
<StyledLinkBase <StyledLinkBase
href="https://docs.microsoft.com/azure/cosmos-db/mongodb-indexing#index-types" href="https://docs.microsoft.com/azure/cosmos-db/mongodb-indexing#index-types"
style={
{
"color": "var(--colorBrandForeground1)",
}
}
target="_blank" target="_blank"
> >
Compound indexes Compound indexes
@@ -83,9 +100,37 @@ exports[`MongoIndexingPolicyComponent renders 1`] = `
{ {
"root": { "root": {
"selectors": { "selectors": {
".ms-DetailsHeader": {
"backgroundColor": "var(--colorNeutralBackground1)",
},
".ms-DetailsHeader-cell": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
":hover": {
"backgroundColor": "var(--colorNeutralBackground1Hover)",
"color": "var(--colorNeutralForeground1)",
},
},
},
".ms-DetailsHeader-cellTitle": {
"color": "var(--colorNeutralForeground1)",
},
".ms-DetailsRow": {
"color": "var(--colorNeutralForeground1)",
},
".ms-DetailsRow-cell": {
"color": "var(--colorNeutralForeground1)",
},
".ms-DetailsRow-cell .ms-TooltipHost": {
"color": "var(--colorNeutralForeground1)",
},
".ms-FocusZone": { ".ms-FocusZone": {
"paddingTop": 0, "paddingTop": 0,
}, },
".ms-TooltipHost": {
"color": "var(--colorNeutralForeground1)",
},
}, },
}, },
} }

View File

@@ -1,6 +1,7 @@
import { import {
DefaultButton, DefaultButton,
FontWeights, FontWeights,
IMessageBarStyles,
Link, Link,
MessageBar, MessageBar,
MessageBarType, MessageBarType,
@@ -32,6 +33,23 @@ export interface PartitionKeyComponentProps {
isReadOnly?: boolean; // true: cannot change partition key isReadOnly?: boolean; // true: cannot change partition key
} }
const darkThemeMessageBarStyles: Partial<IMessageBarStyles> = {
root: {
selectors: {
"&.ms-MessageBar--warning": {
backgroundColor: "var(--colorStatusWarningBackground1)",
border: "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
color: "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
color: "var(--colorNeutralForeground1)",
},
},
},
};
export const PartitionKeyComponent: React.FC<PartitionKeyComponentProps> = ({ export const PartitionKeyComponent: React.FC<PartitionKeyComponentProps> = ({
database, database,
collection, collection,
@@ -66,13 +84,15 @@ export const PartitionKeyComponent: React.FC<PartitionKeyComponentProps> = ({
const partitionKeyValue = getPartitionKeyValue(); const partitionKeyValue = getPartitionKeyValue();
const textHeadingStyle = { const textHeadingStyle = {
root: { fontWeight: FontWeights.semibold, fontSize: 16 }, root: { fontWeight: FontWeights.semibold, fontSize: 16, color: "var(--colorNeutralForeground1)" },
}; };
const textSubHeadingStyle = { const textSubHeadingStyle = {
root: { fontWeight: FontWeights.semibold }, root: { fontWeight: FontWeights.semibold, color: "var(--colorNeutralForeground1)" },
};
const textSubHeadingStyle1 = {
root: { color: "var(--colorNeutralForeground1)" },
}; };
const startPollingforUpdate = (currentJob: DataTransferJobGetResults) => { const startPollingforUpdate = (currentJob: DataTransferJobGetResults) => {
if (isCurrentJobInProgress(currentJob)) { if (isCurrentJobInProgress(currentJob)) {
const jobName = currentJob?.properties?.jobName; const jobName = currentJob?.properties?.jobName;
@@ -167,32 +187,41 @@ export const PartitionKeyComponent: React.FC<PartitionKeyComponentProps> = ({
<Text styles={textSubHeadingStyle}>Current {partitionKeyName.toLowerCase()}</Text> <Text styles={textSubHeadingStyle}>Current {partitionKeyName.toLowerCase()}</Text>
<Text styles={textSubHeadingStyle}>Partitioning</Text> <Text styles={textSubHeadingStyle}>Partitioning</Text>
</Stack> </Stack>
<Stack tokens={{ childrenGap: 5 }}> <Stack tokens={{ childrenGap: 5 }} data-test="partition-key-values">
<Text>{partitionKeyValue}</Text> <Text styles={textSubHeadingStyle1}>{partitionKeyValue}</Text>
<Text>{isHierarchicalPartitionedContainer() ? "Hierarchical" : "Non-hierarchical"}</Text> <Text styles={textSubHeadingStyle1}>
{isHierarchicalPartitionedContainer() ? "Hierarchical" : "Non-hierarchical"}
</Text>
</Stack> </Stack>
</Stack> </Stack>
</Stack> </Stack>
{!isReadOnly && ( {!isReadOnly && (
<> <>
<MessageBar messageBarType={MessageBarType.warning}> <MessageBar
data-test="partition-key-warning"
messageBarType={MessageBarType.warning}
messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }}
styles={darkThemeMessageBarStyles}
>
To safeguard the integrity of the data being copied to the new container, ensure that no updates are made to To safeguard the integrity of the data being copied to the new container, ensure that no updates are made to
the source container for the entire duration of the partition key change process. the source container for the entire duration of the partition key change process.
<Link <Link
href="https://learn.microsoft.com/azure/cosmos-db/container-copy#how-does-container-copy-work" href="https://learn.microsoft.com/azure/cosmos-db/container-copy#how-does-container-copy-work"
target="_blank" target="_blank"
underline underline
style={{ color: "var(--colorBrandForeground1)" }}
> >
Learn more Learn more
</Link> </Link>
</MessageBar> </MessageBar>
<Text> <Text styles={{ root: { color: "var(--colorNeutralForeground1)" } }}>
To change the partition key, a new destination container must be created or an existing destination To change the partition key, a new destination container must be created or an existing destination
container selected. Data will then be copied to the destination container. container selected. Data will then be copied to the destination container.
</Text> </Text>
{configContext.platform !== Platform.Emulator && ( {configContext.platform !== Platform.Emulator && (
<PrimaryButton <PrimaryButton
data-test="change-partition-key-button"
styles={{ root: { width: "fit-content" } }} styles={{ root: { width: "fit-content" } }}
text="Change" text="Change"
onClick={startPartitionkeyChangeWorkflow} onClick={startPartitionkeyChangeWorkflow}

View File

@@ -1,4 +1,15 @@
import { ChoiceGroup, IChoiceGroupOption, Label, Link, MessageBar, Stack, Text, TextField } from "@fluentui/react"; import {
ChoiceGroup,
IChoiceGroupOption,
Label,
Link,
MessageBar,
Stack,
Text,
TextField,
TooltipHost,
mergeStyleSets,
} from "@fluentui/react";
import * as React from "react"; import * as React from "react";
import * as ViewModels from "../../../../Contracts/ViewModels"; import * as ViewModels from "../../../../Contracts/ViewModels";
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
@@ -25,6 +36,11 @@ import {
} from "../SettingsUtils"; } from "../SettingsUtils";
import { ToolTipLabelComponent } from "./ToolTipLabelComponent"; import { ToolTipLabelComponent } from "./ToolTipLabelComponent";
const classNames = mergeStyleSets({
hintText: {
color: "var(--colorNeutralForeground1)", // theme-aware
},
});
export interface SubSettingsComponentProps { export interface SubSettingsComponentProps {
collection: ViewModels.Collection; collection: ViewModels.Collection;
timeToLive: TtlType; timeToLive: TtlType;
@@ -185,13 +201,31 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
userContext.apiType === "Mongo" ? ( userContext.apiType === "Mongo" ? (
<MessageBar <MessageBar
messageBarIconProps={{ iconName: "InfoSolid", className: "messageBarInfoIcon" }} messageBarIconProps={{ iconName: "InfoSolid", className: "messageBarInfoIcon" }}
styles={{ text: { fontSize: 14 } }} styles={{
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
text: {
fontSize: 14,
color: "var(--colorNeutralForeground1)",
},
icon: {
color: "var(--colorNeutralForeground1)",
},
}}
> >
To enable time-to-live (TTL) for your collection/documents, <Text style={{ color: "var(--colorNeutralForeground1)" }}>
<Link href="https://docs.microsoft.com/en-us/azure/cosmos-db/mongodb-time-to-live" target="_blank"> To enable time-to-live (TTL) for your collection/documents,{" "}
create a TTL index <Link
</Link> href="https://docs.microsoft.com/en-us/azure/cosmos-db/mongodb-time-to-live"
. target="_blank"
style={{ color: "var(--colorBrandForeground1)" }}
>
create a TTL index
</Link>
.
</Text>
</MessageBar> </MessageBar>
) : ( ) : (
<Stack {...titleAndInputStackProps}> <Stack {...titleAndInputStackProps}>
@@ -319,23 +353,34 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
private getPartitionKeyComponent = (): JSX.Element => ( private getPartitionKeyComponent = (): JSX.Element => (
<Stack {...titleAndInputStackProps}> <Stack {...titleAndInputStackProps}>
{this.getPartitionKeyVisible() && ( {this.getPartitionKeyVisible() && (
<TextField <TooltipHost
label={this.partitionKeyName} content={`This ${this.partitionKeyName.toLowerCase()} is used to distribute data across multiple partitions for scalability. The value "${
disabled this.partitionKeyValue
styles={getTextFieldStyles(undefined, undefined)} }" determines how documents are partitioned.`}
defaultValue={this.partitionKeyValue} styles={{
/> root: {
display: "block",
},
}}
>
<TextField
label={this.partitionKeyName}
disabled
styles={getTextFieldStyles(undefined, undefined)}
defaultValue={this.partitionKeyValue}
/>
</TooltipHost>
)} )}
{userContext.apiType === "SQL" && this.isLargePartitionKeyEnabled() && ( {userContext.apiType === "SQL" && this.isLargePartitionKeyEnabled() && (
<Text>Large {this.partitionKeyName.toLowerCase()} has been enabled.</Text> <Text className={classNames.hintText}>Large {this.partitionKeyName.toLowerCase()} has been enabled.</Text>
)} )}
{userContext.apiType === "SQL" && {userContext.apiType === "SQL" &&
(this.isHierarchicalPartitionedContainer() ? ( (this.isHierarchicalPartitionedContainer() ? (
<Text>Hierarchically partitioned container.</Text> <Text className={classNames.hintText}>Hierarchically partitioned container.</Text>
) : ( ) : (
<Text>Non-hierarchically partitioned container.</Text> <Text className={classNames.hintText}>Non-hierarchically partitioned container.</Text>
))} ))}
</Stack> </Stack>
); );

View File

@@ -65,7 +65,7 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
return ( return (
<Stack tokens={{ childrenGap: "m" }} styles={{ root: { width: "70%", maxWidth: 700 } }}> <Stack tokens={{ childrenGap: "m" }} styles={{ root: { width: "70%", maxWidth: 700 } }}>
<Label>Throughput Buckets</Label> <Label styles={{ root: { color: "var(--colorNeutralForeground1)" } }}>Throughput Buckets</Label>
<Stack> <Stack>
{throughputBuckets?.map((bucket) => ( {throughputBuckets?.map((bucket) => (
<Stack key={bucket.id} horizontal tokens={{ childrenGap: 8 }} verticalAlign="center"> <Stack key={bucket.id} horizontal tokens={{ childrenGap: 8 }} verticalAlign="center">
@@ -77,7 +77,15 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
onChange={(newValue) => handleBucketChange(bucket.id, newValue)} onChange={(newValue) => handleBucketChange(bucket.id, newValue)}
showValue={false} showValue={false}
label={`Bucket ${bucket.id}${bucket.id === 1 ? " (Data Explorer Query Bucket)" : ""}`} label={`Bucket ${bucket.id}${bucket.id === 1 ? " (Data Explorer Query Bucket)" : ""}`}
styles={{ root: { flex: 2, maxWidth: 400 } }} styles={{
root: { flex: 2, maxWidth: 400 },
titleLabel: {
color:
bucket.maxThroughputPercentage === 100
? "var(--colorNeutralForeground4)"
: "var(--colorNeutralForeground1)",
},
}}
disabled={bucket.maxThroughputPercentage === 100} disabled={bucket.maxThroughputPercentage === 100}
/> />
<TextField <TextField
@@ -95,7 +103,10 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
offText="Inactive" offText="Inactive"
checked={bucket.maxThroughputPercentage !== 100} checked={bucket.maxThroughputPercentage !== 100}
onChange={(event, checked) => onToggle(bucket.id, checked)} onChange={(event, checked) => onToggle(bucket.id, checked)}
styles={{ root: { marginBottom: 0 }, text: { fontSize: 12 } }} styles={{
root: { marginBottom: 0 },
text: { fontSize: 12, color: "var(--colorNeutralForeground1)" },
}}
></Toggle> ></Toggle>
</Stack> </Stack>
))} ))}

View File

@@ -3,6 +3,7 @@ import {
ChoiceGroup, ChoiceGroup,
FontIcon, FontIcon,
IChoiceGroupOption, IChoiceGroupOption,
IMessageBarStyles,
IProgressIndicatorStyles, IProgressIndicatorStyles,
ISeparatorStyles, ISeparatorStyles,
Label, Label,
@@ -37,7 +38,6 @@ import {
getUpdateThroughputBeyondInstantLimitMessage, getUpdateThroughputBeyondInstantLimitMessage,
getUpdateThroughputBeyondSupportLimitMessage, getUpdateThroughputBeyondSupportLimitMessage,
manualToAutoscaleDisclaimerElement, manualToAutoscaleDisclaimerElement,
messageBarStyles,
noLeftPaddingCheckBoxStyle, noLeftPaddingCheckBoxStyle,
relaxedSpacingStackProps, relaxedSpacingStackProps,
saveThroughputWarningMessage, saveThroughputWarningMessage,
@@ -101,6 +101,13 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{ key: "false", text: "Manual" }, { key: "false", text: "Manual" },
]; ];
// Style constants for theme-aware colors and layout
private static readonly TEXT_COLOR_PRIMARY = "var(--colorNeutralForeground1)";
private static readonly TEXT_COLOR_SECONDARY = "var(--colorNeutralForeground2)";
private static readonly TEXT_WIDTH_50 = "50%";
private static readonly TEXT_WIDTH_33 = "33%";
private static readonly LOCALE_EN_US = "en-US";
componentDidMount(): void { componentDidMount(): void {
this.onComponentUpdate(); this.onComponentUpdate();
} }
@@ -236,12 +243,24 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
); );
return ( return (
<div> <div>
<Text style={{ fontWeight: 600 }}>Updated cost per month</Text> <Text style={{ fontWeight: 600, color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY }}>
Updated cost per month
</Text>
<Stack horizontal style={{ marginTop: 5, marginBottom: 10 }}> <Stack horizontal style={{ marginTop: 5, marginBottom: 10 }}>
<Text style={{ width: "50%" }}> <Text
style={{
width: ThroughputInputAutoPilotV3Component.TEXT_WIDTH_50,
color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY,
}}
>
{newPrices.currencySign} {calculateEstimateNumber(newPrices.monthlyPrice / 10)} min {newPrices.currencySign} {calculateEstimateNumber(newPrices.monthlyPrice / 10)} min
</Text> </Text>
<Text style={{ width: "50%" }}> <Text
style={{
width: ThroughputInputAutoPilotV3Component.TEXT_WIDTH_50,
color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY,
}}
>
{newPrices.currencySign} {calculateEstimateNumber(newPrices.monthlyPrice)} max {newPrices.currencySign} {calculateEstimateNumber(newPrices.monthlyPrice)} max
</Text> </Text>
</Stack> </Stack>
@@ -254,12 +273,24 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
return ( return (
<Stack {...checkBoxAndInputStackProps} style={{ marginTop: 15 }}> <Stack {...checkBoxAndInputStackProps} style={{ marginTop: 15 }}>
{newThroughput && newThroughputCostElement()} {newThroughput && newThroughputCostElement()}
<Text style={{ fontWeight: 600 }}>Current cost per month</Text> <Text style={{ fontWeight: 600, color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY }}>
<Stack horizontal style={{ marginTop: 5 }}> Current cost per month
<Text style={{ width: "50%" }}> </Text>
<Stack horizontal style={{ marginTop: 5, color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY }}>
<Text
style={{
width: ThroughputInputAutoPilotV3Component.TEXT_WIDTH_50,
color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY,
}}
>
{prices.currencySign} {calculateEstimateNumber(prices.monthlyPrice / 10)} min {prices.currencySign} {calculateEstimateNumber(prices.monthlyPrice / 10)} min
</Text> </Text>
<Text style={{ width: "50%" }}> <Text
style={{
width: ThroughputInputAutoPilotV3Component.TEXT_WIDTH_50,
color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY,
}}
>
{prices.currencySign} {calculateEstimateNumber(prices.monthlyPrice)} max {prices.currencySign} {calculateEstimateNumber(prices.monthlyPrice)} max
</Text> </Text>
</Stack> </Stack>
@@ -269,7 +300,12 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
return getEstimatedSpendingElement(costElement(), newThroughput ?? throughput, numberOfRegions, prices, true); return getEstimatedSpendingElement(costElement(), newThroughput ?? throughput, numberOfRegions, prices, true);
}; };
settingsAndScaleStyle = {
root: {
width: ThroughputInputAutoPilotV3Component.TEXT_WIDTH_33,
color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY,
},
};
private getEstimatedManualSpendElement = ( private getEstimatedManualSpendElement = (
throughput: number, throughput: number,
serverId: string, serverId: string,
@@ -289,15 +325,17 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
); );
return ( return (
<div> <div>
<Text style={{ fontWeight: 600 }}>Updated cost per month</Text> <Text style={{ fontWeight: 600, color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY }}>
Updated cost per month
</Text>
<Stack horizontal style={{ marginTop: 5, marginBottom: 10 }}> <Stack horizontal style={{ marginTop: 5, marginBottom: 10 }}>
<Text style={{ width: "33%" }}> <Text style={this.settingsAndScaleStyle.root}>
{newPrices.currencySign} {calculateEstimateNumber(newPrices.hourlyPrice)}/hr {newPrices.currencySign} {calculateEstimateNumber(newPrices.hourlyPrice)}/hr
</Text> </Text>
<Text style={{ width: "33%" }}> <Text style={this.settingsAndScaleStyle.root}>
{newPrices.currencySign} {calculateEstimateNumber(newPrices.dailyPrice)}/day {newPrices.currencySign} {calculateEstimateNumber(newPrices.dailyPrice)}/day
</Text> </Text>
<Text style={{ width: "33%" }}> <Text style={this.settingsAndScaleStyle.root}>
{newPrices.currencySign} {calculateEstimateNumber(newPrices.monthlyPrice)}/mo {newPrices.currencySign} {calculateEstimateNumber(newPrices.monthlyPrice)}/mo
</Text> </Text>
</Stack> </Stack>
@@ -310,15 +348,17 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
return ( return (
<Stack {...checkBoxAndInputStackProps} style={{ marginTop: 15 }}> <Stack {...checkBoxAndInputStackProps} style={{ marginTop: 15 }}>
{newThroughput && newThroughputCostElement()} {newThroughput && newThroughputCostElement()}
<Text style={{ fontWeight: 600 }}>Current cost per month</Text> <Text style={{ fontWeight: 600, color: ThroughputInputAutoPilotV3Component.TEXT_COLOR_PRIMARY }}>
Current cost per month
</Text>
<Stack horizontal style={{ marginTop: 5 }}> <Stack horizontal style={{ marginTop: 5 }}>
<Text style={{ width: "33%" }}> <Text style={this.settingsAndScaleStyle.root}>
{prices.currencySign} {calculateEstimateNumber(prices.hourlyPrice)}/hr {prices.currencySign} {calculateEstimateNumber(prices.hourlyPrice)}/hr
</Text> </Text>
<Text style={{ width: "33%" }}> <Text style={this.settingsAndScaleStyle.root}>
{prices.currencySign} {calculateEstimateNumber(prices.dailyPrice)}/day {prices.currencySign} {calculateEstimateNumber(prices.dailyPrice)}/day
</Text> </Text>
<Text style={{ width: "33%" }}> <Text style={this.settingsAndScaleStyle.root}>
{prices.currencySign} {calculateEstimateNumber(prices.monthlyPrice)}/mo {prices.currencySign} {calculateEstimateNumber(prices.monthlyPrice)}/mo
</Text> </Text>
</Stack> </Stack>
@@ -381,7 +421,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{this.overrideWithProvisionedThroughputSettings() && ( {this.overrideWithProvisionedThroughputSettings() && (
<MessageBar <MessageBar
messageBarIconProps={{ iconName: "InfoSolid", className: "messageBarInfoIcon" }} messageBarIconProps={{ iconName: "InfoSolid", className: "messageBarInfoIcon" }}
styles={messageBarStyles} styles={this.darkThemeMessageBarStyles}
> >
{manualToAutoscaleDisclaimerElement} {manualToAutoscaleDisclaimerElement}
</MessageBar> </MessageBar>
@@ -407,8 +447,8 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
const capacity: string = this.props.isFixed ? "Fixed" : "Unlimited"; const capacity: string = this.props.isFixed ? "Fixed" : "Unlimited";
return ( return (
<Stack {...titleAndInputStackProps}> <Stack {...titleAndInputStackProps}>
<Label>Storage capacity</Label> <Label style={{ color: "var(--colorNeutralForeground1)" }}>Storage capacity</Label>
<Text>{capacity}</Text> <Text style={{ color: "var(--colorNeutralForeground1)" }}>{capacity}</Text>
</Stack> </Stack>
); );
}; };
@@ -418,7 +458,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{ {
selectors: { selectors: {
"::before": { "::before": {
backgroundColor: "rgb(200, 200, 200)", backgroundColor: "var(--colorNeutralStroke2)",
height: "3px", height: "3px",
marginTop: "-1px", marginTop: "-1px",
}, },
@@ -457,10 +497,10 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{ {
backgroundColor: backgroundColor:
this.getCurrentRuRange() === "instant" this.getCurrentRuRange() === "instant"
? "rgb(0, 120, 212)" ? "var(--colorBrandBackground)"
: this.getCurrentRuRange() === "delayed" : this.getCurrentRuRange() === "delayed"
? "rgb(255 216 109)" ? "var(--colorStatusWarningBackground1)"
: "rgb(251, 217, 203)", : "var(--colorStatusDangerBackground1)",
}, },
], ],
}); });
@@ -497,14 +537,17 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
<Stack> <Stack>
<Stack horizontal> <Stack horizontal>
<Stack.Item style={{ width: "34%" }}> <Stack.Item style={{ width: "34%" }}>
<span>{this.props.minimum.toLocaleString()}</span> <span>{this.props.minimum.toLocaleString(ThroughputInputAutoPilotV3Component.LOCALE_EN_US)}</span>
</Stack.Item> </Stack.Item>
<Stack.Item style={{ width: "66%" }}> <Stack.Item style={{ width: "66%" }}>
<span style={{ float: "left", transform: "translateX(-50%)" }}> <span style={{ float: "left", transform: "translateX(-50%)" }}>
{this.props.instantMaximumThroughput.toLocaleString()} {this.props.instantMaximumThroughput.toLocaleString(ThroughputInputAutoPilotV3Component.LOCALE_EN_US)}
</span>
<span style={{ float: "right" }}>
{this.props.softAllowedMaximumThroughput.toLocaleString(ThroughputInputAutoPilotV3Component.LOCALE_EN_US)}
</span> </span>
<span style={{ float: "right" }} data-test="soft-allowed-maximum-throughput"> <span style={{ float: "right" }} data-test="soft-allowed-maximum-throughput">
{this.props.softAllowedMaximumThroughput.toLocaleString()} {this.props.softAllowedMaximumThroughput.toLocaleString(ThroughputInputAutoPilotV3Component.LOCALE_EN_US)}
</span> </span>
</Stack.Item> </Stack.Item>
</Stack> </Stack>
@@ -547,12 +590,41 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
} }
}; };
private darkThemeMessageBarStyles: Partial<IMessageBarStyles> = {
root: {
marginTop: "5px",
selectors: {
"&.ms-MessageBar--severeWarning": {
backgroundColor: "var(--colorStatusDangerBackground1)",
border: "1px solid var(--colorStatusDangerBorder1)",
},
"&.ms-MessageBar--warning": {
backgroundColor: "var(--colorStatusWarningBackground1)",
border: "1px solid var(--colorStatusWarningBorder1)",
},
"&.ms-MessageBar--info": {
backgroundColor: "var(--colorNeutralBackground3)",
border: "1px solid var(--colorNeutralStroke1)",
},
".ms-MessageBar-icon": {
color: "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
color: "var(--colorNeutralForeground1)",
},
},
},
};
private getThroughputWarningMessageBar = (): JSX.Element => { private getThroughputWarningMessageBar = (): JSX.Element => {
const isSevereWarning: boolean = const isSevereWarning: boolean =
this.currentThroughputValue() > this.props.softAllowedMaximumThroughput || this.currentThroughputValue() > this.props.softAllowedMaximumThroughput ||
this.currentThroughputValue() < this.props.minimum; this.currentThroughputValue() < this.props.minimum;
return ( return (
<MessageBar messageBarType={isSevereWarning ? MessageBarType.severeWarning : MessageBarType.warning}> <MessageBar
messageBarType={isSevereWarning ? MessageBarType.severeWarning : MessageBarType.warning}
styles={this.darkThemeMessageBarStyles}
>
{this.getThroughputWarningMessageText()} {this.getThroughputWarningMessageText()}
</MessageBar> </MessageBar>
); );
@@ -565,10 +637,13 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{/* Column 1: Minimum RU/s */} {/* Column 1: Minimum RU/s */}
<Stack tokens={{ childrenGap: 4 }}> <Stack tokens={{ childrenGap: 4 }}>
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}> <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}> <Text
variant="small"
style={{ lineHeight: "20px", fontWeight: 600, color: "var(--colorNeutralForeground1)" }}
>
Minimum RU/s Minimum RU/s
</Text> </Text>
<FontIcon iconName="Info" style={{ fontSize: 12, color: "#666" }} /> <FontIcon iconName="Info" style={{ fontSize: 12, color: "var(--colorNeutralForeground2)" }} />
</Stack> </Stack>
<Text <Text
style={{ style={{
@@ -583,6 +658,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
boxSizing: "border-box", boxSizing: "border-box",
color: "var(--colorNeutralForeground1)",
}} }}
> >
{AutoPilotUtils.getMinRUsBasedOnUserInput(this.props.maxAutoPilotThroughput)} {AutoPilotUtils.getMinRUsBasedOnUserInput(this.props.maxAutoPilotThroughput)}
@@ -596,6 +672,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
fontSize: 12, fontSize: 12,
fontWeight: 400, fontWeight: 400,
paddingBottom: 6, paddingBottom: 6,
color: "var(--colorNeutralForeground1)",
}} }}
> >
x 10 = x 10 =
@@ -604,10 +681,13 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{/* Column 3: Maximum RU/s */} {/* Column 3: Maximum RU/s */}
<Stack tokens={{ childrenGap: 4 }}> <Stack tokens={{ childrenGap: 4 }}>
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}> <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}> <Text
variant="small"
style={{ lineHeight: "20px", fontWeight: 600, color: "var(--colorNeutralForeground1)" }}
>
Maximum RU/s Maximum RU/s
</Text> </Text>
<FontIcon iconName="Info" style={{ fontSize: 12, color: "#666" }} /> <FontIcon iconName="Info" style={{ fontSize: 12, color: "var(--colorNeutralForeground2)" }} />
</Stack> </Stack>
<TextField <TextField
required required
@@ -616,8 +696,25 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
key="auto pilot throughput input" key="auto pilot throughput input"
styles={{ styles={{
...getTextFieldStyles(this.props.maxAutoPilotThroughput, this.props.maxAutoPilotThroughputBaseline), ...getTextFieldStyles(this.props.maxAutoPilotThroughput, this.props.maxAutoPilotThroughputBaseline),
fieldGroup: { width: 100, height: 28 }, fieldGroup: {
field: { fontSize: 14, fontWeight: 400 }, width: 100,
height: 28,
backgroundColor: "var(--colorNeutralBackground4)",
},
field: {
fontSize: 14,
fontWeight: 400,
color: "var(--colorNeutralForeground1)",
backgroundColor: "var(--colorNeutralBackground4)",
},
root: {
selectors: {
input: {
backgroundColor: "var(--colorNeutralBackground4)",
color: "var(--colorNeutralForeground1)",
},
},
},
}} }}
disabled={this.overrideWithProvisionedThroughputSettings()} disabled={this.overrideWithProvisionedThroughputSettings()}
step={AutoPilotUtils.autoPilotIncrementStep} step={AutoPilotUtils.autoPilotIncrementStep}
@@ -674,7 +771,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
</Stack> </Stack>
)} )}
{this.props.isAutoPilotSelected ? ( {this.props.isAutoPilotSelected ? (
<Text style={{ marginTop: "40px" }}> <Text style={{ marginTop: "40px", color: "var(--colorNeutralForeground1)" }}>
Based on usage, your {this.props.collectionName ? "container" : "database"} throughput will scale from{" "} Based on usage, your {this.props.collectionName ? "container" : "database"} throughput will scale from{" "}
<b> <b>
{AutoPilotUtils.getMinRUsBasedOnUserInput(this.props.maxAutoPilotThroughput)} RU/s (10% of max RU/s) -{" "} {AutoPilotUtils.getMinRUsBasedOnUserInput(this.props.maxAutoPilotThroughput)} RU/s (10% of max RU/s) -{" "}
@@ -687,7 +784,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{this.state.exceedFreeTierThroughput && ( {this.state.exceedFreeTierThroughput && (
<MessageBar <MessageBar
messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }} messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }}
styles={messageBarStyles} styles={this.darkThemeMessageBarStyles}
style={{ marginTop: "40px" }} style={{ marginTop: "40px" }}
> >
{`Billing will apply if you provision more than ${SharedConstants.FreeTierLimits.RU} RU/s of manual throughput, or if the resource scales beyond ${SharedConstants.FreeTierLimits.RU} RU/s with autoscale.`} {`Billing will apply if you provision more than ${SharedConstants.FreeTierLimits.RU} RU/s of manual throughput, or if the resource scales beyond ${SharedConstants.FreeTierLimits.RU} RU/s with autoscale.`}
@@ -696,7 +793,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
</> </>
)} )}
{!this.overrideWithProvisionedThroughputSettings() && ( {!this.overrideWithProvisionedThroughputSettings() && (
<Text> <Text style={{ color: "var(--colorNeutralForeground1)" }}>
Estimate your required RU/s with Estimate your required RU/s with
<Link target="_blank" href="https://cosmos.azure.com/capacitycalculator/"> <Link target="_blank" href="https://cosmos.azure.com/capacitycalculator/">
{` capacity calculator`} <FontIcon iconName="NavigateExternalInline" /> {` capacity calculator`} <FontIcon iconName="NavigateExternalInline" />
@@ -737,6 +834,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
{warningMessage && ( {warningMessage && (
<MessageBar <MessageBar
messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }} messageBarIconProps={{ iconName: "WarningSolid", className: "messageBarWarningIcon" }}
styles={this.darkThemeMessageBarStyles}
role="alert" role="alert"
> >
{warningMessage} {warningMessage}

View File

@@ -16,17 +16,35 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
} }
} }
role="alert" role="alert"
> styles={
<Text {
styles={ "root": {
{ "marginTop": "5px",
"root": { "selectors": {
"color": "windowtext", "&.ms-MessageBar--info": {
"fontSize": 14, "backgroundColor": "var(--colorNeutralBackground3)",
"border": "1px solid var(--colorNeutralStroke1)",
},
"&.ms-MessageBar--severeWarning": {
"backgroundColor": "var(--colorStatusDangerBackground1)",
"border": "1px solid var(--colorStatusDangerBorder1)",
},
"&.ms-MessageBar--warning": {
"backgroundColor": "var(--colorStatusWarningBackground1)",
"border": "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
"color": "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
"color": "var(--colorNeutralForeground1)",
},
}, },
} },
} }
> }
>
<Text>
Your bill will be affected as you update your throughput settings. Please review the updated cost estimate below before saving your changes Your bill will be affected as you update your throughput settings. Please review the updated cost estimate below before saving your changes
</Text> </Text>
</StyledMessageBar> </StyledMessageBar>
@@ -41,7 +59,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -62,11 +80,27 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
styles={ styles={
{ {
"root": { "root": {
"backgroundColor": "white",
"marginTop": "5px", "marginTop": "5px",
}, "selectors": {
"text": { "&.ms-MessageBar--info": {
"fontSize": 14, "backgroundColor": "var(--colorNeutralBackground3)",
"border": "1px solid var(--colorNeutralStroke1)",
},
"&.ms-MessageBar--severeWarning": {
"backgroundColor": "var(--colorStatusDangerBackground1)",
"border": "1px solid var(--colorStatusDangerBorder1)",
},
"&.ms-MessageBar--warning": {
"backgroundColor": "var(--colorStatusWarningBackground1)",
"border": "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
"color": "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
"color": "var(--colorNeutralForeground1)",
},
},
}, },
} }
} }
@@ -76,7 +110,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -121,15 +155,47 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
".ms-ChoiceField-field.is-checked::before": { ".ms-ChoiceField-field.is-checked::before": {
"borderColor": undefined, "borderColor": undefined,
}, },
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-wrapper label": { ".ms-ChoiceField-wrapper label": {
"color": "var(--colorNeutralForeground1)",
"fontFamily": undefined, "fontFamily": undefined,
"fontSize": 14, "fontSize": 14,
"padding": "2px 5px", "padding": "2px 5px",
"whiteSpace": "nowrap", "whiteSpace": "nowrap",
}, },
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel:hover": {
"color": "var(--colorNeutralForeground1)",
},
}, },
}, },
], ],
"label": {
"color": "var(--colorNeutralForeground1)",
},
"root": {
"selectors": {
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
},
},
} }
} }
/> />
@@ -185,6 +251,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -197,7 +264,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
iconName="Info" iconName="Info"
style={ style={
{ {
"color": "#666", "color": "var(--colorNeutralForeground2)",
"fontSize": 12, "fontSize": 12,
} }
} }
@@ -210,6 +277,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
"backgroundColor": "transparent", "backgroundColor": "transparent",
"border": "none", "border": "none",
"boxSizing": "border-box", "boxSizing": "border-box",
"color": "var(--colorNeutralForeground1)",
"display": "flex", "display": "flex",
"fontFamily": "Segoe UI", "fontFamily": "Segoe UI",
"fontSize": 14, "fontSize": 14,
@@ -226,6 +294,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontFamily": "Segoe UI", "fontFamily": "Segoe UI",
"fontSize": 12, "fontSize": 12,
"fontWeight": 400, "fontWeight": 400,
@@ -254,6 +323,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -266,7 +336,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
iconName="Info" iconName="Info"
style={ style={
{ {
"color": "#666", "color": "var(--colorNeutralForeground2)",
"fontSize": 12, "fontSize": 12,
} }
} }
@@ -285,13 +355,36 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
styles={ styles={
{ {
"field": { "field": {
"backgroundColor": "var(--colorNeutralBackground4)",
"color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
"fontWeight": 400, "fontWeight": 400,
}, },
"fieldGroup": { "fieldGroup": {
"backgroundColor": "var(--colorNeutralBackground4)",
"height": 28, "height": 28,
"width": 100, "width": 100,
}, },
"root": {
"selectors": {
"input": {
"backgroundColor": "var(--colorNeutralBackground4)",
"color": "var(--colorNeutralForeground1)",
},
},
},
"subComponentStyles": {
"label": {
"root": {
"color": "var(--colorNeutralForeground1)",
},
},
},
"suffix": {
"backgroundColor": "var(--colorNeutralBackground2)",
"border": "1px solid var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground1)",
},
} }
} }
type="number" type="number"
@@ -333,6 +426,15 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
> >
5,000 5,000
</span> </span>
<span
style={
{
"float": "right",
}
}
>
1,000,000
</span>
<span <span
data-test="soft-allowed-maximum-throughput" data-test="soft-allowed-maximum-throughput"
style={ style={
@@ -352,7 +454,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
{ {
"progressBar": [ "progressBar": [
{ {
"backgroundColor": "rgb(251, 217, 203)", "backgroundColor": "var(--colorStatusDangerBackground1)",
}, },
], ],
} }
@@ -376,7 +478,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
{ {
"selectors": { "selectors": {
"::before": { "::before": {
"backgroundColor": "rgb(200, 200, 200)", "backgroundColor": "var(--colorNeutralStroke2)",
"height": "3px", "height": "3px",
"marginTop": "-1px", "marginTop": "-1px",
}, },
@@ -404,7 +506,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
{ {
"selectors": { "selectors": {
"::before": { "::before": {
"backgroundColor": "rgb(200, 200, 200)", "backgroundColor": "var(--colorNeutralStroke2)",
"height": "3px", "height": "3px",
"marginTop": "-1px", "marginTop": "-1px",
}, },
@@ -421,12 +523,39 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
</Stack> </Stack>
<StyledMessageBar <StyledMessageBar
messageBarType={3} messageBarType={3}
styles={
{
"root": {
"marginTop": "5px",
"selectors": {
"&.ms-MessageBar--info": {
"backgroundColor": "var(--colorNeutralBackground3)",
"border": "1px solid var(--colorNeutralStroke1)",
},
"&.ms-MessageBar--severeWarning": {
"backgroundColor": "var(--colorStatusDangerBackground1)",
"border": "1px solid var(--colorStatusDangerBorder1)",
},
"&.ms-MessageBar--warning": {
"backgroundColor": "var(--colorStatusWarningBackground1)",
"border": "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
"color": "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
"color": "var(--colorNeutralForeground1)",
},
},
},
}
}
> >
<Text <Text
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -447,6 +576,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"marginTop": "40px", "marginTop": "40px",
} }
} }
@@ -478,10 +608,22 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
} }
} }
> >
<StyledLabelBase> <StyledLabelBase
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Storage capacity Storage capacity
</StyledLabelBase> </StyledLabelBase>
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Unlimited Unlimited
</Text> </Text>
</Stack> </Stack>
@@ -500,6 +642,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -522,6 +665,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -540,6 +684,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "50%", "width": "50%",
} }
} }
@@ -552,6 +697,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "50%", "width": "50%",
} }
} }
@@ -566,6 +712,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -576,6 +723,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
horizontal={true} horizontal={true}
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"marginTop": 5, "marginTop": 5,
} }
} }
@@ -583,6 +731,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "50%", "width": "50%",
} }
} }
@@ -595,6 +744,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "50%", "width": "50%",
} }
} }
@@ -609,6 +759,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"marginTop": 15, "marginTop": 15,
} }
@@ -642,6 +793,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"marginTop": 15, "marginTop": 15,
} }
} }
@@ -676,7 +828,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -717,15 +869,47 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
".ms-ChoiceField-field.is-checked::before": { ".ms-ChoiceField-field.is-checked::before": {
"borderColor": "", "borderColor": "",
}, },
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-wrapper label": { ".ms-ChoiceField-wrapper label": {
"color": "var(--colorNeutralForeground1)",
"fontFamily": undefined, "fontFamily": undefined,
"fontSize": 14, "fontSize": 14,
"padding": "2px 5px", "padding": "2px 5px",
"whiteSpace": "nowrap", "whiteSpace": "nowrap",
}, },
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel:hover": {
"color": "var(--colorNeutralForeground1)",
},
}, },
}, },
], ],
"label": {
"color": "var(--colorNeutralForeground1)",
},
"root": {
"selectors": {
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
},
},
} }
} }
/> />
@@ -765,17 +949,53 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
step={100} step={100}
styles={ styles={
{ {
"field": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
":disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
},
},
},
"fieldGroup": { "fieldGroup": {
"borderColor": "", "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": "var(--colorNeutralStroke1)",
"height": 25, "height": 25,
"selectors": { "selectors": {
":disabled": { ":disabled": {
"backgroundColor": undefined, "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": undefined, "borderColor": "var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground2)",
},
"input": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
},
"input#autopilotInput": {
"backgroundColor": "var(--colorNeutralBackground4)",
"color": "var(--colorNeutralForeground1)",
},
"input:disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
}, },
}, },
"width": 300, "width": 300,
}, },
"subComponentStyles": {
"label": {
"root": {
"color": "var(--colorNeutralForeground1)",
},
},
},
"suffix": {
"backgroundColor": "var(--colorNeutralBackground2)",
"border": "1px solid var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground1)",
},
} }
} }
type="number" type="number"
@@ -814,6 +1034,15 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
> >
5,000 5,000
</span> </span>
<span
style={
{
"float": "right",
}
}
>
1,000,000
</span>
<span <span
data-test="soft-allowed-maximum-throughput" data-test="soft-allowed-maximum-throughput"
style={ style={
@@ -833,7 +1062,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
{ {
"progressBar": [ "progressBar": [
{ {
"backgroundColor": "rgb(251, 217, 203)", "backgroundColor": "var(--colorStatusDangerBackground1)",
}, },
], ],
} }
@@ -857,7 +1086,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
{ {
"selectors": { "selectors": {
"::before": { "::before": {
"backgroundColor": "rgb(200, 200, 200)", "backgroundColor": "var(--colorNeutralStroke2)",
"height": "3px", "height": "3px",
"marginTop": "-1px", "marginTop": "-1px",
}, },
@@ -885,7 +1114,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
{ {
"selectors": { "selectors": {
"::before": { "::before": {
"backgroundColor": "rgb(200, 200, 200)", "backgroundColor": "var(--colorNeutralStroke2)",
"height": "3px", "height": "3px",
"marginTop": "-1px", "marginTop": "-1px",
}, },
@@ -902,12 +1131,39 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
</Stack> </Stack>
<StyledMessageBar <StyledMessageBar
messageBarType={3} messageBarType={3}
styles={
{
"root": {
"marginTop": "5px",
"selectors": {
"&.ms-MessageBar--info": {
"backgroundColor": "var(--colorNeutralBackground3)",
"border": "1px solid var(--colorNeutralStroke1)",
},
"&.ms-MessageBar--severeWarning": {
"backgroundColor": "var(--colorStatusDangerBackground1)",
"border": "1px solid var(--colorStatusDangerBorder1)",
},
"&.ms-MessageBar--warning": {
"backgroundColor": "var(--colorStatusWarningBackground1)",
"border": "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
"color": "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
"color": "var(--colorNeutralForeground1)",
},
},
},
}
}
> >
<Text <Text
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -925,7 +1181,13 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
</Text> </Text>
</StyledMessageBar> </StyledMessageBar>
</Stack> </Stack>
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Estimate your required RU/s with Estimate your required RU/s with
<StyledLinkBase <StyledLinkBase
href="https://cosmos.azure.com/capacitycalculator/" href="https://cosmos.azure.com/capacitycalculator/"
@@ -969,10 +1231,22 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
} }
} }
> >
<StyledLabelBase> <StyledLabelBase
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Storage capacity Storage capacity
</StyledLabelBase> </StyledLabelBase>
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Unlimited Unlimited
</Text> </Text>
</Stack> </Stack>
@@ -991,6 +1265,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -1012,6 +1287,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -1029,6 +1305,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "33%", "width": "33%",
} }
} }
@@ -1041,6 +1318,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "33%", "width": "33%",
} }
} }
@@ -1053,6 +1331,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "33%", "width": "33%",
} }
} }
@@ -1067,6 +1346,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"marginTop": 15, "marginTop": 15,
} }
@@ -1099,6 +1379,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"marginTop": 15, "marginTop": 15,
} }
} }
@@ -1133,7 +1414,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -1174,15 +1455,47 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
".ms-ChoiceField-field.is-checked::before": { ".ms-ChoiceField-field.is-checked::before": {
"borderColor": "", "borderColor": "",
}, },
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-wrapper label": { ".ms-ChoiceField-wrapper label": {
"color": "var(--colorNeutralForeground1)",
"fontFamily": undefined, "fontFamily": undefined,
"fontSize": 14, "fontSize": 14,
"padding": "2px 5px", "padding": "2px 5px",
"whiteSpace": "nowrap", "whiteSpace": "nowrap",
}, },
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel:hover": {
"color": "var(--colorNeutralForeground1)",
},
}, },
}, },
], ],
"label": {
"color": "var(--colorNeutralForeground1)",
},
"root": {
"selectors": {
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
},
},
} }
} }
/> />
@@ -1222,17 +1535,53 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
step={100} step={100}
styles={ styles={
{ {
"field": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
":disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
},
},
},
"fieldGroup": { "fieldGroup": {
"borderColor": "", "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": "var(--colorNeutralStroke1)",
"height": 25, "height": 25,
"selectors": { "selectors": {
":disabled": { ":disabled": {
"backgroundColor": undefined, "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": undefined, "borderColor": "var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground2)",
},
"input": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
},
"input#autopilotInput": {
"backgroundColor": "var(--colorNeutralBackground4)",
"color": "var(--colorNeutralForeground1)",
},
"input:disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
}, },
}, },
"width": 300, "width": 300,
}, },
"subComponentStyles": {
"label": {
"root": {
"color": "var(--colorNeutralForeground1)",
},
},
},
"suffix": {
"backgroundColor": "var(--colorNeutralBackground2)",
"border": "1px solid var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground1)",
},
} }
} }
type="number" type="number"
@@ -1271,6 +1620,15 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
> >
5,000 5,000
</span> </span>
<span
style={
{
"float": "right",
}
}
>
1,000,000
</span>
<span <span
data-test="soft-allowed-maximum-throughput" data-test="soft-allowed-maximum-throughput"
style={ style={
@@ -1290,7 +1648,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
{ {
"progressBar": [ "progressBar": [
{ {
"backgroundColor": "rgb(251, 217, 203)", "backgroundColor": "var(--colorStatusDangerBackground1)",
}, },
], ],
} }
@@ -1314,7 +1672,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
{ {
"selectors": { "selectors": {
"::before": { "::before": {
"backgroundColor": "rgb(200, 200, 200)", "backgroundColor": "var(--colorNeutralStroke2)",
"height": "3px", "height": "3px",
"marginTop": "-1px", "marginTop": "-1px",
}, },
@@ -1342,7 +1700,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
{ {
"selectors": { "selectors": {
"::before": { "::before": {
"backgroundColor": "rgb(200, 200, 200)", "backgroundColor": "var(--colorNeutralStroke2)",
"height": "3px", "height": "3px",
"marginTop": "-1px", "marginTop": "-1px",
}, },
@@ -1359,12 +1717,39 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
</Stack> </Stack>
<StyledMessageBar <StyledMessageBar
messageBarType={3} messageBarType={3}
styles={
{
"root": {
"marginTop": "5px",
"selectors": {
"&.ms-MessageBar--info": {
"backgroundColor": "var(--colorNeutralBackground3)",
"border": "1px solid var(--colorNeutralStroke1)",
},
"&.ms-MessageBar--severeWarning": {
"backgroundColor": "var(--colorStatusDangerBackground1)",
"border": "1px solid var(--colorStatusDangerBorder1)",
},
"&.ms-MessageBar--warning": {
"backgroundColor": "var(--colorStatusWarningBackground1)",
"border": "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
"color": "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
"color": "var(--colorNeutralForeground1)",
},
},
},
}
}
> >
<Text <Text
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -1382,7 +1767,13 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
</Text> </Text>
</StyledMessageBar> </StyledMessageBar>
</Stack> </Stack>
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Estimate your required RU/s with Estimate your required RU/s with
<StyledLinkBase <StyledLinkBase
href="https://cosmos.azure.com/capacitycalculator/" href="https://cosmos.azure.com/capacitycalculator/"
@@ -1409,10 +1800,22 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
} }
} }
> >
<StyledLabelBase> <StyledLabelBase
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Storage capacity Storage capacity
</StyledLabelBase> </StyledLabelBase>
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
Unlimited Unlimited
</Text> </Text>
</Stack> </Stack>
@@ -1431,6 +1834,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -1452,6 +1856,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -1469,6 +1874,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "33%", "width": "33%",
} }
} }
@@ -1481,6 +1887,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "33%", "width": "33%",
} }
} }
@@ -1493,6 +1900,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"width": "33%", "width": "33%",
} }
} }
@@ -1507,6 +1915,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"marginTop": 15, "marginTop": 15,
} }
@@ -1539,6 +1948,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"marginTop": 15, "marginTop": 15,
} }
} }

View File

@@ -1,5 +1,5 @@
import { DirectionalHint, IIconStyles, Icon, Stack, Text, TooltipHost } from "@fluentui/react";
import * as React from "react"; import * as React from "react";
import { Stack, Text, IIconStyles, Icon, TooltipHost, DirectionalHint } from "@fluentui/react";
import { toolTipLabelStackTokens } from "../SettingsRenderUtils"; import { toolTipLabelStackTokens } from "../SettingsRenderUtils";
export interface ToolTipLabelComponentProps { export interface ToolTipLabelComponentProps {
@@ -14,7 +14,9 @@ export class ToolTipLabelComponent extends React.Component<ToolTipLabelComponent
return ( return (
<> <>
<Stack horizontal verticalAlign="center" tokens={toolTipLabelStackTokens}> <Stack horizontal verticalAlign="center" tokens={toolTipLabelStackTokens}>
{this.props.label && <Text style={{ fontWeight: 600 }}>{this.props.label}</Text>} {this.props.label && (
<Text style={{ fontWeight: 600, color: "var(--colorNeutralForeground1)" }}>{this.props.label}</Text>
)}
{this.props.toolTipElement && ( {this.props.toolTipElement && (
<TooltipHost <TooltipHost
content={this.props.toolTipElement} content={this.props.toolTipElement}

View File

@@ -11,6 +11,7 @@ exports[`ComputedPropertiesComponent renders 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"marginBottom": "10px", "marginBottom": "10px",
"marginLeft": "30px", "marginLeft": "30px",
} }

View File

@@ -37,15 +37,47 @@ exports[`ConflictResolutionComponent Path text field displayed 1`] = `
".ms-ChoiceField-field.is-checked::before": { ".ms-ChoiceField-field.is-checked::before": {
"borderColor": undefined, "borderColor": undefined,
}, },
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-wrapper label": { ".ms-ChoiceField-wrapper label": {
"color": "var(--colorNeutralForeground1)",
"fontFamily": undefined, "fontFamily": undefined,
"fontSize": 14, "fontSize": 14,
"padding": "2px 5px", "padding": "2px 5px",
"whiteSpace": "nowrap", "whiteSpace": "nowrap",
}, },
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel:hover": {
"color": "var(--colorNeutralForeground1)",
},
}, },
}, },
], ],
"label": {
"color": "var(--colorNeutralForeground1)",
},
"root": {
"selectors": {
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
},
},
} }
} }
/> />
@@ -56,17 +88,44 @@ exports[`ConflictResolutionComponent Path text field displayed 1`] = `
onRenderLabel={[Function]} onRenderLabel={[Function]}
styles={ styles={
{ {
"field": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
":disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
},
},
},
"fieldGroup": { "fieldGroup": {
"borderColor": "", "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": "var(--colorNeutralStroke1)",
"height": 25, "height": 25,
"selectors": { "selectors": {
":disabled": { ":disabled": {
"backgroundColor": undefined, "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": undefined, "borderColor": "var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground2)",
},
"input": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
},
"input:disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
}, },
}, },
"width": 300, "width": 300,
}, },
"subComponentStyles": {
"label": {
"root": {
"color": "var(--colorNeutralForeground1)",
},
},
},
} }
} }
value="" value=""
@@ -111,15 +170,47 @@ exports[`ConflictResolutionComponent Sproc text field displayed 1`] = `
".ms-ChoiceField-field.is-checked::before": { ".ms-ChoiceField-field.is-checked::before": {
"borderColor": "", "borderColor": "",
}, },
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-wrapper label": { ".ms-ChoiceField-wrapper label": {
"color": "var(--colorNeutralForeground1)",
"fontFamily": undefined, "fontFamily": undefined,
"fontSize": 14, "fontSize": 14,
"padding": "2px 5px", "padding": "2px 5px",
"whiteSpace": "nowrap", "whiteSpace": "nowrap",
}, },
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel:hover": {
"color": "var(--colorNeutralForeground1)",
},
}, },
}, },
], ],
"label": {
"color": "var(--colorNeutralForeground1)",
},
"root": {
"selectors": {
".ms-ChoiceField-field:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceField-innerField": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceField:hover .ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
".ms-ChoiceFieldLabel": {
"color": "var(--colorNeutralForeground1)",
},
},
},
} }
} }
/> />
@@ -130,17 +221,44 @@ exports[`ConflictResolutionComponent Sproc text field displayed 1`] = `
onRenderLabel={[Function]} onRenderLabel={[Function]}
styles={ styles={
{ {
"field": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
":disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
},
},
},
"fieldGroup": { "fieldGroup": {
"borderColor": "", "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": "var(--colorNeutralStroke1)",
"height": 25, "height": 25,
"selectors": { "selectors": {
":disabled": { ":disabled": {
"backgroundColor": undefined, "backgroundColor": "var(--colorNeutralBackground2)",
"borderColor": undefined, "borderColor": "var(--colorNeutralStroke1)",
"color": "var(--colorNeutralForeground2)",
},
"input": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground1)",
},
"input:disabled": {
"backgroundColor": "var(--colorNeutralBackground2)",
"color": "var(--colorNeutralForeground2)",
}, },
}, },
"width": 300, "width": 300,
}, },
"subComponentStyles": {
"label": {
"root": {
"color": "var(--colorNeutralForeground1)",
},
},
},
} }
} }
value="" value=""

View File

@@ -26,6 +26,7 @@ exports[`PartitionKeyComponent renders default component and matches snapshot 1`
styles={ styles={
{ {
"root": { "root": {
"color": "var(--colorNeutralForeground1)",
"fontSize": 16, "fontSize": 16,
"fontWeight": 600, "fontWeight": 600,
}, },
@@ -54,6 +55,7 @@ exports[`PartitionKeyComponent renders default component and matches snapshot 1`
styles={ styles={
{ {
"root": { "root": {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
}, },
} }
@@ -66,6 +68,7 @@ exports[`PartitionKeyComponent renders default component and matches snapshot 1`
styles={ styles={
{ {
"root": { "root": {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
}, },
} }
@@ -75,35 +78,91 @@ exports[`PartitionKeyComponent renders default component and matches snapshot 1`
</Text> </Text>
</Stack> </Stack>
<Stack <Stack
data-test="partition-key-values"
tokens={ tokens={
{ {
"childrenGap": 5, "childrenGap": 5,
} }
} }
> >
<Text /> <Text
<Text> styles={
{
"root": {
"color": "var(--colorNeutralForeground1)",
},
}
}
/>
<Text
styles={
{
"root": {
"color": "var(--colorNeutralForeground1)",
},
}
}
>
Non-hierarchical Non-hierarchical
</Text> </Text>
</Stack> </Stack>
</Stack> </Stack>
</Stack> </Stack>
<StyledMessageBar <StyledMessageBar
data-test="partition-key-warning"
messageBarIconProps={
{
"className": "messageBarWarningIcon",
"iconName": "WarningSolid",
}
}
messageBarType={5} messageBarType={5}
styles={
{
"root": {
"selectors": {
"&.ms-MessageBar--warning": {
"backgroundColor": "var(--colorStatusWarningBackground1)",
"border": "1px solid var(--colorStatusWarningBorder1)",
},
".ms-MessageBar-icon": {
"color": "var(--colorNeutralForeground1)",
},
".ms-MessageBar-text": {
"color": "var(--colorNeutralForeground1)",
},
},
},
}
}
> >
To safeguard the integrity of the data being copied to the new container, ensure that no updates are made to the source container for the entire duration of the partition key change process. To safeguard the integrity of the data being copied to the new container, ensure that no updates are made to the source container for the entire duration of the partition key change process.
<StyledLinkBase <StyledLinkBase
href="https://learn.microsoft.com/azure/cosmos-db/container-copy#how-does-container-copy-work" href="https://learn.microsoft.com/azure/cosmos-db/container-copy#how-does-container-copy-work"
style={
{
"color": "var(--colorBrandForeground1)",
}
}
target="_blank" target="_blank"
underline={true} underline={true}
> >
Learn more Learn more
</StyledLinkBase> </StyledLinkBase>
</StyledMessageBar> </StyledMessageBar>
<Text> <Text
styles={
{
"root": {
"color": "var(--colorNeutralForeground1)",
},
}
}
>
To change the partition key, a new destination container must be created or an existing destination container selected. Data will then be copied to the destination container. To change the partition key, a new destination container must be created or an existing destination container selected. Data will then be copied to the destination container.
</Text> </Text>
<CustomizedPrimaryButton <CustomizedPrimaryButton
data-test="change-partition-key-button"
onClick={[Function]} onClick={[Function]}
styles={ styles={
{ {
@@ -158,6 +217,7 @@ exports[`PartitionKeyComponent renders read-only component and matches snapshot
styles={ styles={
{ {
"root": { "root": {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
}, },
} }
@@ -170,6 +230,7 @@ exports[`PartitionKeyComponent renders read-only component and matches snapshot
styles={ styles={
{ {
"root": { "root": {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
}, },
} }
@@ -179,14 +240,31 @@ exports[`PartitionKeyComponent renders read-only component and matches snapshot
</Text> </Text>
</Stack> </Stack>
<Stack <Stack
data-test="partition-key-values"
tokens={ tokens={
{ {
"childrenGap": 5, "childrenGap": 5,
} }
} }
> >
<Text /> <Text
<Text> styles={
{
"root": {
"color": "var(--colorNeutralForeground1)",
},
}
}
/>
<Text
styles={
{
"root": {
"color": "var(--colorNeutralForeground1)",
},
}
}
>
Non-hierarchical Non-hierarchical
</Text> </Text>
</Stack> </Stack>

View File

@@ -14,6 +14,7 @@ exports[`ToolTipLabelComponent renders 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }

View File

@@ -3,13 +3,76 @@
exports[`SettingsComponent renders 1`] = ` exports[`SettingsComponent renders 1`] = `
<div <div
className="settingsV2MainContainer" className="settingsV2MainContainer"
style={
{
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"position": "relative",
}
}
> >
<div <div
className="settingsV2TabsContainer" className="settingsV2TabsContainer"
style={
{
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"padding": "20px 24px",
"position": "relative",
}
}
> >
<StyledPivot <StyledPivot
onLinkClick={[Function]} onLinkClick={[Function]}
selectedKey="ScaleTab" selectedKey="ScaleTab"
styles={
{
"itemContainer": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
},
"link": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
"&:active": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
},
"&:hover": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
},
"&[aria-selected="true"]": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
"&:active": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
},
"&:hover": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
},
},
},
},
},
"root": {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"selectors": {
"& .ms-Pivot-link": {
"color": "var(--colorNeutralForeground1)",
},
"& .ms-Pivot-link.is-selected::before": {
"backgroundColor": "var(--colorCompoundBrandBackground)",
},
},
},
}
}
> >
<PivotItem <PivotItem
headerButtonProps={ headerButtonProps={
@@ -22,89 +85,102 @@ exports[`SettingsComponent renders 1`] = `
key="ScaleTab" key="ScaleTab"
style={ style={
{ {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"marginTop": 20, "marginTop": 20,
} }
} }
> >
<ScaleComponent <Stack
collection={ styles={
{ {
"analyticalStorageTtl": [Function], "root": {
"changeFeedPolicy": [Function], "backgroundColor": "var(--colorNeutralBackground1)",
"computedProperties": [Function], "color": "var(--colorNeutralForeground1)",
"conflictResolutionPolicy": [Function],
"container": Explorer {
"_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function],
"onRefreshDatabasesKeyPress": [Function],
"onRefreshResourcesClick": [Function],
"phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
}, },
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
} }
} }
isAutoPilotSelected={false} >
isFixedContainer={false} <ScaleComponent
isGlobalSecondaryIndex={true} collection={
onAutoPilotSelected={[Function]} {
onMaxAutoPilotThroughputChange={[Function]} "analyticalStorageTtl": [Function],
onScaleDiscardableChange={[Function]} "changeFeedPolicy": [Function],
onScaleSaveableChange={[Function]} "computedProperties": [Function],
onThroughputChange={[Function]} "conflictResolutionPolicy": [Function],
throughput={10000} "container": Explorer {
throughputBaseline={10000} "_isInitializingNotebooks": false,
wasAutopilotOriginallySet={false} "isFixedCollectionWithSharedThroughputSupported": [Function],
/> "isTabsContentExpanded": [Function],
"onRefreshDatabasesKeyPress": [Function],
"onRefreshResourcesClick": [Function],
"phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
},
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
}
}
isAutoPilotSelected={false}
isFixedContainer={false}
isGlobalSecondaryIndex={true}
onAutoPilotSelected={[Function]}
onMaxAutoPilotThroughputChange={[Function]}
onScaleDiscardableChange={[Function]}
onScaleSaveableChange={[Function]}
onThroughputChange={[Function]}
throughput={10000}
throughputBaseline={10000}
wasAutopilotOriginallySet={false}
/>
</Stack>
</PivotItem> </PivotItem>
<PivotItem <PivotItem
headerButtonProps={ headerButtonProps={
@@ -117,98 +193,111 @@ exports[`SettingsComponent renders 1`] = `
key="SubSettingsTab" key="SubSettingsTab"
style={ style={
{ {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"marginTop": 20, "marginTop": 20,
} }
} }
> >
<SubSettingsComponent <Stack
changeFeedPolicy="Off" styles={
changeFeedPolicyBaseline="Off"
changeFeedPolicyVisible={false}
collection={
{ {
"analyticalStorageTtl": [Function], "root": {
"changeFeedPolicy": [Function], "backgroundColor": "var(--colorNeutralBackground1)",
"computedProperties": [Function], "color": "var(--colorNeutralForeground1)",
"conflictResolutionPolicy": [Function],
"container": Explorer {
"_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function],
"onRefreshDatabasesKeyPress": [Function],
"onRefreshResourcesClick": [Function],
"phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
}, },
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
} }
} }
displayedTtlSeconds="5" >
geospatialConfigType="Geometry" <SubSettingsComponent
geospatialConfigTypeBaseline="Geometry" changeFeedPolicy="Off"
isAnalyticalStorageEnabled={false} changeFeedPolicyBaseline="Off"
onAnalyticalStorageTtlSecondsChange={[Function]} changeFeedPolicyVisible={false}
onAnalyticalStorageTtlSelectionChange={[Function]} collection={
onChangeFeedPolicyChange={[Function]} {
onDisplayedTtlSecondsChange={[Function]} "analyticalStorageTtl": [Function],
onGeoSpatialConfigTypeChange={[Function]} "changeFeedPolicy": [Function],
onSubSettingsDiscardableChange={[Function]} "computedProperties": [Function],
onSubSettingsSaveableChange={[Function]} "conflictResolutionPolicy": [Function],
onTimeToLiveSecondsChange={[Function]} "container": Explorer {
onTtlChange={[Function]} "_isInitializingNotebooks": false,
timeToLive="on" "isFixedCollectionWithSharedThroughputSupported": [Function],
timeToLiveBaseline="on" "isTabsContentExpanded": [Function],
timeToLiveSeconds={5} "onRefreshDatabasesKeyPress": [Function],
timeToLiveSecondsBaseline={5} "onRefreshResourcesClick": [Function],
/> "phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
},
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
}
}
displayedTtlSeconds="5"
geospatialConfigType="Geometry"
geospatialConfigTypeBaseline="Geometry"
isAnalyticalStorageEnabled={false}
onAnalyticalStorageTtlSecondsChange={[Function]}
onAnalyticalStorageTtlSelectionChange={[Function]}
onChangeFeedPolicyChange={[Function]}
onDisplayedTtlSecondsChange={[Function]}
onGeoSpatialConfigTypeChange={[Function]}
onSubSettingsDiscardableChange={[Function]}
onSubSettingsSaveableChange={[Function]}
onTimeToLiveSecondsChange={[Function]}
onTtlChange={[Function]}
timeToLive="on"
timeToLiveBaseline="on"
timeToLiveSeconds={5}
timeToLiveSecondsBaseline={5}
/>
</Stack>
</PivotItem> </PivotItem>
<PivotItem <PivotItem
headerButtonProps={ headerButtonProps={
@@ -221,25 +310,38 @@ exports[`SettingsComponent renders 1`] = `
key="ContainerVectorPolicyTab" key="ContainerVectorPolicyTab"
style={ style={
{ {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"marginTop": 20, "marginTop": 20,
} }
} }
> >
<ContainerPolicyComponent <Stack
fullTextPolicy={{}} styles={
fullTextPolicyBaseline={{}} {
isFullTextSearchEnabled={true} "root": {
isGlobalSecondaryIndex={true} "backgroundColor": "var(--colorNeutralBackground1)",
isVectorSearchEnabled={false} "color": "var(--colorNeutralForeground1)",
onFullTextPolicyChange={[Function]} },
onFullTextPolicyDirtyChange={[Function]} }
onVectorEmbeddingPolicyChange={[Function]} }
onVectorEmbeddingPolicyDirtyChange={[Function]} >
resetShouldDiscardContainerPolicyChange={[Function]} <ContainerPolicyComponent
shouldDiscardContainerPolicies={false} fullTextPolicy={{}}
vectorEmbeddingPolicy={{}} fullTextPolicyBaseline={{}}
vectorEmbeddingPolicyBaseline={{}} isFullTextSearchEnabled={true}
/> isGlobalSecondaryIndex={true}
isVectorSearchEnabled={false}
onFullTextPolicyChange={[Function]}
onFullTextPolicyDirtyChange={[Function]}
onVectorEmbeddingPolicyChange={[Function]}
onVectorEmbeddingPolicyDirtyChange={[Function]}
resetShouldDiscardContainerPolicyChange={[Function]}
shouldDiscardContainerPolicies={false}
vectorEmbeddingPolicy={{}}
vectorEmbeddingPolicyBaseline={{}}
/>
</Stack>
</PivotItem> </PivotItem>
<PivotItem <PivotItem
headerButtonProps={ headerButtonProps={
@@ -252,35 +354,48 @@ exports[`SettingsComponent renders 1`] = `
key="IndexingPolicyTab" key="IndexingPolicyTab"
style={ style={
{ {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"marginTop": 20, "marginTop": 20,
} }
} }
> >
<IndexingPolicyComponent <Stack
indexingPolicyContent={ styles={
{ {
"automatic": true, "root": {
"excludedPaths": [], "backgroundColor": "var(--colorNeutralBackground1)",
"includedPaths": [], "color": "var(--colorNeutralForeground1)",
"indexingMode": "consistent", },
} }
} }
indexingPolicyContentBaseline={ >
{ <IndexingPolicyComponent
"automatic": true, indexingPolicyContent={
"excludedPaths": [], {
"includedPaths": [], "automatic": true,
"indexingMode": "consistent", "excludedPaths": [],
"includedPaths": [],
"indexingMode": "consistent",
}
} }
} indexingPolicyContentBaseline={
isVectorSearchEnabled={false} {
logIndexingPolicySuccessMessage={[Function]} "automatic": true,
onIndexingPolicyContentChange={[Function]} "excludedPaths": [],
onIndexingPolicyDirtyChange={[Function]} "includedPaths": [],
refreshIndexTransformationProgress={[Function]} "indexingMode": "consistent",
resetShouldDiscardIndexingPolicy={[Function]} }
shouldDiscardIndexingPolicy={false} }
/> isVectorSearchEnabled={false}
logIndexingPolicySuccessMessage={[Function]}
onIndexingPolicyContentChange={[Function]}
onIndexingPolicyDirtyChange={[Function]}
refreshIndexTransformationProgress={[Function]}
resetShouldDiscardIndexingPolicy={[Function]}
shouldDiscardIndexingPolicy={false}
/>
</Stack>
</PivotItem> </PivotItem>
<PivotItem <PivotItem
headerButtonProps={ headerButtonProps={
@@ -293,18 +408,91 @@ exports[`SettingsComponent renders 1`] = `
key="PartitionKeyTab" key="PartitionKeyTab"
style={ style={
{ {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"marginTop": 20, "marginTop": 20,
} }
} }
> >
<PartitionKeyComponent <Stack
collection={ styles={
{ {
"analyticalStorageTtl": [Function], "root": {
"changeFeedPolicy": [Function], "backgroundColor": "var(--colorNeutralBackground1)",
"computedProperties": [Function], "color": "var(--colorNeutralForeground1)",
"conflictResolutionPolicy": [Function], },
"container": Explorer { }
}
>
<PartitionKeyComponent
collection={
{
"analyticalStorageTtl": [Function],
"changeFeedPolicy": [Function],
"computedProperties": [Function],
"conflictResolutionPolicy": [Function],
"container": Explorer {
"_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function],
"onRefreshDatabasesKeyPress": [Function],
"onRefreshResourcesClick": [Function],
"phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
},
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
}
}
explorer={
Explorer {
"_isInitializingNotebooks": false, "_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function], "isTabsContentExpanded": [Function],
@@ -328,71 +516,11 @@ exports[`SettingsComponent renders 1`] = `
"copyNotebook": [Function], "copyNotebook": [Function],
"parameters": [Function], "parameters": [Function],
}, },
}, }
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
} }
} isReadOnly={false}
explorer={ />
Explorer { </Stack>
"_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function],
"onRefreshDatabasesKeyPress": [Function],
"onRefreshResourcesClick": [Function],
"phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
}
}
isReadOnly={false}
/>
</PivotItem> </PivotItem>
<PivotItem <PivotItem
headerButtonProps={ headerButtonProps={
@@ -405,33 +533,46 @@ exports[`SettingsComponent renders 1`] = `
key="ComputedPropertiesTab" key="ComputedPropertiesTab"
style={ style={
{ {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"marginTop": 20, "marginTop": 20,
} }
} }
> >
<ComputedPropertiesComponent <Stack
computedPropertiesContent={ styles={
[ {
{ "root": {
"name": "queryName", "backgroundColor": "var(--colorNeutralBackground1)",
"query": "query", "color": "var(--colorNeutralForeground1)",
}, },
] }
} }
computedPropertiesContentBaseline={ >
[ <ComputedPropertiesComponent
{ computedPropertiesContent={
"name": "queryName", [
"query": "query", {
}, "name": "queryName",
] "query": "query",
} },
logComputedPropertiesSuccessMessage={[Function]} ]
onComputedPropertiesContentChange={[Function]} }
onComputedPropertiesDirtyChange={[Function]} computedPropertiesContentBaseline={
resetShouldDiscardComputedProperties={[Function]} [
shouldDiscardComputedProperties={false} {
/> "name": "queryName",
"query": "query",
},
]
}
logComputedPropertiesSuccessMessage={[Function]}
onComputedPropertiesContentChange={[Function]}
onComputedPropertiesDirtyChange={[Function]}
resetShouldDiscardComputedProperties={[Function]}
shouldDiscardComputedProperties={false}
/>
</Stack>
</PivotItem> </PivotItem>
<PivotItem <PivotItem
headerButtonProps={ headerButtonProps={
@@ -444,18 +585,91 @@ exports[`SettingsComponent renders 1`] = `
key="GlobalSecondaryIndexTab" key="GlobalSecondaryIndexTab"
style={ style={
{ {
"backgroundColor": "var(--colorNeutralBackground1)",
"color": "var(--colorNeutralForeground1)",
"marginTop": 20, "marginTop": 20,
} }
} }
> >
<GlobalSecondaryIndexComponent <Stack
collection={ styles={
{ {
"analyticalStorageTtl": [Function], "root": {
"changeFeedPolicy": [Function], "backgroundColor": "var(--colorNeutralBackground1)",
"computedProperties": [Function], "color": "var(--colorNeutralForeground1)",
"conflictResolutionPolicy": [Function], },
"container": Explorer { }
}
>
<GlobalSecondaryIndexComponent
collection={
{
"analyticalStorageTtl": [Function],
"changeFeedPolicy": [Function],
"computedProperties": [Function],
"conflictResolutionPolicy": [Function],
"container": Explorer {
"_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function],
"onRefreshDatabasesKeyPress": [Function],
"onRefreshResourcesClick": [Function],
"phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
},
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
}
}
explorer={
Explorer {
"_isInitializingNotebooks": false, "_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function], "isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function], "isTabsContentExpanded": [Function],
@@ -479,70 +693,10 @@ exports[`SettingsComponent renders 1`] = `
"copyNotebook": [Function], "copyNotebook": [Function],
"parameters": [Function], "parameters": [Function],
}, },
}, }
"dataMaskingPolicy": [Function],
"databaseId": "test",
"defaultTtl": [Function],
"fullTextPolicy": [Function],
"geospatialConfig": [Function],
"getDatabase": [Function],
"id": [Function],
"indexingPolicy": [Function],
"materializedViewDefinition": [Function],
"materializedViews": [Function],
"offer": [Function],
"partitionKey": {
"kind": "hash",
"paths": [],
"version": 2,
},
"partitionKeyProperties": [
"partitionKey",
],
"rawDataModel": {
"uniqueKeyPolicy": {
"uniqueKeys": [
{
"paths": [
"/id",
],
},
],
},
},
"readSettings": [Function],
"usageSizeInKB": [Function],
"vectorEmbeddingPolicy": [Function],
} }
} />
explorer={ </Stack>
Explorer {
"_isInitializingNotebooks": false,
"isFixedCollectionWithSharedThroughputSupported": [Function],
"isTabsContentExpanded": [Function],
"onRefreshDatabasesKeyPress": [Function],
"onRefreshResourcesClick": [Function],
"phoenixClient": PhoenixClient {
"armResourceId": undefined,
"retryOptions": {
"maxTimeout": 5000,
"minTimeout": 5000,
"retries": 3,
},
},
"provideFeedbackEmail": [Function],
"queriesClient": QueriesClient {
"container": [Circular],
},
"refreshNotebookList": [Function],
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"parameters": [Function],
},
}
}
/>
</PivotItem> </PivotItem>
</StyledPivot> </StyledPivot>
</div> </div>

View File

@@ -6,6 +6,7 @@ exports[`SettingsUtils functions render 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
} }
} }
@@ -15,6 +16,7 @@ exports[`SettingsUtils functions render 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"marginTop": 15, "marginTop": 15,
} }
@@ -50,6 +52,7 @@ exports[`SettingsUtils functions render 1`] = `
<Text <Text
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"marginTop": 15, "marginTop": 15,
} }
} }
@@ -65,7 +68,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -83,7 +86,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -104,7 +107,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -116,7 +119,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -136,7 +139,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -152,7 +155,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -167,7 +170,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -181,7 +184,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -193,7 +196,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -213,7 +216,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -221,10 +224,21 @@ exports[`SettingsUtils functions render 1`] = `
> >
Enable change feed log retention policy to retain last 10 minutes of history for items in the container by default. To support this, the request unit (RU) charge for this container will be multiplied by a factor of two for writes. Reads are unaffected. Enable change feed log retention policy to retain last 10 minutes of history for items in the container by default. To support this, the request unit (RU) charge for this container will be multiplied by a factor of two for writes. Reads are unaffected.
</Text> </Text>
<Text> <Text
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
>
For queries that filter on multiple properties, create multiple single field indexes instead of a compound index. For queries that filter on multiple properties, create multiple single field indexes instead of a compound index.
<StyledLinkBase <StyledLinkBase
href="https://docs.microsoft.com/azure/cosmos-db/mongodb-indexing#index-types" href="https://docs.microsoft.com/azure/cosmos-db/mongodb-indexing#index-types"
style={
{
"color": "var(--colorBrandForeground1)",
}
}
target="_blank" target="_blank"
> >
Compound indexes Compound indexes
@@ -256,7 +270,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -272,7 +286,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }
@@ -289,7 +303,7 @@ exports[`SettingsUtils functions render 1`] = `
styles={ styles={
{ {
"root": { "root": {
"color": "windowtext", "color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
}, },
} }

View File

@@ -54,8 +54,8 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
if (isAutoscale) { if (isAutoscale) {
return ( return (
<Stack style={{ marginBottom: 6 }}> <Stack style={{ marginBottom: 6, color: "var(--colorNeutralForeground1)" }}>
<Text variant="small"> <Text variant="small" style={{ color: "var(--colorNeutralForeground1)" }}>
{estimatedMonthlyCost} ({currency}){iconWithEstimatedCostDisclaimer}:{" "} {estimatedMonthlyCost} ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
<b> <b>
{currencySign + calculateEstimateNumber(monthlyPrice / 10)} -{" "} {currencySign + calculateEstimateNumber(monthlyPrice / 10)} -{" "}
@@ -70,7 +70,7 @@ export const CostEstimateText: FunctionComponent<CostEstimateTextProps> = ({
return ( return (
<Stack style={{ marginBottom: 8 }}> <Stack style={{ marginBottom: 8 }}>
<Text variant="small"> <Text variant="small" style={{ color: "var(--colorNeutralForeground1)" }}>
Estimated cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "} Estimated cost ({currency}){iconWithEstimatedCostDisclaimer}:{" "}
<b> <b>
{currencySign + calculateEstimateNumber(hourlyPrice)} hourly /{" "} {currencySign + calculateEstimateNumber(hourlyPrice)} hourly /{" "}

View File

@@ -10,9 +10,13 @@
font-size: @mediumFontSize; font-size: @mediumFontSize;
padding: 0 @LargeSpace 0 @SmallSpace; padding: 0 @LargeSpace 0 @SmallSpace;
} }
// .throughputInputSpacing{
// color: "var(--colorNeutralForeground1)";
// }
.throughputInputSpacing > :not(:last-child) { .throughputInputSpacing > :not(:last-child) {
margin-bottom: @DefaultSpace; margin-bottom: @DefaultSpace;
color: "var(--colorNeutralForeground1)";
} }
.capacitycalculator-link:focus { .capacitycalculator-link:focus {
@@ -28,3 +32,16 @@
.deleteQuery:focus::after { .deleteQuery:focus::after {
outline: none !important; outline: none !important;
} }
// Override Fluent UI TextField focus styles
.throughputInputContainer {
:global {
.ms-TextField {
.ms-TextField-fieldGroup {
&:focus-within {
border-color: var(--colorCompoundBrandStroke1, @SelectionColor);
}
}
}
}
}

View File

@@ -193,7 +193,11 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
<div className="throughputInputContainer throughputInputSpacing"> <div className="throughputInputContainer throughputInputSpacing">
<Stack horizontal> <Stack horizontal>
<span className="mandatoryStar">*&nbsp;</span> <span className="mandatoryStar">*&nbsp;</span>
<Text aria-label="Throughput header" variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}> <Text
aria-label="Throughput header"
variant="small"
style={{ lineHeight: "20px", fontWeight: 600, color: "var(--colorNeutralForeground1)" }}
>
{getThroughputLabelText()} {getThroughputLabelText()}
</Text> </Text>
<InfoTooltip>{PricingUtils.getRuToolTipText()}</InfoTooltip> <InfoTooltip>{PricingUtils.getRuToolTipText()}</InfoTooltip>
@@ -236,14 +240,17 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
{isAutoscaleSelected && ( {isAutoscaleSelected && (
<Stack className="throughputInputSpacing"> <Stack className="throughputInputSpacing">
<Text style={{ marginTop: -2, fontSize: 12 }}> <Text style={{ marginTop: -2, fontSize: 12, color: "var(--colorNeutralForeground1)" }}>
Your container throughput will automatically scale up to the maximum value you select, from a minimum of 10% Your container throughput will automatically scale up to the maximum value you select, from a minimum of 10%
of that value. of that value.
</Text> </Text>
<Stack horizontal verticalAlign="end" tokens={{ childrenGap: 8 }}> <Stack horizontal verticalAlign="end" tokens={{ childrenGap: 8 }}>
<Stack tokens={{ childrenGap: 4 }}> <Stack tokens={{ childrenGap: 4 }}>
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}> <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}> <Text
variant="small"
style={{ lineHeight: "20px", fontWeight: 600, color: "var(--colorNeutralForeground1)" }}
>
Minimum RU/s Minimum RU/s
</Text> </Text>
<InfoTooltip>The minimum RU/s your container will scale to</InfoTooltip> <InfoTooltip>The minimum RU/s your container will scale to</InfoTooltip>
@@ -260,6 +267,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
color: "var(--colorNeutralForeground1)",
}} }}
> >
{Math.round(throughput / 10).toString()} {Math.round(throughput / 10).toString()}
@@ -272,6 +280,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
fontSize: 12, fontSize: 12,
fontWeight: 400, fontWeight: 400,
paddingBottom: 6, paddingBottom: 6,
color: "var(--colorNeutralForeground1)",
}} }}
> >
x 10 = x 10 =
@@ -279,7 +288,10 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
<Stack tokens={{ childrenGap: 4 }}> <Stack tokens={{ childrenGap: 4 }}>
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}> <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}> <Text
variant="small"
style={{ lineHeight: "20px", fontWeight: 600, color: "var(--colorNeutralForeground1)" }}
>
Maximum RU/s Maximum RU/s
</Text> </Text>
<InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip> <InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip>
@@ -290,7 +302,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
type="number" type="number"
styles={{ styles={{
fieldGroup: { width: 100, height: 27, flexShrink: 0 }, fieldGroup: { width: 100, height: 27, flexShrink: 0 },
field: { fontSize: 14, fontWeight: 400 }, field: { fontSize: 14, fontWeight: 400, color: "var(--colorNeutralForeground1)" },
}} }}
onChange={(_event, newInput?: string) => onThroughputValueChange(newInput)} onChange={(_event, newInput?: string) => onThroughputValueChange(newInput)}
step={AutoPilotUtils.autoPilotIncrementStep} step={AutoPilotUtils.autoPilotIncrementStep}
@@ -306,7 +318,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
<CostEstimateText requestUnits={throughput} isAutoscale={isAutoscaleSelected} /> <CostEstimateText requestUnits={throughput} isAutoscale={isAutoscaleSelected} />
<Stack className="throughputInputSpacing"> <Stack className="throughputInputSpacing">
<Text variant="small" aria-label="ruDescription"> <Text variant="small" aria-label="ruDescription" style={{ color: "var(--colorNeutralForeground1)" }}>
Estimate your required RU/s with&nbsp; Estimate your required RU/s with&nbsp;
<Link <Link
className="underlinedLink" className="underlinedLink"
@@ -325,7 +337,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
{!isAutoscaleSelected && ( {!isAutoscaleSelected && (
<Stack className="throughputInputSpacing"> <Stack className="throughputInputSpacing">
<Text variant="small" aria-label="ruDescription"> <Text variant="small" aria-label="ruDescription" style={{ color: "var(--colorNeutralForeground1)" }}>
Estimate your required RU/s with&nbsp; Estimate your required RU/s with&nbsp;
<Link <Link
className="underlinedLink" className="underlinedLink"
@@ -338,7 +350,11 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
. .
</Text> </Text>
<Stack horizontal> <Stack horizontal>
<Text variant="small" style={{ lineHeight: "20px", fontWeight: 600 }} aria-label="maxRUDescription"> <Text
variant="small"
style={{ lineHeight: "20px", fontWeight: 600, color: "var(--colorNeutralForeground1)" }}
aria-label="maxRUDescription"
>
{isDatabase ? "Database" : getCollectionName()} Required RU/s {isDatabase ? "Database" : getCollectionName()} Required RU/s
</Text> </Text>
<InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip> <InfoTooltip>{getAutoScaleTooltip()}</InfoTooltip>

View File

@@ -31,6 +31,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
key=".0:$.$.1" key=".0:$.$.1"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -42,6 +43,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
className="css-110" className="css-110"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -724,6 +726,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
key=".0:$.$.0" key=".0:$.$.0"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontSize": 12, "fontSize": 12,
"marginTop": -2, "marginTop": -2,
} }
@@ -733,6 +736,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
className="css-117" className="css-117"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontSize": 12, "fontSize": 12,
"marginTop": -2, "marginTop": -2,
} }
@@ -782,6 +786,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
key=".0:$.$.0" key=".0:$.$.0"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -792,6 +797,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
className="css-110" className="css-110"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -1423,6 +1429,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
"alignItems": "center", "alignItems": "center",
"backgroundColor": "transparent", "backgroundColor": "transparent",
"border": "none", "border": "none",
"color": "var(--colorNeutralForeground1)",
"display": "flex", "display": "flex",
"fontFamily": "Segoe UI", "fontFamily": "Segoe UI",
"fontSize": 14, "fontSize": 14,
@@ -1440,6 +1447,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
"alignItems": "center", "alignItems": "center",
"backgroundColor": "transparent", "backgroundColor": "transparent",
"border": "none", "border": "none",
"color": "var(--colorNeutralForeground1)",
"display": "flex", "display": "flex",
"fontFamily": "Segoe UI", "fontFamily": "Segoe UI",
"fontSize": 14, "fontSize": 14,
@@ -1459,6 +1467,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
key=".0:$.$.1" key=".0:$.$.1"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontFamily": "Segoe UI", "fontFamily": "Segoe UI",
"fontSize": 12, "fontSize": 12,
"fontWeight": 400, "fontWeight": 400,
@@ -1470,6 +1479,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
className="css-117" className="css-117"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontFamily": "Segoe UI", "fontFamily": "Segoe UI",
"fontSize": 12, "fontSize": 12,
"fontWeight": 400, "fontWeight": 400,
@@ -1508,6 +1518,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
key=".0:$.$.0" key=".0:$.$.0"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -1518,6 +1529,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
className="css-110" className="css-110"
style={ style={
{ {
"color": "var(--colorNeutralForeground1)",
"fontWeight": 600, "fontWeight": 600,
"lineHeight": "20px", "lineHeight": "20px",
} }
@@ -2156,6 +2168,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
styles={ styles={
{ {
"field": { "field": {
"color": "var(--colorNeutralForeground1)",
"fontSize": 14, "fontSize": 14,
"fontWeight": 400, "fontWeight": 400,
}, },
@@ -2509,11 +2522,21 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
<Text <Text
aria-label="ruDescription" aria-label="ruDescription"
key=".0:$.$.0" key=".0:$.$.0"
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
variant="small" variant="small"
> >
<span <span
aria-label="ruDescription" aria-label="ruDescription"
className="css-110" className="css-110"
style={
{
"color": "var(--colorNeutralForeground1)",
}
}
> >
Estimate your required RU/s with  Estimate your required RU/s with 
<StyledLinkBase <StyledLinkBase

View File

@@ -10,6 +10,7 @@ const actionButtonBackground = "--cosmos-Tree--actionButtonBackground" as const;
export const useTreeStyles = makeStyles({ export const useTreeStyles = makeStyles({
treeContainer: { treeContainer: {
height: "100%", height: "100%",
maxHeight: "100vh",
...shorthands.overflow("auto"), ...shorthands.overflow("auto"),
}, },
tree: { tree: {

View File

@@ -0,0 +1,47 @@
import { Button as FluentButton, makeStyles, tokens } from "@fluentui/react-components";
import * as React from "react";
export type CustomButtonProps = {
primary?: boolean;
className?: string;
children?: React.ReactNode;
onClick?: (ev: React.MouseEvent<HTMLButtonElement>) => void;
disabled?: boolean;
type?: "button" | "submit" | "reset";
};
const useStyles = makeStyles({
button: {
backgroundColor: tokens.colorNeutralBackground1,
color: tokens.colorNeutralForeground1,
"&:hover": {
backgroundColor: tokens.colorNeutralBackground1Hover,
color: tokens.colorNeutralForeground1Hover,
},
"&:active": {
backgroundColor: tokens.colorNeutralBackground1Pressed,
color: tokens.colorNeutralForeground1Pressed,
},
},
primary: {
backgroundColor: tokens.colorBrandBackground,
color: tokens.colorNeutralForegroundOnBrand,
"&:hover": {
backgroundColor: tokens.colorBrandBackgroundHover,
},
"&:active": {
backgroundColor: tokens.colorBrandBackgroundPressed,
},
},
});
export const Button = React.forwardRef<HTMLButtonElement, CustomButtonProps>(({ primary, ...props }, ref) => {
const baseStyles = useStyles();
const buttonClassName = primary ? baseStyles.primary : baseStyles.button;
return (
<FluentButton {...props} ref={ref} appearance={primary ? "primary" : "secondary"} className={buttonClassName} />
);
});
Button.displayName = "Button";

View File

@@ -53,6 +53,7 @@ type VectorEmbeddingPolicyProperty = "dataType" | "distanceFunction" | "indexTyp
const labelStyles = { const labelStyles = {
root: { root: {
fontSize: 12, fontSize: 12,
color: "var(--colorNeutralForeground1)",
}, },
}; };
@@ -63,6 +64,8 @@ const textFieldStyles: IStyleFunctionOrObject<ITextFieldStyleProps, ITextFieldSt
field: { field: {
fontSize: 12, fontSize: 12,
padding: "0 8px", padding: "0 8px",
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
}, },
}; };

View File

@@ -0,0 +1,26 @@
import { makeStyles } from "@fluentui/react-components";
import React from "react";
import type { Explorer } from "../Contracts/ViewModels";
interface DataExplorerProps {
dataExplorer?: Explorer;
}
const useStyles = makeStyles({
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
height: "100%",
width: "100%",
},
});
export const DataExplorer: React.FC<DataExplorerProps> = () => {
const styles = useStyles();
return (
<div className={`dataExplorerContainer ${styles.root}`}>
<div>Data Explorer Content</div>
</div>
);
};

View File

@@ -0,0 +1,38 @@
import React, { Component, ReactNode } from "react";
interface Props {
children: ReactNode;
}
interface State {
hasError: boolean;
error: Error | null;
}
export class ErrorBoundary extends Component<Props, State> {
public state: State = {
hasError: false,
error: null,
};
public static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
public componentDidCatch(error: Error): void {
console.error("Error caught in boundary:", error);
}
public render() {
if (this.state.hasError) {
return (
<div style={{ padding: "20px", color: "red" }}>
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: "pre-wrap" }}>{this.state.error && this.state.error.toString()}</details>
</div>
);
}
return this.props.children;
}
}

View File

@@ -4,11 +4,10 @@
padding: @SmallSpace 0px @SmallSpace 0px; padding: @SmallSpace 0px @SmallSpace 0px;
.flex-display(); .flex-display();
span { span {
border-left: @ButtonBorderWidth solid @BaseMediumHigh;
margin: 0 10px 0 10px; margin: 0 10px 0 10px;
} }
} }
.commandBarContainer { .commandBarContainer {
border-bottom: 1px solid @BaseMedium; border-bottom: 1px solid var(--colorNeutralStroke1);
} }

View File

@@ -4,6 +4,7 @@
* and update any knockout observables passed from the parent. * and update any knockout observables passed from the parent.
*/ */
import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react"; import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react";
import { makeStyles, useFluent } from "@fluentui/react-components";
import { useNotebook } from "Explorer/Notebook/useNotebook"; import { useNotebook } from "Explorer/Notebook/useNotebook";
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane"; import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
import { KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts"; import { KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts";
@@ -12,7 +13,6 @@ import { userContext } from "UserContext";
import * as React from "react"; import * as React from "react";
import create, { UseStore } from "zustand"; import create, { UseStore } from "zustand";
import { ConnectionStatusType, PoolIdType } from "../../../Common/Constants"; import { ConnectionStatusType, PoolIdType } from "../../../Common/Constants";
import { StyleConstants } from "../../../Common/StyleConstants";
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
import Explorer from "../../Explorer"; import Explorer from "../../Explorer";
import { useSelectedNode } from "../../useSelectedNode"; import { useSelectedNode } from "../../useSelectedNode";
@@ -37,12 +37,49 @@ export const useCommandBar: UseStore<CommandBarStore> = create((set) => ({
setIsHidden: (isHidden: boolean) => set((state) => ({ ...state, isHidden })), setIsHidden: (isHidden: boolean) => set((state) => ({ ...state, isHidden })),
})); }));
const useStyles = makeStyles({
commandBarContainer: {
borderBottom: "1px solid var(--colorNeutralStroke1)",
// backgroundColor: "var(--colorNeutralBackground1)",
},
toolbarButton: {
backgroundColor: "transparent",
"&:hover": {
backgroundColor: "var(--colorNeutralBackground2)",
},
"&:active": {
backgroundColor: "var(--colorNeutralBackground3)",
},
},
buttonIcon: {
width: "16px",
height: "16px",
display: "flex",
alignItems: "center",
justifyContent: "center",
"& img": {
width: "100%",
height: "100%",
objectFit: "contain",
},
},
});
export const CommandBar: React.FC<Props> = ({ container }: Props) => { export const CommandBar: React.FC<Props> = ({ container }: Props) => {
const selectedNodeState = useSelectedNode(); const selectedNodeState = useSelectedNode();
const buttons = useCommandBar((state) => state.contextButtons); const buttons = useCommandBar((state) => state.contextButtons);
const isHidden = useCommandBar((state) => state.isHidden); const isHidden = useCommandBar((state) => state.isHidden);
const backgroundColor = StyleConstants.BaseLight; // targetDocument is used by referenced components
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { targetDocument } = useFluent();
const setKeyboardHandlers = useKeyboardActionGroup(KeyboardActionGroup.COMMAND_BAR); const setKeyboardHandlers = useKeyboardActionGroup(KeyboardActionGroup.COMMAND_BAR);
const styles = useStyles();
const { connectionInfo, isPhoenixNotebooks, isPhoenixFeatures } = useNotebook((state) => ({
connectionInfo: state.connectionInfo,
isPhoenixNotebooks: state.isPhoenixNotebooks,
isPhoenixFeatures: state.isPhoenixFeatures,
}));
// Subscribe to the store changes that affect button creation // Subscribe to the store changes that affect button creation
const dataPlaneRbacEnabled = useDataPlaneRbac((state) => state.dataPlaneRbacEnabled); const dataPlaneRbacEnabled = useDataPlaneRbac((state) => state.dataPlaneRbacEnabled);
@@ -59,12 +96,15 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
? CommandBarComponentButtonFactory.createPostgreButtons(container) ? CommandBarComponentButtonFactory.createPostgreButtons(container)
: CommandBarComponentButtonFactory.createVCoreMongoButtons(container); : CommandBarComponentButtonFactory.createVCoreMongoButtons(container);
return ( return (
<div className="commandBarContainer" style={{ display: isHidden ? "none" : "initial" }}> <div className={styles.commandBarContainer} style={{ display: isHidden ? "none" : "initial" }}>
<FluentCommandBar <FluentCommandBar
ariaLabel="Use left and right arrow keys to navigate between commands" ariaLabel="Use left and right arrow keys to navigate between commands"
items={CommandBarUtil.convertButton(buttons, backgroundColor)} items={CommandBarUtil.convertButton(buttons, "var(--colorNeutralBackground1)")}
styles={{ styles={{
root: { backgroundColor: backgroundColor }, root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
}} }}
overflowButtonProps={{ ariaLabel: "More commands" }} overflowButtonProps={{ ariaLabel: "More commands" }}
/> />
@@ -77,50 +117,69 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
); );
const controlButtons = CommandBarComponentButtonFactory.createControlCommandBarButtons(container); const controlButtons = CommandBarComponentButtonFactory.createControlCommandBarButtons(container);
const uiFabricStaticButtons = CommandBarUtil.convertButton(staticButtons, backgroundColor); const uiFabricStaticButtons = CommandBarUtil.convertButton(staticButtons, "var(--colorNeutralBackground1)");
if (buttons && buttons.length > 0) { if (buttons && buttons.length > 0) {
uiFabricStaticButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true)); uiFabricStaticButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
} }
const uiFabricTabsButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(contextButtons, backgroundColor); const uiFabricTabsButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(
contextButtons,
"var(--colorNeutralBackground1)",
);
if (uiFabricTabsButtons.length > 0) { if (uiFabricTabsButtons.length > 0) {
uiFabricStaticButtons.push(CommandBarUtil.createDivider("commandBarDivider")); uiFabricStaticButtons.push(CommandBarUtil.createDivider("commandBarDivider"));
} }
const uiFabricControlButtons = CommandBarUtil.convertButton(controlButtons, backgroundColor); const uiFabricControlButtons = CommandBarUtil.convertButton(controlButtons, "var(--colorNeutralBackground1)");
uiFabricControlButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true)); uiFabricControlButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
const connectionInfo = useNotebook((state) => state.connectionInfo); // Add connection status if needed (using the hook values we got at the top level)
if ((isPhoenixNotebooks || isPhoenixFeatures) && connectionInfo?.status !== ConnectionStatusType.Connect) {
if (
(useNotebook.getState().isPhoenixNotebooks || useNotebook.getState().isPhoenixFeatures) &&
connectionInfo?.status !== ConnectionStatusType.Connect
) {
uiFabricControlButtons.unshift( uiFabricControlButtons.unshift(
CommandBarUtil.createConnectionStatus(container, PoolIdType.DefaultPoolId, "connectionStatus"), CommandBarUtil.createConnectionStatus(container, PoolIdType.DefaultPoolId, "connectionStatus"),
); );
} }
const rootStyle = isFabric() const rootStyle = {
? { root: {
root: { backgroundColor: "var(--colorNeutralBackground1)",
backgroundColor: "transparent", color: "var(--colorNeutralForeground1)",
padding: "2px 8px 0px 8px", padding: isFabric() ? "2px 8px 0px 8px" : undefined,
},
button: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: {
":hover": {
backgroundColor: "var(--colorNeutralBackground2)",
color: "var(--colorNeutralForeground1)",
}, },
} ":active": {
: { backgroundColor: "var(--colorNeutralBackground3)",
root: { color: "var(--colorNeutralForeground1)",
backgroundColor: backgroundColor,
}, },
}; },
},
menuIcon: {
color: "var(--colorNeutralForeground1)",
},
item: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
link: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
};
const allButtons = staticButtons.concat(contextButtons).concat(controlButtons); const allButtons = staticButtons.concat(contextButtons).concat(controlButtons);
const keyboardHandlers = CommandBarUtil.createKeyboardHandlers(allButtons); const keyboardHandlers = CommandBarUtil.createKeyboardHandlers(allButtons);
setKeyboardHandlers(keyboardHandlers); setKeyboardHandlers(keyboardHandlers);
return ( return (
<div className="commandBarContainer" style={{ display: isHidden ? "none" : "initial" }}> <div className={styles.commandBarContainer} style={{ display: isHidden ? "none" : "initial" }}>
<FluentCommandBar <FluentCommandBar
ariaLabel="Use left and right arrow keys to navigate between commands" ariaLabel="Use left and right arrow keys to navigate between commands"
items={uiFabricStaticButtons.concat(uiFabricTabsButtons)} items={uiFabricStaticButtons.concat(uiFabricTabsButtons)}

View File

@@ -1,3 +1,4 @@
import { OpenFullScreen } from "Explorer/OpenFullScreen";
import { KeyboardAction } from "KeyboardShortcuts"; import { KeyboardAction } from "KeyboardShortcuts";
import { isDataplaneRbacSupported } from "Utils/APITypeUtils"; import { isDataplaneRbacSupported } from "Utils/APITypeUtils";
import * as React from "react"; import * as React from "react";
@@ -24,12 +25,12 @@ import { useSidePanel } from "../../../hooks/useSidePanel";
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
import Explorer from "../../Explorer"; import Explorer from "../../Explorer";
import { useNotebook } from "../../Notebook/useNotebook"; import { useNotebook } from "../../Notebook/useNotebook";
import { OpenFullScreen } from "../../OpenFullScreen";
import { BrowseQueriesPane } from "../../Panes/BrowseQueriesPane/BrowseQueriesPane"; import { BrowseQueriesPane } from "../../Panes/BrowseQueriesPane/BrowseQueriesPane";
import { LoadQueryPane } from "../../Panes/LoadQueryPane/LoadQueryPane"; import { LoadQueryPane } from "../../Panes/LoadQueryPane/LoadQueryPane";
import { SettingsPane, useDataPlaneRbac } from "../../Panes/SettingsPane/SettingsPane"; import { SettingsPane, useDataPlaneRbac } from "../../Panes/SettingsPane/SettingsPane";
import { useDatabases } from "../../useDatabases"; import { useDatabases } from "../../useDatabases";
import { SelectedNodeState, useSelectedNode } from "../../useSelectedNode"; import { SelectedNodeState, useSelectedNode } from "../../useSelectedNode";
import { ThemeToggleButton } from "./ThemeToggleButton";
let counter = 0; let counter = 0;
@@ -166,6 +167,7 @@ export function createContextCommandBarButtons(
export function createControlCommandBarButtons(container: Explorer): CommandButtonComponentProps[] { export function createControlCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
const buttons: CommandButtonComponentProps[] = [ const buttons: CommandButtonComponentProps[] = [
ThemeToggleButton(),
{ {
iconSrc: SettingsIcon, iconSrc: SettingsIcon,
iconAlt: "Settings", iconAlt: "Settings",
@@ -361,6 +363,22 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState)
disabled: disabled:
useSelectedNode.getState().isQueryCopilotCollectionSelected() || useSelectedNode.getState().isQueryCopilotCollectionSelected() ||
selectedNodeState.isDatabaseNodeOrNoneSelected(), selectedNodeState.isDatabaseNodeOrNoneSelected(),
styles: {
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: {
":hover": {
backgroundColor: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1Hover)",
},
":active": {
backgroundColor: "var(--colorNeutralBackground1Pressed)",
color: "var(--colorNeutralForeground1Pressed)",
},
},
},
},
}; };
buttons.push(newStoredProcedureBtn); buttons.push(newStoredProcedureBtn);
} }
@@ -381,6 +399,22 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState)
disabled: disabled:
useSelectedNode.getState().isQueryCopilotCollectionSelected() || useSelectedNode.getState().isQueryCopilotCollectionSelected() ||
selectedNodeState.isDatabaseNodeOrNoneSelected(), selectedNodeState.isDatabaseNodeOrNoneSelected(),
styles: {
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: {
":hover": {
backgroundColor: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1Hover)",
},
":active": {
backgroundColor: "var(--colorNeutralBackground1Pressed)",
color: "var(--colorNeutralForeground1Pressed)",
},
},
},
},
}; };
buttons.push(newUserDefinedFunctionBtn); buttons.push(newUserDefinedFunctionBtn);
} }
@@ -401,6 +435,22 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState)
disabled: disabled:
useSelectedNode.getState().isQueryCopilotCollectionSelected() || useSelectedNode.getState().isQueryCopilotCollectionSelected() ||
selectedNodeState.isDatabaseNodeOrNoneSelected(), selectedNodeState.isDatabaseNodeOrNoneSelected(),
styles: {
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
selectors: {
":hover": {
backgroundColor: "var(--colorNeutralBackground1Hover)",
color: "var(--colorNeutralForeground1Hover)",
},
":active": {
backgroundColor: "var(--colorNeutralBackground1Pressed)",
color: "var(--colorNeutralForeground1Pressed)",
},
},
},
},
}; };
buttons.push(newTriggerBtn); buttons.push(newTriggerBtn);
} }

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