diff --git a/packages/databricks-vscode/package.json b/packages/databricks-vscode/package.json index 8b1b590f1..e80a6062b 100644 --- a/packages/databricks-vscode/package.json +++ b/packages/databricks-vscode/package.json @@ -389,7 +389,7 @@ "view/item/context": [ { "command": "databricks.utils.openExternal", - "when": "view == configurationView && viewItem =~ /^databricks.configuration.(cluster|sync).*$/", + "when": "viewItem =~ /^databricks.*\\.(has-url).*$/", "group": "inline@1" }, { diff --git a/packages/databricks-vscode/resources/light/logo.svg b/packages/databricks-vscode/resources/light/logo.svg index 3fd304f7c..6b1398df7 100644 --- a/packages/databricks-vscode/resources/light/logo.svg +++ b/packages/databricks-vscode/resources/light/logo.svg @@ -1 +1,21 @@ - \ No newline at end of file + + + + + + + + + + + + + + + diff --git a/packages/databricks-vscode/src/configuration/ConnectionCommands.ts b/packages/databricks-vscode/src/configuration/ConnectionCommands.ts index 356e16ad2..5e3a9831e 100644 --- a/packages/databricks-vscode/src/configuration/ConnectionCommands.ts +++ b/packages/databricks-vscode/src/configuration/ConnectionCommands.ts @@ -67,7 +67,15 @@ export class ConnectionCommands implements Disposable { } async configureLoginCommand() { - await this.connectionManager.configureLogin(); + await window.withProgress( + { + location: {viewId: "configurationView"}, + title: "Configuring Databricks login", + }, + async () => { + await this.connectionManager.configureLogin(); + } + ); } openDatabricksConfigFileCommand() { diff --git a/packages/databricks-vscode/src/configuration/LoginWizard.ts b/packages/databricks-vscode/src/configuration/LoginWizard.ts index 07977726f..6aa35d317 100644 --- a/packages/databricks-vscode/src/configuration/LoginWizard.ts +++ b/packages/databricks-vscode/src/configuration/LoginWizard.ts @@ -1,4 +1,10 @@ -import {commands, QuickPickItem, QuickPickItemKind, window} from "vscode"; +import { + commands, + QuickPickItem, + QuickPickItemKind, + window, + ProgressLocation, +} from "vscode"; import { InputFlowAction, InputStep, @@ -136,11 +142,18 @@ export class LoginWizard { ); }) .map((profile) => { + const humanisedAuthType = humaniseSdkAuthType( + profile.authType + ); + const detail = humanisedAuthType + ? `Authenticate using ${humaniseSdkAuthType( + profile.authType + )}` + : `Authenticate using profile ${profile.name}`; + return { label: profile.name, - detail: `Authenticate using ${humaniseSdkAuthType( - profile.authType - )} from ${profile.name} profile`, + detail, authType: profile.authType as SdkAuthType, profile: profile.name, }; @@ -357,18 +370,28 @@ function humaniseSdkAuthType(sdkAuthType: string) { } export async function listProfiles(cliWrapper: CliWrapper) { - const profiles = ( - await cliWrapper.listProfiles(workspaceConfigs.databrickscfgLocation) - ).filter((profile) => { - try { - UrlUtils.normalizeHost(profile.host!.toString()); - return true; - } catch (e) { - return false; - } - }); + return await window.withProgress( + { + location: ProgressLocation.Notification, + title: "Loading Databricks profiles", + }, + async () => { + const profiles = ( + await cliWrapper.listProfiles( + workspaceConfigs.databrickscfgLocation + ) + ).filter((profile) => { + try { + UrlUtils.normalizeHost(profile.host!.toString()); + return true; + } catch (e) { + return false; + } + }); - return profiles; + return profiles; + } + ); } async function validateDatabricksHost( diff --git a/packages/databricks-vscode/src/configuration/ui/ClusterComponent.ts b/packages/databricks-vscode/src/configuration/ui/ClusterComponent.ts index b83f8c36a..47b662762 100644 --- a/packages/databricks-vscode/src/configuration/ui/ClusterComponent.ts +++ b/packages/databricks-vscode/src/configuration/ui/ClusterComponent.ts @@ -10,6 +10,7 @@ import { import {ConfigurationTreeItem} from "./types"; import {Cluster} from "../../sdk-extensions"; import {onError} from "../../utils/onErrorDecorator"; +import {LabelUtils} from "../../ui/bundle-resource-explorer/utils"; const TREE_ICON_ID = "CLUSTER"; function getContextValue(key: string) { @@ -116,15 +117,19 @@ export class ClusterComponent extends BaseComponent { return []; } const {icon, contextValue} = getTreeItemsForClusterState(cluster); - + const url = await cluster.url; return [ { - label: "Cluster", + label: url + ? "Cluster" + : LabelUtils.addModifiedTag("Cluster", "created"), + tooltip: url ? undefined : "Created after deploy", description: cluster.name, collapsibleState: TreeItemCollapsibleState.Expanded, - contextValue: contextValue, + contextValue: url ? `${contextValue}.has-url` : contextValue, iconPath: icon, id: TREE_ICON_ID, + url, }, ]; } diff --git a/packages/databricks-vscode/src/configuration/ui/SyncDestinationComponent.ts b/packages/databricks-vscode/src/configuration/ui/SyncDestinationComponent.ts index d66cd9b06..69c25598e 100644 --- a/packages/databricks-vscode/src/configuration/ui/SyncDestinationComponent.ts +++ b/packages/databricks-vscode/src/configuration/ui/SyncDestinationComponent.ts @@ -5,6 +5,7 @@ import {ConnectionManager} from "../ConnectionManager"; import {BaseComponent} from "./BaseComponent"; import {ConfigurationTreeItem} from "./types"; import {TreeItemCollapsibleState, ThemeIcon, ThemeColor} from "vscode"; +import {LabelUtils} from "../../ui/bundle-resource-explorer/utils"; const TREE_ICON_ID = "WORKSPACE"; function getContextValue(key: string) { @@ -70,10 +71,20 @@ export class SyncDestinationComponent extends BaseComponent { }), this.configModel.onDidChangeKey("remoteRootPath")(() => { this.onDidChangeEmitter.fire(); + }), + this.configModel.onDidChangeKey("remoteStateConfig")(() => { + this.onDidChangeEmitter.fire(); }) ); } + async getUrl() { + return this.connectionManager.workspaceClient + ? await this.connectionManager.syncDestinationMapper?.remoteUri.getUrl( + this.connectionManager.workspaceClient + ) + : undefined; + } private async getRoot(): Promise { const config = await this.configModel.get("remoteRootPath"); if (config === undefined) { @@ -86,19 +97,20 @@ export class SyncDestinationComponent extends BaseComponent { this.codeSynchronizer ); + const url = await this.getUrl(); + return [ { - label: "Sync", + label: url + ? "Sync" + : LabelUtils.addModifiedTag("Sync", "created"), + tooltip: url ? undefined : "Created after deploy", description: posix.basename(posix.dirname(config)), collapsibleState: TreeItemCollapsibleState.Expanded, - contextValue: contextValue, + contextValue: url ? `${contextValue}.has-url` : contextValue, iconPath: icon, id: TREE_ICON_ID, - url: this.connectionManager.workspaceClient - ? await this.connectionManager.syncDestinationMapper?.remoteUri.getUrl( - this.connectionManager.workspaceClient - ) - : undefined, + url: url, }, ]; } @@ -121,7 +133,6 @@ export class SyncDestinationComponent extends BaseComponent { if (workspaceFsPath === undefined) { return []; } - //TODO: Disable syncing for all targets (dev/staging/prod) const children: ConfigurationTreeItem[] = [ {