Files
cosmos-explorer/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx
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

193 lines
7.4 KiB
TypeScript

/**
* This adapter is responsible to render the React component
* If the component signals a change through the callback passed in the properties, it must render the React component when appropriate
* and update any knockout observables passed from the parent.
*/
import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react";
import { makeStyles, useFluent } from "@fluentui/react-components";
import { useNotebook } from "Explorer/Notebook/useNotebook";
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
import { KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts";
import { isFabric } from "Platform/Fabric/FabricUtil";
import { userContext } from "UserContext";
import * as React from "react";
import create, { UseStore } from "zustand";
import { ConnectionStatusType, PoolIdType } from "../../../Common/Constants";
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
import Explorer from "../../Explorer";
import { useSelectedNode } from "../../useSelectedNode";
import * as CommandBarComponentButtonFactory from "./CommandBarComponentButtonFactory";
import * as CommandBarUtil from "./CommandBarUtil";
interface Props {
container: Explorer;
}
export interface CommandBarStore {
contextButtons: CommandButtonComponentProps[];
setContextButtons: (contextButtons: CommandButtonComponentProps[]) => void;
isHidden: boolean;
setIsHidden: (isHidden: boolean) => void;
}
export const useCommandBar: UseStore<CommandBarStore> = create((set) => ({
contextButtons: [] as CommandButtonComponentProps[],
setContextButtons: (contextButtons: CommandButtonComponentProps[]) => set((state) => ({ ...state, contextButtons })),
isHidden: false,
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) => {
const selectedNodeState = useSelectedNode();
const buttons = useCommandBar((state) => state.contextButtons);
const isHidden = useCommandBar((state) => state.isHidden);
// 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 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
const dataPlaneRbacEnabled = useDataPlaneRbac((state) => state.dataPlaneRbacEnabled);
const aadTokenUpdated = useDataPlaneRbac((state) => state.aadTokenUpdated);
// Memoize the expensive button creation
const staticButtons = React.useMemo(() => {
return CommandBarComponentButtonFactory.createStaticCommandBarButtons(container, selectedNodeState);
}, [container, selectedNodeState, dataPlaneRbacEnabled, aadTokenUpdated]);
if (userContext.apiType === "Postgres" || userContext.apiType === "VCoreMongo") {
const buttons =
userContext.apiType === "Postgres"
? CommandBarComponentButtonFactory.createPostgreButtons(container)
: CommandBarComponentButtonFactory.createVCoreMongoButtons(container);
return (
<div className={styles.commandBarContainer} style={{ display: isHidden ? "none" : "initial" }}>
<FluentCommandBar
ariaLabel="Use left and right arrow keys to navigate between commands"
items={CommandBarUtil.convertButton(buttons, "var(--colorNeutralBackground1)")}
styles={{
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
},
}}
overflowButtonProps={{ ariaLabel: "More commands" }}
/>
</div>
);
}
const contextButtons = (buttons || []).concat(
CommandBarComponentButtonFactory.createContextCommandBarButtons(container, selectedNodeState),
);
const controlButtons = CommandBarComponentButtonFactory.createControlCommandBarButtons(container);
const uiFabricStaticButtons = CommandBarUtil.convertButton(staticButtons, "var(--colorNeutralBackground1)");
if (buttons && buttons.length > 0) {
uiFabricStaticButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
}
const uiFabricTabsButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(
contextButtons,
"var(--colorNeutralBackground1)",
);
if (uiFabricTabsButtons.length > 0) {
uiFabricStaticButtons.push(CommandBarUtil.createDivider("commandBarDivider"));
}
const uiFabricControlButtons = CommandBarUtil.convertButton(controlButtons, "var(--colorNeutralBackground1)");
uiFabricControlButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
// Add connection status if needed (using the hook values we got at the top level)
if ((isPhoenixNotebooks || isPhoenixFeatures) && connectionInfo?.status !== ConnectionStatusType.Connect) {
uiFabricControlButtons.unshift(
CommandBarUtil.createConnectionStatus(container, PoolIdType.DefaultPoolId, "connectionStatus"),
);
}
const rootStyle = {
root: {
backgroundColor: "var(--colorNeutralBackground1)",
color: "var(--colorNeutralForeground1)",
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)",
color: "var(--colorNeutralForeground1)",
},
},
},
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 keyboardHandlers = CommandBarUtil.createKeyboardHandlers(allButtons);
setKeyboardHandlers(keyboardHandlers);
return (
<div className={styles.commandBarContainer} style={{ display: isHidden ? "none" : "initial" }}>
<FluentCommandBar
ariaLabel="Use left and right arrow keys to navigate between commands"
items={uiFabricStaticButtons.concat(uiFabricTabsButtons)}
farItems={uiFabricControlButtons}
styles={rootStyle}
overflowButtonProps={{ ariaLabel: "More commands" }}
/>
</div>
);
};