add new command bar behind a feature flag
This commit is contained in:
parent
7128133874
commit
53d3413c62
|
@ -2618,6 +2618,7 @@ a:link {
|
|||
.tabPanesContainer {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,14 @@
|
|||
/**
|
||||
* React component for Command button component.
|
||||
*/
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import { KeyboardAction } from "KeyboardShortcuts";
|
||||
import * as React from "react";
|
||||
import CollapseChevronDownIcon from "../../../../images/QueryBuilder/CollapseChevronDown_16x.png";
|
||||
import { KeyCodes } from "../../../Common/Constants";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import * as StringUtils from "../../../Utils/StringUtils";
|
||||
|
||||
/**
|
||||
* Options for this component
|
||||
*/
|
||||
export interface CommandButtonComponentProps {
|
||||
/**
|
||||
* font icon name for the button
|
||||
*/
|
||||
iconName?: string;
|
||||
|
||||
/**
|
||||
* image source for the button icon
|
||||
*/
|
||||
|
@ -31,7 +22,7 @@ export interface CommandButtonComponentProps {
|
|||
/**
|
||||
* Click handler for command button click
|
||||
*/
|
||||
onCommandClick?: (e: React.SyntheticEvent | KeyboardEvent) => void;
|
||||
onCommandClick?: (e: React.SyntheticEvent | KeyboardEvent, container: Explorer) => void;
|
||||
|
||||
/**
|
||||
* Label for the button
|
||||
|
@ -120,157 +111,3 @@ export interface CommandButtonComponentProps {
|
|||
*/
|
||||
keyboardAction?: KeyboardAction;
|
||||
}
|
||||
|
||||
export class CommandButtonComponent extends React.Component<CommandButtonComponentProps> {
|
||||
private dropdownElt: HTMLElement;
|
||||
private expandButtonElt: HTMLElement;
|
||||
|
||||
public componentDidUpdate(): void {
|
||||
if (!this.dropdownElt || !this.expandButtonElt) {
|
||||
return;
|
||||
}
|
||||
$(this.dropdownElt).offset({ left: $(this.expandButtonElt).offset().left });
|
||||
}
|
||||
|
||||
private onKeyPress(event: React.KeyboardEvent): boolean {
|
||||
if (event.keyCode === KeyCodes.Space || event.keyCode === KeyCodes.Enter) {
|
||||
this.commandClickCallback && this.commandClickCallback(event);
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private onLauncherKeyDown(event: React.KeyboardEvent<HTMLDivElement>): boolean {
|
||||
if (event.keyCode === KeyCodes.DownArrow) {
|
||||
$(this.dropdownElt).hide();
|
||||
$(this.dropdownElt).show().focus();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
if (event.keyCode === KeyCodes.UpArrow) {
|
||||
$(this.dropdownElt).hide();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private getCommandButtonId(): string {
|
||||
if (this.props.id) {
|
||||
return this.props.id;
|
||||
} else {
|
||||
return `commandButton-${StringUtils.stripSpacesFromString(this.props.commandButtonLabel)}`;
|
||||
}
|
||||
}
|
||||
|
||||
public static renderButton(options: CommandButtonComponentProps, key?: string): JSX.Element {
|
||||
return <CommandButtonComponent key={key} {...options} />;
|
||||
}
|
||||
|
||||
private commandClickCallback(e: React.SyntheticEvent): void {
|
||||
if (this.props.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Query component's parent, not document
|
||||
const el = document.querySelector(".commandDropdownContainer") as HTMLElement;
|
||||
if (el) {
|
||||
el.style.display = "none";
|
||||
}
|
||||
this.props.onCommandClick(e);
|
||||
TelemetryProcessor.trace(Action.SelectItem, ActionModifiers.Mark, {
|
||||
commandButtonClicked: this.props.commandButtonLabel,
|
||||
});
|
||||
}
|
||||
|
||||
private renderChildren(): JSX.Element {
|
||||
if (!this.props.children || this.props.children.length < 1) {
|
||||
return <React.Fragment />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="commandExpand"
|
||||
tabIndex={0}
|
||||
ref={(ref: HTMLElement) => {
|
||||
this.expandButtonElt = ref;
|
||||
}}
|
||||
onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => this.onLauncherKeyDown(e)}
|
||||
>
|
||||
<div className="commandDropdownLauncher">
|
||||
<span className="partialSplitter" />
|
||||
<span className="expandDropdown">
|
||||
<img src={CollapseChevronDownIcon} />
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="commandDropdownContainer"
|
||||
ref={(ref: HTMLElement) => {
|
||||
this.dropdownElt = ref;
|
||||
}}
|
||||
>
|
||||
<div className="commandDropdown">
|
||||
{this.props.children.map((c: CommandButtonComponentProps, index: number): JSX.Element => {
|
||||
return CommandButtonComponent.renderButton(c, `${index}`);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public static renderLabel(
|
||||
props: CommandButtonComponentProps,
|
||||
key?: string,
|
||||
refct?: (input: HTMLElement) => void,
|
||||
): JSX.Element {
|
||||
if (!props.commandButtonLabel) {
|
||||
return <React.Fragment />;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="commandLabel" key={key} ref={refct}>
|
||||
{props.commandButtonLabel}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
let mainClassName = "commandButtonComponent";
|
||||
if (this.props.disabled) {
|
||||
mainClassName += " commandDisabled";
|
||||
}
|
||||
if (this.props.isSelected) {
|
||||
mainClassName += " selectedButton";
|
||||
}
|
||||
|
||||
let contentClassName = "commandContent";
|
||||
if (this.props.children && this.props.children.length > 0) {
|
||||
contentClassName += " hasHiddenItems";
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="commandButtonReact">
|
||||
<span
|
||||
className={mainClassName}
|
||||
role="menuitem"
|
||||
tabIndex={this.props.tabIndex}
|
||||
onKeyPress={(e: React.KeyboardEvent<HTMLSpanElement>) => this.onKeyPress(e)}
|
||||
title={this.props.tooltipText}
|
||||
id={this.getCommandButtonId()}
|
||||
aria-disabled={this.props.disabled}
|
||||
aria-haspopup={this.props.hasPopup}
|
||||
aria-label={this.props.ariaLabel}
|
||||
onClick={(e: React.MouseEvent<HTMLSpanElement>) => this.commandClickCallback(e)}
|
||||
>
|
||||
<div className={contentClassName}>
|
||||
<img className="commandIcon" src={this.props.iconSrc} alt={this.props.iconAlt} />
|
||||
{CommandButtonComponent.renderLabel(this.props)}
|
||||
</div>
|
||||
</span>
|
||||
{this.props.children && this.renderChildren()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
ContainerVectorPolicyComponent,
|
||||
ContainerVectorPolicyComponentProps,
|
||||
} from "Explorer/Controls/Settings/SettingsSubComponents/ContainerVectorPolicyComponent";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { useDatabases } from "Explorer/useDatabases";
|
||||
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
||||
|
@ -32,7 +33,6 @@ import {
|
|||
PartitionKeyComponent,
|
||||
PartitionKeyComponentProps,
|
||||
} from "../../Controls/Settings/SettingsSubComponents/PartitionKeyComponent";
|
||||
import { useCommandBar } from "../../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { SettingsTabV2 } from "../../Tabs/SettingsTabV2";
|
||||
import "./SettingsComponent.less";
|
||||
import { mongoIndexingPolicyAADError } from "./SettingsRenderUtils";
|
||||
|
|
|
@ -107,7 +107,7 @@ export const TreeNodeComponent: React.FC<TreeNodeComponentProps> = ({
|
|||
|
||||
const onOpenChange = useCallback(
|
||||
(_: TreeOpenChangeEvent, data: TreeOpenChangeData) => {
|
||||
if (data.type === "Click" && !isBranch && node.onClick) {
|
||||
if (data.type === "Click" && node.onClick) {
|
||||
node.onClick();
|
||||
}
|
||||
if (!node.isExpanded && data.open && node.onExpanded) {
|
||||
|
@ -119,7 +119,7 @@ export const TreeNodeComponent: React.FC<TreeNodeComponentProps> = ({
|
|||
node.onCollapsed?.();
|
||||
}
|
||||
},
|
||||
[isBranch, node, setIsLoading],
|
||||
[node, setIsLoading],
|
||||
);
|
||||
|
||||
const onMenuOpenChange = useCallback(
|
||||
|
|
|
@ -5,6 +5,7 @@ import { Environment, getEnvironment } from "Common/EnvironmentUtility";
|
|||
import { sendMessage } from "Common/MessageHandler";
|
||||
import { Platform, configContext } from "ConfigContext";
|
||||
import { MessageTypes } from "Contracts/ExplorerContracts";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
|
||||
import { getCopilotEnabled, isCopilotFeatureRegistered } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||
import { IGalleryItem } from "Juno/JunoClient";
|
||||
|
@ -47,7 +48,6 @@ import { useTabs } from "../hooks/useTabs";
|
|||
import "./ComponentRegisterer";
|
||||
import { DialogProps, useDialog } from "./Controls/Dialog";
|
||||
import { GalleryTab as GalleryTabKind } from "./Controls/NotebookGallery/GalleryViewerComponent";
|
||||
import { useCommandBar } from "./Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import * as FileSystemUtil from "./Notebook/FileSystemUtil";
|
||||
import { SnapshotRequest } from "./Notebook/NotebookComponent/types";
|
||||
import { NotebookContentItem, NotebookContentItemType } from "./Notebook/NotebookContentItem";
|
||||
|
|
|
@ -4,83 +4,51 @@
|
|||
* and update any knockout observables passed from the parent.
|
||||
*/
|
||||
import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react";
|
||||
import {
|
||||
createPlatformButtons,
|
||||
createStaticCommandBarButtons,
|
||||
} from "Explorer/Menus/CommandBar/CommandBarComponentButtonFactory";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { useNotebook } from "Explorer/Notebook/useNotebook";
|
||||
import { KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts";
|
||||
import { userContext } from "UserContext";
|
||||
import * as React from "react";
|
||||
import create, { UseStore } from "zustand";
|
||||
import { ConnectionStatusType, PoolIdType } from "../../../Common/Constants";
|
||||
import { StyleConstants } from "../../../Common/StyleConstants";
|
||||
import { Platform, configContext } from "../../../ConfigContext";
|
||||
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: [],
|
||||
setContextButtons: (contextButtons: CommandButtonComponentProps[]) => set((state) => ({ ...state, contextButtons })),
|
||||
isHidden: false,
|
||||
setIsHidden: (isHidden: boolean) => set((state) => ({ ...state, isHidden })),
|
||||
}));
|
||||
|
||||
export const CommandBar: React.FC<Props> = ({ container }: Props) => {
|
||||
const selectedNodeState = useSelectedNode();
|
||||
const buttons = useCommandBar((state) => state.contextButtons);
|
||||
const contextButtons = useCommandBar((state) => state.contextButtons);
|
||||
const isHidden = useCommandBar((state) => state.isHidden);
|
||||
const backgroundColor = StyleConstants.BaseLight;
|
||||
const setKeyboardHandlers = useKeyboardActionGroup(KeyboardActionGroup.COMMAND_BAR);
|
||||
const staticButtons = createStaticCommandBarButtons(selectedNodeState);
|
||||
const platformButtons = createPlatformButtons();
|
||||
|
||||
if (userContext.apiType === "Postgres" || userContext.apiType === "VCoreMongo") {
|
||||
const buttons =
|
||||
userContext.apiType === "Postgres"
|
||||
? CommandBarComponentButtonFactory.createPostgreButtons(container)
|
||||
: CommandBarComponentButtonFactory.createVCoreMongoButtons(container);
|
||||
return (
|
||||
<div className="commandBarContainer" style={{ display: isHidden ? "none" : "initial" }}>
|
||||
<FluentCommandBar
|
||||
ariaLabel="Use left and right arrow keys to navigate between commands"
|
||||
items={CommandBarUtil.convertButton(buttons, backgroundColor)}
|
||||
styles={{
|
||||
root: { backgroundColor: backgroundColor },
|
||||
}}
|
||||
overflowButtonProps={{ ariaLabel: "More commands" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const staticButtons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(container, selectedNodeState);
|
||||
const contextButtons = (buttons || []).concat(
|
||||
CommandBarComponentButtonFactory.createContextCommandBarButtons(container, selectedNodeState),
|
||||
);
|
||||
const controlButtons = CommandBarComponentButtonFactory.createControlCommandBarButtons(container);
|
||||
|
||||
const uiFabricStaticButtons = CommandBarUtil.convertButton(staticButtons, backgroundColor);
|
||||
if (buttons && buttons.length > 0) {
|
||||
const uiFabricStaticButtons = CommandBarUtil.convertButton(staticButtons, backgroundColor, container);
|
||||
if (contextButtons?.length > 0) {
|
||||
uiFabricStaticButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
|
||||
}
|
||||
|
||||
const uiFabricTabsButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(contextButtons, backgroundColor);
|
||||
const uiFabricTabsButtons: ICommandBarItemProps[] = CommandBarUtil.convertButton(
|
||||
contextButtons || [],
|
||||
backgroundColor,
|
||||
container,
|
||||
);
|
||||
|
||||
if (uiFabricTabsButtons.length > 0) {
|
||||
uiFabricStaticButtons.push(CommandBarUtil.createDivider("commandBarDivider"));
|
||||
}
|
||||
|
||||
const uiFabricControlButtons = CommandBarUtil.convertButton(controlButtons, backgroundColor);
|
||||
uiFabricControlButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
|
||||
const uiFabricPlatformButtons = CommandBarUtil.convertButton(platformButtons || [], backgroundColor, container);
|
||||
uiFabricPlatformButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
|
||||
|
||||
const connectionInfo = useNotebook((state) => state.connectionInfo);
|
||||
|
||||
|
@ -88,7 +56,7 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
|
|||
(useNotebook.getState().isPhoenixNotebooks || useNotebook.getState().isPhoenixFeatures) &&
|
||||
connectionInfo?.status !== ConnectionStatusType.Connect
|
||||
) {
|
||||
uiFabricControlButtons.unshift(
|
||||
uiFabricPlatformButtons.unshift(
|
||||
CommandBarUtil.createConnectionStatus(container, PoolIdType.DefaultPoolId, "connectionStatus"),
|
||||
);
|
||||
}
|
||||
|
@ -107,8 +75,8 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
|
|||
},
|
||||
};
|
||||
|
||||
const allButtons = staticButtons.concat(contextButtons).concat(controlButtons);
|
||||
const keyboardHandlers = CommandBarUtil.createKeyboardHandlers(allButtons);
|
||||
const allButtons = staticButtons.concat(contextButtons).concat(platformButtons);
|
||||
const keyboardHandlers = CommandBarUtil.createKeyboardHandlers(allButtons, container);
|
||||
setKeyboardHandlers(keyboardHandlers);
|
||||
|
||||
return (
|
||||
|
@ -116,7 +84,7 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
|
|||
<FluentCommandBar
|
||||
ariaLabel="Use left and right arrow keys to navigate between commands"
|
||||
items={uiFabricStaticButtons.concat(uiFabricTabsButtons)}
|
||||
farItems={uiFabricControlButtons}
|
||||
farItems={uiFabricPlatformButtons}
|
||||
styles={rootStyle}
|
||||
overflowButtonProps={{ ariaLabel: "More commands" }}
|
||||
/>
|
||||
|
|
|
@ -3,15 +3,12 @@ import { AuthType } from "../../../AuthType";
|
|||
import { DatabaseAccount } from "../../../Contracts/DataModels";
|
||||
import { CollectionBase } from "../../../Contracts/ViewModels";
|
||||
import { updateUserContext } from "../../../UserContext";
|
||||
import Explorer from "../../Explorer";
|
||||
import { useNotebook } from "../../Notebook/useNotebook";
|
||||
import { useDatabases } from "../../useDatabases";
|
||||
import { useSelectedNode } from "../../useSelectedNode";
|
||||
import * as CommandBarComponentButtonFactory from "./CommandBarComponentButtonFactory";
|
||||
|
||||
describe("CommandBarComponentButtonFactory tests", () => {
|
||||
let mockExplorer: Explorer;
|
||||
|
||||
afterEach(() => useSelectedNode.getState().setSelectedNode(undefined));
|
||||
|
||||
describe("Enable Azure Synapse Link Button", () => {
|
||||
|
@ -19,7 +16,6 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
const selectedNodeState = useSelectedNode.getState();
|
||||
|
||||
beforeAll(() => {
|
||||
mockExplorer = {} as Explorer;
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
properties: {
|
||||
|
@ -30,7 +26,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
});
|
||||
|
||||
it("Button should be visible", () => {
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(selectedNodeState);
|
||||
const enableAzureSynapseLinkBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel,
|
||||
);
|
||||
|
@ -46,7 +42,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
} as DatabaseAccount,
|
||||
});
|
||||
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(selectedNodeState);
|
||||
const enableAzureSynapseLinkBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel,
|
||||
);
|
||||
|
@ -62,7 +58,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
} as DatabaseAccount,
|
||||
});
|
||||
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(selectedNodeState);
|
||||
const enableAzureSynapseLinkBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel,
|
||||
);
|
||||
|
@ -75,7 +71,6 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
const selectedNodeState = useSelectedNode.getState();
|
||||
|
||||
beforeAll(() => {
|
||||
mockExplorer = {} as Explorer;
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
properties: {
|
||||
|
@ -108,7 +103,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
},
|
||||
} as DatabaseAccount,
|
||||
});
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(selectedNodeState);
|
||||
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
|
||||
expect(openCassandraShellBtn).toBeUndefined();
|
||||
});
|
||||
|
@ -118,13 +113,13 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
portalEnv: "mooncake",
|
||||
});
|
||||
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(selectedNodeState);
|
||||
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
|
||||
expect(openCassandraShellBtn).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Notebooks is not enabled and is unavailable - button should be shown and disabled", () => {
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(selectedNodeState);
|
||||
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
|
||||
expect(openCassandraShellBtn).toBeUndefined();
|
||||
});
|
||||
|
@ -134,12 +129,8 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
const openPostgresShellButtonLabel = "Open PSQL shell";
|
||||
const openVCoreMongoShellButtonLabel = "Open MongoDB (vCore) shell";
|
||||
|
||||
beforeAll(() => {
|
||||
mockExplorer = {} as Explorer;
|
||||
});
|
||||
|
||||
it("creates Postgres shell button", () => {
|
||||
const buttons = CommandBarComponentButtonFactory.createPostgreButtons(mockExplorer);
|
||||
const buttons = CommandBarComponentButtonFactory.createPostgreButtons();
|
||||
const openPostgresShellButton = buttons.find(
|
||||
(button) => button.commandButtonLabel === openPostgresShellButtonLabel,
|
||||
);
|
||||
|
@ -147,7 +138,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
});
|
||||
|
||||
it("creates vCore Mongo shell button", () => {
|
||||
const buttons = CommandBarComponentButtonFactory.createVCoreMongoButtons(mockExplorer);
|
||||
const buttons = CommandBarComponentButtonFactory.createVCoreMongoButtons();
|
||||
const openVCoreMongoShellButton = buttons.find(
|
||||
(button) => button.commandButtonLabel === openVCoreMongoShellButtonLabel,
|
||||
);
|
||||
|
@ -162,8 +153,6 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
const selectedNodeState = useSelectedNode.getState();
|
||||
|
||||
beforeAll(() => {
|
||||
mockExplorer = {} as Explorer;
|
||||
|
||||
updateUserContext({
|
||||
authType: AuthType.ResourceToken,
|
||||
});
|
||||
|
@ -175,7 +164,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
|||
kind: "DocumentDB",
|
||||
} as DatabaseAccount,
|
||||
});
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(selectedNodeState);
|
||||
expect(buttons.length).toBe(2);
|
||||
expect(buttons[0].commandButtonLabel).toBe("New SQL Query");
|
||||
expect(buttons[0].disabled).toBe(false);
|
||||
|
|
|
@ -21,7 +21,6 @@ import { userContext } from "../../../UserContext";
|
|||
import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils";
|
||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import Explorer from "../../Explorer";
|
||||
import { useNotebook } from "../../Notebook/useNotebook";
|
||||
import { OpenFullScreen } from "../../OpenFullScreen";
|
||||
import { BrowseQueriesPane } from "../../Panes/BrowseQueriesPane/BrowseQueriesPane";
|
||||
|
@ -32,19 +31,20 @@ import { SelectedNodeState, useSelectedNode } from "../../useSelectedNode";
|
|||
|
||||
let counter = 0;
|
||||
|
||||
export function createStaticCommandBarButtons(
|
||||
container: Explorer,
|
||||
selectedNodeState: SelectedNodeState,
|
||||
): CommandButtonComponentProps[] {
|
||||
export function createStaticCommandBarButtons(selectedNodeState: SelectedNodeState): CommandButtonComponentProps[] {
|
||||
if (userContext.apiType === "Postgres" || userContext.apiType === "VCoreMongo") {
|
||||
return userContext.apiType === "Postgres" ? createPostgreButtons() : createVCoreMongoButtons();
|
||||
}
|
||||
|
||||
if (userContext.authType === AuthType.ResourceToken) {
|
||||
return createStaticCommandBarButtonsForResourceToken(container, selectedNodeState);
|
||||
return createStaticCommandBarButtonsForResourceToken(selectedNodeState);
|
||||
}
|
||||
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
// Avoid starting with a divider
|
||||
const addDivider = () => {
|
||||
if (buttons.length > 0) {
|
||||
if (buttons.length > 0 && !buttons[buttons.length - 1].isDivider) {
|
||||
buttons.push(createDivider());
|
||||
}
|
||||
};
|
||||
|
@ -54,7 +54,7 @@ export function createStaticCommandBarButtons(
|
|||
userContext.apiType !== "Tables" &&
|
||||
userContext.apiType !== "Cassandra"
|
||||
) {
|
||||
const addSynapseLink = createOpenSynapseLinkDialogButton(container);
|
||||
const addSynapseLink = createOpenSynapseLinkDialogButton();
|
||||
if (addSynapseLink) {
|
||||
addDivider();
|
||||
buttons.push(addSynapseLink);
|
||||
|
@ -67,9 +67,9 @@ export function createStaticCommandBarButtons(
|
|||
const aadTokenUpdated = useDataPlaneRbac((state) => state.aadTokenUpdated);
|
||||
|
||||
useEffect(() => {
|
||||
const buttonProps = createLoginForEntraIDButton(container);
|
||||
const buttonProps = createLoginForEntraIDButton();
|
||||
setLoginButtonProps(buttonProps);
|
||||
}, [dataPlaneRbacEnabled, aadTokenUpdated, container]);
|
||||
}, [dataPlaneRbacEnabled, aadTokenUpdated]);
|
||||
|
||||
if (loginButtonProps) {
|
||||
addDivider();
|
||||
|
@ -87,8 +87,8 @@ export function createStaticCommandBarButtons(
|
|||
}
|
||||
|
||||
if (isQuerySupported && selectedNodeState.findSelectedCollection() && configContext.platform !== Platform.Fabric) {
|
||||
const openQueryBtn = createOpenQueryButton(container);
|
||||
openQueryBtn.children = [createOpenQueryButton(container), createOpenQueryFromDiskButton()];
|
||||
const openQueryBtn = createOpenQueryButton();
|
||||
openQueryBtn.children = [createOpenQueryButton(), createOpenQueryFromDiskButton()];
|
||||
buttons.push(openQueryBtn);
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,7 @@ export function createStaticCommandBarButtons(
|
|||
selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
tooltipText: userContext.features.commandBarV2 ? "New..." : label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled:
|
||||
|
@ -115,21 +116,12 @@ export function createStaticCommandBarButtons(
|
|||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
export function createContextCommandBarButtons(
|
||||
container: Explorer,
|
||||
selectedNodeState: SelectedNodeState,
|
||||
): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
if (!selectedNodeState.isDatabaseNodeOrNoneSelected() && userContext.apiType === "Mongo") {
|
||||
const label = useNotebook.getState().isShellEnabled ? "Open Mongo Shell" : "New Shell";
|
||||
const newMongoShellBtn: CommandButtonComponentProps = {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
onCommandClick: (_, container) => {
|
||||
const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection();
|
||||
if (useNotebook.getState().isShellEnabled) {
|
||||
container.openNotebookTerminal(ViewModels.TerminalKind.Mongo);
|
||||
|
@ -141,6 +133,7 @@ export function createContextCommandBarButtons(
|
|||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
};
|
||||
addDivider();
|
||||
buttons.push(newMongoShellBtn);
|
||||
}
|
||||
|
||||
|
@ -153,25 +146,27 @@ export function createContextCommandBarButtons(
|
|||
const newCassandraShellButton: CommandButtonComponentProps = {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
onCommandClick: (_, container) => {
|
||||
container.openNotebookTerminal(ViewModels.TerminalKind.Cassandra);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
};
|
||||
addDivider();
|
||||
buttons.push(newCassandraShellButton);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
export function createControlCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
export function createPlatformButtons(): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [
|
||||
{
|
||||
iconSrc: SettingsIcon,
|
||||
iconAlt: "Settings",
|
||||
onCommandClick: () => useSidePanel.getState().openSidePanel("Settings", <SettingsPane explorer={container} />),
|
||||
onCommandClick: (_, container) =>
|
||||
useSidePanel.getState().openSidePanel("Settings", <SettingsPane explorer={container} />),
|
||||
commandButtonLabel: undefined,
|
||||
ariaLabel: "Settings",
|
||||
tooltipText: "Settings",
|
||||
|
@ -207,7 +202,7 @@ export function createControlCommandBarButtons(container: Explorer): CommandButt
|
|||
const feedbackButtonOptions: CommandButtonComponentProps = {
|
||||
iconSrc: FeedbackIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.openCESCVAFeedbackBlade(),
|
||||
onCommandClick: (_, container) => container.openCESCVAFeedbackBlade(),
|
||||
commandButtonLabel: undefined,
|
||||
ariaLabel: label,
|
||||
tooltipText: label,
|
||||
|
@ -239,7 +234,7 @@ function areScriptsSupported(): boolean {
|
|||
);
|
||||
}
|
||||
|
||||
function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||
function createOpenSynapseLinkDialogButton(): CommandButtonComponentProps {
|
||||
if (configContext.platform === Platform.Emulator) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -257,7 +252,7 @@ function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonCo
|
|||
return {
|
||||
iconSrc: SynapseIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.openEnableSynapseLinkDialog(),
|
||||
onCommandClick: (_, container) => container.openEnableSynapseLinkDialog(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled:
|
||||
|
@ -266,12 +261,12 @@ function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonCo
|
|||
};
|
||||
}
|
||||
|
||||
function createLoginForEntraIDButton(container: Explorer): CommandButtonComponentProps {
|
||||
function createLoginForEntraIDButton(): CommandButtonComponentProps {
|
||||
if (configContext.platform !== Platform.Portal) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const handleCommandClick = async () => {
|
||||
const handleCommandClick: CommandButtonComponentProps["onCommandClick"] = async (_, container) => {
|
||||
await container.openLoginForEntraIDPopUp();
|
||||
useDataPlaneRbac.setState({ dataPlaneRbacEnabled: true });
|
||||
};
|
||||
|
@ -398,13 +393,14 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState)
|
|||
return buttons;
|
||||
}
|
||||
|
||||
function createOpenQueryButton(container: Explorer): CommandButtonComponentProps {
|
||||
function createOpenQueryButton(): CommandButtonComponentProps {
|
||||
const label = "Open Query";
|
||||
return {
|
||||
iconSrc: BrowseQueriesIcon,
|
||||
iconAlt: label,
|
||||
tooltipText: userContext.features.commandBarV2 ? "Open Query..." : "Open Query",
|
||||
keyboardAction: KeyboardAction.OPEN_QUERY,
|
||||
onCommandClick: () =>
|
||||
onCommandClick: (_, container) =>
|
||||
useSidePanel.getState().openSidePanel("Open Saved Queries", <BrowseQueriesPane explorer={container} />),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
|
@ -427,10 +423,7 @@ function createOpenQueryFromDiskButton(): CommandButtonComponentProps {
|
|||
};
|
||||
}
|
||||
|
||||
function createOpenTerminalButtonByKind(
|
||||
container: Explorer,
|
||||
terminalKind: ViewModels.TerminalKind,
|
||||
): CommandButtonComponentProps {
|
||||
function createOpenTerminalButtonByKind(terminalKind: ViewModels.TerminalKind): CommandButtonComponentProps {
|
||||
const terminalFriendlyName = (): string => {
|
||||
switch (terminalKind) {
|
||||
case ViewModels.TerminalKind.Cassandra:
|
||||
|
@ -453,7 +446,7 @@ function createOpenTerminalButtonByKind(
|
|||
return {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
onCommandClick: (_, container) => {
|
||||
if (useNotebook.getState().isNotebookEnabled) {
|
||||
container.openNotebookTerminal(terminalKind);
|
||||
}
|
||||
|
@ -467,11 +460,10 @@ function createOpenTerminalButtonByKind(
|
|||
}
|
||||
|
||||
function createStaticCommandBarButtonsForResourceToken(
|
||||
container: Explorer,
|
||||
selectedNodeState: SelectedNodeState,
|
||||
): CommandButtonComponentProps[] {
|
||||
const newSqlQueryBtn = createNewSQLQueryButton(selectedNodeState);
|
||||
const openQueryBtn = createOpenQueryButton(container);
|
||||
const openQueryBtn = createOpenQueryButton();
|
||||
|
||||
const resourceTokenCollection: ViewModels.CollectionBase = useDatabases.getState().resourceTokenCollection;
|
||||
const isResourceTokenCollectionNodeSelected: boolean =
|
||||
|
@ -484,20 +476,20 @@ function createStaticCommandBarButtonsForResourceToken(
|
|||
|
||||
openQueryBtn.disabled = !isResourceTokenCollectionNodeSelected;
|
||||
if (!openQueryBtn.disabled) {
|
||||
openQueryBtn.children = [createOpenQueryButton(container), createOpenQueryFromDiskButton()];
|
||||
openQueryBtn.children = [createOpenQueryButton(), createOpenQueryFromDiskButton()];
|
||||
}
|
||||
|
||||
return [newSqlQueryBtn, openQueryBtn];
|
||||
}
|
||||
|
||||
export function createPostgreButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const openPostgreShellBtn = createOpenTerminalButtonByKind(container, ViewModels.TerminalKind.Postgres);
|
||||
export function createPostgreButtons(): CommandButtonComponentProps[] {
|
||||
const openPostgreShellBtn = createOpenTerminalButtonByKind(ViewModels.TerminalKind.Postgres);
|
||||
|
||||
return [openPostgreShellBtn];
|
||||
}
|
||||
|
||||
export function createVCoreMongoButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const openVCoreMongoTerminalButton = createOpenTerminalButtonByKind(container, ViewModels.TerminalKind.VCoreMongo);
|
||||
export function createVCoreMongoButtons(): CommandButtonComponentProps[] {
|
||||
const openVCoreMongoTerminalButton = createOpenTerminalButtonByKind(ViewModels.TerminalKind.VCoreMongo);
|
||||
|
||||
return [openVCoreMongoTerminalButton];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { ICommandBarItemProps } from "@fluentui/react";
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import * as CommandBarUtil from "./CommandBarUtil";
|
||||
|
||||
describe("CommandBarUtil tests", () => {
|
||||
const mockExplorer = {} as Explorer;
|
||||
const createButton = (): CommandButtonComponentProps => {
|
||||
return {
|
||||
iconSrc: "icon",
|
||||
|
@ -22,7 +24,7 @@ describe("CommandBarUtil tests", () => {
|
|||
const btn = createButton();
|
||||
const backgroundColor = "backgroundColor";
|
||||
|
||||
const converteds = CommandBarUtil.convertButton([btn], backgroundColor);
|
||||
const converteds = CommandBarUtil.convertButton([btn], backgroundColor, mockExplorer);
|
||||
expect(converteds.length).toBe(1);
|
||||
const converted = converteds[0];
|
||||
expect(converted.split).toBe(undefined);
|
||||
|
@ -46,7 +48,7 @@ describe("CommandBarUtil tests", () => {
|
|||
btn.children.push(child);
|
||||
}
|
||||
|
||||
const converteds = CommandBarUtil.convertButton([btn], "backgroundColor");
|
||||
const converteds = CommandBarUtil.convertButton([btn], "backgroundColor", mockExplorer);
|
||||
expect(converteds.length).toBe(1);
|
||||
const converted = converteds[0];
|
||||
expect(converted.split).toBe(true);
|
||||
|
@ -62,7 +64,7 @@ describe("CommandBarUtil tests", () => {
|
|||
btns.push(createButton());
|
||||
}
|
||||
|
||||
const converteds = CommandBarUtil.convertButton(btns, "backgroundColor");
|
||||
const converteds = CommandBarUtil.convertButton(btns, "backgroundColor", mockExplorer);
|
||||
const uniqueKeys = converteds
|
||||
.map((btn: ICommandBarItemProps) => btn.key)
|
||||
.filter((value: string, index: number, self: string[]) => self.indexOf(value) === index);
|
||||
|
@ -74,10 +76,10 @@ describe("CommandBarUtil tests", () => {
|
|||
const backgroundColor = "backgroundColor";
|
||||
|
||||
btn.commandButtonLabel = undefined;
|
||||
let converted = CommandBarUtil.convertButton([btn], backgroundColor)[0];
|
||||
let converted = CommandBarUtil.convertButton([btn], backgroundColor, mockExplorer)[0];
|
||||
expect(converted.text).toEqual(btn.tooltipText);
|
||||
|
||||
converted = CommandBarUtil.convertButton([btn], backgroundColor)[0];
|
||||
converted = CommandBarUtil.convertButton([btn], backgroundColor, mockExplorer)[0];
|
||||
delete btn.commandButtonLabel;
|
||||
expect(converted.text).toEqual(btn.tooltipText);
|
||||
});
|
||||
|
|
|
@ -25,7 +25,11 @@ import { MemoryTracker } from "./MemoryTrackerComponent";
|
|||
* Convert our NavbarButtonConfig to UI Fabric buttons
|
||||
* @param btns
|
||||
*/
|
||||
export const convertButton = (btns: CommandButtonComponentProps[], backgroundColor: string): ICommandBarItemProps[] => {
|
||||
export const convertButton = (
|
||||
btns: CommandButtonComponentProps[],
|
||||
backgroundColor: string,
|
||||
container: Explorer,
|
||||
): ICommandBarItemProps[] => {
|
||||
const buttonHeightPx =
|
||||
configContext.platform == Platform.Fabric
|
||||
? StyleConstants.FabricCommandBarButtonHeight
|
||||
|
@ -54,15 +58,14 @@ export const convertButton = (btns: CommandButtonComponentProps[], backgroundCol
|
|||
iconProps: {
|
||||
style: {
|
||||
width: StyleConstants.CommandBarIconWidth, // 16
|
||||
alignSelf: btn.iconName ? "baseline" : undefined,
|
||||
alignSelf: undefined,
|
||||
filter: getFilter(btn.disabled),
|
||||
},
|
||||
imageProps: btn.iconSrc ? { src: btn.iconSrc, alt: btn.iconAlt } : undefined,
|
||||
iconName: btn.iconName,
|
||||
},
|
||||
onClick: btn.onCommandClick
|
||||
? (ev?: React.MouseEvent<HTMLElement, MouseEvent> | React.KeyboardEvent<HTMLElement>) => {
|
||||
btn.onCommandClick(ev);
|
||||
btn.onCommandClick(ev, container);
|
||||
let copilotEnabled = false;
|
||||
if (useQueryCopilot.getState().copilotEnabled && useQueryCopilot.getState().copilotUserDBEnabled) {
|
||||
copilotEnabled = useQueryCopilot.getState().copilotEnabledforExecution;
|
||||
|
@ -135,7 +138,7 @@ export const convertButton = (btns: CommandButtonComponentProps[], backgroundCol
|
|||
result.split = true;
|
||||
|
||||
result.subMenuProps = {
|
||||
items: convertButton(btn.children, backgroundColor),
|
||||
items: convertButton(btn.children, backgroundColor, container),
|
||||
styles: {
|
||||
list: {
|
||||
// TODO Figure out how to do it the proper way with subComponentStyles.
|
||||
|
@ -186,7 +189,7 @@ export const convertButton = (btns: CommandButtonComponentProps[], backgroundCol
|
|||
option?: IDropdownOption,
|
||||
index?: number,
|
||||
): void => {
|
||||
btn.children[index].onCommandClick(event);
|
||||
btn.children[index].onCommandClick(event, container);
|
||||
TelemetryProcessor.trace(Action.ClickCommandBarButton, ActionModifiers.Mark, { label: option.text });
|
||||
};
|
||||
|
||||
|
@ -237,14 +240,17 @@ export const createConnectionStatus = (container: Explorer, poolId: PoolIdType,
|
|||
};
|
||||
};
|
||||
|
||||
export function createKeyboardHandlers(allButtons: CommandButtonComponentProps[]): KeyboardHandlerMap {
|
||||
export function createKeyboardHandlers(
|
||||
allButtons: CommandButtonComponentProps[],
|
||||
container: Explorer,
|
||||
): KeyboardHandlerMap {
|
||||
const handlers: KeyboardHandlerMap = {};
|
||||
|
||||
function createHandlers(buttons: CommandButtonComponentProps[]) {
|
||||
buttons.forEach((button) => {
|
||||
if (!button.disabled && button.keyboardAction) {
|
||||
handlers[button.keyboardAction] = (e) => {
|
||||
button.onCommandClick(e);
|
||||
button.onCommandClick(e, container);
|
||||
|
||||
// If the handler is bound, it means the button is visible and enabled, so we should prevent the default action
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||
import create, { UseStore } from "zustand";
|
||||
|
||||
export interface CommandBarStore {
|
||||
contextButtons: CommandButtonComponentProps[];
|
||||
setContextButtons: (contextButtons: CommandButtonComponentProps[]) => void;
|
||||
isHidden: boolean;
|
||||
setIsHidden: (isHidden: boolean) => void;
|
||||
}
|
||||
|
||||
export const useCommandBar: UseStore<CommandBarStore> = create((set) => ({
|
||||
contextButtons: [],
|
||||
setContextButtons: (contextButtons: CommandButtonComponentProps[]) => set((state) => ({ ...state, contextButtons })),
|
||||
isHidden: false,
|
||||
setIsHidden: (isHidden: boolean) => set((state) => ({ ...state, isHidden })),
|
||||
}));
|
|
@ -0,0 +1,159 @@
|
|||
import {
|
||||
makeStyles,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
MenuPopover,
|
||||
MenuTrigger,
|
||||
Toolbar,
|
||||
ToolbarButton,
|
||||
ToolbarDivider,
|
||||
ToolbarGroup,
|
||||
Tooltip,
|
||||
} from "@fluentui/react-components";
|
||||
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import {
|
||||
createPlatformButtons,
|
||||
createStaticCommandBarButtons,
|
||||
} from "Explorer/Menus/CommandBar/CommandBarComponentButtonFactory";
|
||||
import { createKeyboardHandlers } from "Explorer/Menus/CommandBar/CommandBarUtil";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { CosmosFluentProvider, cosmosShorthands, tokens } from "Explorer/Theme/ThemeUtil";
|
||||
import { useSelectedNode } from "Explorer/useSelectedNode";
|
||||
import { KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts";
|
||||
import React, { MouseEventHandler } from "react";
|
||||
|
||||
const useToolbarStyles = makeStyles({
|
||||
toolbar: {
|
||||
height: tokens.layoutRowHeight,
|
||||
justifyContent: "space-between", // Ensures that the two toolbar groups are at opposite ends of the toolbar
|
||||
...cosmosShorthands.borderBottom(),
|
||||
},
|
||||
toolbarGroup: {
|
||||
display: "flex",
|
||||
},
|
||||
});
|
||||
|
||||
export interface CommandBarV2Props {
|
||||
explorer: Explorer;
|
||||
}
|
||||
|
||||
export const CommandBarV2: React.FC<CommandBarV2Props> = ({ explorer }: CommandBarV2Props) => {
|
||||
const styles = useToolbarStyles();
|
||||
const selectedNodeState = useSelectedNode();
|
||||
const contextButtons = useCommandBar((state) => state.contextButtons);
|
||||
const isHidden = useCommandBar((state) => state.isHidden);
|
||||
const setKeyboardHandlers = useKeyboardActionGroup(KeyboardActionGroup.COMMAND_BAR);
|
||||
const staticButtons = createStaticCommandBarButtons(selectedNodeState);
|
||||
const platformButtons = createPlatformButtons();
|
||||
|
||||
if (isHidden) {
|
||||
setKeyboardHandlers({});
|
||||
return null;
|
||||
}
|
||||
|
||||
const allButtons = staticButtons.concat(contextButtons).concat(platformButtons);
|
||||
const keyboardHandlers = createKeyboardHandlers(allButtons, explorer);
|
||||
setKeyboardHandlers(keyboardHandlers);
|
||||
|
||||
return (
|
||||
<CosmosFluentProvider>
|
||||
<Toolbar className={styles.toolbar}>
|
||||
<ToolbarGroup role="presentation" className={styles.toolbarGroup}>
|
||||
{staticButtons.map((button, index) =>
|
||||
renderButton(explorer, button, `static-${index}`, contextButtons?.length > 0),
|
||||
)}
|
||||
{staticButtons.length > 0 && contextButtons?.length > 0 && <ToolbarDivider />}
|
||||
{contextButtons.map((button, index) => renderButton(explorer, button, `context-${index}`, false))}
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup role="presentation">
|
||||
{platformButtons.map((button, index) => renderButton(explorer, button, `platform-${index}`, true))}
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
</CosmosFluentProvider>
|
||||
);
|
||||
};
|
||||
|
||||
// This allows us to migrate individual buttons over to using a JSX.Element for the icon, without requiring us to change them all at once.
|
||||
function renderIcon(iconSrcOrElement: string | JSX.Element, alt?: string): JSX.Element {
|
||||
if (typeof iconSrcOrElement === "string") {
|
||||
return <img src={iconSrcOrElement} alt={alt} />;
|
||||
}
|
||||
return iconSrcOrElement;
|
||||
}
|
||||
|
||||
function renderButton(
|
||||
explorer: Explorer,
|
||||
btn: CommandButtonComponentProps,
|
||||
key: string,
|
||||
iconOnly: boolean,
|
||||
): JSX.Element {
|
||||
if (btn.isDivider) {
|
||||
return <ToolbarDivider key={key} />;
|
||||
}
|
||||
|
||||
const hasChildren = !!btn.children && btn.children.length > 0;
|
||||
const label = btn.commandButtonLabel || btn.tooltipText;
|
||||
const tooltip = btn.tooltipText || (iconOnly ? label : undefined);
|
||||
const onClick: MouseEventHandler | undefined =
|
||||
btn.onCommandClick && !hasChildren ? (e) => btn.onCommandClick(e, explorer) : undefined;
|
||||
|
||||
// We don't know which element will be the top-level element, so just slap a key on all of 'em
|
||||
|
||||
let button = hasChildren ? (
|
||||
<MenuButton key={key} appearance="subtle" aria-label={btn.ariaLabel} icon={renderIcon(btn.iconSrc, btn.iconAlt)}>
|
||||
{!iconOnly && label}
|
||||
</MenuButton>
|
||||
) : (
|
||||
<ToolbarButton key={key} aria-label={btn.ariaLabel} onClick={onClick} icon={renderIcon(btn.iconSrc, btn.iconAlt)}>
|
||||
{!iconOnly && label}
|
||||
</ToolbarButton>
|
||||
);
|
||||
|
||||
if (tooltip) {
|
||||
button = (
|
||||
<Tooltip key={key} content={tooltip} relationship="description" withArrow>
|
||||
{button}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
if (hasChildren) {
|
||||
button = (
|
||||
<Menu key={key}>
|
||||
<MenuTrigger disableButtonEnhancement>{button}</MenuTrigger>
|
||||
<MenuPopover>
|
||||
<MenuList>{btn.children.map((child, index) => renderMenuItem(explorer, child, index.toString()))}</MenuList>
|
||||
</MenuPopover>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
function renderMenuItem(explorer: Explorer, btn: CommandButtonComponentProps, key: string): JSX.Element {
|
||||
const hasChildren = !!btn.children && btn.children.length > 0;
|
||||
const onClick: MouseEventHandler | undefined = btn.onCommandClick
|
||||
? (e) => btn.onCommandClick(e, explorer)
|
||||
: undefined;
|
||||
const item = (
|
||||
<MenuItem key={key} onClick={onClick} icon={renderIcon(btn.iconSrc, btn.iconAlt)}>
|
||||
{btn.commandButtonLabel || btn.tooltipText}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
if (hasChildren) {
|
||||
return (
|
||||
<Menu>
|
||||
<MenuTrigger disableButtonEnhancement>{item}</MenuTrigger>
|
||||
<MenuPopover>
|
||||
<MenuList>{btn.children.map((child, index) => renderMenuItem(explorer, child, index.toString()))}</MenuList>
|
||||
</MenuPopover>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
return item;
|
||||
}
|
|
@ -3,7 +3,7 @@ import { Stack } from "@fluentui/react";
|
|||
import { QueryCopilotSampleContainerId, QueryCopilotSampleDatabaseId } from "Common/Constants";
|
||||
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { SaveQueryPane } from "Explorer/Panes/SaveQueryPane/SaveQueryPane";
|
||||
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||
import { readCopilotToggleStatus, saveCopilotToggleStatus } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Platform, updateConfigContext } from "ConfigContext";
|
|||
import { useDialog } from "Explorer/Controls/Dialog";
|
||||
import { EditorReactProps } from "Explorer/Controls/Editor/EditorReact";
|
||||
import { ProgressModalDialog } from "Explorer/Controls/ProgressModalDialog";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import {
|
||||
ButtonsDependencies,
|
||||
DELETE_BUTTON_ID,
|
||||
|
@ -461,7 +461,7 @@ describe("Documents tab (noSql API)", () => {
|
|||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
expect(wrapper.findWhere((node) => node.text().includes("replace_with_new_document_id")).exists()).toBeTruthy();
|
||||
});
|
||||
|
@ -471,7 +471,7 @@ describe("Documents tab (noSql API)", () => {
|
|||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === SAVE_BUTTON_ID)).toBeDefined();
|
||||
|
@ -483,7 +483,7 @@ describe("Documents tab (noSql API)", () => {
|
|||
await useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === DELETE_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
|
||||
expect(useDialog.getState().showOkCancelModalDialog).toHaveBeenCalled();
|
||||
|
@ -494,7 +494,7 @@ describe("Documents tab (noSql API)", () => {
|
|||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === DELETE_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
|
||||
expect(ProgressModalDialog).toHaveBeenCalled();
|
||||
|
@ -508,7 +508,7 @@ describe("Documents tab (noSql API)", () => {
|
|||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === DELETE_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
|
||||
// The implementation uses setTimeout, so wait for it to finish
|
||||
|
|
|
@ -28,7 +28,7 @@ import { useDialog } from "Explorer/Controls/Dialog";
|
|||
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||
import { ProgressModalDialog } from "Explorer/Controls/ProgressModalDialog";
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { querySampleDocuments, readSampleDocument } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
||||
import {
|
||||
ColumnsSelection,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { deleteDocuments } from "Common/MongoProxyClient";
|
||||
import { Platform, updateConfigContext } from "ConfigContext";
|
||||
import { EditorReactProps } from "Explorer/Controls/Editor/EditorReact";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import {
|
||||
DELETE_BUTTON_ID,
|
||||
DISCARD_BUTTON_ID,
|
||||
|
@ -163,7 +163,7 @@ describe("Documents tab (Mongo API)", () => {
|
|||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
expect(wrapper.findWhere((node) => node.text().includes("replace_with_new_document_id")).exists()).toBeTruthy();
|
||||
});
|
||||
|
@ -173,7 +173,7 @@ describe("Documents tab (Mongo API)", () => {
|
|||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === SAVE_BUTTON_ID)).toBeDefined();
|
||||
|
@ -188,7 +188,7 @@ describe("Documents tab (Mongo API)", () => {
|
|||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === DELETE_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
.onCommandClick(undefined, undefined);
|
||||
});
|
||||
|
||||
expect(mockDeleteDocuments).toHaveBeenCalled();
|
||||
|
|
|
@ -152,7 +152,6 @@ export default class NotebookTabV2 extends NotebookTabBase {
|
|||
ariaLabel: saveLabel,
|
||||
children: saveButtonChildren.length && [
|
||||
{
|
||||
iconName: "Save",
|
||||
onCommandClick: () => this.notebookComponentAdapter.notebookSave(),
|
||||
commandButtonLabel: saveLabel,
|
||||
hasPopup: false,
|
||||
|
|
|
@ -6,6 +6,7 @@ import { SplitterDirection } from "Common/Splitter";
|
|||
import { Platform, configContext } from "ConfigContext";
|
||||
import { useDialog } from "Explorer/Controls/Dialog";
|
||||
import { monaco } from "Explorer/LazyMonaco";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
|
||||
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
|
||||
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||
|
@ -54,7 +55,6 @@ import { useSidePanel } from "../../../hooks/useSidePanel";
|
|||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import { EditorReact } from "../../Controls/Editor/EditorReact";
|
||||
import Explorer from "../../Explorer";
|
||||
import { useCommandBar } from "../../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { BrowseQueriesPane } from "../../Panes/BrowseQueriesPane/BrowseQueriesPane";
|
||||
import { SaveQueryPane } from "../../Panes/SaveQueryPane/SaveQueryPane";
|
||||
import TabsBase from "../TabsBase";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Resource, StoredProcedureDefinition } from "@azure/cosmos";
|
||||
import { Pivot, PivotItem } from "@fluentui/react";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { KeyboardAction } from "KeyboardShortcuts";
|
||||
import React from "react";
|
||||
import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg";
|
||||
|
@ -15,7 +16,6 @@ import { useTabs } from "../../../hooks/useTabs";
|
|||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import { EditorReact } from "../../Controls/Editor/EditorReact";
|
||||
import Explorer from "../../Explorer";
|
||||
import { useCommandBar } from "../../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import StoredProcedure from "../../Tree/StoredProcedure";
|
||||
import { useSelectedNode } from "../../useSelectedNode";
|
||||
import ScriptTabBase from "../ScriptTabBase";
|
||||
|
|
|
@ -6,7 +6,8 @@ import { IpRule } from "Contracts/DataModels";
|
|||
import { MessageTypes } from "Contracts/ExplorerContracts";
|
||||
import { CollectionTabKind } from "Contracts/ViewModels";
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { CommandBarV2 } from "Explorer/Menus/CommandBarV2/CommandBarV2";
|
||||
import { QueryCopilotTab } from "Explorer/QueryCopilot/QueryCopilotTab";
|
||||
import { SplashScreen } from "Explorer/SplashScreen/SplashScreen";
|
||||
import { ConnectTab } from "Explorer/Tabs/ConnectTab";
|
||||
|
@ -106,6 +107,7 @@ export const Tabs = ({ explorer }: TabsProps): JSX.Element => {
|
|||
</ul>
|
||||
</div>
|
||||
<div className="tabPanesContainer">
|
||||
{userContext.features.commandBarV2 && <CommandBarV2 explorer={explorer} />}
|
||||
{activeReactTab !== undefined && getReactTabContent(activeReactTab, explorer)}
|
||||
{openedTabs.map((tab) => (
|
||||
<TabPane key={tab.tabId} tab={tab} active={activeTab === tab} />
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { KeyboardActionGroup, clearKeyboardActionGroup } from "KeyboardShortcuts";
|
||||
import * as ko from "knockout";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
|
@ -9,7 +10,6 @@ import { useNotificationConsole } from "../../hooks/useNotificationConsole";
|
|||
import { useTabs } from "../../hooks/useTabs";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import Explorer from "../Explorer";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { WaitsForTemplateViewModel } from "../WaitsForTemplateViewModel";
|
||||
import { useSelectedNode } from "../useSelectedNode";
|
||||
// TODO: Use specific actions for logging telemetry data
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { TriggerDefinition } from "@azure/cosmos";
|
||||
import { Dropdown, IDropdownOption, Label, TextField } from "@fluentui/react";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { KeyboardAction } from "KeyboardShortcuts";
|
||||
import React, { Component } from "react";
|
||||
import DiscardIcon from "../../../images/discard.svg";
|
||||
|
@ -14,7 +15,6 @@ import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
|||
import { SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import { EditorReact } from "../Controls/Editor/EditorReact";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import TriggerTab from "./TriggerTab";
|
||||
|
||||
const triggerTypeOptions: IDropdownOption[] = [
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { UserDefinedFunctionDefinition } from "@azure/cosmos";
|
||||
import { Label, TextField } from "@fluentui/react";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { KeyboardAction } from "KeyboardShortcuts";
|
||||
import React, { Component } from "react";
|
||||
import DiscardIcon from "../../../images/discard.svg";
|
||||
|
@ -13,7 +14,6 @@ import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
|||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import { EditorReact } from "../Controls/Editor/EditorReact";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import UserDefinedFunctionTab from "./UserDefinedFunctionTab";
|
||||
|
||||
interface IUserDefinedFunctionTabContentState {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Resource, StoredProcedureDefinition, TriggerDefinition, UserDefinedFunctionDefinition } from "@azure/cosmos";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { useNotebook } from "Explorer/Notebook/useNotebook";
|
||||
import { DocumentsTabV2 } from "Explorer/Tabs/DocumentsTabV2/DocumentsTabV2";
|
||||
import * as ko from "knockout";
|
||||
|
@ -23,7 +24,6 @@ import { logConsoleInfo } from "../../Utils/NotificationConsoleUtils";
|
|||
import { SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
|
||||
import { useTabs } from "../../hooks/useTabs";
|
||||
import Explorer from "../Explorer";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { CassandraAPIDataClient, CassandraTableKey, CassandraTableKeys } from "../Tables/TableDataClient";
|
||||
import ConflictsTab from "../Tabs/ConflictsTab";
|
||||
import GraphTab from "../Tabs/GraphTab";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { TreeNodeMenuItem } from "Explorer/Controls/TreeComponent/TreeNodeComponent";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { collectionWasOpened } from "Explorer/MostRecentActivity/MostRecentActivity";
|
||||
import { shouldShowScriptNodes } from "Explorer/Tree/treeNodeUtil";
|
||||
import { getItemName } from "Utils/APITypeUtils";
|
||||
|
@ -28,7 +29,6 @@ import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFacto
|
|||
import { useDialog } from "../Controls/Dialog";
|
||||
import { LegacyTreeComponent, LegacyTreeNode } from "../Controls/TreeComponent/LegacyTreeComponent";
|
||||
import Explorer from "../Explorer";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { NotebookContentItem, NotebookContentItemType } from "../Notebook/NotebookContentItem";
|
||||
import { NotebookUtil } from "../Notebook/NotebookUtil";
|
||||
import { useNotebook } from "../Notebook/useNotebook";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import TabsBase from "Explorer/Tabs/TabsBase";
|
||||
import { useSelectedNode } from "Explorer/useSelectedNode";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
|
|
|
@ -2,7 +2,7 @@ import { CapabilityNames } from "Common/Constants";
|
|||
import { Platform, updateConfigContext } from "ConfigContext";
|
||||
import { TreeNode } from "Explorer/Controls/TreeComponent/TreeNodeComponent";
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { useNotebook } from "Explorer/Notebook/useNotebook";
|
||||
import { DeleteDatabaseConfirmationPanel } from "Explorer/Panes/DeleteDatabaseConfirmationPanel";
|
||||
import TabsBase from "Explorer/Tabs/TabsBase";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { DatabaseRegular, DocumentMultipleRegular, SettingsRegular } from "@fluentui/react-icons";
|
||||
import { TreeNode } from "Explorer/Controls/TreeComponent/TreeNodeComponent";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/useCommandBar";
|
||||
import { collectionWasOpened } from "Explorer/MostRecentActivity/MostRecentActivity";
|
||||
import TabsBase from "Explorer/Tabs/TabsBase";
|
||||
import StoredProcedure from "Explorer/Tree/StoredProcedure";
|
||||
|
@ -17,7 +18,6 @@ import * as ViewModels from "../../Contracts/ViewModels";
|
|||
import { userContext } from "../../UserContext";
|
||||
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
||||
import Explorer from "../Explorer";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { useNotebook } from "../Notebook/useNotebook";
|
||||
import { useSelectedNode } from "../useSelectedNode";
|
||||
|
||||
|
|
|
@ -20,9 +20,11 @@ import "../externals/jquery.typeahead.min.css";
|
|||
import "../externals/jquery.typeahead.min.js";
|
||||
// Image Dependencies
|
||||
import { Platform } from "ConfigContext";
|
||||
import { CommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import { QueryCopilotCarousel } from "Explorer/QueryCopilot/CopilotCarousel";
|
||||
import { SidebarContainer } from "Explorer/Sidebar";
|
||||
import { KeyboardShortcutRoot } from "KeyboardShortcuts";
|
||||
import { userContext } from "UserContext";
|
||||
import "allotment/dist/style.css";
|
||||
import "../images/CosmosDB_rgb_ui_lighttheme.ico";
|
||||
import hdeConnectImage from "../images/HdeConnectCosmosDB.svg";
|
||||
|
@ -48,7 +50,6 @@ import "./Explorer/Controls/Notebook/NotebookTerminalComponent.less";
|
|||
import "./Explorer/Controls/TreeComponent/treeComponent.less";
|
||||
import "./Explorer/Graph/GraphExplorerComponent/graphExplorer.less";
|
||||
import "./Explorer/Menus/CommandBar/CommandBarComponent.less";
|
||||
import { CommandBar } from "./Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import "./Explorer/Menus/CommandBar/ConnectionStatusComponent.less";
|
||||
import "./Explorer/Menus/CommandBar/MemoryTrackerComponent.less";
|
||||
import "./Explorer/Menus/NotificationConsole/NotificationConsole.less";
|
||||
|
@ -86,7 +87,7 @@ const App: React.FunctionComponent = () => {
|
|||
<div id="divExplorer" className="flexContainer hideOverflows">
|
||||
<div id="freeTierTeachingBubble"> </div>
|
||||
{/* Main Command Bar - Start */}
|
||||
<CommandBar container={explorer} />
|
||||
{!userContext.features.commandBarV2 && <CommandBar container={explorer} />}
|
||||
{/* Collections Tree and Tabs - Begin */}
|
||||
<SidebarContainer explorer={explorer} />
|
||||
{/* Collections Tree and Tabs - End */}
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
import * as React from "react";
|
||||
import { CommandButtonComponent } from "../../../Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||
import FeedbackIcon from "../../../../images/Feedback.svg";
|
||||
|
||||
export const FeedbackCommandButton: React.FunctionComponent = () => {
|
||||
const onClick = () => {
|
||||
window.open("https://aka.ms/cosmosdbfeedback?subject=Cosmos%20DB%20Hosted%20Data%20Explorer%20Feedback");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="feedbackConnectSettingIcons">
|
||||
<CommandButtonComponent
|
||||
id="commandbutton-feedback"
|
||||
iconSrc={FeedbackIcon}
|
||||
iconAlt="feeback button"
|
||||
onCommandClick={() =>
|
||||
window.open("https://aka.ms/cosmosdbfeedback?subject=Cosmos%20DB%20Hosted%20Data%20Explorer%20Feedback")
|
||||
}
|
||||
ariaLabel="feeback button"
|
||||
tooltipText="Send feedback"
|
||||
hasPopup={true}
|
||||
disabled={false}
|
||||
/>
|
||||
<div className="commandButtonReact">
|
||||
<a href="#" title="Send feedback" aria-haspopup="dialog" onClick={onClick}>
|
||||
<img src={FeedbackIcon} alt="Send feedback" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@ export type Features = {
|
|||
readonly copilotChatFixedMonacoEditorHeight: boolean;
|
||||
readonly enablePriorityBasedExecution: boolean;
|
||||
readonly disableConnectionStringLogin: boolean;
|
||||
readonly commandBarV2: boolean;
|
||||
|
||||
// can be set via both flight and feature flag
|
||||
autoscaleDefault: boolean;
|
||||
|
@ -108,6 +109,7 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
|
|||
copilotChatFixedMonacoEditorHeight: "true" === get("copilotchatfixedmonacoeditorheight"),
|
||||
enablePriorityBasedExecution: "true" === get("enableprioritybasedexecution"),
|
||||
disableConnectionStringLogin: "true" === get("disableconnectionstringlogin"),
|
||||
commandBarV2: "true" === get("commandbarv2"),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue