diff --git a/less/documentDB.less b/less/documentDB.less index 3950aad9c..83a2f1a2b 100644 --- a/less/documentDB.less +++ b/less/documentDB.less @@ -406,7 +406,11 @@ body { width: 440px; min-height: 565px; } - +.dataExplorerLoaderforcopyJobs{ + width: 100%; + min-height: 565px; + right: 0; +} .dataExplorerTabLoaderContainer { left: initial; top: initial; diff --git a/src/Common/LoadingOverlay.tsx b/src/Common/LoadingOverlay.tsx index 320576533..2d14f7fad 100644 --- a/src/Common/LoadingOverlay.tsx +++ b/src/Common/LoadingOverlay.tsx @@ -1,4 +1,5 @@ import { Overlay, Spinner, SpinnerSize } from "@fluentui/react"; +import { useThemeStore } from "hooks/useTheme"; import React from "react"; interface LoadingOverlayProps { @@ -7,6 +8,7 @@ interface LoadingOverlayProps { } const LoadingOverlay: React.FC = ({ isLoading, label }) => { + const isDarkMode = useThemeStore((state) => state.isDarkMode); if (!isLoading) { return null; } @@ -15,7 +17,7 @@ const LoadingOverlay: React.FC = ({ isLoading, label }) => = ({ isLoading, label }) => }, }} > - + ); }; diff --git a/src/Common/Pager/Pager.css b/src/Common/Pager/Pager.css index a29b6f50a..3379c2094 100644 --- a/src/Common/Pager/Pager.css +++ b/src/Common/Pager/Pager.css @@ -11,3 +11,14 @@ gap: 8px; 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); +} \ No newline at end of file diff --git a/src/Common/Pager/index.tsx b/src/Common/Pager/index.tsx index 06ff7f2be..ec6091b46 100644 --- a/src/Common/Pager/index.tsx +++ b/src/Common/Pager/index.tsx @@ -31,6 +31,7 @@ const iconButtonStyles = { outline: "none", }, }; +const textStyle: React.CSSProperties = { color: "var(--colorNeutralForeground1)" }; const Pager: React.FC = ({ startIndex, @@ -59,7 +60,7 @@ const Pager: React.FC = ({ return (
{showItemCount && ( - + Showing {startIndex + 1} - {endIndex} of {totalCount} items )} @@ -82,7 +83,7 @@ const Pager: React.FC = ({ disabled={disabled || currentPage === 1} styles={iconButtonStyles} /> - + Page {currentPage} of {totalPages} = ({ 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); const controlButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(commandBarItems, backgroundColor); return ( -
+
{ it("should include feedback button when platform is Portal", () => { const buttons = getCommandBarButtons(mockExplorer); - expect(buttons.length).toBe(3); + expect(buttons.length).toBe(4); - const feedbackButton = buttons[2]; + const feedbackButton = buttons[3]; expect(feedbackButton).toBeDefined(); expect(feedbackButton.ariaLabel).toBe("Provide feedback on copy jobs"); expect(feedbackButton.tooltipText).toBe("Feedback"); @@ -107,7 +107,7 @@ describe("CommandBar Utils", () => { const { getCommandBarButtons: getCommandBarButtonsEmulator } = await import("./Utils"); const buttons = getCommandBarButtonsEmulator(mockExplorer); - expect(buttons.length).toBe(2); + expect(buttons.length).toBe(3); }); it("should call openCreateCopyJobPanel when create button is clicked", () => { @@ -131,7 +131,7 @@ describe("CommandBar Utils", () => { it("should call openContainerCopyFeedbackBlade when feedback button is clicked", () => { const buttons = getCommandBarButtons(mockExplorer); - const feedbackButton = buttons[2]; + const feedbackButton = buttons[3]; feedbackButton.onCommandClick({} as React.SyntheticEvent); @@ -148,7 +148,10 @@ describe("CommandBar Utils", () => { expect(buttons[1].iconAlt).toBe("Refresh"); 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", () => { @@ -202,12 +205,13 @@ describe("CommandBar Utils", () => { }); }); - it("should maintain button order: create, refresh, feedback", () => { + it("should maintain button order: create, refresh, themeToggle, feedback", () => { const buttons = getCommandBarButtons(mockExplorer); expect(buttons[0].tooltipText).toBe("Create Copy Job"); 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"); }); }); @@ -229,7 +233,8 @@ describe("CommandBar Utils", () => { buttons[1].onCommandClick({} as React.SyntheticEvent); expect(mockRefreshJobList).toHaveBeenCalled(); - buttons[2].onCommandClick({} as React.SyntheticEvent); + + buttons[3].onCommandClick({} as React.SyntheticEvent); expect(mockOpenContainerCopyFeedbackBlade).toHaveBeenCalled(); }); }); diff --git a/src/Explorer/ContainerCopy/CommandBar/Utils.ts b/src/Explorer/ContainerCopy/CommandBar/Utils.ts index 152c2dfbd..e79dcc052 100644 --- a/src/Explorer/ContainerCopy/CommandBar/Utils.ts +++ b/src/Explorer/ContainerCopy/CommandBar/Utils.ts @@ -1,7 +1,10 @@ import AddIcon from "../../../../images/Add.svg"; import FeedbackIcon from "../../../../images/Feedback-Command.svg"; +import MoonIcon from "../../../../images/MoonIcon.svg"; import RefreshIcon from "../../../../images/refresh-cosmos.svg"; +import SunIcon from "../../../../images/SunIcon.svg"; import { configContext, Platform } from "../../../ConfigContext"; +import { useThemeStore } from "../../../hooks/useTheme"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import Explorer from "../../Explorer"; import * as Actions from "../Actions/CopyJobActions"; @@ -11,6 +14,7 @@ import { CopyJobCommandBarBtnType } from "../Types/CopyJobTypes"; function getCopyJobBtns(explorer: Explorer): CopyJobCommandBarBtnType[] { const monitorCopyJobsRef = MonitorCopyJobsRefState((state) => state.ref); + const isDarkMode = useThemeStore.getState().isDarkMode; const buttons: CopyJobCommandBarBtnType[] = [ { key: "createCopyJob", @@ -26,7 +30,15 @@ function getCopyJobBtns(explorer: Explorer): CopyJobCommandBarBtnType[] { ariaLabel: ContainerCopyMessages.refreshButtonAriaLabel, 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) { buttons.push({ key: "feedback", diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddManagedIdentity.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddManagedIdentity.tsx index 1cff2c213..631a823e3 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddManagedIdentity.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddManagedIdentity.tsx @@ -12,7 +12,12 @@ import useToggle from "./hooks/useToggle"; const managedIdentityTooltip = ( {ContainerCopyMessages.addManagedIdentity.tooltip.content}   - + {ContainerCopyMessages.addManagedIdentity.tooltip.hrefText} @@ -26,7 +31,7 @@ const AddManagedIdentity: React.FC = () => { return ( - + {ContainerCopyMessages.addManagedIdentity.description}  {ContainerCopyMessages.addManagedIdentity.descriptionHrefText} diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddReadPermissionToDefaultIdentity.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddReadPermissionToDefaultIdentity.tsx index 075257644..193fe340f 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddReadPermissionToDefaultIdentity.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AddReadPermissionToDefaultIdentity.tsx @@ -13,7 +13,12 @@ import useToggle from "./hooks/useToggle"; const TooltipContent = ( {ContainerCopyMessages.readPermissionAssigned.tooltip.content}   - + {ContainerCopyMessages.readPermissionAssigned.tooltip.hrefText} diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AssignPermissions.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AssignPermissions.tsx index 7b1f96241..8b4d902ca 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AssignPermissions.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/AssignPermissions.tsx @@ -47,8 +47,8 @@ const PermissionGroup: React.FC = ({ title, description, tokens={{ childrenGap: 15 }} styles={{ root: { - background: "#fafafa", - border: "1px solid #e1e1e1", + background: "var(--colorNeutralBackground2)", + border: "1px solid var(--colorNeutralStroke1)", borderRadius: 8, padding: 16, boxShadow: "0 1px 3px rgba(0,0,0,0.1)", @@ -56,11 +56,11 @@ const PermissionGroup: React.FC = ({ title, description, }} > - + {title} {description && ( - + {description} )} @@ -100,7 +100,7 @@ const AssignPermissions = () => { return ( - + {isSameAccount && copyJobState.migrationType === CopyJobMigrationType.Online ? ContainerCopyMessages.assignPermissions.intraAccountOnlineDescription( copyJobState?.source?.account?.name || "", diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/DefaultManagedIdentity.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/DefaultManagedIdentity.tsx index 69e12e72e..a7980f02c 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/DefaultManagedIdentity.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/DefaultManagedIdentity.tsx @@ -12,7 +12,12 @@ import useToggle from "./hooks/useToggle"; const managedIdentityTooltip = ( {ContainerCopyMessages.defaultManagedIdentity.tooltip.content}   - + {ContainerCopyMessages.defaultManagedIdentity.tooltip.hrefText} diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/PointInTimeRestore.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/PointInTimeRestore.tsx index 95d10c49a..d076931d2 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/PointInTimeRestore.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/PointInTimeRestore.tsx @@ -13,7 +13,12 @@ import InfoTooltip from "../Components/InfoTooltip"; const tooltipContent = ( {ContainerCopyMessages.pointInTimeRestore.tooltip.content}   - + {ContainerCopyMessages.pointInTimeRestore.tooltip.hrefText} diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/__snapshots__/AddManagedIdentity.test.tsx.snap b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/__snapshots__/AddManagedIdentity.test.tsx.snap index a0d1c3033..2d6a2ffb3 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/__snapshots__/AddManagedIdentity.test.tsx.snap +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/AssignPermissions/__snapshots__/AddManagedIdentity.test.tsx.snap @@ -5,7 +5,7 @@ exports[`AddManagedIdentity Snapshot Tests renders initial state correctly 1`] = class="ms-Stack addManagedIdentityContainer css-109" > 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 don’t have to store any credentials in code.   @@ -92,7 +92,7 @@ exports[`AddManagedIdentity Snapshot Tests renders loading state 1`] = ` class="ms-Stack addManagedIdentityContainer css-109" > 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 don’t have to store any credentials in code.   @@ -192,13 +192,13 @@ exports[`AddManagedIdentity Snapshot Tests renders loading state 1`] = `
Enable system assigned managed identity Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button. @@ -261,7 +261,7 @@ exports[`AddManagedIdentity Snapshot Tests renders with toggle on and popover vi class="ms-Stack addManagedIdentityContainer css-109" > 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 don’t have to store any credentials in code.   @@ -345,13 +345,13 @@ exports[`AddManagedIdentity Snapshot Tests renders with toggle on and popover vi style="max-width: 450px;" > Enable system assigned managed identity Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button. diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/PopoverContainer.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/PopoverContainer.tsx index 5a76d66eb..6be20ef92 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/PopoverContainer.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/PopoverContainer.tsx @@ -22,10 +22,10 @@ const PopoverContainer: React.FC = React.memo( style={{ maxWidth: 450 }} > - + {title} - {children} + {children} diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/__snapshots__/PopoverContainer.test.tsx.snap b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/__snapshots__/PopoverContainer.test.tsx.snap index 978f38f5b..99b5ea8ce 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/__snapshots__/PopoverContainer.test.tsx.snap +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/Components/__snapshots__/PopoverContainer.test.tsx.snap @@ -7,11 +7,11 @@ exports[`PopoverMessage Component Edge Cases should handle empty string title 1` style="max-width: 450px;" >
Test content @@ -74,7 +74,7 @@ exports[`PopoverMessage Component Edge Cases should handle null children 1`] = ` style="max-width: 450px;" > Test Title @@ -136,7 +136,7 @@ exports[`PopoverMessage Component Edge Cases should handle undefined children 1` style="max-width: 450px;" > Test Title @@ -198,13 +198,13 @@ exports[`PopoverMessage Component Edge Cases should handle very long title 1`] = style="max-width: 450px;" > This is a very long title that might cause layout issues or text wrapping in the popover component
Test content @@ -269,13 +269,13 @@ exports[`PopoverMessage Component Rendering should render correctly when visible style="max-width: 450px;" > Test Title
Test content @@ -338,13 +338,13 @@ exports[`PopoverMessage Component Rendering should render correctly with differe style="max-width: 450px;" > Test Title

@@ -412,13 +412,13 @@ exports[`PopoverMessage Component Rendering should render correctly with differe style="max-width: 450px;" > Custom Title

Test content @@ -485,13 +485,13 @@ exports[`PopoverMessage Component Rendering should render correctly with loading data-testid="loading-overlay" /> Test Title
Test content diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/AddCollectionPanelWrapper.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/AddCollectionPanelWrapper.tsx index 01a2db73f..a274c9bbc 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/AddCollectionPanelWrapper.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/AddCollectionPanelWrapper.tsx @@ -41,7 +41,7 @@ const AddCollectionPanelWrapper: React.FunctionComponent - {ContainerCopyMessages.createNewContainerSubHeading} + {ContainerCopyMessages.createNewContainerSubHeading} diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/__snapshots__/AddCollectionPanelWrapper.test.tsx.snap b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/__snapshots__/AddCollectionPanelWrapper.test.tsx.snap index 6824baba9..ae6d7b4ec 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/__snapshots__/AddCollectionPanelWrapper.test.tsx.snap +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/CreateContainer/__snapshots__/AddCollectionPanelWrapper.test.tsx.snap @@ -9,7 +9,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot 1`] class="ms-StackItem addCollectionPanelHeader css-110" > Select the properties for your container. @@ -50,7 +50,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot wit class="ms-StackItem addCollectionPanelHeader css-110" > Select the properties for your container. @@ -91,7 +91,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot wit class="ms-StackItem addCollectionPanelHeader css-110" > Select the properties for your container. @@ -132,7 +132,7 @@ exports[`AddCollectionPanelWrapper Component Rendering should match snapshot wit class="ms-StackItem addCollectionPanelHeader css-110" > Select the properties for your container. diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/Components/MigrationTypeCheckbox.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/Components/MigrationTypeCheckbox.tsx index a72965fc6..34cb3743f 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/Components/MigrationTypeCheckbox.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/Components/MigrationTypeCheckbox.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/prop-types */ /* eslint-disable react/display-name */ -import { Checkbox, Stack } from "@fluentui/react"; +import { Checkbox, ICheckboxStyles, Stack } from "@fluentui/react"; import React from "react"; import ContainerCopyMessages from "../../../../ContainerCopyMessages"; @@ -9,8 +9,25 @@ interface MigrationTypeCheckboxProps { onChange: (_ev?: React.FormEvent, checked?: boolean) => void; } -export const MigrationTypeCheckbox: React.FC = React.memo(({ checked, onChange }) => ( - - - -)); +const checkboxStyles: ICheckboxStyles = { + text: { color: "var(--colorNeutralForeground1)" }, + checkbox: { borderColor: "var(--colorNeutralStroke1)" }, + root: { + selectors: { + ":hover .ms-Checkbox-text": { color: "var(--colorNeutralForeground1)" }, + }, + }, +}; + +export const MigrationTypeCheckbox: React.FC = React.memo(({ checked, onChange }) => { + return ( + + + + ); +}); diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/SelectAccount.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/SelectAccount.tsx index ba1072de7..1d7715f48 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/SelectAccount.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/SelectAccount.tsx @@ -21,7 +21,7 @@ const SelectAccount = React.memo(() => { return ( - {ContainerCopyMessages.selectAccountDescription} + {ContainerCopyMessages.selectAccountDescription} diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/__snapshots__/SelectAccount.test.tsx.snap b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/__snapshots__/SelectAccount.test.tsx.snap index 90a8ddc2b..b84b677cc 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/__snapshots__/SelectAccount.test.tsx.snap +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectAccount/__snapshots__/SelectAccount.test.tsx.snap @@ -6,7 +6,7 @@ exports[`SelectAccount Component Rendering should render correctly with snapshot data-test="Panel:SelectAccountContainer" > Please select a source account from which to copy. diff --git a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectSourceAndTargetContainers/SelectSourceAndTargetContainers.tsx b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectSourceAndTargetContainers/SelectSourceAndTargetContainers.tsx index 2dbb9d1df..26e1155c3 100644 --- a/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectSourceAndTargetContainers/SelectSourceAndTargetContainers.tsx +++ b/src/Explorer/ContainerCopy/CreateCopyJob/Screens/SelectSourceAndTargetContainers/SelectSourceAndTargetContainers.tsx @@ -48,7 +48,7 @@ const SelectSourceAndTargetContainers = ({ showAddCollectionPanel }: SelectSourc return ( - {ContainerCopyMessages.selectSourceAndTargetContainersDescription} + {ContainerCopyMessages.selectSourceAndTargetContainersDescription} {handleOnDemandCreateContainer && ( - handleOnDemandCreateContainer()}> + handleOnDemandCreateContainer()} + > {ContainerCopyMessages.createContainerButtonLabel} )} diff --git a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobDetails.tsx b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobDetails.tsx index f131cc4e5..63c7fcf46 100644 --- a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobDetails.tsx +++ b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobDetails.tsx @@ -1,5 +1,6 @@ import { DetailsList, DetailsListLayoutMode, IColumn, Stack, Text } from "@fluentui/react"; import React, { memo } from "react"; +import { useThemeStore } from "../../../../hooks/useTheme"; import ContainerCopyMessages from "../../ContainerCopyMessages"; import { CopyJobStatusType } from "../../Enums/CopyJobEnums"; import { CopyJobType } from "../../Types/CopyJobTypes"; @@ -63,6 +64,19 @@ const getCopyJobDetailsListColumns = (): IColumn[] => { }; const CopyJobDetails: React.FC = ({ 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 = [ { sourceContainerName: job?.Source?.containerName || "N/A", @@ -77,10 +91,10 @@ const CopyJobDetails: React.FC = ({ job }) => { {job.Error ? ( - + {ContainerCopyMessages.errorTitle} - + {job.Error.message} @@ -88,16 +102,16 @@ const CopyJobDetails: React.FC = ({ job }) => { - {ContainerCopyMessages.MonitorJobs.Columns.lastUpdatedTime} - {job.LastUpdatedTime} + {ContainerCopyMessages.MonitorJobs.Columns.lastUpdatedTime} + {job.LastUpdatedTime} - {ContainerCopyMessages.sourceAccountLabel} - {job.Source?.remoteAccountName} + {ContainerCopyMessages.sourceAccountLabel} + {job.Source?.remoteAccountName} - {ContainerCopyMessages.MonitorJobs.Columns.mode} - {job.Mode} + {ContainerCopyMessages.MonitorJobs.Columns.mode} + {job.Mode} diff --git a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobStatusWithIcon.tsx b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobStatusWithIcon.tsx index f4061a3b5..122e005c8 100644 --- a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobStatusWithIcon.tsx +++ b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobStatusWithIcon.tsx @@ -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 React from "react"; import ContainerCopyMessages from "../../ContainerCopyMessages"; import { CopyJobStatusType } from "../../Enums/CopyJobEnums"; -const theme = getTheme(); - const iconClass = mergeStyles({ fontSize: "16px", 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> = { [CopyJobStatusType.Pending]: "Clock", [CopyJobStatusType.Paused]: "CirclePause", @@ -35,6 +19,17 @@ const iconMap: Partial> = { [CopyJobStatusType.Completed]: "CompletedSolid", }; +// Icon colors for different statuses +const statusIconColors: Partial> = { + [CopyJobStatusType.Failed]: "var(--colorPaletteRedForeground1)", + [CopyJobStatusType.Faulted]: "var(--colorPaletteRedForeground1)", + [CopyJobStatusType.Completed]: "#107c10", // Green color for success + [CopyJobStatusType.InProgress]: "var(--colorBrandForeground1)", + [CopyJobStatusType.Running]: "var(--colorBrandForeground1)", + [CopyJobStatusType.Partitioning]: "var(--colorBrandForeground1)", + [CopyJobStatusType.Paused]: "var(--colorBrandForeground1)", +}; + export interface CopyJobStatusWithIconProps { status: CopyJobStatusType; } @@ -47,19 +42,17 @@ const CopyJobStatusWithIcon: React.FC = React.memo(( CopyJobStatusType.InProgress, CopyJobStatusType.Partitioning, ].includes(status); + const iconColor = statusIconColors[status] || "var(--colorNeutralForeground2)"; + const iconStyle = mergeStyles(iconClass, { color: iconColor }); return ( {isSpinnerStatus ? ( ) : ( - + )} - {statusText} + {statusText} ); }); diff --git a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobsList.tsx b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobsList.tsx index c1be75912..350a9432b 100644 --- a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobsList.tsx +++ b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/CopyJobsList.tsx @@ -15,6 +15,8 @@ import { } from "@fluentui/react"; import React, { useEffect } from "react"; import Pager from "../../../../Common/Pager"; +import { useThemeStore } from "../../../../hooks/useTheme"; +import { getThemeTokens } from "../../../Theme/ThemeUtil"; import { openCopyJobDetailsPanel } from "../../Actions/CopyJobActions"; import { CopyJobType, HandleJobActionClickType } from "../../Types/CopyJobTypes"; import { getColumns } from "./CopyJobColumns"; @@ -26,13 +28,15 @@ interface CopyJobsListProps { } const styles = { - container: { height: "calc(100vh - 25em)" } as React.CSSProperties, + container: { height: "100%" } as React.CSSProperties, stackItem: { position: "relative", marginBottom: "20px" } as React.CSSProperties, }; const PAGE_SIZE = 10; const CopyJobsList: React.FC = ({ jobs, handleActionClick, pageSize = PAGE_SIZE }) => { + const isDarkMode = useThemeStore((state) => state.isDarkMode); + const themeTokens = getThemeTokens(isDarkMode); const [startIndex, setStartIndex] = React.useState(0); const [sortedJobs, setSortedJobs] = React.useState(jobs); const [sortedColumnKey, setSortedColumnKey] = React.useState(undefined); @@ -87,11 +91,28 @@ const CopyJobsList: React.FC = ({ jobs, handleActionClick, pa enableShimmer={false} constrainMode={ConstrainMode.unconstrained} layoutMode={DetailsListLayoutMode.justified} - onRenderDetailsHeader={(props, defaultRender) => ( - - {defaultRender({ ...props })} - - )} + onRenderDetailsHeader={(props, defaultRender) => { + const bgColor = themeTokens.colorNeutralBackground3; + const textColor = themeTokens.colorNeutralForeground1; + return ( + +
+ {defaultRender({ + ...props, + styles: { + root: { + backgroundColor: bgColor, + selectors: { + ".ms-DetailsHeader-cellTitle": { color: textColor }, + ".ms-DetailsHeader-cellName": { color: textColor }, + }, + }, + }, + })} +
+
+ ); + }} />
diff --git a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/__snapshots__/CopyJobStatusWithIcon.test.tsx.snap b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/__snapshots__/CopyJobStatusWithIcon.test.tsx.snap index 9940ee7e9..d2e4482ce 100644 --- a/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/__snapshots__/CopyJobStatusWithIcon.test.tsx.snap +++ b/src/Explorer/ContainerCopy/MonitorCopyJobs/Components/__snapshots__/CopyJobStatusWithIcon.test.tsx.snap @@ -13,7 +13,7 @@ exports[`CopyJobStatusWithIcon Spinner Status Types renders InProgress with spin />
Running @@ -33,7 +33,7 @@ exports[`CopyJobStatusWithIcon Spinner Status Types renders Partitioning with sp />
Running @@ -53,7 +53,7 @@ exports[`CopyJobStatusWithIcon Spinner Status Types renders Running with spinner />
Running @@ -66,7 +66,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders > Cancelled @@ -87,7 +87,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders > Completed @@ -108,7 +108,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders > Failed @@ -129,7 +129,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders > Failed @@ -150,7 +150,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders > Paused @@ -171,7 +171,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders > Queued @@ -192,7 +192,7 @@ exports[`CopyJobStatusWithIcon Static Icon Status Types - Snapshot Tests renders > Cancelled diff --git a/src/Explorer/ContainerCopy/containerCopyStyles.less b/src/Explorer/ContainerCopy/containerCopyStyles.less index 05d9facec..14f004215 100644 --- a/src/Explorer/ContainerCopy/containerCopyStyles.less +++ b/src/Explorer/ContainerCopy/containerCopyStyles.less @@ -1,6 +1,30 @@ @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 { + background-color: var(--colorNeutralBackground1); + color: var(--colorNeutralForeground1); + .centerContent { justify-content: center; align-items: center; @@ -9,20 +33,30 @@ .noCopyJobsMessage { font-weight: 600; margin: 0 auto; - color: @FocusColor; + color: var(--colorNeutralForeground2); } button.createCopyJobButton { - color: @LinkColor; + color: var(--colorBrandForeground1); } } } .createCopyJobScreensContainer { height: 100%; padding: 1em 1.5em; + background-color: var(--colorNeutralBackground1); + color: var(--colorNeutralForeground1); .pointInTimeRestoreContainer, .onlineCopyContainer { position: relative; } + + .toggle-label { + color: var(--colorNeutralForeground1); + } + + .accordionHeaderText { + color: var(--colorNeutralForeground1); + } label { padding: 0; @@ -71,7 +105,7 @@ } .foreground { z-index: 10; - background-color: #f9f9f9; + background-color: var(--colorNeutralBackground2); padding: 20px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); transform: translate(0%, -9%); @@ -83,11 +117,12 @@ .create-container-link-btn { padding: 0; height: 25px; - color: @LinkColor; + color: var(--colorBrandForeground1); &:focus { outline: none; } + } /* Create collection panel */ @@ -105,7 +140,6 @@ width: 100%; max-width: 100%; margin: 0 auto; - .ms-DetailsList { width: 100%; @@ -114,33 +148,33 @@ padding: @DefaultSpace 20px; font-weight: 600; font-size: @DefaultFontSize; - color: @BaseHigh; - background-color: @BaseLow; - border-bottom: @ButtonBorderWidth solid @BaseMedium; + color: var(--colorNeutralForeground1); + background-color: var(--colorNeutralBackground2); + border-bottom: @ButtonBorderWidth solid var(--colorNeutralStroke1); &:hover { - background-color: @BaseMediumLow; + background-color: var(--colorNeutralBackground3); } } } .ms-DetailsRow { - border-bottom: @ButtonBorderWidth solid @BaseMedium; + border-bottom: @ButtonBorderWidth solid var(--colorNeutralStroke1); &:hover { - background-color: @BaseMediumLow; + background-color: var(--colorNeutralBackground2); } .ms-DetailsRow-cell { padding: @MediumSpace 20px; font-size: @DefaultFontSize; - color: @BaseHigh; + color: var(--colorNeutralForeground1); min-height: 48px; display: flex; align-items: center; .jobNameLink { - color: @LinkColor; + color: var(--colorBrandForeground1); text-overflow: ellipsis; white-space: nowrap; overflow: hidden; @@ -168,7 +202,7 @@ } .ms-DetailsRow-cell { font-size: @DefaultFontSize; - color: @BaseHigh; + color: var(--colorNeutralForeground1); } } } diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent.tsx index f49d60967..bd8f638cd 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent.tsx @@ -103,7 +103,10 @@ export const ThroughputBucketsComponent: FC = ( offText="Inactive" checked={bucket.maxThroughputPercentage !== 100} onChange={(event, checked) => onToggle(bucket.id, checked)} - styles={{ root: { marginBottom: 0 }, text: { fontSize: 12 } }} + styles={{ + root: { marginBottom: 0 }, + text: { fontSize: 12, color: "var(--colorNeutralForeground1)" }, + }} > ))} diff --git a/src/Explorer/Controls/VectorSearch/VectorEmbeddingPoliciesComponent.tsx b/src/Explorer/Controls/VectorSearch/VectorEmbeddingPoliciesComponent.tsx index ba0c5b62b..21aa1483c 100644 --- a/src/Explorer/Controls/VectorSearch/VectorEmbeddingPoliciesComponent.tsx +++ b/src/Explorer/Controls/VectorSearch/VectorEmbeddingPoliciesComponent.tsx @@ -53,6 +53,7 @@ type VectorEmbeddingPolicyProperty = "dataType" | "distanceFunction" | "indexTyp const labelStyles = { root: { fontSize: 12, + color: "var(--colorNeutralForeground1)", }, }; @@ -63,6 +64,8 @@ const textFieldStyles: IStyleFunctionOrObject - + Azure Synapse Link is required for creating an analytical store{" "} {getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account.
Azure Synapse Link is required for creating an analytical store diff --git a/src/Explorer/Panes/PanelLoadingScreen.tsx b/src/Explorer/Panes/PanelLoadingScreen.tsx index 8068b7945..a8b7856a8 100644 --- a/src/Explorer/Panes/PanelLoadingScreen.tsx +++ b/src/Explorer/Panes/PanelLoadingScreen.tsx @@ -2,7 +2,7 @@ import React from "react"; import LoadingIndicator_3Squares from "../../../images/LoadingIndicator_3Squares.gif"; export const PanelLoadingScreen: React.FunctionComponent = () => ( -
+
); diff --git a/src/less/DarkModeMenus.less b/src/less/DarkModeMenus.less index a0724ea5d..5b2ab9296 100644 --- a/src/less/DarkModeMenus.less +++ b/src/less/DarkModeMenus.less @@ -438,7 +438,6 @@ body.isDarkMode { button { &:not(.ms-Button):not(.ms-IconButton) { - background-color: var(--colorNeutralBackground1); color: var(--colorNeutralForeground1); &:hover {