mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Add extension API for using the same file browser dialog that's used for Restore (#24151)
Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
This commit is contained in:
21
src/sql/azdata.proposed.d.ts
vendored
21
src/sql/azdata.proposed.d.ts
vendored
@@ -2011,6 +2011,27 @@ declare module 'azdata' {
|
|||||||
*/
|
*/
|
||||||
isPrimary: boolean;
|
isPrimary: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FileFilters {
|
||||||
|
/**
|
||||||
|
* The label to display in the file filter field next to the list of filters.
|
||||||
|
*/
|
||||||
|
label: string;
|
||||||
|
/**
|
||||||
|
* The filters to limit what files are visible in the file browser (e.g. '*.sql' for SQL files).
|
||||||
|
*/
|
||||||
|
filters: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a dialog to select a file path on the specified server's machine. Note: The dialog for just browsing local
|
||||||
|
* files without any connection is opened via vscode.window.showOpenDialog.
|
||||||
|
* @param connectionUri The URI of the connection to the target server
|
||||||
|
* @param targetPath The file path on the server machine to open by default in the dialog
|
||||||
|
* @param fileFilters The filters used to limit which files are displayed in the file browser
|
||||||
|
* @returns The path of the file chosen from the dialog, and undefined if the dialog is closed without selecting anything.
|
||||||
|
*/
|
||||||
|
export function openServerFileBrowserDialog(connectionUri: string, targetPath: string, fileFilters: FileFilters[]): Thenable<string | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TableComponent {
|
export interface TableComponent {
|
||||||
|
|||||||
@@ -24,3 +24,4 @@ import './mainThreadResourceProvider';
|
|||||||
import './mainThreadErrorDiagnostics';
|
import './mainThreadErrorDiagnostics';
|
||||||
import './mainThreadTasks';
|
import './mainThreadTasks';
|
||||||
import './mainThreadWorkspace';
|
import './mainThreadWorkspace';
|
||||||
|
import './mainThreadWindow';
|
||||||
|
|||||||
36
src/sql/workbench/api/browser/mainThreadWindow.ts
Normal file
36
src/sql/workbench/api/browser/mainThreadWindow.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import type * as azdata from 'azdata';
|
||||||
|
import { MainThreadWindowShape } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
||||||
|
import { IFileBrowserDialogController } from 'sql/workbench/services/fileBrowser/common/fileBrowserDialogController';
|
||||||
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
import { SqlMainContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
|
import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
||||||
|
|
||||||
|
@extHostNamedCustomer(SqlMainContext.MainThreadWindow)
|
||||||
|
export class MainThreadWindow extends Disposable implements MainThreadWindowShape {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
extHostContext: IExtHostContext,
|
||||||
|
@IFileBrowserDialogController private _fileBrowserDialogService: IFileBrowserDialogController
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async $openServerFileBrowserDialog(connectionUri: string, targetPath: string, fileFilters: azdata.window.FileFilters[]): Promise<string | undefined> {
|
||||||
|
let completion = new Promise<string | undefined>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const handleOnClosed = (path: string | undefined) => {
|
||||||
|
resolve(path);
|
||||||
|
};
|
||||||
|
this._fileBrowserDialogService.showDialog(connectionUri, targetPath, fileFilters, '', true, handleOnClosed);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return await completion;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/sql/workbench/api/common/extHostWindow.ts
Normal file
23
src/sql/workbench/api/common/extHostWindow.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import type * as azdata from 'azdata';
|
||||||
|
import { IMainContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
|
|
||||||
|
import { ExtHostWindowShape, MainThreadWindowShape } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
||||||
|
import { SqlMainContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
|
|
||||||
|
export class ExtHostWindow implements ExtHostWindowShape {
|
||||||
|
|
||||||
|
private readonly _proxy: MainThreadWindowShape;
|
||||||
|
|
||||||
|
constructor(_mainContext: IMainContext) {
|
||||||
|
this._proxy = _mainContext.getProxy(SqlMainContext.MainThreadWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
$openServerFileBrowserDialog(connectionUri: string, targetPath: string, fileFilters: azdata.window.FileFilters[]): Promise<string | undefined> {
|
||||||
|
return this._proxy.$openServerFileBrowserDialog(connectionUri, targetPath, fileFilters);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,6 +42,7 @@ import { ExtHostAzureBlob } from 'sql/workbench/api/common/extHostAzureBlob';
|
|||||||
import { ExtHostAzureAccount } from 'sql/workbench/api/common/extHostAzureAccount';
|
import { ExtHostAzureAccount } from 'sql/workbench/api/common/extHostAzureAccount';
|
||||||
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
|
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
|
||||||
import { AuthenticationType } from 'sql/platform/connection/common/constants';
|
import { AuthenticationType } from 'sql/platform/connection/common/constants';
|
||||||
|
import { ExtHostWindow } from 'sql/workbench/api/common/extHostWindow';
|
||||||
|
|
||||||
export interface IAzdataExtensionApiFactory {
|
export interface IAzdataExtensionApiFactory {
|
||||||
(extension: IExtensionDescription): typeof azdata;
|
(extension: IExtensionDescription): typeof azdata;
|
||||||
@@ -102,6 +103,7 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
|
|||||||
const extHostNotebook = rpcProtocol.set(SqlExtHostContext.ExtHostNotebook, new ExtHostNotebook(rpcProtocol));
|
const extHostNotebook = rpcProtocol.set(SqlExtHostContext.ExtHostNotebook, new ExtHostNotebook(rpcProtocol));
|
||||||
const extHostExtensionManagement = rpcProtocol.set(SqlExtHostContext.ExtHostExtensionManagement, new ExtHostExtensionManagement(rpcProtocol));
|
const extHostExtensionManagement = rpcProtocol.set(SqlExtHostContext.ExtHostExtensionManagement, new ExtHostExtensionManagement(rpcProtocol));
|
||||||
const extHostWorkspace = rpcProtocol.set(SqlExtHostContext.ExtHostWorkspace, new ExtHostWorkspace(rpcProtocol));
|
const extHostWorkspace = rpcProtocol.set(SqlExtHostContext.ExtHostWorkspace, new ExtHostWorkspace(rpcProtocol));
|
||||||
|
const extHostWindow = rpcProtocol.set(SqlExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
|
||||||
return {
|
return {
|
||||||
azdata: function (extension: IExtensionDescription): typeof azdata {
|
azdata: function (extension: IExtensionDescription): typeof azdata {
|
||||||
// namespace: connection
|
// namespace: connection
|
||||||
@@ -480,6 +482,9 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
|
|||||||
MessageLevel: sqlExtHostTypes.MessageLevel,
|
MessageLevel: sqlExtHostTypes.MessageLevel,
|
||||||
openCustomErrorDialog(options: sqlExtHostTypes.IErrorDialogOptions): Thenable<string | undefined> {
|
openCustomErrorDialog(options: sqlExtHostTypes.IErrorDialogOptions): Thenable<string | undefined> {
|
||||||
return extHostModelViewDialog.openCustomErrorDialog(options);
|
return extHostModelViewDialog.openCustomErrorDialog(options);
|
||||||
|
},
|
||||||
|
openServerFileBrowserDialog(connectionUri: string, targetPath: string, fileFilters: azdata.window.FileFilters[]): Thenable<string | undefined> {
|
||||||
|
return extHostWindow.$openServerFileBrowserDialog(connectionUri, targetPath, fileFilters);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -827,12 +827,20 @@ export interface ExtHostWorkspaceShape {
|
|||||||
$saveAndEnterWorkspace(workspaceFile: vscode.Uri): Promise<void>;
|
$saveAndEnterWorkspace(workspaceFile: vscode.Uri): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ExtHostWindowShape {
|
||||||
|
$openServerFileBrowserDialog(connectionUri: string, targetPath: string, fileFilters: azdata.window.FileFilters[]): Promise<string | undefined>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MainThreadWorkspaceShape {
|
export interface MainThreadWorkspaceShape {
|
||||||
$createAndEnterWorkspace(folder: vscode.Uri, workspaceFile: vscode.Uri): Promise<void>;
|
$createAndEnterWorkspace(folder: vscode.Uri, workspaceFile: vscode.Uri): Promise<void>;
|
||||||
$enterWorkspace(workspaceFile: vscode.Uri): Promise<void>;
|
$enterWorkspace(workspaceFile: vscode.Uri): Promise<void>;
|
||||||
$saveAndEnterWorkspace(workspaceFile: vscode.Uri): Promise<void>;
|
$saveAndEnterWorkspace(workspaceFile: vscode.Uri): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MainThreadWindowShape {
|
||||||
|
$openServerFileBrowserDialog(connectionUri: string, targetPath: string, fileFilters: azdata.window.FileFilters[]): Promise<string | undefined>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MainThreadBackgroundTaskManagementShape extends IDisposable {
|
export interface MainThreadBackgroundTaskManagementShape extends IDisposable {
|
||||||
$registerTask(taskInfo: azdata.TaskInfo): void;
|
$registerTask(taskInfo: azdata.TaskInfo): void;
|
||||||
$updateTask(taskProgressInfo: azdata.TaskProgressInfo): void;
|
$updateTask(taskProgressInfo: azdata.TaskProgressInfo): void;
|
||||||
|
|||||||
@@ -766,7 +766,7 @@ export class BackupComponent extends AngularDisposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleFilePathAdded(filepath: string): void {
|
private handleFilePathAdded(filepath?: string): void {
|
||||||
if (filepath && !this.backupPathTypePairs![filepath]) {
|
if (filepath && !this.backupPathTypePairs![filepath]) {
|
||||||
if ((this.getBackupPathCount() < BackupConstants.maxDevices)) {
|
if ((this.getBackupPathCount() < BackupConstants.maxDevices)) {
|
||||||
this.backupPathTypePairs![filepath] = BackupConstants.MediaDeviceType.File;
|
this.backupPathTypePairs![filepath] = BackupConstants.MediaDeviceType.File;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export class FileBrowserDialogController implements IFileBrowserDialogController
|
|||||||
fileFilters: [{ label: string, filters: string[] }],
|
fileFilters: [{ label: string, filters: string[] }],
|
||||||
fileValidationServiceType: string,
|
fileValidationServiceType: string,
|
||||||
isWide: boolean,
|
isWide: boolean,
|
||||||
handleOnOk: (path: string) => void
|
handleOnClosed: (path: string | undefined) => void
|
||||||
): void {
|
): void {
|
||||||
if (!this._fileBrowserDialog) {
|
if (!this._fileBrowserDialog) {
|
||||||
this._fileBrowserDialog = this._instantiationService.createInstance(FileBrowserDialog, localize('filebrowser.selectFile', "Select a file"));
|
this._fileBrowserDialog = this._instantiationService.createInstance(FileBrowserDialog, localize('filebrowser.selectFile', "Select a file"));
|
||||||
@@ -33,7 +33,17 @@ export class FileBrowserDialogController implements IFileBrowserDialogController
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._fileBrowserDialog.setWide(isWide);
|
this._fileBrowserDialog.setWide(isWide);
|
||||||
this._fileBrowserDialog.onOk((filepath) => handleOnOk(filepath));
|
var onOK = this._fileBrowserDialog.onOk((filepath) => handleOnClosed(filepath));
|
||||||
|
var onClosed = this._fileBrowserDialog.onClosed((hideReason) => {
|
||||||
|
if (hideReason !== 'ok') {
|
||||||
|
handleOnClosed(undefined);
|
||||||
|
}
|
||||||
|
onOK.dispose();
|
||||||
|
onClosed.dispose();
|
||||||
|
this._fileBrowserDialog.dispose();
|
||||||
|
this._fileBrowserDialog = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
this._fileBrowserDialog.open(ownerUri, expandPath, fileFilters, fileValidationServiceType);
|
this._fileBrowserDialog.open(ownerUri, expandPath, fileFilters, fileValidationServiceType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ export interface IFileBrowserDialogController {
|
|||||||
fileFilters: { label: string, filters: string[] }[],
|
fileFilters: { label: string, filters: string[] }[],
|
||||||
fileValidationServiceType: string,
|
fileValidationServiceType: string,
|
||||||
isWide: boolean,
|
isWide: boolean,
|
||||||
handleOnOk: (path: string) => void): void;
|
handleOnOk: (path: string | undefined) => void): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -725,16 +725,18 @@ export class RestoreDialog extends Modal {
|
|||||||
.then(url => this._urlInputBox!.value = url);
|
.then(url => this._urlInputBox!.value = url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onFileBrowsed(filepath: string): void {
|
private onFileBrowsed(filepath?: string): void {
|
||||||
const oldFilePath = this._filePathInputBox!.value;
|
if (filepath) {
|
||||||
if (strings.isFalsyOrWhitespace(this._filePathInputBox!.value)) {
|
const oldFilePath = this._filePathInputBox!.value;
|
||||||
this._filePathInputBox!.value = filepath;
|
if (strings.isFalsyOrWhitespace(this._filePathInputBox!.value)) {
|
||||||
} else {
|
this._filePathInputBox!.value = filepath;
|
||||||
this._filePathInputBox!.value = this._filePathInputBox!.value + ', ' + filepath;
|
} else {
|
||||||
}
|
this._filePathInputBox!.value = this._filePathInputBox!.value + ', ' + filepath;
|
||||||
|
}
|
||||||
|
|
||||||
if (oldFilePath !== this._filePathInputBox!.value) {
|
if (oldFilePath !== this._filePathInputBox!.value) {
|
||||||
this.onFilePathChanged(this._filePathInputBox!.value);
|
this.onFilePathChanged(this._filePathInputBox!.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,11 +87,13 @@ import {
|
|||||||
MainThreadModalDialogShape, MainThreadModelViewDialogShape, MainThreadModelViewShape, MainThreadNotebookDocumentsAndEditorsShape,
|
MainThreadModalDialogShape, MainThreadModelViewDialogShape, MainThreadModelViewShape, MainThreadNotebookDocumentsAndEditorsShape,
|
||||||
MainThreadObjectExplorerShape, MainThreadQueryEditorShape, MainThreadResourceProviderShape, MainThreadErrorDiagnosticsShape, MainThreadTasksShape,
|
MainThreadObjectExplorerShape, MainThreadQueryEditorShape, MainThreadResourceProviderShape, MainThreadErrorDiagnosticsShape, MainThreadTasksShape,
|
||||||
MainThreadNotebookShape as SqlMainThreadNotebookShape, MainThreadWorkspaceShape as SqlMainThreadWorkspaceShape,
|
MainThreadNotebookShape as SqlMainThreadNotebookShape, MainThreadWorkspaceShape as SqlMainThreadWorkspaceShape,
|
||||||
|
MainThreadWindowShape as SqlMainThreadWindowShape,
|
||||||
ExtHostAccountManagementShape, ExtHostAzureAccountShape, ExtHostConnectionManagementShape, ExtHostCredentialManagementShape,
|
ExtHostAccountManagementShape, ExtHostAzureAccountShape, ExtHostConnectionManagementShape, ExtHostCredentialManagementShape,
|
||||||
ExtHostDataProtocolShape, ExtHostObjectExplorerShape, ExtHostResourceProviderShape, ExtHostErrorDiagnosticsShape, ExtHostModalDialogsShape, ExtHostTasksShape,
|
ExtHostDataProtocolShape, ExtHostObjectExplorerShape, ExtHostResourceProviderShape, ExtHostErrorDiagnosticsShape, ExtHostModalDialogsShape, ExtHostTasksShape,
|
||||||
ExtHostBackgroundTaskManagementShape, ExtHostDashboardWebviewsShape, ExtHostModelViewShape, ExtHostModelViewTreeViewsShape,
|
ExtHostBackgroundTaskManagementShape, ExtHostDashboardWebviewsShape, ExtHostModelViewShape, ExtHostModelViewTreeViewsShape,
|
||||||
ExtHostDashboardShape, ExtHostModelViewDialogShape, ExtHostQueryEditorShape, ExtHostExtensionManagementShape, ExtHostAzureBlobShape,
|
ExtHostDashboardShape, ExtHostModelViewDialogShape, ExtHostQueryEditorShape, ExtHostExtensionManagementShape, ExtHostAzureBlobShape,
|
||||||
ExtHostNotebookShape as SqlExtHostNotebookShape, ExtHostWorkspaceShape as SqlExtHostWorkspaceShape,
|
ExtHostNotebookShape as SqlExtHostNotebookShape, ExtHostWorkspaceShape as SqlExtHostWorkspaceShape,
|
||||||
|
ExtHostWindowShape as SqlExtHostWindowShape,
|
||||||
ExtHostNotebookDocumentsAndEditorsShape as SqlExtHostNotebookDocumentsAndEditorsShape,
|
ExtHostNotebookDocumentsAndEditorsShape as SqlExtHostNotebookDocumentsAndEditorsShape,
|
||||||
ExtHostPerfShape,
|
ExtHostPerfShape,
|
||||||
MainThreadPerfShape
|
MainThreadPerfShape
|
||||||
@@ -2684,7 +2686,8 @@ export const SqlMainContext = {
|
|||||||
MainThreadExtensionManagement: createProxyIdentifier<MainThreadExtensionManagementShape>('MainThreadExtensionManagement'),
|
MainThreadExtensionManagement: createProxyIdentifier<MainThreadExtensionManagementShape>('MainThreadExtensionManagement'),
|
||||||
MainThreadWorkspace: createProxyIdentifier<SqlMainThreadWorkspaceShape>('MainThreadWorkspace'),
|
MainThreadWorkspace: createProxyIdentifier<SqlMainThreadWorkspaceShape>('MainThreadWorkspace'),
|
||||||
MainThreadAzureBlob: createProxyIdentifier<MainThreadAzureBlobShape>('MainThreadAzureBlob'),
|
MainThreadAzureBlob: createProxyIdentifier<MainThreadAzureBlobShape>('MainThreadAzureBlob'),
|
||||||
MainThreadPerf: createProxyIdentifier<MainThreadPerfShape>('MainThreadPerf')
|
MainThreadPerf: createProxyIdentifier<MainThreadPerfShape>('MainThreadPerf'),
|
||||||
|
MainThreadWindow: createProxyIdentifier<SqlMainThreadWindowShape>('MainThreadWindow')
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SqlExtHostContext = {
|
export const SqlExtHostContext = {
|
||||||
@@ -2709,6 +2712,7 @@ export const SqlExtHostContext = {
|
|||||||
ExtHostNotebookDocumentsAndEditors: createProxyIdentifier<SqlExtHostNotebookDocumentsAndEditorsShape>('ExtHostNotebookDocumentsAndEditors'),
|
ExtHostNotebookDocumentsAndEditors: createProxyIdentifier<SqlExtHostNotebookDocumentsAndEditorsShape>('ExtHostNotebookDocumentsAndEditors'),
|
||||||
ExtHostExtensionManagement: createProxyIdentifier<ExtHostExtensionManagementShape>('ExtHostExtensionManagement'),
|
ExtHostExtensionManagement: createProxyIdentifier<ExtHostExtensionManagementShape>('ExtHostExtensionManagement'),
|
||||||
ExtHostWorkspace: createProxyIdentifier<SqlExtHostWorkspaceShape>('ExtHostWorkspace'),
|
ExtHostWorkspace: createProxyIdentifier<SqlExtHostWorkspaceShape>('ExtHostWorkspace'),
|
||||||
|
ExtHostWindow: createProxyIdentifier<SqlExtHostWindowShape>('ExtHostWindow'),
|
||||||
ExtHostAzureBlob: createProxyIdentifier<ExtHostAzureBlobShape>('ExtHostAzureBlob'),
|
ExtHostAzureBlob: createProxyIdentifier<ExtHostAzureBlobShape>('ExtHostAzureBlob'),
|
||||||
ExtHostPerf: createProxyIdentifier<ExtHostPerfShape>('ExtHostPerf')
|
ExtHostPerf: createProxyIdentifier<ExtHostPerfShape>('ExtHostPerf')
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user