Compare commits

...

8 Commits

Author SHA1 Message Date
Ashley Stanton-Nurse
eed4df8c67 remove pr template 2024-04-03 09:36:16 -07:00
Ashley Stanton-Nurse
3418ce93ec post the preview URL, with PR number, as a PR comment during the build 2024-04-03 09:29:46 -07:00
sunghyunkang1111
3c5d899e47 add the new message to the bottom to avoid contract breaking (#1786) 2024-04-02 17:54:53 -05:00
Ashley Stanton-Nurse
b44778b00a fix #3061738 by unclobbering some Monaco styles we clobber (#1784) 2024-04-02 10:51:19 -07:00
sunghyunkang1111
1464745659 Add activate/close tab contracts and add to queryTab (#1783) 2024-04-02 11:49:33 -05:00
Asier Isayas
18cc2a4195 Activate Mongo and Cassandra Proxies in MPAC (#1776)
* Fix API endpoint for CassandraProxy query API

* activated mongo proxy

* added mpac

* Activate CassandraProxy API endpoints for MPAC

* Run npm format

* Set CASSANDRA_PROXY_OUTBOUND_IPS_ALLOWLISTED when we detect new
Cassandra Proxy endpoints in IP rules.

* query documents API fix

* simplify ip check

---------

Co-authored-by: Senthamil Sindhu <sindhuba@microsoft.com>
Co-authored-by: Asier Isayas <aisayas@microsoft.com>
Co-authored-by: Jade Welton <jawelton@microsoft.com>
2024-04-02 09:34:58 -07:00
sindhuba
86f2bc171f Remove notebooks UI (#1779)
* Fix API endpoint for CassandraProxy query API

* Remove notebooks UI components

* Fix tests

* Address comments

* Fix unit tests

* Remove commented code
2024-04-01 08:44:42 -07:00
jawelton74
cabedf4a29 Enable new backend endpoint to be passed to Data Explorer via message. (#1782) 2024-04-01 07:54:04 -07:00
16 changed files with 70 additions and 457 deletions

View File

@@ -1 +0,0 @@
[Preview this branch](https://cosmos-explorer-preview.azurewebsites.net/pull/EDIT_THIS_NUMBER_IN_THE_PR_DESCRIPTION?feature.someFeatureFlagYouMightNeed=true)

View File

@@ -101,6 +101,12 @@ jobs:
run: az storage blob upload -c '$web' -f ./preview/config.json --account-name cosmosexplorerpreview --name "${{github.event.pull_request.head.sha || github.sha}}/config.json" --account-key="${PREVIEW_STORAGE_KEY}" --overwrite true
env:
PREVIEW_STORAGE_KEY: ${{ secrets.PREVIEW_STORAGE_KEY }}
- name: Post a comment with the preview URL
if: ${{ github.event_name == 'pull_request' }}
run: gh pr comment $PR_NUMBER --body "Build complete. You can now [preview this branch in the portal](https://cosmos-explorer-preview.azurewebsites.net/pull/$PR_NUMBER?feature.someFeatureFlagYouMightNeed=true)"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
endtoendemulator:
name: "End To End Emulator Tests"
# Temporarily disabled. This test needs to be rewritten in playwright

View File

@@ -2296,6 +2296,17 @@ a:link {
display: none !important;
}
.monaco-editor .quick-input-list-label {
/* Restore some of Monaco's default styles that are clobbered by our global styles */
padding: 0;
line-height: 22px;
}
.monaco-editor .quick-input-list .highlight {
/* Padding in highlighted text within the quick input list breaks the flow of the text */
padding: 0;
}
td a {
color: #393939;
}

View File

@@ -67,7 +67,7 @@ export function queryDocuments(
query: string,
continuationToken?: string,
): Promise<QueryResponse> {
if (!useMongoProxyEndpoint("resourcelist")) {
if (!useMongoProxyEndpoint("resourcelist") || !useMongoProxyEndpoint("queryDocuments")) {
return queryDocuments_ToBeDeprecated(databaseId, collection, isResourceList, query, continuationToken);
}
@@ -106,7 +106,7 @@ export function queryDocuments(
headers[CosmosSDKConstants.HttpHeaders.Continuation] = continuationToken;
}
const path = isResourceList ? "/resourcelist" : "";
const path = isResourceList ? "/resourcelist" : "/queryDocuments";
return window
.fetch(`${endpoint}${path}`, {
@@ -690,7 +690,7 @@ export function getARMCreateCollectionEndpoint(params: DataModels.MongoParameter
}
function useMongoProxyEndpoint(api: string): boolean {
const activeMongoProxyEndpoints: string[] = [MongoProxyEndpoints.Development];
const activeMongoProxyEndpoints: string[] = [MongoProxyEndpoints.Development, MongoProxyEndpoints.Mpac];
let canAccessMongoProxy: boolean = userContext.databaseAccount.properties.publicNetworkAccess === "Enabled";
if (userContext.databaseAccount.properties.ipRules?.length > 0) {
canAccessMongoProxy = canAccessMongoProxy && configContext.MONGO_PROXY_OUTBOUND_IPS_ALLOWLISTED;

View File

@@ -102,21 +102,17 @@ let configContext: Readonly<ConfigContext> = {
NEW_BACKEND_APIS: [BackendApi.GenerateToken],
MONGO_PROXY_ENDPOINT: MongoProxyEndpoints.Prod,
NEW_MONGO_APIS: [
// "resourcelist",
// "createDocument",
// "readDocument",
// "updateDocument",
// "deleteDocument",
// "createCollectionWithProxy",
"resourcelist",
"queryDocuments",
"createDocument",
"readDocument",
"updateDocument",
"deleteDocument",
"createCollectionWithProxy",
],
MONGO_PROXY_OUTBOUND_IPS_ALLOWLISTED: false,
CASSANDRA_PROXY_ENDPOINT: CassandraProxyEndpoints.Prod,
NEW_CASSANDRA_APIS: [
// "postQuery",
// "createOrDelete",
// "getKeys",
// "getSchema",
],
NEW_CASSANDRA_APIS: ["postQuery", "createOrDelete", "getKeys", "getSchema"],
CASSANDRA_PROXY_OUTBOUND_IPS_ALLOWLISTED: false,
isTerminalEnabled: false,
isPhoenixEnabled: false,

View File

@@ -47,6 +47,7 @@ export enum MessageTypes {
GetAllResourceTokens, // Data Explorer -> Fabric
Ready, // Data Explorer -> Fabric
OpenCESCVAFeedbackBlade,
ActivateTab,
}
export interface AuthorizationToken {

View File

@@ -387,6 +387,7 @@ export interface DataExplorerInputsFrame {
dnsSuffix?: string;
serverId?: string;
extensionEndpoint?: string;
portalBackendEndpoint?: string;
mongoProxyEndpoint?: string;
cassandraProxyEndpoint?: string;
subscriptionType?: SubscriptionType;

View File

@@ -2,10 +2,8 @@ import * as ko from "knockout";
import { AuthType } from "../../../AuthType";
import { DatabaseAccount } from "../../../Contracts/DataModels";
import { CollectionBase } from "../../../Contracts/ViewModels";
import { GitHubOAuthService } from "../../../GitHub/GitHubOAuthService";
import { updateUserContext } from "../../../UserContext";
import Explorer from "../../Explorer";
import NotebookManager from "../../Notebook/NotebookManager";
import { useNotebook } from "../../Notebook/useNotebook";
import { useDatabases } from "../../useDatabases";
import { useSelectedNode } from "../../useSelectedNode";
@@ -72,181 +70,6 @@ describe("CommandBarComponentButtonFactory tests", () => {
});
});
describe("Enable notebook button", () => {
const enableNotebookBtnLabel = "Enable Notebooks (Preview)";
const selectedNodeState = useSelectedNode.getState();
beforeAll(() => {
mockExplorer = {} as Explorer;
updateUserContext({
portalEnv: "prod",
databaseAccount: {
properties: {
capabilities: [{ name: "EnableTable" }],
},
} as DatabaseAccount,
});
});
afterEach(() => {
updateUserContext({
portalEnv: "prod",
});
useNotebook.getState().setIsNotebookEnabled(false);
useNotebook.getState().setIsNotebooksEnabledForAccount(false);
});
it("Notebooks is already enabled - button should be hidden", () => {
useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel);
expect(enableNotebookBtn).toBeUndefined();
});
it("Account is running on one of the national clouds - button should be hidden", () => {
updateUserContext({
portalEnv: "mooncake",
});
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel);
expect(enableNotebookBtn).toBeUndefined();
});
it("Notebooks is not enabled but is available - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel);
//TODO: modify once notebooks are available
expect(enableNotebookBtn).toBeUndefined();
//expect(enableNotebookBtn).toBeDefined();
//expect(enableNotebookBtn.disabled).toBe(false);
//expect(enableNotebookBtn.tooltipText).toBe("");
});
it("Notebooks is not enabled and is unavailable - button should be shown and disabled", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel);
//TODO: modify once notebooks are available
expect(enableNotebookBtn).toBeUndefined();
//expect(enableNotebookBtn).toBeDefined();
//expect(enableNotebookBtn.disabled).toBe(true);
//expect(enableNotebookBtn.tooltipText).toBe(
// "Notebooks are not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks."
//);
});
});
describe("Open Mongo shell button", () => {
const openMongoShellBtnLabel = "Open Mongo shell";
const selectedNodeState = useSelectedNode.getState();
beforeAll(() => {
mockExplorer = {} as Explorer;
updateUserContext({
databaseAccount: {
properties: {
capabilities: [{ name: "EnableTable" }],
},
} as DatabaseAccount,
});
});
afterAll(() => {
updateUserContext({
apiType: "SQL",
});
useNotebook.getState().setIsShellEnabled(false);
});
beforeEach(() => {
updateUserContext({
apiType: "Mongo",
});
useNotebook.getState().setIsShellEnabled(true);
});
afterEach(() => {
useNotebook.getState().setIsNotebookEnabled(false);
useNotebook.getState().setIsNotebooksEnabledForAccount(false);
});
it("Mongo Api not available - button should be hidden", () => {
updateUserContext({
apiType: "SQL",
});
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeUndefined();
});
it("Running on a national cloud - button should be hidden", () => {
updateUserContext({
portalEnv: "mooncake",
});
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeUndefined();
});
it("Notebooks is not enabled and is unavailable - button should be hidden", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeUndefined();
});
it("Notebooks is not enabled and is available - button should be hidden", () => {
useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeUndefined();
});
it("Notebooks is enabled and is unavailable - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openMongoShellBtn.disabled).toBe(true);
//expect(openMongoShellBtn.disabled).toBe(false);
//expect(openMongoShellBtn.tooltipText).toBe("");
});
it("Notebooks is enabled and is available - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openMongoShellBtn.disabled).toBe(true);
//expect(openMongoShellBtn.disabled).toBe(false);
//expect(openMongoShellBtn.tooltipText).toBe("");
});
it("Notebooks is enabled and is available, terminal is unavailable due to ipRules - button should be hidden", () => {
useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsNotebooksEnabledForAccount(true);
useNotebook.getState().setIsShellEnabled(false);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeUndefined();
});
});
describe("Open Cassandra shell button", () => {
const openCassandraShellBtnLabel = "Open Cassandra shell";
const selectedNodeState = useSelectedNode.getState();
@@ -305,42 +128,6 @@ describe("CommandBarComponentButtonFactory tests", () => {
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeUndefined();
});
it("Notebooks is not enabled and is available - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeUndefined();
});
it("Notebooks is enabled and is unavailable - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openCassandraShellBtn.disabled).toBe(true);
//expect(openCassandraShellBtn.disabled).toBe(false);
//expect(openCassandraShellBtn.tooltipText).toBe("");
});
it("Notebooks is enabled and is available - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openCassandraShellBtn.disabled).toBe(true);
//expect(openCassandraShellBtn.disabled).toBe(false);
//expect(openCassandraShellBtn.tooltipText).toBe("");
});
});
describe("Open Postgres and vCore Mongo buttons", () => {
@@ -368,62 +155,6 @@ describe("CommandBarComponentButtonFactory tests", () => {
});
});
describe("GitHub buttons", () => {
const connectToGitHubBtnLabel = "Connect to GitHub";
const manageGitHubSettingsBtnLabel = "Manage GitHub settings";
const selectedNodeState = useSelectedNode.getState();
beforeAll(() => {
mockExplorer = {} as Explorer;
updateUserContext({
databaseAccount: {
properties: {
capabilities: [{ name: "EnableTable" }],
},
} as DatabaseAccount,
});
mockExplorer.notebookManager = new NotebookManager();
mockExplorer.notebookManager.gitHubOAuthService = new GitHubOAuthService(undefined);
});
afterEach(() => {
jest.resetAllMocks();
useNotebook.getState().setIsNotebookEnabled(false);
});
it("Notebooks is enabled and GitHubOAuthService is not logged in - connect to github button should be visible", () => {
useNotebook.getState().setIsNotebookEnabled(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const connectToGitHubBtn = buttons.find((button) => button.commandButtonLabel === connectToGitHubBtnLabel);
expect(connectToGitHubBtn).toBeDefined();
});
it("Notebooks is enabled and GitHubOAuthService is logged in - manage github settings button should be visible", () => {
useNotebook.getState().setIsNotebookEnabled(true);
mockExplorer.notebookManager.gitHubOAuthService.isLoggedIn = jest.fn().mockReturnValue(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const manageGitHubSettingsBtn = buttons.find(
(button) => button.commandButtonLabel === manageGitHubSettingsBtnLabel,
);
expect(manageGitHubSettingsBtn).toBeDefined();
});
it("Notebooks is not enabled - connect to github and manage github settings buttons should be hidden", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const connectToGitHubBtn = buttons.find((button) => button.commandButtonLabel === connectToGitHubBtnLabel);
expect(connectToGitHubBtn).toBeUndefined();
const manageGitHubSettingsBtn = buttons.find(
(button) => button.commandButtonLabel === manageGitHubSettingsBtnLabel,
);
expect(manageGitHubSettingsBtn).toBeUndefined();
});
});
describe("Resource token", () => {
const mockCollection = { id: ko.observable("test") } as CollectionBase;
useSelectedNode.getState().setSelectedNode(mockCollection);

View File

@@ -7,14 +7,10 @@ import AddStoredProcedureIcon from "../../../../images/AddStoredProcedure.svg";
import AddTriggerIcon from "../../../../images/AddTrigger.svg";
import AddUdfIcon from "../../../../images/AddUdf.svg";
import BrowseQueriesIcon from "../../../../images/BrowseQuery.svg";
import CosmosTerminalIcon from "../../../../images/Cosmos-Terminal.svg";
import FeedbackIcon from "../../../../images/Feedback-Command.svg";
import HomeIcon from "../../../../images/Home_16.svg";
import HostedTerminalIcon from "../../../../images/Hosted-Terminal.svg";
import OpenQueryFromDiskIcon from "../../../../images/OpenQueryFromDisk.svg";
import GitHubIcon from "../../../../images/github.svg";
import NewNotebookIcon from "../../../../images/notebook/Notebook-new.svg";
import ResetWorkspaceIcon from "../../../../images/notebook/Notebook-reset-workspace.svg";
import OpenInTabIcon from "../../../../images/open-in-tab.svg";
import SettingsIcon from "../../../../images/settings_15x15.svg";
import SynapseIcon from "../../../../images/synapse-link.svg";
@@ -22,7 +18,6 @@ import { AuthType } from "../../../AuthType";
import * as Constants from "../../../Common/Constants";
import { Platform, configContext } from "../../../ConfigContext";
import * as ViewModels from "../../../Contracts/ViewModels";
import { JunoClient } from "../../../Juno/JunoClient";
import { userContext } from "../../../UserContext";
import { getCollectionName, getDatabaseName } from "../../../Utils/APITypeUtils";
import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils";
@@ -33,7 +28,6 @@ import { useNotebook } from "../../Notebook/useNotebook";
import { OpenFullScreen } from "../../OpenFullScreen";
import { AddDatabasePanel } from "../../Panes/AddDatabasePanel/AddDatabasePanel";
import { BrowseQueriesPane } from "../../Panes/BrowseQueriesPane/BrowseQueriesPane";
import { GitHubReposPanel } from "../../Panes/GitHubReposPanel/GitHubReposPanel";
import { LoadQueryPane } from "../../Panes/LoadQueryPane/LoadQueryPane";
import { SettingsPane } from "../../Panes/SettingsPane/SettingsPane";
import { useDatabases } from "../../useDatabases";
@@ -80,57 +74,6 @@ export function createStaticCommandBarButtons(
}
}
if (useNotebook.getState().isNotebookEnabled) {
addDivider();
const notebookButtons: CommandButtonComponentProps[] = [];
const newNotebookButton = createNewNotebookButton(container);
newNotebookButton.children = [createNewNotebookButton(container), createuploadNotebookButton(container)];
notebookButtons.push(newNotebookButton);
if (container.notebookManager?.gitHubOAuthService) {
notebookButtons.push(createManageGitHubAccountButton(container));
}
if (useNotebook.getState().isPhoenixFeatures && configContext.isTerminalEnabled) {
notebookButtons.push(createOpenTerminalButton(container));
}
if (useNotebook.getState().isPhoenixNotebooks && selectedNodeState.isConnectedToContainer()) {
notebookButtons.push(createNotebookWorkspaceResetButton(container));
}
if (
(userContext.apiType === "Mongo" &&
useNotebook.getState().isShellEnabled &&
selectedNodeState.isDatabaseNodeOrNoneSelected()) ||
userContext.apiType === "Cassandra"
) {
notebookButtons.push(createDivider());
if (userContext.apiType === "Cassandra") {
notebookButtons.push(createOpenTerminalButtonByKind(container, ViewModels.TerminalKind.Cassandra));
} else {
notebookButtons.push(createOpenTerminalButtonByKind(container, ViewModels.TerminalKind.Mongo));
}
}
notebookButtons.forEach((btn) => {
if (btn.commandButtonLabel.indexOf("Cassandra") !== -1) {
if (!useNotebook.getState().isPhoenixFeatures) {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.cassandraShellTemporarilyDownMsg);
}
} else if (btn.commandButtonLabel.indexOf("Mongo") !== -1) {
if (!useNotebook.getState().isPhoenixFeatures) {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.mongoShellTemporarilyDownMsg);
}
} else if (btn.commandButtonLabel.indexOf("Open Terminal") !== -1) {
if (!useNotebook.getState().isPhoenixFeatures) {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.temporarilyDownMsg);
}
} else if (!useNotebook.getState().isPhoenixNotebooks) {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.temporarilyDownMsg);
}
buttons.push(btn);
});
}
if (!selectedNodeState.isDatabaseNodeOrNoneSelected()) {
const isQuerySupported = userContext.apiType === "SQL" || userContext.apiType === "Gremlin";
@@ -449,40 +392,6 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState)
return buttons;
}
function applyNotebooksTemporarilyDownStyle(buttonProps: CommandButtonComponentProps, tooltip: string): void {
if (!buttonProps.isDivider) {
buttonProps.disabled = true;
buttonProps.tooltipText = tooltip;
}
}
function createNewNotebookButton(container: Explorer): CommandButtonComponentProps {
const label = "New Notebook";
return {
id: "newNotebookBtn",
iconSrc: NewNotebookIcon,
iconAlt: label,
onCommandClick: () => container.onNewNotebookClicked(),
commandButtonLabel: label,
hasPopup: false,
disabled: useSelectedNode.getState().isQueryCopilotCollectionSelected(),
ariaLabel: label,
};
}
function createuploadNotebookButton(container: Explorer): CommandButtonComponentProps {
const label = "Upload to Notebook Server";
return {
iconSrc: NewNotebookIcon,
iconAlt: label,
onCommandClick: () => container.openUploadFilePanel(),
commandButtonLabel: label,
hasPopup: false,
disabled: useSelectedNode.getState().isQueryCopilotCollectionSelected(),
ariaLabel: label,
};
}
function createOpenQueryButton(container: Explorer): CommandButtonComponentProps {
const label = "Open Query";
return {
@@ -510,19 +419,6 @@ function createOpenQueryFromDiskButton(): CommandButtonComponentProps {
};
}
function createOpenTerminalButton(container: Explorer): CommandButtonComponentProps {
const label = "Open Terminal";
return {
iconSrc: CosmosTerminalIcon,
iconAlt: label,
onCommandClick: () => container.openNotebookTerminal(ViewModels.TerminalKind.Default),
commandButtonLabel: label,
hasPopup: false,
disabled: useSelectedNode.getState().isQueryCopilotCollectionSelected(),
ariaLabel: label,
};
}
function createOpenTerminalButtonByKind(
container: Explorer,
terminalKind: ViewModels.TerminalKind,
@@ -562,45 +458,6 @@ function createOpenTerminalButtonByKind(
};
}
function createNotebookWorkspaceResetButton(container: Explorer): CommandButtonComponentProps {
const label = "Reset Workspace";
return {
iconSrc: ResetWorkspaceIcon,
iconAlt: label,
onCommandClick: () => container.resetNotebookWorkspace(),
commandButtonLabel: label,
hasPopup: false,
disabled: useSelectedNode.getState().isQueryCopilotCollectionSelected(),
ariaLabel: label,
};
}
function createManageGitHubAccountButton(container: Explorer): CommandButtonComponentProps {
const connectedToGitHub: boolean = container.notebookManager?.gitHubOAuthService.isLoggedIn();
const label = connectedToGitHub ? "Manage GitHub settings" : "Connect to GitHub";
const junoClient = new JunoClient();
return {
iconSrc: GitHubIcon,
iconAlt: label,
onCommandClick: () => {
useSidePanel
.getState()
.openSidePanel(
label,
<GitHubReposPanel
explorer={container}
gitHubClientProp={container.notebookManager.gitHubClient}
junoClientProp={junoClient}
/>,
);
},
commandButtonLabel: label,
hasPopup: false,
disabled: useSelectedNode.getState().isQueryCopilotCollectionSelected(),
ariaLabel: label,
};
}
function createStaticCommandBarButtonsForResourceToken(
container: Explorer,
selectedNodeState: SelectedNodeState,

View File

@@ -19,7 +19,7 @@ import Explorer from "../Explorer";
import * as TableConstants from "./Constants";
import * as Entities from "./Entities";
import * as TableEntityProcessor from "./TableEntityProcessor";
import { CassandraProxyAPIs } from "../../Common/Constants";
import { CassandraProxyAPIs, CassandraProxyEndpoints } from "../../Common/Constants";
export interface CassandraTableKeys {
partitionKeys: CassandraTableKey[];
@@ -458,7 +458,7 @@ export class CassandraAPIDataClient extends TableDataClient {
}
public getTableKeys(collection: ViewModels.Collection): Q.Promise<CassandraTableKeys> {
if (!this.useCassandraProxyEndpoint("getTableKeys")) {
if (!this.useCassandraProxyEndpoint("getKeys")) {
return this.getTableKeys_ToBeDeprecated(collection);
}
@@ -732,6 +732,7 @@ export class CassandraAPIDataClient extends TableDataClient {
}
private useCassandraProxyEndpoint(api: string): boolean {
const activeCassandraProxyEndpoints: string[] = [CassandraProxyEndpoints.Development, CassandraProxyEndpoints.Mpac];
let canAccessCassandraProxy: boolean = userContext.databaseAccount.properties.publicNetworkAccess === "Enabled";
if (userContext.databaseAccount.properties.ipRules?.length > 0) {
canAccessCassandraProxy = canAccessCassandraProxy && configContext.CASSANDRA_PROXY_OUTBOUND_IPS_ALLOWLISTED;
@@ -740,9 +741,7 @@ export class CassandraAPIDataClient extends TableDataClient {
return (
canAccessCassandraProxy &&
configContext.NEW_CASSANDRA_APIS?.includes(api) &&
[Constants.CassandraProxyEndpoints.Development, Constants.CassandraProxyEndpoints.Mpac].includes(
configContext.CASSANDRA_PROXY_ENDPOINT,
)
activeCassandraProxyEndpoints.includes(configContext.CASSANDRA_PROXY_ENDPOINT)
);
}
}

View File

@@ -1,3 +1,5 @@
import { sendMessage } from "Common/MessageHandler";
import { MessageTypes } from "Contracts/MessageTypes";
import { CopilotProvider } from "Explorer/QueryCopilot/QueryCopilotContext";
import { userContext } from "UserContext";
import React from "react";
@@ -54,6 +56,11 @@ export class NewQueryTab extends TabsBase {
);
}
public onActivate(): void {
this.propagateTabInformation(MessageTypes.ActivateTab);
super.onActivate();
}
public onTabClick(): void {
useTabs.getState().activateTab(this);
this.iTabAccessor.onTabClickEvent();
@@ -61,6 +68,7 @@ export class NewQueryTab extends TabsBase {
public onCloseTabButtonClick(): void {
useTabs.getState().closeTab(this);
this.propagateTabInformation(MessageTypes.CloseTab);
if (this.iTabAccessor) {
this.iTabAccessor.onCloseClickEvent(true);
}
@@ -69,4 +77,15 @@ export class NewQueryTab extends TabsBase {
public getContainer(): Explorer {
return this.props.container;
}
private propagateTabInformation(type: MessageTypes): void {
sendMessage({
type,
data: {
kind: this.tabKind,
databaseId: this.collection?.databaseId,
collectionId: this.collection?.id?.(),
},
});
}
}

View File

@@ -134,7 +134,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
this.state = {
toggleState: ToggleState.Result,
sqlQueryEditorContent: props.queryText || "SELECT * FROM c",
sqlQueryEditorContent: props.isPreferredApiMongoDB ? "{}" : props.queryText || "SELECT * FROM c",
selectedContent: "",
queryResults: undefined,
error: "",

View File

@@ -327,10 +327,9 @@ const showMongoAndCassandraProxiesNetworkSettingsWarning = (): boolean => {
if ((userContext.apiType === "Mongo" || userContext.apiType === "Cassandra") && ipRules?.length) {
const legacyPortalBackendIPs: string[] = PortalBackendIPs[configContext.BACKEND_ENDPOINT];
const ipAddressesFromIPRules: string[] = ipRules.map((ipRule) => ipRule.ipAddressOrRange);
const ipRulesIncludeLegacyPortalBackend: boolean =
ipAddressesFromIPRules.filter((ipAddressFromIPRule) => legacyPortalBackendIPs.includes(ipAddressFromIPRule))
?.length === legacyPortalBackendIPs.length;
const ipRulesIncludeLegacyPortalBackend: boolean = legacyPortalBackendIPs.every((legacyPortalBackendIP: string) =>
ipAddressesFromIPRules.includes(legacyPortalBackendIP),
);
if (!ipRulesIncludeLegacyPortalBackend) {
return false;
}
@@ -344,9 +343,9 @@ const showMongoAndCassandraProxiesNetworkSettingsWarning = (): boolean => {
? [...MongoProxyOutboundIPs[MongoProxyEndpoints.Mpac], ...MongoProxyOutboundIPs[MongoProxyEndpoints.Prod]]
: MongoProxyOutboundIPs[configContext.MONGO_PROXY_ENDPOINT];
const ipRulesIncludeMongoProxy: boolean =
ipAddressesFromIPRules.filter((ipAddressFromIPRule) => mongoProxyOutboundIPs.includes(ipAddressFromIPRule))
?.length === mongoProxyOutboundIPs.length;
const ipRulesIncludeMongoProxy: boolean = mongoProxyOutboundIPs.every((mongoProxyOutboundIP: string) =>
ipAddressesFromIPRules.includes(mongoProxyOutboundIP),
);
if (ipRulesIncludeMongoProxy) {
updateConfigContext({
@@ -368,9 +367,15 @@ const showMongoAndCassandraProxiesNetworkSettingsWarning = (): boolean => {
]
: CassandraProxyOutboundIPs[configContext.CASSANDRA_PROXY_ENDPOINT];
const ipRulesIncludeCassandraProxy: boolean =
ipAddressesFromIPRules.filter((ipAddressFromIPRule) => cassandraProxyOutboundIPs.includes(ipAddressFromIPRule))
?.length === cassandraProxyOutboundIPs.length;
const ipRulesIncludeCassandraProxy: boolean = cassandraProxyOutboundIPs.every(
(cassandraProxyOutboundIP: string) => ipAddressesFromIPRules.includes(cassandraProxyOutboundIP),
);
if (ipRulesIncludeCassandraProxy) {
updateConfigContext({
CASSANDRA_PROXY_OUTBOUND_IPS_ALLOWLISTED: true,
});
}
return !ipRulesIncludeCassandraProxy;
}

View File

@@ -373,11 +373,6 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
iconSrc: NewNotebookIcon,
onClick: () => container.onCreateDirectory(item, isGithubTree),
},
{
label: "New Notebook",
iconSrc: NewNotebookIcon,
onClick: () => container.onNewNotebookClicked(item, isGithubTree),
},
{
label: "Upload File",
iconSrc: NewNotebookIcon,
@@ -786,9 +781,6 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
<AccordionItemComponent title={"DATA"} isExpanded={!gitHubNotebooksContentRoot}>
<TreeComponent className="dataResourceTree" rootNode={dataRootNode} />
</AccordionItemComponent>
<AccordionItemComponent title={"NOTEBOOKS"}>
<TreeComponent className="notebookResourceTree" rootNode={buildNotebooksTree()} />
</AccordionItemComponent>
</AccordionComponent>
{/* {buildGalleryCallout()} */}

View File

@@ -800,11 +800,6 @@ export class ResourceTreeAdapter implements ReactAdapter {
iconSrc: NewNotebookIcon,
onClick: () => this.container.onCreateDirectory(item),
},
{
label: "New Notebook",
iconSrc: NewNotebookIcon,
onClick: () => this.container.onNewNotebookClicked(item),
},
{
label: "Upload File",
iconSrc: NewNotebookIcon,

View File

@@ -497,6 +497,7 @@ function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) {
ARM_ENDPOINT: normalizeArmEndpoint(inputs.csmEndpoint || configContext.ARM_ENDPOINT),
MONGO_PROXY_ENDPOINT: inputs.mongoProxyEndpoint,
CASSANDRA_PROXY_ENDPOINT: inputs.cassandraProxyEndpoint,
PORTAL_BACKEND_ENDPOINT: inputs.portalBackendEndpoint,
});
updateUserContext({